From 09f789869f27202ffe2fdaa49ba2836dbb57e70c Mon Sep 17 00:00:00 2001 From: weidong Date: Wed, 31 Dec 2025 08:54:07 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9EFT32F407XE=E5=BC=80=E5=8F=91?= =?UTF-8?q?=E6=9D=BF=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/ALL_BSP_COMPILE.json | 1 + bsp/ft32/ft32f072xb-starter/project.uvprojx | 1331 +- bsp/ft32/ft32f407xe-starter/.config | 1417 ++ bsp/ft32/ft32f407xe-starter/.gitignore | 42 + bsp/ft32/ft32f407xe-starter/Kconfig | 13 + bsp/ft32/ft32f407xe-starter/README.md | 53 + bsp/ft32/ft32f407xe-starter/SConscript | 15 + bsp/ft32/ft32f407xe-starter/SConstruct | 60 + .../applications/SConscript | 9 + .../ft32f407xe-starter/applications/main.c | 30 + bsp/ft32/ft32f407xe-starter/board/Kconfig | 52 + bsp/ft32/ft32f407xe-starter/board/SConscript | 29 + bsp/ft32/ft32f407xe-starter/board/board.c | 153 + bsp/ft32/ft32f407xe-starter/board/board.h | 57 + .../board/linker_scripts/link.icf | 34 + .../board/linker_scripts/link.lds | 157 + .../board/linker_scripts/link.sct | 15 + .../figures/ft32f407xe-starter.jpg | Bin 0 -> 831855 bytes bsp/ft32/ft32f407xe-starter/project.uvprojx | 2275 ++ bsp/ft32/ft32f407xe-starter/rtconfig.h | 413 + bsp/ft32/ft32f407xe-starter/rtconfig.py | 185 + bsp/ft32/ft32f407xe-starter/template.uvprojx | 397 + bsp/ft32/libraries/Drivers/drv_config.h | 5 + bsp/ft32/libraries/Drivers/drv_dma.h | 4 + bsp/ft32/libraries/Drivers/drv_gpio.c | 120 +- bsp/ft32/libraries/Drivers/drv_gpio.h | 11 + bsp/ft32/libraries/Drivers/drv_usart.c | 403 +- bsp/ft32/libraries/Drivers/drv_usart.h | 17 +- bsp/ft32/libraries/Drivers/uart_config.h | 22 - .../CMSIS/FT32F4xx/include/cachel1_armv7.h | 411 + .../CMSIS/FT32F4xx/include/cmsis_armcc.h | 888 + .../CMSIS/FT32F4xx/include/cmsis_armclang.h | 1503 ++ .../FT32F4xx/include/cmsis_armclang_ltm.h | 1928 ++ .../CMSIS/FT32F4xx/include/cmsis_compiler.h | 292 + .../CMSIS/FT32F4xx/include/cmsis_gcc.h | 2211 ++ .../CMSIS/FT32F4xx/include/cmsis_iccarm.h | 1002 + .../CMSIS/FT32F4xx/include/cmsis_version.h | 39 + .../CMSIS/FT32F4xx/include/core_armv81mml.h | 4228 ++++ .../CMSIS/FT32F4xx/include/core_armv8mbl.h | 2222 ++ .../CMSIS/FT32F4xx/include/core_armv8mml.h | 3209 +++ .../CMSIS/FT32F4xx/include/core_cm4.h | 2129 ++ .../CMSIS/FT32F4xx/include/ft32f407xe.h | 20900 ++++++++++++++++ .../CMSIS/FT32F4xx/include/ft32f4xx.h | 117 + .../CMSIS/FT32F4xx/include/mpu_armv7.h | 277 + .../CMSIS/FT32F4xx/include/mpu_armv8.h | 352 + .../CMSIS/FT32F4xx/include/pac_armv81.h | 206 + .../CMSIS/FT32F4xx/include/pmu_armv8.h | 337 + .../CMSIS/FT32F4xx/include/system_ft32f4xx.h | 49 + .../CMSIS/FT32F4xx/include/tz_context.h | 70 + .../CMSIS/FT32F4xx/source/arm/FT32F407_OPT.s | 128 + .../FT32F4xx/source/arm/startup_ft32f407xe.s | 491 + .../FT32F4xx/source/gcc/startup_ft32f407xe.s | 583 + .../source/iar/linker/ft32f407xe_flash.icf | 34 + .../FT32F4xx/source/iar/startup_ft32f407xe.s | 742 + .../CMSIS/FT32F4xx/source/system_ft32f4xx.c | 561 + .../FT32F4xx_Driver/inc/ft32f4xx_adc.h | 1855 ++ .../FT32F4xx_Driver/inc/ft32f4xx_comp.h | 441 + .../FT32F4xx_Driver/inc/ft32f4xx_crc.h | 97 + .../FT32F4xx_Driver/inc/ft32f4xx_crs.h | 141 + .../FT32F4xx_Driver/inc/ft32f4xx_dac.h | 208 + .../FT32F4xx_Driver/inc/ft32f4xx_debug.h | 107 + .../FT32F4xx_Driver/inc/ft32f4xx_dma.h | 743 + .../FT32F4xx_Driver/inc/ft32f4xx_ecap.h | 422 + .../FT32F4xx_Driver/inc/ft32f4xx_epwm.h | 779 + .../FT32F4xx_Driver/inc/ft32f4xx_eqep.h | 895 + .../FT32F4xx_Driver/inc/ft32f4xx_eth.h | 1809 ++ .../FT32F4xx_Driver/inc/ft32f4xx_exti.h | 186 + .../FT32F4xx_Driver/inc/ft32f4xx_fdcan.h | 816 + .../FT32F4xx_Driver/inc/ft32f4xx_flash.h | 371 + .../FT32F4xx_Driver/inc/ft32f4xx_fmc.h | 1132 + .../FT32F4xx_Driver/inc/ft32f4xx_gpio.h | 340 + .../FT32F4xx_Driver/inc/ft32f4xx_hcd_fs.h | 152 + .../FT32F4xx_Driver/inc/ft32f4xx_hcd_hs.h | 234 + .../FT32F4xx_Driver/inc/ft32f4xx_i2c.h | 475 + .../FT32F4xx_Driver/inc/ft32f4xx_i2s.h | 488 + .../FT32F4xx_Driver/inc/ft32f4xx_iwdg.h | 121 + .../FT32F4xx_Driver/inc/ft32f4xx_lptim.h | 410 + .../FT32F4xx_Driver/inc/ft32f4xx_misc.h | 177 + .../FT32F4xx_Driver/inc/ft32f4xx_opamp.h | 363 + .../FT32F4xx_Driver/inc/ft32f4xx_pcd_ex_hs.h | 66 + .../FT32F4xx_Driver/inc/ft32f4xx_pcd_fs.h | 186 + .../FT32F4xx_Driver/inc/ft32f4xx_pcd_hs.h | 304 + .../FT32F4xx_Driver/inc/ft32f4xx_pwr.h | 251 + .../FT32F4xx_Driver/inc/ft32f4xx_qspi.h | 732 + .../FT32F4xx_Driver/inc/ft32f4xx_rcc.h | 1096 + .../FT32F4xx_Driver/inc/ft32f4xx_rng.h | 47 + .../FT32F4xx_Driver/inc/ft32f4xx_rtc.h | 911 + .../FT32F4xx_Driver/inc/ft32f4xx_sdio.h | 1155 + .../FT32F4xx_Driver/inc/ft32f4xx_spdif.h | 151 + .../FT32F4xx_Driver/inc/ft32f4xx_spi.h | 443 + .../FT32F4xx_Driver/inc/ft32f4xx_ssi.h | 625 + .../FT32F4xx_Driver/inc/ft32f4xx_syscfg.h | 275 + .../FT32F4xx_Driver/inc/ft32f4xx_tim.h | 1609 ++ .../FT32F4xx_Driver/inc/ft32f4xx_uart.h | 917 + .../FT32F4xx_Driver/inc/ft32f4xx_usart.h | 1188 + .../FT32F4xx_Driver/inc/ft32f4xx_usb_fs.h | 472 + .../FT32F4xx_Driver/inc/ft32f4xx_usb_hs.h | 585 + .../FT32F4xx_Driver/inc/ft32f4xx_wwdg.h | 91 + .../FT32F4xx_Driver/src/ft32f4xx_adc.c | 2214 ++ .../FT32F4xx_Driver/src/ft32f4xx_comp.c | 689 + .../FT32F4xx_Driver/src/ft32f4xx_crc.c | 239 + .../FT32F4xx_Driver/src/ft32f4xx_crs.c | 381 + .../FT32F4xx_Driver/src/ft32f4xx_dac.c | 514 + .../FT32F4xx_Driver/src/ft32f4xx_debug.c | 166 + .../FT32F4xx_Driver/src/ft32f4xx_dma.c | 732 + .../FT32F4xx_Driver/src/ft32f4xx_ecap.c | 549 + .../FT32F4xx_Driver/src/ft32f4xx_epwm.c | 2027 ++ .../FT32F4xx_Driver/src/ft32f4xx_eqep.c | 956 + .../FT32F4xx_Driver/src/ft32f4xx_eth.c | 2841 +++ .../FT32F4xx_Driver/src/ft32f4xx_exti.c | 211 + .../FT32F4xx_Driver/src/ft32f4xx_fdcan.c | 2449 ++ .../FT32F4xx_Driver/src/ft32f4xx_flash.c | 900 + .../FT32F4xx_Driver/src/ft32f4xx_fmc.c | 1251 + .../FT32F4xx_Driver/src/ft32f4xx_gpio.c | 395 + .../FT32F4xx_Driver/src/ft32f4xx_hcd_fs.c | 1173 + .../FT32F4xx_Driver/src/ft32f4xx_hcd_hs.c | 1573 ++ .../FT32F4xx_Driver/src/ft32f4xx_i2c.c | 1320 + .../FT32F4xx_Driver/src/ft32f4xx_i2s.c | 1626 ++ .../FT32F4xx_Driver/src/ft32f4xx_iwdg.c | 167 + .../FT32F4xx_Driver/src/ft32f4xx_lptim.c | 673 + .../FT32F4xx_Driver/src/ft32f4xx_misc.c | 256 + .../FT32F4xx_Driver/src/ft32f4xx_opamp.c | 483 + .../FT32F4xx_Driver/src/ft32f4xx_pcd_ex_hs.c | 112 + .../FT32F4xx_Driver/src/ft32f4xx_pcd_fs.c | 1413 ++ .../FT32F4xx_Driver/src/ft32f4xx_pcd_hs.c | 1438 ++ .../FT32F4xx_Driver/src/ft32f4xx_pwr.c | 575 + .../FT32F4xx_Driver/src/ft32f4xx_qspi.c | 1047 + .../FT32F4xx_Driver/src/ft32f4xx_rcc.c | 2730 ++ .../FT32F4xx_Driver/src/ft32f4xx_rng.c | 103 + .../FT32F4xx_Driver/src/ft32f4xx_rtc.c | 2403 ++ .../FT32F4xx_Driver/src/ft32f4xx_sdio.c | 246 + .../FT32F4xx_Driver/src/ft32f4xx_spdif.c | 207 + .../FT32F4xx_Driver/src/ft32f4xx_spi.c | 827 + .../FT32F4xx_Driver/src/ft32f4xx_ssi.c | 1297 + .../FT32F4xx_Driver/src/ft32f4xx_syscfg.c | 252 + .../FT32F4xx_Driver/src/ft32f4xx_tim.c | 4243 ++++ .../FT32F4xx_Driver/src/ft32f4xx_uart.c | 2391 ++ .../FT32F4xx_Driver/src/ft32f4xx_usart.c | 3188 +++ .../FT32F4xx_Driver/src/ft32f4xx_usb_fs.c | 1451 ++ .../FT32F4xx_Driver/src/ft32f4xx_usb_hs.c | 2128 ++ .../FT32F4xx_Driver/src/ft32f4xx_wwdg.c | 176 + .../templates/inc/FT32F4xx_it.h | 54 + .../FT32F4xx_Driver/templates/inc/main.h | 36 + .../templates/src/FT32F4xx_it.c | 162 + .../FT32F4xx_Driver/templates/src/main.c | 73 + bsp/ft32/libraries/FT32F4xx/SConscript | 97 + bsp/ft32/libraries/Kconfig | 5 +- 147 files changed, 126042 insertions(+), 492 deletions(-) create mode 100644 bsp/ft32/ft32f407xe-starter/.config create mode 100644 bsp/ft32/ft32f407xe-starter/.gitignore create mode 100644 bsp/ft32/ft32f407xe-starter/Kconfig create mode 100644 bsp/ft32/ft32f407xe-starter/README.md create mode 100644 bsp/ft32/ft32f407xe-starter/SConscript create mode 100644 bsp/ft32/ft32f407xe-starter/SConstruct create mode 100644 bsp/ft32/ft32f407xe-starter/applications/SConscript create mode 100644 bsp/ft32/ft32f407xe-starter/applications/main.c create mode 100644 bsp/ft32/ft32f407xe-starter/board/Kconfig create mode 100644 bsp/ft32/ft32f407xe-starter/board/SConscript create mode 100644 bsp/ft32/ft32f407xe-starter/board/board.c create mode 100644 bsp/ft32/ft32f407xe-starter/board/board.h create mode 100644 bsp/ft32/ft32f407xe-starter/board/linker_scripts/link.icf create mode 100644 bsp/ft32/ft32f407xe-starter/board/linker_scripts/link.lds create mode 100644 bsp/ft32/ft32f407xe-starter/board/linker_scripts/link.sct create mode 100644 bsp/ft32/ft32f407xe-starter/figures/ft32f407xe-starter.jpg create mode 100644 bsp/ft32/ft32f407xe-starter/project.uvprojx create mode 100644 bsp/ft32/ft32f407xe-starter/rtconfig.h create mode 100644 bsp/ft32/ft32f407xe-starter/rtconfig.py create mode 100644 bsp/ft32/ft32f407xe-starter/template.uvprojx create mode 100644 bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/cachel1_armv7.h create mode 100644 bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/cmsis_armcc.h create mode 100644 bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/cmsis_armclang.h create mode 100644 bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/cmsis_armclang_ltm.h create mode 100644 bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/cmsis_compiler.h create mode 100644 bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/cmsis_gcc.h create mode 100644 bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/cmsis_iccarm.h create mode 100644 bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/cmsis_version.h create mode 100644 bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/core_armv81mml.h create mode 100644 bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/core_armv8mbl.h create mode 100644 bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/core_armv8mml.h create mode 100644 bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/core_cm4.h create mode 100644 bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/ft32f407xe.h create mode 100644 bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/ft32f4xx.h create mode 100644 bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/mpu_armv7.h create mode 100644 bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/mpu_armv8.h create mode 100644 bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/pac_armv81.h create mode 100644 bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/pmu_armv8.h create mode 100644 bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/system_ft32f4xx.h create mode 100644 bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/tz_context.h create mode 100644 bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/source/arm/FT32F407_OPT.s create mode 100644 bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/source/arm/startup_ft32f407xe.s create mode 100644 bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/source/gcc/startup_ft32f407xe.s create mode 100644 bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/source/iar/linker/ft32f407xe_flash.icf create mode 100644 bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/source/iar/startup_ft32f407xe.s create mode 100644 bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/source/system_ft32f4xx.c create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_adc.h create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_comp.h create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_crc.h create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_crs.h create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_dac.h create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_debug.h create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_dma.h create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_ecap.h create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_epwm.h create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_eqep.h create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_eth.h create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_exti.h create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_fdcan.h create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_flash.h create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_fmc.h create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_gpio.h create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_hcd_fs.h create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_hcd_hs.h create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_i2c.h create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_i2s.h create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_iwdg.h create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_lptim.h create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_misc.h create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_opamp.h create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_pcd_ex_hs.h create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_pcd_fs.h create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_pcd_hs.h create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_pwr.h create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_qspi.h create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_rcc.h create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_rng.h create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_rtc.h create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_sdio.h create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_spdif.h create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_spi.h create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_ssi.h create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_syscfg.h create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_tim.h create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_uart.h create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_usart.h create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_usb_fs.h create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_usb_hs.h create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_wwdg.h create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_adc.c create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_comp.c create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_crc.c create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_crs.c create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_dac.c create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_debug.c create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_dma.c create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_ecap.c create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_epwm.c create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_eqep.c create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_eth.c create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_exti.c create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_fdcan.c create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_flash.c create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_fmc.c create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_gpio.c create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_hcd_fs.c create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_hcd_hs.c create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_i2c.c create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_i2s.c create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_iwdg.c create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_lptim.c create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_misc.c create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_opamp.c create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_pcd_ex_hs.c create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_pcd_fs.c create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_pcd_hs.c create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_pwr.c create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_qspi.c create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_rcc.c create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_rng.c create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_rtc.c create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_sdio.c create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_spdif.c create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_spi.c create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_ssi.c create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_syscfg.c create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_tim.c create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_uart.c create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_usart.c create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_usb_fs.c create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_usb_hs.c create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_wwdg.c create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/templates/inc/FT32F4xx_it.h create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/templates/inc/main.h create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/templates/src/FT32F4xx_it.c create mode 100644 bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/templates/src/main.c create mode 100644 bsp/ft32/libraries/FT32F4xx/SConscript diff --git a/.github/ALL_BSP_COMPILE.json b/.github/ALL_BSP_COMPILE.json index 3dae5e30fca..6d503086dd2 100644 --- a/.github/ALL_BSP_COMPILE.json +++ b/.github/ALL_BSP_COMPILE.json @@ -73,6 +73,7 @@ "asm9260t", "allwinner_tina", "ft32/ft32f072xb-starter", + "ft32/ft32f407xe-starter", "mini2440", "at91/at91sam9g45", "at91/at91sam9260", diff --git a/bsp/ft32/ft32f072xb-starter/project.uvprojx b/bsp/ft32/ft32f072xb-starter/project.uvprojx index a529cc31b2c..61fc4e1f607 100644 --- a/bsp/ft32/ft32f072xb-starter/project.uvprojx +++ b/bsp/ft32/ft32f072xb-starter/project.uvprojx @@ -1,43 +1,46 @@ + 2.1 +
### uVision Project, (C) Keil Software
+ rt-thread 0x4 ARM-ADS - 5060960::V5.06 update 7 (build 960)::.\ARMCC + 5060528::V5.06 update 5 (build 528)::.\ARMCC 0 FT32F072RBATx FMD - FMD.FT32F0xx_DFP.1.0.5 + FMD.FT32F0xx_DFP.1.1.2 https://www.fremontmicro.com/upload/tools/pack/ IRAM(0x20000000,0x00006000) IROM(0x08000000,0x00020000) CPUTYPE("Cortex-M0") CLOCK(12000000) ELITTLE - - + + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0FT32F0xx_128 -FS08000000 -FL020000 -FP0($$Device:FT32F072RBATx$CMSIS\Flash\FT32F0xx_128.FLM)) 0 $$Device:FT32F072RBATx$Drivers\CMSIS\FT32F0xx\Include\ft32f0xx.h - - - - - - - - - + + + + + + + + + $$Device:FT32F072RBATx$CMSIS\SVD\FT32F0xx.svd 0 0 - - - - - + + + + + 0 0 @@ -59,8 +62,8 @@ 0 0 - - + + 0 0 0 @@ -69,8 +72,8 @@ 0 0 - - + + 0 0 0 @@ -80,14 +83,14 @@ 1 0 fromelf --bin !L --output rtthread.bin - + 0 0 0 0 0 - + 0 @@ -101,8 +104,8 @@ 0 0 3 - - + + 1 @@ -135,11 +138,11 @@ 1 BIN\UL2CM3.DLL - - - - - + + + + + 0 @@ -172,7 +175,7 @@ 0 0 "Cortex-M0" - + 0 0 0 @@ -183,6 +186,7 @@ 0 0 0 + 0 0 0 8 @@ -306,7 +310,7 @@ 0x0 - + 1 @@ -333,9 +337,9 @@ 0 0 - + FT32F072xB, RT_USING_LIBC, __STDC_LIMIT_MACROS, __RTTHREAD__, __CLK_TCK=RT_TICK_PER_SECOND, RT_USING_ARMLIBC - + ..\..\..\components\libc\posix\ipc;..\..\..\components\libc\compilers\common\extension\fcntl\octal;..\..\..\libcpu\arm\cortex-m0;..\..\..\components\libc\posix\io\eventfd;..\..\..\components\drivers\include;..\..\..\components\finsh;..\..\..\components\libc\posix\io\poll;..\..\..\components\drivers\include;..\..\..\components\drivers\smp_call;board;..\libraries\Drivers;..\..\..\components\libc\compilers\common\include;..\..\..\components\drivers\phy;..\..\..\components\libc\compilers\common\extension;..\..\..\components\drivers\include;..\libraries\FT32F0xx\FT32F0xx_Driver\Inc;..\..\..\components\drivers\include;applications;..\libraries\FT32F0xx\FT32F0xx_Driver\templates\Inc;.;..\..\..\include;..\..\..\components\libc\posix\io\epoll;..\..\..\libcpu\arm\common;..\..\..\components\drivers\include;..\libraries\FT32F0xx\CMSIS\FT32F0xx\Include @@ -351,10 +355,10 @@ 0 4 - - - - + + + + @@ -366,13 +370,13 @@ 0 0x08000000 0x20000000 - + .\board\linker_scripts\link.sct - - - - - + + + + + @@ -395,50 +399,36 @@ 1 ..\..\..\components\libc\compilers\armlibc\syscall_mem.c - - syscalls.c 1 ..\..\..\components\libc\compilers\armlibc\syscalls.c - - cctype.c 1 ..\..\..\components\libc\compilers\common\cctype.c - - cstdlib.c 1 ..\..\..\components\libc\compilers\common\cstdlib.c - - cstring.c 1 ..\..\..\components\libc\compilers\common\cstring.c - - ctime.c 1 ..\..\..\components\libc\compilers\common\ctime.c - - cunistd.c 1 ..\..\..\components\libc\compilers\common\cunistd.c - - cwchar.c 1 @@ -454,222 +444,668 @@ 1 ..\..\..\components\drivers\core\device.c + + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 __RT_IPC_SOURCE__ - + - - completion_comm.c 1 ..\..\..\components\drivers\ipc\completion_comm.c + + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 __RT_IPC_SOURCE__ - + - - completion_up.c 1 ..\..\..\components\drivers\ipc\completion_up.c + + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 __RT_IPC_SOURCE__ - + - - condvar.c 1 ..\..\..\components\drivers\ipc\condvar.c + + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 __RT_IPC_SOURCE__ - + - - dataqueue.c 1 ..\..\..\components\drivers\ipc\dataqueue.c + + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 __RT_IPC_SOURCE__ - + - - pipe.c 1 ..\..\..\components\drivers\ipc\pipe.c + + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 __RT_IPC_SOURCE__ - + - - ringblk_buf.c 1 ..\..\..\components\drivers\ipc\ringblk_buf.c + + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 __RT_IPC_SOURCE__ - + - - ringbuffer.c 1 ..\..\..\components\drivers\ipc\ringbuffer.c + + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 __RT_IPC_SOURCE__ - + - - waitqueue.c 1 ..\..\..\components\drivers\ipc\waitqueue.c + + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 __RT_IPC_SOURCE__ - + - - workqueue.c 1 ..\..\..\components\drivers\ipc\workqueue.c + + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 __RT_IPC_SOURCE__ - + - - dev_pin.c 1 ..\..\..\components\drivers\pin\dev_pin.c + + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 __RT_IPC_SOURCE__ - + - - dev_serial.c 1 ..\..\..\components\drivers\serial\dev_serial.c + + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 __RT_IPC_SOURCE__ - + @@ -685,22 +1121,16 @@ 1 board\board.c - - startup_ft32f072xb.s 2 ..\libraries\FT32F0xx\CMSIS\FT32F0xx\source\arm\startup_ft32f072xb.s - - drv_gpio.c 1 ..\libraries\Drivers\drv_gpio.c - - drv_usart.c 1 @@ -716,22 +1146,16 @@ 1 ..\..\..\components\finsh\cmd.c - - msh_parse.c 1 ..\..\..\components\finsh\msh_parse.c - - shell.c 1 ..\..\..\components\finsh\shell.c - - msh.c 1 @@ -747,279 +1171,836 @@ 1 ..\..\..\src\clock.c + + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 __RT_KERNEL_SOURCE__ - + - - components.c 1 ..\..\..\src\components.c + + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 __RT_KERNEL_SOURCE__ - + - - cpu_up.c 1 ..\..\..\src\cpu_up.c + + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 __RT_KERNEL_SOURCE__ - + - - defunct.c 1 ..\..\..\src\defunct.c + + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 __RT_KERNEL_SOURCE__ - + - - idle.c 1 ..\..\..\src\idle.c + + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 __RT_KERNEL_SOURCE__ - + - - ipc.c 1 ..\..\..\src\ipc.c + + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 __RT_KERNEL_SOURCE__ - + - - irq.c 1 ..\..\..\src\irq.c + + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 __RT_KERNEL_SOURCE__ - + - - kservice.c 1 ..\..\..\src\kservice.c + + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 __RT_KERNEL_SOURCE__ - + - - mem.c 1 ..\..\..\src\mem.c + + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 __RT_KERNEL_SOURCE__ - + - - mempool.c 1 ..\..\..\src\mempool.c + + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 __RT_KERNEL_SOURCE__ - + - - object.c 1 ..\..\..\src\object.c + + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 __RT_KERNEL_SOURCE__ - + - - scheduler_comm.c 1 ..\..\..\src\scheduler_comm.c + + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 __RT_KERNEL_SOURCE__ - + - - scheduler_up.c 1 ..\..\..\src\scheduler_up.c + + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 __RT_KERNEL_SOURCE__ - + - - thread.c 1 ..\..\..\src\thread.c + + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 __RT_KERNEL_SOURCE__ - + - - timer.c 1 ..\..\..\src\timer.c + + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 __RT_KERNEL_SOURCE__ - + @@ -1035,29 +2016,21 @@ 1 ..\..\..\src\klibc\kstring.c - - kerrno.c 1 ..\..\..\src\klibc\kerrno.c - - rt_vsnprintf_tiny.c 1 ..\..\..\src\klibc\rt_vsnprintf_tiny.c - - rt_vsscanf.c 1 ..\..\..\src\klibc\rt_vsscanf.c - - kstdio.c 1 @@ -1073,22 +2046,16 @@ 1 ..\..\..\libcpu\arm\common\div0.c - - showmem.c 1 ..\..\..\libcpu\arm\common\showmem.c - - context_rvds.S 2 ..\..\..\libcpu\arm\cortex-m0\context_rvds.S - - cpuport.c 1 @@ -1104,113 +2071,81 @@ 1 ..\libraries\FT32F0xx\FT32F0xx_Driver\Src\ft32f0xx_syscfg.c - - ft32f0xx_comp.c 1 ..\libraries\FT32F0xx\FT32F0xx_Driver\Src\ft32f0xx_comp.c - - system_ft32f0xx.c 1 ..\libraries\FT32F0xx\CMSIS\FT32F0xx\source\system_ft32f0xx.c - - ft32f0xx_dma.c 1 ..\libraries\FT32F0xx\FT32F0xx_Driver\Src\ft32f0xx_dma.c - - ft32f0xx_gpio.c 1 ..\libraries\FT32F0xx\FT32F0xx_Driver\Src\ft32f0xx_gpio.c - - ft32f0xx_misc.c 1 ..\libraries\FT32F0xx\FT32F0xx_Driver\Src\ft32f0xx_misc.c - - ft32f0xx_crs.c 1 ..\libraries\FT32F0xx\FT32F0xx_Driver\Src\ft32f0xx_crs.c - - ft32f0xx_opa.c 1 ..\libraries\FT32F0xx\FT32F0xx_Driver\Src\ft32f0xx_opa.c - - ft32f0xx_pwr.c 1 ..\libraries\FT32F0xx\FT32F0xx_Driver\Src\ft32f0xx_pwr.c - - ft32f0xx_rcc.c 1 ..\libraries\FT32F0xx\FT32F0xx_Driver\Src\ft32f0xx_rcc.c - - ft32f0xx_tim.c 1 ..\libraries\FT32F0xx\FT32F0xx_Driver\Src\ft32f0xx_tim.c - - ft32f0xx_usart.c 1 ..\libraries\FT32F0xx\FT32F0xx_Driver\Src\ft32f0xx_usart.c - - ft32f0xx_exti.c 1 ..\libraries\FT32F0xx\FT32F0xx_Driver\Src\ft32f0xx_exti.c - - ft32f0xx_debug.c 1 ..\libraries\FT32F0xx\FT32F0xx_Driver\Src\ft32f0xx_debug.c - - ft32f0xx_div.c 1 ..\libraries\FT32F0xx\FT32F0xx_Driver\Src\ft32f0xx_div.c - - ft32f0xx_crc.c 1 ..\libraries\FT32F0xx\FT32F0xx_Driver\Src\ft32f0xx_crc.c - - ft32f0xx_iwdg.c 1 @@ -1221,9 +2156,11 @@ + - - - + + + +
diff --git a/bsp/ft32/ft32f407xe-starter/.config b/bsp/ft32/ft32f407xe-starter/.config new file mode 100644 index 00000000000..95af1822427 --- /dev/null +++ b/bsp/ft32/ft32f407xe-starter/.config @@ -0,0 +1,1417 @@ + +# +# RT-Thread Kernel +# + +# +# klibc options +# + +# +# rt_vsnprintf options +# +# CONFIG_RT_KLIBC_USING_LIBC_VSNPRINTF is not set +# CONFIG_RT_KLIBC_USING_VSNPRINTF_LONGLONG is not set +# CONFIG_RT_KLIBC_USING_VSNPRINTF_STANDARD is not set +# end of rt_vsnprintf options + +# +# rt_vsscanf options +# +# CONFIG_RT_KLIBC_USING_LIBC_VSSCANF is not set +# end of rt_vsscanf options + +# +# rt_memset options +# +# CONFIG_RT_KLIBC_USING_USER_MEMSET is not set +# CONFIG_RT_KLIBC_USING_LIBC_MEMSET is not set +# CONFIG_RT_KLIBC_USING_TINY_MEMSET is not set +# end of rt_memset options + +# +# rt_memcpy options +# +# CONFIG_RT_KLIBC_USING_USER_MEMCPY is not set +# CONFIG_RT_KLIBC_USING_LIBC_MEMCPY is not set +# CONFIG_RT_KLIBC_USING_TINY_MEMCPY is not set +# end of rt_memcpy options + +# +# rt_memmove options +# +# CONFIG_RT_KLIBC_USING_USER_MEMMOVE is not set +# CONFIG_RT_KLIBC_USING_LIBC_MEMMOVE is not set +# end of rt_memmove options + +# +# rt_memcmp options +# +# CONFIG_RT_KLIBC_USING_USER_MEMCMP is not set +# CONFIG_RT_KLIBC_USING_LIBC_MEMCMP is not set +# end of rt_memcmp options + +# +# rt_strstr options +# +# CONFIG_RT_KLIBC_USING_USER_STRSTR is not set +# CONFIG_RT_KLIBC_USING_LIBC_STRSTR is not set +# end of rt_strstr options + +# +# rt_strcasecmp options +# +# CONFIG_RT_KLIBC_USING_USER_STRCASECMP is not set +# end of rt_strcasecmp options + +# +# rt_strncpy options +# +# CONFIG_RT_KLIBC_USING_USER_STRNCPY is not set +# CONFIG_RT_KLIBC_USING_LIBC_STRNCPY is not set +# end of rt_strncpy options + +# +# rt_strcpy options +# +# CONFIG_RT_KLIBC_USING_USER_STRCPY is not set +# CONFIG_RT_KLIBC_USING_LIBC_STRCPY is not set +# end of rt_strcpy options + +# +# rt_strncmp options +# +# CONFIG_RT_KLIBC_USING_USER_STRNCMP is not set +# CONFIG_RT_KLIBC_USING_LIBC_STRNCMP is not set +# end of rt_strncmp options + +# +# rt_strcmp options +# +# CONFIG_RT_KLIBC_USING_USER_STRCMP is not set +# CONFIG_RT_KLIBC_USING_LIBC_STRCMP is not set +# end of rt_strcmp options + +# +# rt_strlen options +# +# CONFIG_RT_KLIBC_USING_USER_STRLEN is not set +# CONFIG_RT_KLIBC_USING_LIBC_STRLEN is not set +# end of rt_strlen options + +# +# rt_strnlen options +# +# CONFIG_RT_KLIBC_USING_USER_STRNLEN is not set +# end of rt_strnlen options +# end of klibc options + +CONFIG_RT_NAME_MAX=12 +# CONFIG_RT_USING_ARCH_DATA_TYPE is not set +# CONFIG_RT_USING_NANO is not set +# CONFIG_RT_USING_SMART is not set +# CONFIG_RT_USING_AMP is not set +# CONFIG_RT_USING_SMP is not set +CONFIG_RT_CPUS_NR=1 +CONFIG_RT_ALIGN_SIZE=8 +# CONFIG_RT_THREAD_PRIORITY_8 is not set +CONFIG_RT_THREAD_PRIORITY_32=y +# CONFIG_RT_THREAD_PRIORITY_256 is not set +CONFIG_RT_THREAD_PRIORITY_MAX=32 +CONFIG_RT_TICK_PER_SECOND=1000 +CONFIG_RT_USING_OVERFLOW_CHECK=y +CONFIG_RT_USING_HOOK=y +CONFIG_RT_HOOK_USING_FUNC_PTR=y +# CONFIG_RT_USING_HOOKLIST is not set +CONFIG_RT_USING_IDLE_HOOK=y +CONFIG_RT_IDLE_HOOK_LIST_SIZE=4 +CONFIG_IDLE_THREAD_STACK_SIZE=256 +# CONFIG_RT_USING_TIMER_SOFT is not set +# CONFIG_RT_USING_CPU_USAGE_TRACER is not set + +# +# kservice options +# +# CONFIG_RT_USING_TINY_FFS is not set +# end of kservice options + +CONFIG_RT_USING_DEBUG=y +CONFIG_RT_DEBUGING_ASSERT=y +CONFIG_RT_DEBUGING_COLOR=y +CONFIG_RT_DEBUGING_CONTEXT=y +# CONFIG_RT_DEBUGING_AUTO_INIT is not set +# CONFIG_RT_USING_CI_ACTION is not set + +# +# Inter-Thread communication +# +CONFIG_RT_USING_SEMAPHORE=y +CONFIG_RT_USING_MUTEX=y +CONFIG_RT_USING_EVENT=y +CONFIG_RT_USING_MAILBOX=y +CONFIG_RT_USING_MESSAGEQUEUE=y +# CONFIG_RT_USING_MESSAGEQUEUE_PRIORITY is not set +# CONFIG_RT_USING_SIGNALS is not set +# end of Inter-Thread communication + +# +# Memory Management +# +CONFIG_RT_USING_MEMPOOL=y +CONFIG_RT_USING_SMALL_MEM=y +# CONFIG_RT_USING_SLAB is not set +# CONFIG_RT_USING_MEMHEAP is not set +CONFIG_RT_USING_SMALL_MEM_AS_HEAP=y +# CONFIG_RT_USING_MEMHEAP_AS_HEAP is not set +# CONFIG_RT_USING_SLAB_AS_HEAP is not set +# CONFIG_RT_USING_USERHEAP is not set +# CONFIG_RT_USING_NOHEAP is not set +# CONFIG_RT_USING_MEMTRACE is not set +# CONFIG_RT_USING_HEAP_ISR is not set +CONFIG_RT_USING_HEAP=y +# end of Memory Management + +CONFIG_RT_USING_DEVICE=y +# CONFIG_RT_USING_DEVICE_OPS is not set +# CONFIG_RT_USING_INTERRUPT_INFO is not set +# CONFIG_RT_USING_THREADSAFE_PRINTF is not set +CONFIG_RT_USING_CONSOLE=y +CONFIG_RT_CONSOLEBUF_SIZE=128 +CONFIG_RT_CONSOLE_DEVICE_NAME="uart2" +CONFIG_RT_VER_NUM=0x50201 +# CONFIG_RT_USING_STDC_ATOMIC is not set +CONFIG_RT_BACKTRACE_LEVEL_MAX_NR=32 +# end of RT-Thread Kernel + +CONFIG_ARCH_ARM=y +CONFIG_ARCH_ARM_CORTEX_M=y +CONFIG_ARCH_ARM_CORTEX_M0=y + +# +# RT-Thread Components +# +CONFIG_RT_USING_COMPONENTS_INIT=y +CONFIG_RT_USING_USER_MAIN=y +CONFIG_RT_MAIN_THREAD_STACK_SIZE=2048 +CONFIG_RT_MAIN_THREAD_PRIORITY=10 +# CONFIG_RT_USING_LEGACY is not set +CONFIG_RT_USING_MSH=y +CONFIG_RT_USING_FINSH=y +CONFIG_FINSH_USING_MSH=y +CONFIG_FINSH_THREAD_NAME="tshell" +CONFIG_FINSH_THREAD_PRIORITY=20 +CONFIG_FINSH_THREAD_STACK_SIZE=4096 +CONFIG_FINSH_USING_HISTORY=y +CONFIG_FINSH_HISTORY_LINES=5 +# CONFIG_FINSH_USING_WORD_OPERATION is not set +# CONFIG_FINSH_USING_FUNC_EXT is not set +CONFIG_FINSH_USING_SYMTAB=y +CONFIG_FINSH_CMD_SIZE=80 +CONFIG_MSH_USING_BUILT_IN_COMMANDS=y +CONFIG_FINSH_USING_DESCRIPTION=y +# CONFIG_FINSH_ECHO_DISABLE_DEFAULT is not set +# CONFIG_FINSH_USING_AUTH is not set +CONFIG_FINSH_ARG_MAX=10 +CONFIG_FINSH_USING_OPTION_COMPLETION=y + +# +# DFS: device virtual file system +# +# CONFIG_RT_USING_DFS is not set +# end of DFS: device virtual file system + +# CONFIG_RT_USING_FAL is not set + +# +# Device Drivers +# +# CONFIG_RT_USING_DM is not set +# CONFIG_RT_USING_DEV_BUS is not set +CONFIG_RT_USING_DEVICE_IPC=y +CONFIG_RT_UNAMED_PIPE_NUMBER=64 +# CONFIG_RT_USING_SYSTEM_WORKQUEUE is not set +CONFIG_RT_USING_SERIAL=y +CONFIG_RT_USING_SERIAL_V1=y +# CONFIG_RT_USING_SERIAL_V2 is not set +# CONFIG_RT_SERIAL_USING_DMA is not set +CONFIG_RT_SERIAL_RB_BUFSZ=64 +# CONFIG_RT_USING_SERIAL_BYPASS is not set +# CONFIG_RT_USING_CAN is not set +# CONFIG_RT_USING_CPUTIME is not set +# CONFIG_RT_USING_I2C is not set +# CONFIG_RT_USING_PHY is not set +# CONFIG_RT_USING_PHY_V2 is not set +# CONFIG_RT_USING_ADC is not set +# CONFIG_RT_USING_DAC is not set +# CONFIG_RT_USING_NULL is not set +# CONFIG_RT_USING_ZERO is not set +# CONFIG_RT_USING_RANDOM is not set +# CONFIG_RT_USING_PWM is not set +# CONFIG_RT_USING_PULSE_ENCODER is not set +# CONFIG_RT_USING_INPUT_CAPTURE is not set +# CONFIG_RT_USING_MTD_NOR is not set +# CONFIG_RT_USING_MTD_NAND is not set +# CONFIG_RT_USING_PM is not set +# CONFIG_RT_USING_RTC is not set +# CONFIG_RT_USING_SDIO is not set +# CONFIG_RT_USING_SPI is not set +# CONFIG_RT_USING_WDT is not set +# CONFIG_RT_USING_AUDIO is not set +# CONFIG_RT_USING_SENSOR is not set +# CONFIG_RT_USING_TOUCH is not set +# CONFIG_RT_USING_LCD is not set +# CONFIG_RT_USING_HWCRYPTO is not set +# CONFIG_RT_USING_WIFI is not set +# CONFIG_RT_USING_BLK is not set +# CONFIG_RT_USING_VIRTIO is not set +CONFIG_RT_USING_PIN=y +# CONFIG_RT_USING_KTIME is not set +# CONFIG_RT_USING_HWTIMER is not set +# CONFIG_RT_USING_CHERRYUSB is not set +# end of Device Drivers + +# +# C/C++ and POSIX layer +# + +# +# ISO-ANSI C layer +# + +# +# Timezone and Daylight Saving Time +# +# CONFIG_RT_LIBC_USING_FULL_TZ_DST is not set +CONFIG_RT_LIBC_USING_LIGHT_TZ_DST=y +CONFIG_RT_LIBC_TZ_DEFAULT_HOUR=8 +CONFIG_RT_LIBC_TZ_DEFAULT_MIN=0 +CONFIG_RT_LIBC_TZ_DEFAULT_SEC=0 +# end of Timezone and Daylight Saving Time +# end of ISO-ANSI C layer + +# +# POSIX (Portable Operating System Interface) layer +# +# CONFIG_RT_USING_POSIX_FS is not set +# CONFIG_RT_USING_POSIX_DELAY is not set +# CONFIG_RT_USING_POSIX_CLOCK is not set +# CONFIG_RT_USING_POSIX_TIMER is not set +# CONFIG_RT_USING_PTHREADS is not set +# CONFIG_RT_USING_MODULE is not set + +# +# Interprocess Communication (IPC) +# +# CONFIG_RT_USING_POSIX_PIPE is not set +# CONFIG_RT_USING_POSIX_MESSAGE_QUEUE is not set +# CONFIG_RT_USING_POSIX_MESSAGE_SEMAPHORE is not set + +# +# Socket is in the 'Network' category +# +# end of Interprocess Communication (IPC) +# end of POSIX (Portable Operating System Interface) layer + +# CONFIG_RT_USING_CPLUSPLUS is not set +# end of C/C++ and POSIX layer + +# +# Network +# +# CONFIG_RT_USING_SAL is not set +# CONFIG_RT_USING_NETDEV is not set +# CONFIG_RT_USING_LWIP is not set +# CONFIG_RT_USING_AT is not set +# end of Network + +# +# Memory protection +# +# CONFIG_RT_USING_MEM_PROTECTION is not set +# CONFIG_RT_USING_HW_STACK_GUARD is not set +# end of Memory protection + +# +# Utilities +# +# CONFIG_RT_USING_RYM is not set +# CONFIG_RT_USING_ULOG is not set +# CONFIG_RT_USING_UTEST is not set +# CONFIG_RT_USING_VAR_EXPORT is not set +# CONFIG_RT_USING_RESOURCE_ID is not set +# CONFIG_RT_USING_ADT is not set +# CONFIG_RT_USING_RT_LINK is not set +# end of Utilities + +# CONFIG_RT_USING_VBUS is not set + +# +# Using USB legacy version +# +# CONFIG_RT_USING_USB_HOST is not set +# CONFIG_RT_USING_USB_DEVICE is not set +# end of Using USB legacy version + +# CONFIG_RT_USING_FDT is not set +# end of RT-Thread Components + +# +# RT-Thread Utestcases +# +# CONFIG_RT_USING_UTESTCASES is not set +# end of RT-Thread Utestcases + +# +# RT-Thread online packages +# + +# +# IoT - internet of things +# +# CONFIG_PKG_USING_LORAWAN_DRIVER is not set +# CONFIG_PKG_USING_PAHOMQTT is not set +# CONFIG_PKG_USING_UMQTT is not set +# CONFIG_PKG_USING_WEBCLIENT is not set +# CONFIG_PKG_USING_WEBNET is not set +# CONFIG_PKG_USING_MONGOOSE is not set +# CONFIG_PKG_USING_MYMQTT is not set +# CONFIG_PKG_USING_KAWAII_MQTT is not set +# CONFIG_PKG_USING_BC28_MQTT is not set +# CONFIG_PKG_USING_WEBTERMINAL is not set +# CONFIG_PKG_USING_FREEMODBUS is not set +# CONFIG_PKG_USING_NANOPB is not set +# CONFIG_PKG_USING_WIFI_HOST_DRIVER is not set +# CONFIG_PKG_USING_ESP_HOSTED is not set + +# +# Wi-Fi +# + +# +# Marvell WiFi +# +# CONFIG_PKG_USING_WLANMARVELL is not set +# end of Marvell WiFi + +# +# Wiced WiFi +# +# CONFIG_PKG_USING_WLAN_WICED is not set +# end of Wiced WiFi + +# CONFIG_PKG_USING_RW007 is not set + +# +# CYW43012 WiFi +# +# CONFIG_PKG_USING_WLAN_CYW43012 is not set +# end of CYW43012 WiFi + +# +# BL808 WiFi +# +# CONFIG_PKG_USING_WLAN_BL808 is not set +# end of BL808 WiFi + +# +# CYW43439 WiFi +# +# CONFIG_PKG_USING_WLAN_CYW43439 is not set +# end of CYW43439 WiFi +# end of Wi-Fi + +# CONFIG_PKG_USING_COAP is not set +# CONFIG_PKG_USING_NOPOLL is not set +# CONFIG_PKG_USING_NETUTILS is not set +# CONFIG_PKG_USING_CMUX is not set +# CONFIG_PKG_USING_PPP_DEVICE is not set +# CONFIG_PKG_USING_AT_DEVICE is not set +# CONFIG_PKG_USING_ATSRV_SOCKET is not set +# CONFIG_PKG_USING_WIZNET is not set +# CONFIG_PKG_USING_ZB_COORDINATOR is not set + +# +# IoT Cloud +# +# CONFIG_PKG_USING_ONENET is not set +# CONFIG_PKG_USING_GAGENT_CLOUD is not set +# CONFIG_PKG_USING_ALI_IOTKIT is not set +# CONFIG_PKG_USING_AZURE is not set +# CONFIG_PKG_USING_TENCENT_IOT_EXPLORER is not set +# CONFIG_PKG_USING_JIOT-C-SDK is not set +# CONFIG_PKG_USING_UCLOUD_IOT_SDK is not set +# CONFIG_PKG_USING_JOYLINK is not set +# CONFIG_PKG_USING_IOTSHARP_SDK is not set +# end of IoT Cloud + +# CONFIG_PKG_USING_NIMBLE is not set +# CONFIG_PKG_USING_LLSYNC_SDK_ADAPTER is not set +# CONFIG_PKG_USING_OTA_DOWNLOADER is not set +# CONFIG_PKG_USING_IPMSG is not set +# CONFIG_PKG_USING_LSSDP is not set +# CONFIG_PKG_USING_AIRKISS_OPEN is not set +# CONFIG_PKG_USING_LIBRWS is not set +# CONFIG_PKG_USING_TCPSERVER is not set +# CONFIG_PKG_USING_PROTOBUF_C is not set +# CONFIG_PKG_USING_DLT645 is not set +# CONFIG_PKG_USING_QXWZ is not set +# CONFIG_PKG_USING_SMTP_CLIENT is not set +# CONFIG_PKG_USING_ABUP_FOTA is not set +# CONFIG_PKG_USING_LIBCURL2RTT is not set +# CONFIG_PKG_USING_CAPNP is not set +# CONFIG_PKG_USING_AGILE_TELNET is not set +# CONFIG_PKG_USING_NMEALIB is not set +# CONFIG_PKG_USING_PDULIB is not set +# CONFIG_PKG_USING_BTSTACK is not set +# CONFIG_PKG_USING_BT_CYW43012 is not set +# CONFIG_PKG_USING_CYW43XX is not set +# CONFIG_PKG_USING_LORAWAN_ED_STACK is not set +# CONFIG_PKG_USING_WAYZ_IOTKIT is not set +# CONFIG_PKG_USING_MAVLINK is not set +# CONFIG_PKG_USING_BSAL is not set +# CONFIG_PKG_USING_AGILE_MODBUS is not set +# CONFIG_PKG_USING_AGILE_FTP is not set +# CONFIG_PKG_USING_EMBEDDEDPROTO is not set +# CONFIG_PKG_USING_RT_LINK_HW is not set +# CONFIG_PKG_USING_RYANMQTT is not set +# CONFIG_PKG_USING_RYANW5500 is not set +# CONFIG_PKG_USING_LORA_PKT_FWD is not set +# CONFIG_PKG_USING_LORA_GW_DRIVER_LIB is not set +# CONFIG_PKG_USING_LORA_PKT_SNIFFER is not set +# CONFIG_PKG_USING_HM is not set +# CONFIG_PKG_USING_SMALL_MODBUS is not set +# CONFIG_PKG_USING_NET_SERVER is not set +# CONFIG_PKG_USING_ZFTP is not set +# CONFIG_PKG_USING_WOL is not set +# CONFIG_PKG_USING_ZEPHYR_POLLING is not set +# CONFIG_PKG_USING_MATTER_ADAPTATION_LAYER is not set +# CONFIG_PKG_USING_LHC_MODBUS is not set +# CONFIG_PKG_USING_QMODBUS is not set +# CONFIG_PKG_USING_PNET is not set +# CONFIG_PKG_USING_OPENER is not set +# CONFIG_PKG_USING_FREEMQTT is not set +# end of IoT - internet of things + +# +# security packages +# +# CONFIG_PKG_USING_MBEDTLS is not set +# CONFIG_PKG_USING_LIBSODIUM is not set +# CONFIG_PKG_USING_LIBHYDROGEN is not set +# CONFIG_PKG_USING_TINYCRYPT is not set +# CONFIG_PKG_USING_TFM is not set +# CONFIG_PKG_USING_YD_CRYPTO is not set +# end of security packages + +# +# language packages +# + +# +# JSON: JavaScript Object Notation, a lightweight data-interchange format +# +# CONFIG_PKG_USING_CJSON is not set +# CONFIG_PKG_USING_LJSON is not set +# CONFIG_PKG_USING_RT_CJSON_TOOLS is not set +# CONFIG_PKG_USING_RAPIDJSON is not set +# CONFIG_PKG_USING_JSMN is not set +# CONFIG_PKG_USING_AGILE_JSMN is not set +# CONFIG_PKG_USING_PARSON is not set +# CONFIG_PKG_USING_RYAN_JSON is not set +# end of JSON: JavaScript Object Notation, a lightweight data-interchange format + +# +# XML: Extensible Markup Language +# +# CONFIG_PKG_USING_SIMPLE_XML is not set +# CONFIG_PKG_USING_EZXML is not set +# end of XML: Extensible Markup Language + +# CONFIG_PKG_USING_LUATOS_SOC is not set +# CONFIG_PKG_USING_LUA is not set +# CONFIG_PKG_USING_JERRYSCRIPT is not set +# CONFIG_PKG_USING_MICROPYTHON is not set +# CONFIG_PKG_USING_PIKASCRIPT is not set +# CONFIG_PKG_USING_RTT_RUST is not set +# end of language packages + +# +# multimedia packages +# + +# +# LVGL: powerful and easy-to-use embedded GUI library +# +# CONFIG_PKG_USING_LVGL is not set +# CONFIG_PKG_USING_LV_MUSIC_DEMO is not set +# CONFIG_PKG_USING_GUI_GUIDER_DEMO is not set +# end of LVGL: powerful and easy-to-use embedded GUI library + +# +# u8g2: a monochrome graphic library +# +# CONFIG_PKG_USING_U8G2_OFFICIAL is not set +# CONFIG_PKG_USING_U8G2 is not set +# end of u8g2: a monochrome graphic library + +# CONFIG_PKG_USING_OPENMV is not set +# CONFIG_PKG_USING_MUPDF is not set +# CONFIG_PKG_USING_STEMWIN is not set +# CONFIG_PKG_USING_WAVPLAYER is not set +# CONFIG_PKG_USING_TJPGD is not set +# CONFIG_PKG_USING_PDFGEN is not set +# CONFIG_PKG_USING_HELIX is not set +# CONFIG_PKG_USING_AZUREGUIX is not set +# CONFIG_PKG_USING_TOUCHGFX2RTT is not set +# CONFIG_PKG_USING_NUEMWIN is not set +# CONFIG_PKG_USING_MP3PLAYER is not set +# CONFIG_PKG_USING_TINYJPEG is not set +# CONFIG_PKG_USING_UGUI is not set +# CONFIG_PKG_USING_MCURSES is not set +# CONFIG_PKG_USING_TERMBOX is not set +# CONFIG_PKG_USING_VT100 is not set +# CONFIG_PKG_USING_QRCODE is not set +# CONFIG_PKG_USING_GUIENGINE is not set +# CONFIG_PKG_USING_3GPP_AMRNB is not set +# end of multimedia packages + +# +# tools packages +# +# CONFIG_PKG_USING_CMBACKTRACE is not set +# CONFIG_PKG_USING_MCOREDUMP is not set +# CONFIG_PKG_USING_EASYFLASH is not set +# CONFIG_PKG_USING_EASYLOGGER is not set +# CONFIG_PKG_USING_SYSTEMVIEW is not set +# CONFIG_PKG_USING_SEGGER_RTT is not set +# CONFIG_PKG_USING_RTT_AUTO_EXE_CMD is not set +# CONFIG_PKG_USING_RDB is not set +# CONFIG_PKG_USING_ULOG_EASYFLASH is not set +# CONFIG_PKG_USING_LOGMGR is not set +# CONFIG_PKG_USING_ADBD is not set +# CONFIG_PKG_USING_COREMARK is not set +# CONFIG_PKG_USING_DHRYSTONE is not set +# CONFIG_PKG_USING_MEMORYPERF is not set +# CONFIG_PKG_USING_NR_MICRO_SHELL is not set +# CONFIG_PKG_USING_CHINESE_FONT_LIBRARY is not set +# CONFIG_PKG_USING_LUNAR_CALENDAR is not set +# CONFIG_PKG_USING_BS8116A is not set +# CONFIG_PKG_USING_GPS_RMC is not set +# CONFIG_PKG_USING_URLENCODE is not set +# CONFIG_PKG_USING_UMCN is not set +# CONFIG_PKG_USING_LWRB2RTT is not set +# CONFIG_PKG_USING_CPU_USAGE is not set +# CONFIG_PKG_USING_GBK2UTF8 is not set +# CONFIG_PKG_USING_VCONSOLE is not set +# CONFIG_PKG_USING_KDB is not set +# CONFIG_PKG_USING_WAMR is not set +# CONFIG_PKG_USING_MICRO_XRCE_DDS_CLIENT is not set +# CONFIG_PKG_USING_LWLOG is not set +# CONFIG_PKG_USING_ANV_TRACE is not set +# CONFIG_PKG_USING_ANV_MEMLEAK is not set +# CONFIG_PKG_USING_ANV_TESTSUIT is not set +# CONFIG_PKG_USING_ANV_BENCH is not set +# CONFIG_PKG_USING_DEVMEM is not set +# CONFIG_PKG_USING_REGEX is not set +# CONFIG_PKG_USING_MEM_SANDBOX is not set +# CONFIG_PKG_USING_SOLAR_TERMS is not set +# CONFIG_PKG_USING_GAN_ZHI is not set +# CONFIG_PKG_USING_FDT is not set +# CONFIG_PKG_USING_CBOX is not set +# CONFIG_PKG_USING_SNOWFLAKE is not set +# CONFIG_PKG_USING_HASH_MATCH is not set +# CONFIG_PKG_USING_ARMV7M_DWT_TOOL is not set +# CONFIG_PKG_USING_VOFA_PLUS is not set +# CONFIG_PKG_USING_RT_TRACE is not set +# CONFIG_PKG_USING_ZDEBUG is not set +# CONFIG_PKG_USING_RVBACKTRACE is not set +# CONFIG_PKG_USING_HPATCHLITE is not set +# CONFIG_PKG_USING_THREAD_METRIC is not set +# end of tools packages + +# +# system packages +# + +# +# enhanced kernel services +# +# CONFIG_PKG_USING_RT_MEMCPY_CM is not set +# CONFIG_PKG_USING_RT_KPRINTF_THREADSAFE is not set +# end of enhanced kernel services + +# CONFIG_PKG_USING_AUNITY is not set + +# +# acceleration: Assembly language or algorithmic acceleration packages +# +# CONFIG_PKG_USING_QFPLIB_M0_FULL is not set +# CONFIG_PKG_USING_QFPLIB_M0_TINY is not set +# CONFIG_PKG_USING_QFPLIB_M3 is not set +# end of acceleration: Assembly language or algorithmic acceleration packages + +# +# CMSIS: ARM Cortex-M Microcontroller Software Interface Standard +# +# CONFIG_PKG_USING_CMSIS_5 is not set +# CONFIG_PKG_USING_CMSIS_CORE is not set +# CONFIG_PKG_USING_CMSIS_NN is not set +# CONFIG_PKG_USING_CMSIS_RTOS1 is not set +# CONFIG_PKG_USING_CMSIS_RTOS2 is not set +# end of CMSIS: ARM Cortex-M Microcontroller Software Interface Standard + +# +# Micrium: Micrium software products porting for RT-Thread +# +# CONFIG_PKG_USING_UCOSIII_WRAPPER is not set +# CONFIG_PKG_USING_UCOSII_WRAPPER is not set +# CONFIG_PKG_USING_UC_CRC is not set +# CONFIG_PKG_USING_UC_CLK is not set +# CONFIG_PKG_USING_UC_COMMON is not set +# CONFIG_PKG_USING_UC_MODBUS is not set +# end of Micrium: Micrium software products porting for RT-Thread + +# CONFIG_PKG_USING_FREERTOS_WRAPPER is not set +# CONFIG_PKG_USING_LITEOS_SDK is not set +# CONFIG_PKG_USING_TZ_DATABASE is not set +# CONFIG_PKG_USING_CAIRO is not set +# CONFIG_PKG_USING_PIXMAN is not set +# CONFIG_PKG_USING_PARTITION is not set +# CONFIG_PKG_USING_PERF_COUNTER is not set +# CONFIG_PKG_USING_FILEX is not set +# CONFIG_PKG_USING_LEVELX is not set +# CONFIG_PKG_USING_FLASHDB is not set +# CONFIG_PKG_USING_SQLITE is not set +# CONFIG_PKG_USING_RTI is not set +# CONFIG_PKG_USING_DFS_YAFFS is not set +# CONFIG_PKG_USING_LITTLEFS is not set +# CONFIG_PKG_USING_DFS_JFFS2 is not set +# CONFIG_PKG_USING_DFS_UFFS is not set +# CONFIG_PKG_USING_LWEXT4 is not set +# CONFIG_PKG_USING_THREAD_POOL is not set +# CONFIG_PKG_USING_ROBOTS is not set +# CONFIG_PKG_USING_EV is not set +# CONFIG_PKG_USING_SYSWATCH is not set +# CONFIG_PKG_USING_SYS_LOAD_MONITOR is not set +# CONFIG_PKG_USING_PLCCORE is not set +# CONFIG_PKG_USING_RAMDISK is not set +# CONFIG_PKG_USING_MININI is not set +# CONFIG_PKG_USING_QBOOT is not set +# CONFIG_PKG_USING_PPOOL is not set +# CONFIG_PKG_USING_OPENAMP is not set +# CONFIG_PKG_USING_RPMSG_LITE is not set +# CONFIG_PKG_USING_LPM is not set +# CONFIG_PKG_USING_TLSF is not set +# CONFIG_PKG_USING_EVENT_RECORDER is not set +# CONFIG_PKG_USING_ARM_2D is not set +# CONFIG_PKG_USING_MCUBOOT is not set +# CONFIG_PKG_USING_TINYUSB is not set +# CONFIG_PKG_USING_KMULTI_RTIMER is not set +# CONFIG_PKG_USING_TFDB is not set +# CONFIG_PKG_USING_QPC is not set +# CONFIG_PKG_USING_AGILE_UPGRADE is not set +# CONFIG_PKG_USING_FLASH_BLOB is not set +# CONFIG_PKG_USING_MLIBC is not set +# CONFIG_PKG_USING_TASK_MSG_BUS is not set +# CONFIG_PKG_USING_UART_FRAMEWORK is not set +# CONFIG_PKG_USING_SFDB is not set +# CONFIG_PKG_USING_RTP is not set +# CONFIG_PKG_USING_REB is not set +# CONFIG_PKG_USING_RMP is not set +# CONFIG_PKG_USING_R_RHEALSTONE is not set +# CONFIG_PKG_USING_HEARTBEAT is not set +# CONFIG_PKG_USING_MICRO_ROS_RTTHREAD_PACKAGE is not set +# end of system packages + +# +# peripheral libraries and drivers +# + +# +# HAL & SDK Drivers +# + +# +# STM32 HAL & SDK Drivers +# +# CONFIG_PKG_USING_STM32F0_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32F0_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32F1_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32F1_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32F2_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32F2_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32F3_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32F3_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32F4_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32F4_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32F7_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32F7_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32G0_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32G0_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32G4_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32G4_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32H5_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32H5_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32H7_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32H7_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32H7RS_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32H7RS_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32L0_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32L0_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32L4_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32L4_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32L5_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32L5_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32U5_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32U5_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32WB55_SDK is not set +# CONFIG_PKG_USING_STM32_SDIO is not set +# CONFIG_PKG_USING_STM32WL_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32WL_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32WB_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32WB_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32MP1_M4_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32MP1_M4_CMSIS_DRIVER is not set +# end of STM32 HAL & SDK Drivers + +# +# Infineon HAL Packages +# +# CONFIG_PKG_USING_INFINEON_CAT1CM0P is not set +# CONFIG_PKG_USING_INFINEON_CMSIS is not set +# CONFIG_PKG_USING_INFINEON_CORE_LIB is not set +# CONFIG_PKG_USING_INFINEON_MTB_HAL_CAT1 is not set +# CONFIG_PKG_USING_INFINEON_MTB_PDL_CAT1 is not set +# CONFIG_PKG_USING_INFINEON_RETARGET_IO is not set +# CONFIG_PKG_USING_INFINEON_CAPSENSE is not set +# CONFIG_PKG_USING_INFINEON_CSDIDAC is not set +# CONFIG_PKG_USING_INFINEON_SERIAL_FLASH is not set +# CONFIG_PKG_USING_INFINEON_USBDEV is not set +# end of Infineon HAL Packages + +# CONFIG_PKG_USING_BLUETRUM_SDK is not set +# CONFIG_PKG_USING_EMBARC_BSP is not set +# CONFIG_PKG_USING_ESP_IDF is not set + +# +# Kendryte SDK +# +# CONFIG_PKG_USING_K210_SDK is not set +# CONFIG_PKG_USING_KENDRYTE_SDK is not set +# end of Kendryte SDK + +# CONFIG_PKG_USING_NRF5X_SDK is not set +# CONFIG_PKG_USING_NRFX is not set +# CONFIG_PKG_USING_RASPBERRYPI_PICO_RP2350_SDK is not set +# CONFIG_PKG_USING_RASPBERRYPI_PICO_SDK is not set +# CONFIG_PKG_USING_MM32 is not set + +# +# WCH HAL & SDK Drivers +# +# CONFIG_PKG_USING_CH32V20x_SDK is not set +# CONFIG_PKG_USING_CH32V307_SDK is not set +# end of WCH HAL & SDK Drivers + +# +# AT32 HAL & SDK Drivers +# +# CONFIG_PKG_USING_AT32A403A_HAL_DRIVER is not set +# CONFIG_PKG_USING_AT32A403A_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_AT32A423_HAL_DRIVER is not set +# CONFIG_PKG_USING_AT32A423_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_AT32F45x_HAL_DRIVER is not set +# CONFIG_PKG_USING_AT32F45x_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_AT32F402_405_HAL_DRIVER is not set +# CONFIG_PKG_USING_AT32F402_405_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_AT32F403A_407_HAL_DRIVER is not set +# CONFIG_PKG_USING_AT32F403A_407_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_AT32F413_HAL_DRIVER is not set +# CONFIG_PKG_USING_AT32F413_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_AT32F415_HAL_DRIVER is not set +# CONFIG_PKG_USING_AT32F415_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_AT32F421_HAL_DRIVER is not set +# CONFIG_PKG_USING_AT32F421_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_AT32F423_HAL_DRIVER is not set +# CONFIG_PKG_USING_AT32F423_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_AT32F425_HAL_DRIVER is not set +# CONFIG_PKG_USING_AT32F425_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_AT32F435_437_HAL_DRIVER is not set +# CONFIG_PKG_USING_AT32F435_437_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_AT32M412_416_HAL_DRIVER is not set +# CONFIG_PKG_USING_AT32M412_416_CMSIS_DRIVER is not set +# end of AT32 HAL & SDK Drivers + +# +# HC32 DDL Drivers +# +# CONFIG_PKG_USING_HC32F3_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_HC32F3_SERIES_DRIVER is not set +# CONFIG_PKG_USING_HC32F4_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_HC32F4_SERIES_DRIVER is not set +# end of HC32 DDL Drivers + +# +# NXP HAL & SDK Drivers +# +# CONFIG_PKG_USING_NXP_MCX_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_NXP_MCX_SERIES_DRIVER is not set +# CONFIG_PKG_USING_NXP_LPC_DRIVER is not set +# CONFIG_PKG_USING_NXP_LPC55S_DRIVER is not set +# CONFIG_PKG_USING_NXP_IMX6SX_DRIVER is not set +# CONFIG_PKG_USING_NXP_IMX6UL_DRIVER is not set +# CONFIG_PKG_USING_NXP_IMXRT_DRIVER is not set +# end of NXP HAL & SDK Drivers + +# +# NUVOTON Drivers +# +# CONFIG_PKG_USING_NUVOTON_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_NUVOTON_SERIES_DRIVER is not set +# CONFIG_PKG_USING_NUVOTON_ARM926_LIB is not set +# end of NUVOTON Drivers + +# +# GD32 Drivers +# +# CONFIG_PKG_USING_GD32_ARM_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_GD32_ARM_SERIES_DRIVER is not set +# end of GD32 Drivers +# end of HAL & SDK Drivers + +# +# sensors drivers +# +# CONFIG_PKG_USING_LSM6DSM is not set +# CONFIG_PKG_USING_LSM6DSL is not set +# CONFIG_PKG_USING_LPS22HB is not set +# CONFIG_PKG_USING_HTS221 is not set +# CONFIG_PKG_USING_LSM303AGR is not set +# CONFIG_PKG_USING_BME280 is not set +# CONFIG_PKG_USING_BME680 is not set +# CONFIG_PKG_USING_BMA400 is not set +# CONFIG_PKG_USING_BMI160_BMX160 is not set +# CONFIG_PKG_USING_SPL0601 is not set +# CONFIG_PKG_USING_MS5805 is not set +# CONFIG_PKG_USING_DA270 is not set +# CONFIG_PKG_USING_DF220 is not set +# CONFIG_PKG_USING_HSHCAL001 is not set +# CONFIG_PKG_USING_BH1750 is not set +# CONFIG_PKG_USING_MPU6XXX is not set +# CONFIG_PKG_USING_AHT10 is not set +# CONFIG_PKG_USING_AP3216C is not set +# CONFIG_PKG_USING_TSL4531 is not set +# CONFIG_PKG_USING_DS18B20 is not set +# CONFIG_PKG_USING_DHT11 is not set +# CONFIG_PKG_USING_DHTXX is not set +# CONFIG_PKG_USING_GY271 is not set +# CONFIG_PKG_USING_GP2Y10 is not set +# CONFIG_PKG_USING_SGP30 is not set +# CONFIG_PKG_USING_HDC1000 is not set +# CONFIG_PKG_USING_BMP180 is not set +# CONFIG_PKG_USING_BMP280 is not set +# CONFIG_PKG_USING_SHTC1 is not set +# CONFIG_PKG_USING_BMI088 is not set +# CONFIG_PKG_USING_HMC5883 is not set +# CONFIG_PKG_USING_MAX6675 is not set +# CONFIG_PKG_USING_MAX31855 is not set +# CONFIG_PKG_USING_TMP1075 is not set +# CONFIG_PKG_USING_SR04 is not set +# CONFIG_PKG_USING_CCS811 is not set +# CONFIG_PKG_USING_PMSXX is not set +# CONFIG_PKG_USING_RT3020 is not set +# CONFIG_PKG_USING_MLX90632 is not set +# CONFIG_PKG_USING_MLX90382 is not set +# CONFIG_PKG_USING_MLX90393 is not set +# CONFIG_PKG_USING_MLX90392 is not set +# CONFIG_PKG_USING_MLX90394 is not set +# CONFIG_PKG_USING_MLX90397 is not set +# CONFIG_PKG_USING_MS5611 is not set +# CONFIG_PKG_USING_MAX31865 is not set +# CONFIG_PKG_USING_VL53L0X is not set +# CONFIG_PKG_USING_INA260 is not set +# CONFIG_PKG_USING_MAX30102 is not set +# CONFIG_PKG_USING_INA226 is not set +# CONFIG_PKG_USING_LIS2DH12 is not set +# CONFIG_PKG_USING_HS300X is not set +# CONFIG_PKG_USING_ZMOD4410 is not set +# CONFIG_PKG_USING_ISL29035 is not set +# CONFIG_PKG_USING_MMC3680KJ is not set +# CONFIG_PKG_USING_QMP6989 is not set +# CONFIG_PKG_USING_BALANCE is not set +# CONFIG_PKG_USING_SHT2X is not set +# CONFIG_PKG_USING_SHT3X is not set +# CONFIG_PKG_USING_SHT4X is not set +# CONFIG_PKG_USING_AD7746 is not set +# CONFIG_PKG_USING_ADT74XX is not set +# CONFIG_PKG_USING_MAX17048 is not set +# CONFIG_PKG_USING_AS7341 is not set +# CONFIG_PKG_USING_CW2015 is not set +# CONFIG_PKG_USING_ICM20608 is not set +# CONFIG_PKG_USING_PAJ7620 is not set +# CONFIG_PKG_USING_STHS34PF80 is not set +# CONFIG_PKG_USING_P3T1755 is not set +# CONFIG_PKG_USING_QMI8658 is not set +# CONFIG_PKG_USING_ICM20948 is not set +# end of sensors drivers + +# +# touch drivers +# +# CONFIG_PKG_USING_GT9147 is not set +# CONFIG_PKG_USING_GT1151 is not set +# CONFIG_PKG_USING_GT917S is not set +# CONFIG_PKG_USING_GT911 is not set +# CONFIG_PKG_USING_FT6206 is not set +# CONFIG_PKG_USING_FT5426 is not set +# CONFIG_PKG_USING_FT6236 is not set +# CONFIG_PKG_USING_XPT2046_TOUCH is not set +# CONFIG_PKG_USING_CST816X is not set +# CONFIG_PKG_USING_CST812T is not set +# end of touch drivers + +# CONFIG_PKG_USING_REALTEK_AMEBA is not set +# CONFIG_PKG_USING_BUTTON is not set +# CONFIG_PKG_USING_PCF8574 is not set +# CONFIG_PKG_USING_SX12XX is not set +# CONFIG_PKG_USING_SIGNAL_LED is not set +# CONFIG_PKG_USING_LEDBLINK is not set +# CONFIG_PKG_USING_LITTLED is not set +# CONFIG_PKG_USING_LKDGUI is not set +# CONFIG_PKG_USING_INFRARED is not set +# CONFIG_PKG_USING_MULTI_INFRARED is not set +# CONFIG_PKG_USING_AGILE_BUTTON is not set +# CONFIG_PKG_USING_AGILE_LED is not set +# CONFIG_PKG_USING_AT24CXX is not set +# CONFIG_PKG_USING_MOTIONDRIVER2RTT is not set +# CONFIG_PKG_USING_PCA9685 is not set +# CONFIG_PKG_USING_ILI9341 is not set +# CONFIG_PKG_USING_I2C_TOOLS is not set +# CONFIG_PKG_USING_NRF24L01 is not set +# CONFIG_PKG_USING_RPLIDAR is not set +# CONFIG_PKG_USING_AS608 is not set +# CONFIG_PKG_USING_RC522 is not set +# CONFIG_PKG_USING_WS2812B is not set +# CONFIG_PKG_USING_EXTERN_RTC_DRIVERS is not set +# CONFIG_PKG_USING_MULTI_RTIMER is not set +# CONFIG_PKG_USING_MAX7219 is not set +# CONFIG_PKG_USING_BEEP is not set +# CONFIG_PKG_USING_EASYBLINK is not set +# CONFIG_PKG_USING_PMS_SERIES is not set +# CONFIG_PKG_USING_CAN_YMODEM is not set +# CONFIG_PKG_USING_LORA_RADIO_DRIVER is not set +# CONFIG_PKG_USING_QLED is not set +# CONFIG_PKG_USING_AGILE_CONSOLE is not set +# CONFIG_PKG_USING_LD3320 is not set +# CONFIG_PKG_USING_WK2124 is not set +# CONFIG_PKG_USING_LY68L6400 is not set +# CONFIG_PKG_USING_DM9051 is not set +# CONFIG_PKG_USING_SSD1306 is not set +# CONFIG_PKG_USING_QKEY is not set +# CONFIG_PKG_USING_RS485 is not set +# CONFIG_PKG_USING_RS232 is not set +# CONFIG_PKG_USING_NES is not set +# CONFIG_PKG_USING_VIRTUAL_SENSOR is not set +# CONFIG_PKG_USING_VDEVICE is not set +# CONFIG_PKG_USING_SGM706 is not set +# CONFIG_PKG_USING_RDA58XX is not set +# CONFIG_PKG_USING_LIBNFC is not set +# CONFIG_PKG_USING_MFOC is not set +# CONFIG_PKG_USING_TMC51XX is not set +# CONFIG_PKG_USING_TCA9534 is not set +# CONFIG_PKG_USING_KOBUKI is not set +# CONFIG_PKG_USING_ROSSERIAL is not set +# CONFIG_PKG_USING_MICRO_ROS is not set +# CONFIG_PKG_USING_MCP23008 is not set +# CONFIG_PKG_USING_MISAKA_AT24CXX is not set +# CONFIG_PKG_USING_MISAKA_RGB_BLING is not set +# CONFIG_PKG_USING_LORA_MODEM_DRIVER is not set +# CONFIG_PKG_USING_SOFT_SERIAL is not set +# CONFIG_PKG_USING_MB85RS16 is not set +# CONFIG_PKG_USING_RFM300 is not set +# CONFIG_PKG_USING_IO_INPUT_FILTER is not set +# CONFIG_PKG_USING_LRF_NV7LIDAR is not set +# CONFIG_PKG_USING_AIP650 is not set +# CONFIG_PKG_USING_FINGERPRINT is not set +# CONFIG_PKG_USING_BT_ECB02C is not set +# CONFIG_PKG_USING_UAT is not set +# CONFIG_PKG_USING_ST7789 is not set +# CONFIG_PKG_USING_VS1003 is not set +# CONFIG_PKG_USING_X9555 is not set +# CONFIG_PKG_USING_SYSTEM_RUN_LED is not set +# CONFIG_PKG_USING_BT_MX01 is not set +# CONFIG_PKG_USING_RGPOWER is not set +# CONFIG_PKG_USING_BT_MX02 is not set +# CONFIG_PKG_USING_GC9A01 is not set +# CONFIG_PKG_USING_IK485 is not set +# CONFIG_PKG_USING_SERVO is not set +# CONFIG_PKG_USING_SEAN_WS2812B is not set +# CONFIG_PKG_USING_IC74HC165 is not set +# CONFIG_PKG_USING_IST8310 is not set +# CONFIG_PKG_USING_ST7789_SPI is not set +# CONFIG_PKG_USING_SPI_TOOLS is not set +# end of peripheral libraries and drivers + +# +# AI packages +# +# CONFIG_PKG_USING_LIBANN is not set +# CONFIG_PKG_USING_NNOM is not set +# CONFIG_PKG_USING_ONNX_BACKEND is not set +# CONFIG_PKG_USING_ONNX_PARSER is not set +# CONFIG_PKG_USING_TENSORFLOWLITEMICRO is not set +# CONFIG_PKG_USING_ELAPACK is not set +# CONFIG_PKG_USING_ULAPACK is not set +# CONFIG_PKG_USING_QUEST is not set +# CONFIG_PKG_USING_NAXOS is not set +# CONFIG_PKG_USING_R_TINYMAIX is not set +# CONFIG_PKG_USING_LLMCHAT is not set +# end of AI packages + +# +# Signal Processing and Control Algorithm Packages +# +# CONFIG_PKG_USING_APID is not set +# CONFIG_PKG_USING_FIRE_PID_CURVE is not set +# CONFIG_PKG_USING_QPID is not set +# CONFIG_PKG_USING_UKAL is not set +# CONFIG_PKG_USING_DIGITALCTRL is not set +# CONFIG_PKG_USING_KISSFFT is not set +# CONFIG_PKG_USING_CMSIS_DSP is not set +# end of Signal Processing and Control Algorithm Packages + +# +# miscellaneous packages +# + +# +# project laboratory +# +# end of project laboratory + +# +# samples: kernel and components samples +# +# CONFIG_PKG_USING_KERNEL_SAMPLES is not set +# CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set +# CONFIG_PKG_USING_NETWORK_SAMPLES is not set +# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set +# end of samples: kernel and components samples + +# +# entertainment: terminal games and other interesting software packages +# +# CONFIG_PKG_USING_CMATRIX is not set +# CONFIG_PKG_USING_SL is not set +# CONFIG_PKG_USING_CAL is not set +# CONFIG_PKG_USING_ACLOCK is not set +# CONFIG_PKG_USING_THREES is not set +# CONFIG_PKG_USING_2048 is not set +# CONFIG_PKG_USING_SNAKE is not set +# CONFIG_PKG_USING_TETRIS is not set +# CONFIG_PKG_USING_DONUT is not set +# CONFIG_PKG_USING_COWSAY is not set +# CONFIG_PKG_USING_MORSE is not set +# CONFIG_PKG_USING_TINYSQUARE is not set +# end of entertainment: terminal games and other interesting software packages + +# CONFIG_PKG_USING_LIBCSV is not set +# CONFIG_PKG_USING_OPTPARSE is not set +# CONFIG_PKG_USING_FASTLZ is not set +# CONFIG_PKG_USING_MINILZO is not set +# CONFIG_PKG_USING_QUICKLZ is not set +# CONFIG_PKG_USING_LZMA is not set +# CONFIG_PKG_USING_RALARAM is not set +# CONFIG_PKG_USING_MULTIBUTTON is not set +# CONFIG_PKG_USING_FLEXIBLE_BUTTON is not set +# CONFIG_PKG_USING_CANFESTIVAL is not set +# CONFIG_PKG_USING_ZLIB is not set +# CONFIG_PKG_USING_MINIZIP is not set +# CONFIG_PKG_USING_HEATSHRINK is not set +# CONFIG_PKG_USING_DSTR is not set +# CONFIG_PKG_USING_TINYFRAME is not set +# CONFIG_PKG_USING_KENDRYTE_DEMO is not set +# CONFIG_PKG_USING_UPACKER is not set +# CONFIG_PKG_USING_UPARAM is not set +# CONFIG_PKG_USING_HELLO is not set +# CONFIG_PKG_USING_VI is not set +# CONFIG_PKG_USING_KI is not set +# CONFIG_PKG_USING_ARMv7M_DWT is not set +# CONFIG_PKG_USING_CRCLIB is not set +# CONFIG_PKG_USING_LIBCRC is not set +# CONFIG_PKG_USING_LWGPS is not set +# CONFIG_PKG_USING_STATE_MACHINE is not set +# CONFIG_PKG_USING_DESIGN_PATTERN is not set +# CONFIG_PKG_USING_CONTROLLER is not set +# CONFIG_PKG_USING_PHASE_LOCKED_LOOP is not set +# CONFIG_PKG_USING_MFBD is not set +# CONFIG_PKG_USING_SLCAN2RTT is not set +# CONFIG_PKG_USING_SOEM is not set +# CONFIG_PKG_USING_QPARAM is not set +# CONFIG_PKG_USING_CorevMCU_CLI is not set +# CONFIG_PKG_USING_DRMP is not set +# end of miscellaneous packages + +# +# Arduino libraries +# +# CONFIG_PKG_USING_RTDUINO is not set + +# +# Projects and Demos +# +# CONFIG_PKG_USING_ARDUINO_MSGQ_C_CPP_DEMO is not set +# CONFIG_PKG_USING_ARDUINO_SKETCH_LOADER_DEMO is not set +# CONFIG_PKG_USING_ARDUINO_ULTRASOUND_RADAR is not set +# CONFIG_PKG_USING_ARDUINO_RTDUINO_SENSORFUSION_SHIELD is not set +# CONFIG_PKG_USING_ARDUINO_NINEINONE_SENSOR_SHIELD is not set +# CONFIG_PKG_USING_ARDUINO_SENSOR_KIT is not set +# CONFIG_PKG_USING_ARDUINO_MATLAB_SUPPORT is not set +# end of Projects and Demos + +# +# Sensors +# +# CONFIG_PKG_USING_ARDUINO_SENSOR_DEVICE_DRIVERS is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSOR is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSORLAB is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL375 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL53L0X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL53L1X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL6180X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31855 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31865 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31856 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX6675 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90614 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM9DS1 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AHTX0 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM9DS0 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP280 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADT7410 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP085 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BME680 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP9808 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP4728 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_INA219 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LTR390 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL345 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DHT is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP9600 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM6DS is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO055 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX1704X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MMC56X3 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90393 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90395 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ICM20X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DPS310 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTS221 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHT4X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHT31 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL343 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BME280 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AS726X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AMG88XX is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AM2320 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AM2315 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LTR329_LTR303 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP085_UNIFIED is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP183 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP183_UNIFIED is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP3XX is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MS8607 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS3MDL is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90640 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MMA8451 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MSA301 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPL115A2 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO08X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO08X_RVC is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS2MDL is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM303DLH_MAG is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LC709203F is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_CAP1188 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_CCS811 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_NAU7802 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS331 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LPS2X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LPS35HW is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM303_ACCEL is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS3DH is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8591 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPL3115A2 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPR121 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPRLS is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPU6050 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCT2075 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PM25AQI is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_EMC2101 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_FXAS21002C is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SCD30 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_FXOS8700 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HMC5883_UNIFIED is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SGP30 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP006 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TLA202X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TCS34725 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI7021 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI1145 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SGP40 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHTC3 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HDC1000 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU21DF is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AS7341 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU31D is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_INA260 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP007_LIBRARY is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_L3GD20 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP117 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSC2007 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSL2561 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSL2591_LIBRARY is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VCNL4040 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6070 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6075 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML7700 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LIS3DHTR is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_DHT is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_ADXL335 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_ADXL345 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_BME280 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_BMP280 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_H3LIS331DL is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_MMA7660 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_TSL2561 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_PAJ7620 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_VL53L0X is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_ITG3200 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_SHT31 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HP20X is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_DRV2605L is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_BBM150 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HMC5883L is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LSM303DLH is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_TCS3414CS is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_MP503 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_BMP085 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HIGHTEMP is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_VEML6070 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_SI1145 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_SHT35 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_AT42QT1070 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LSM6DS3 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HDC1000 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HM3301 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_MCP9600 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LTC2941 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LDC1612 is not set +# CONFIG_PKG_USING_ARDUINO_CAPACITIVESENSOR is not set +# CONFIG_PKG_USING_ARDUINO_JARZEBSKI_MPU6050 is not set +# end of Sensors + +# +# Display +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_GFX_LIBRARY is not set +# CONFIG_PKG_USING_ARDUINO_U8G2 is not set +# CONFIG_PKG_USING_ARDUINO_TFT_ESPI is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ST7735 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SSD1306 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ILI9341 is not set +# CONFIG_PKG_USING_SEEED_TM1637 is not set +# end of Display + +# +# Timing +# +# CONFIG_PKG_USING_ARDUINO_RTCLIB is not set +# CONFIG_PKG_USING_ARDUINO_MSTIMER2 is not set +# CONFIG_PKG_USING_ARDUINO_TICKER is not set +# CONFIG_PKG_USING_ARDUINO_TASKSCHEDULER is not set +# end of Timing + +# +# Data Processing +# +# CONFIG_PKG_USING_ARDUINO_KALMANFILTER is not set +# CONFIG_PKG_USING_ARDUINO_ARDUINOJSON is not set +# CONFIG_PKG_USING_ARDUINO_TENSORFLOW_LITE_MICRO is not set +# CONFIG_PKG_USING_ARDUINO_RUNNINGMEDIAN is not set +# end of Data Processing + +# +# Data Storage +# + +# +# Communication +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PN532 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI4713 is not set +# end of Communication + +# +# Device Control +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8574 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCA9685 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TPA2016 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DRV2605 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DS1841 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DS3502 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_PCF85063TP is not set +# end of Device Control + +# +# Other +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MFRC630 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI5351 is not set +# end of Other + +# +# Signal IO +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BUSIO is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TCA8418 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP23017 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADS1X15 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AW9523 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP3008 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP4725 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BD3491FS is not set +# end of Signal IO + +# +# Uncategorized +# +# end of Arduino libraries +# end of RT-Thread online packages + +CONFIG_SOC_FAMILY_FT32=y +CONFIG_SOC_SERIES_FT32F4=y + +# +# Hardware Drivers Config +# +CONFIG_SOC_FT32F407VE=y + +# +# Onboard Peripheral Drivers +# + +# +# On-chip Peripheral Drivers +# +CONFIG_BSP_USING_GPIO=y +CONFIG_BSP_USING_UART=y +# CONFIG_BSP_USING_UART1 is not set +CONFIG_BSP_USING_UART2=y +# CONFIG_BSP_USING_CRC is not set +# end of On-chip Peripheral Drivers + +# +# Board extended module Drivers +# +# end of Hardware Drivers Config diff --git a/bsp/ft32/ft32f407xe-starter/.gitignore b/bsp/ft32/ft32f407xe-starter/.gitignore new file mode 100644 index 00000000000..7221bde019d --- /dev/null +++ b/bsp/ft32/ft32f407xe-starter/.gitignore @@ -0,0 +1,42 @@ +*.pyc +*.map +*.dblite +*.elf +*.bin +*.hex +*.axf +*.exe +*.pdb +*.idb +*.ilk +*.old +build +Debug +documentation/html +packages/ +*~ +*.o +*.obj +*.out +*.bak +*.dep +*.lib +*.i +*.d +.DS_Stor* +.config 3 +.config 4 +.config 5 +Midea-X1 +*.uimg +GPATH +GRTAGS +GTAGS +.vscode +JLinkLog.txt +JLinkSettings.ini +DebugConfig/ +RTE/ +settings/ +*.uvguix* +cconfig.h diff --git a/bsp/ft32/ft32f407xe-starter/Kconfig b/bsp/ft32/ft32f407xe-starter/Kconfig new file mode 100644 index 00000000000..029e5afd21a --- /dev/null +++ b/bsp/ft32/ft32f407xe-starter/Kconfig @@ -0,0 +1,13 @@ +mainmenu "RT-Thread Configuration" + +BSP_DIR := . + +RTT_DIR := ../../.. + +PKGS_DIR := packages + +source "$(RTT_DIR)/Kconfig" +osource "$PKGS_DIR/Kconfig" +rsource "../libraries/Kconfig" +rsource "board/Kconfig" + diff --git a/bsp/ft32/ft32f407xe-starter/README.md b/bsp/ft32/ft32f407xe-starter/README.md new file mode 100644 index 00000000000..181d7cf9317 --- /dev/null +++ b/bsp/ft32/ft32f407xe-starter/README.md @@ -0,0 +1,53 @@ +# FT32F407xx-StarterKit-32 # + +## 1. 简介 + +[StarterKit-32](https://www.fremontmicro.com/down/demoboard/index.aspx)是辉芒微提供的开发板,使用 Cortex-M4 内核的 FT32F407xE 作为主控制器。提供包括扩展引脚等外设资源。 + +板载主要资源如下: + +| 硬件 | 描述 | +| -- | -- | +|CPU| Cortex-M4 | +|主频| 210MHz | +|SRAM| 128KB+64KB | +|Flash| 512KB | + +- 常用外设 + - LED:3个,(PD13、PD14、PD15) + - 按键:1个,(PA0或PC13) +- 常用接口:串口(PA2、PA3) + +## 2. 编译说明 + +StarterKit-32板级包支持 MDK5,以下是具体版本信息: + +| IDE/编译器 | 已测试版本 | +| -- | -- | +| MDK5(ARM Compiler 5 and 6) | MDK5.38 | + +## 3. 烧写及执行 + +下载程序:使用 CMSIS-DAP或者J-link等工具。 + +### 3.1 配置和仿真 + +工程已经默认使能了RT-Thread UART驱动、GPIO驱动。若想进一步配置工程请 +使用ENV工具。 + +## 4. 驱动支持情况及计划 + +| 驱动 | 支持情况 | 备注 | +| ------ | ---- | :------: | +| UART | 支持 | USART0/1 | +| GPIO | 支持 | | + +## 5. 联系人信息 + +维护人: + +- [FMD-AE](https://github.com/FmdAE) + +## 6. 参考 + +* [StarterKit-32](https://www.fremontmicro.com/down/demoboard/index.aspx) diff --git a/bsp/ft32/ft32f407xe-starter/SConscript b/bsp/ft32/ft32f407xe-starter/SConscript new file mode 100644 index 00000000000..20f7689c53c --- /dev/null +++ b/bsp/ft32/ft32f407xe-starter/SConscript @@ -0,0 +1,15 @@ +# for module compiling +import os +Import('RTT_ROOT') +from building import * + +cwd = GetCurrentDir() +objs = [] +list = os.listdir(cwd) + +for d in list: + path = os.path.join(cwd, d) + if os.path.isfile(os.path.join(path, 'SConscript')): + objs = objs + SConscript(os.path.join(d, 'SConscript')) + +Return('objs') diff --git a/bsp/ft32/ft32f407xe-starter/SConstruct b/bsp/ft32/ft32f407xe-starter/SConstruct new file mode 100644 index 00000000000..77382caa378 --- /dev/null +++ b/bsp/ft32/ft32f407xe-starter/SConstruct @@ -0,0 +1,60 @@ +import os +import sys +import rtconfig + +if os.getenv('RTT_ROOT'): + RTT_ROOT = os.getenv('RTT_ROOT') +else: + RTT_ROOT = os.path.normpath(os.getcwd() + '/../../..') + +sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')] +try: + from building import * +except: + print('Cannot found RT-Thread root directory, please check RTT_ROOT') + print(RTT_ROOT) + exit(-1) + +TARGET = 'rt-thread_ft32f407.' + rtconfig.TARGET_EXT + +DefaultEnvironment(tools=[]) +env = Environment(tools = ['mingw'], + AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS, + CC = rtconfig.CC, CFLAGS = rtconfig.CFLAGS, + AR = rtconfig.AR, ARFLAGS = '-rc', + CXX = rtconfig.CXX, CXXFLAGS = rtconfig.CXXFLAGS, + LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS) +env.PrependENVPath('PATH', rtconfig.EXEC_PATH) + +if rtconfig.PLATFORM in ['iccarm']: + env.Replace(CCCOM = ['$CC $CFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -o $TARGET $SOURCES']) + env.Replace(ARFLAGS = ['']) + env.Replace(LINKCOM = env["LINKCOM"] + ' --map rt-thread.map') + +Export('RTT_ROOT') +Export('rtconfig') + +SDK_ROOT = os.path.abspath('./') + +if os.path.exists(SDK_ROOT + '/libraries'): + libraries_path_prefix = SDK_ROOT + '/libraries' +else: + libraries_path_prefix = os.path.dirname(SDK_ROOT) + '/libraries' + +SDK_LIB = libraries_path_prefix +Export('SDK_LIB') + +# prepare building environment +objs = PrepareBuilding(env, RTT_ROOT, has_libcpu=False) + +ft32_library = 'FT32F4xx' +rtconfig.BSP_LIBRARY_TYPE = ft32_library + +# include libraries +objs.extend(SConscript(os.path.join(libraries_path_prefix, ft32_library, 'SConscript'))) + +# include drivers +objs.extend(SConscript(os.path.join(libraries_path_prefix, 'Drivers', 'SConscript'))) + +# make a building +DoBuilding(TARGET, objs) diff --git a/bsp/ft32/ft32f407xe-starter/applications/SConscript b/bsp/ft32/ft32f407xe-starter/applications/SConscript new file mode 100644 index 00000000000..5efd37ed23c --- /dev/null +++ b/bsp/ft32/ft32f407xe-starter/applications/SConscript @@ -0,0 +1,9 @@ +from building import * + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') +CPPPATH = [cwd] + +group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/ft32/ft32f407xe-starter/applications/main.c b/bsp/ft32/ft32f407xe-starter/applications/main.c new file mode 100644 index 00000000000..f9919d8538d --- /dev/null +++ b/bsp/ft32/ft32f407xe-starter/applications/main.c @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-03-02 FMD-AE first version + */ + +#include +#include +#include + +/* defined the LED2 pin: PD13 */ +#define LED2_PIN GET_PIN(D, 13) + +int main(void) +{ + /* set LED0 pin mode to output */ + rt_pin_mode(LED2_PIN, PIN_MODE_OUTPUT); + + while (1) + { + rt_pin_write(LED2_PIN, PIN_HIGH); + rt_thread_mdelay(500); + rt_pin_write(LED2_PIN, PIN_LOW); + rt_thread_mdelay(500); + } +} diff --git a/bsp/ft32/ft32f407xe-starter/board/Kconfig b/bsp/ft32/ft32f407xe-starter/board/Kconfig new file mode 100644 index 00000000000..64d0cff977b --- /dev/null +++ b/bsp/ft32/ft32f407xe-starter/board/Kconfig @@ -0,0 +1,52 @@ +menu "Hardware Drivers Config" + +config SOC_FT32F407VE + bool + select SOC_SERIES_FT32F4 + select RT_USING_COMPONENTS_INIT + select RT_USING_USER_MAIN + default y + +menu "Onboard Peripheral Drivers" + +endmenu + +menu "On-chip Peripheral Drivers" + + config BSP_USING_GPIO + bool "Enable GPIO" + select RT_USING_PIN + default y + + menuconfig BSP_USING_UART + bool "Enable UART" + default y + select RT_USING_SERIAL + if BSP_USING_UART + config BSP_USING_UART1 + bool "Enable UART1" + default n + + config BSP_UART1_RX_USING_DMA + bool "Enable UART1 RX DMA" + depends on BSP_USING_UART1 && RT_SERIAL_USING_DMA + default n + + config BSP_USING_UART2 + bool "Enable UART2" + default y + + config BSP_UART2_RX_USING_DMA + bool "Enable UART2 RX DMA" + depends on BSP_USING_UART2 && RT_SERIAL_USING_DMA + default n + endif + rsource "../../libraries/Drivers/Kconfig" + +endmenu + +menu "Board extended module Drivers" + +endmenu + +endmenu diff --git a/bsp/ft32/ft32f407xe-starter/board/SConscript b/bsp/ft32/ft32f407xe-starter/board/SConscript new file mode 100644 index 00000000000..16f55269efa --- /dev/null +++ b/bsp/ft32/ft32f407xe-starter/board/SConscript @@ -0,0 +1,29 @@ +import os +import rtconfig +from building import * + +Import('SDK_LIB') + +cwd = GetCurrentDir() + +# add general drivers +src = Split(''' +board.c +''') + +path = [cwd] + +startup_path_prefix = SDK_LIB + +if rtconfig.PLATFORM in ['gcc']: + src += [startup_path_prefix + '/FT32F4xx/CMSIS/FT32F4xx/source/gcc/startup_ft32f407xe.s'] +elif rtconfig.PLATFORM in ['armcc', 'armclang']: + src += [startup_path_prefix + '/FT32F4xx/CMSIS/FT32F4xx/source/arm/startup_ft32f407xe.s'] +elif rtconfig.PLATFORM in ['iccarm']: + src += [startup_path_prefix + '/FT32F4xx/CMSIS/FT32F4xx/source/iar/startup_ft32f407xe.s'] + +# FT32F407xE +# You can select chips from the list above +CPPDEFINES = ['FT32F407xE'] +group = DefineGroup('Drivers', src, depend = [''], CPPPATH = path, CPPDEFINES = CPPDEFINES) +Return('group') diff --git a/bsp/ft32/ft32f407xe-starter/board/board.c b/bsp/ft32/ft32f407xe-starter/board/board.c new file mode 100644 index 00000000000..41b06ac6de7 --- /dev/null +++ b/bsp/ft32/ft32f407xe-starter/board/board.c @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-03-02 FMD-AE first version + */ + +#include "board.h" + +#ifdef RT_USING_SERIAL + #include "drv_usart.h" +#endif /* RT_USING_SERIAL */ + +#define DBG_TAG "drv_common" +#define DBG_LVL DBG_INFO +#include + +#ifdef RT_USING_FINSH +#include + +static void reboot(uint8_t argc, char **argv) +{ + rt_hw_cpu_reset(); +} +MSH_CMD_EXPORT(reboot, Reboot System); +#endif /* RT_USING_FINSH */ + +__IO uint32_t uwTick; +static uint32_t _systick_ms = 1; + +void IncTick(void) +{ + uwTick += _systick_ms; +} +/** + * This is the timer interrupt service routine. + * + */ +void SysTick_Handler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + + if (SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) + IncTick(); + + rt_tick_increase(); + + /* leave interrupt */ + rt_interrupt_leave(); +} + +uint32_t GetTick(void) +{ + if (SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) + IncTick(); + + return uwTick; +} + +void SuspendTick(void) +{ +} + +void ResumeTick(void) +{ +} + +void Delay(__IO uint32_t Delay) +{ + if (rt_thread_self()) + { + rt_thread_mdelay(Delay); + } + else + { + for (rt_uint32_t count = 0; count < Delay; count++) + { + rt_hw_us_delay(1000); + } + } +} +/** + * This function will delay for some us. + * + * @param us the delay time of us + */ +void rt_hw_us_delay(rt_uint32_t us) +{ + rt_uint32_t ticks; + rt_uint32_t told, tnow, tcnt = 0; + rt_uint32_t reload = SysTick->LOAD; + + ticks = us * reload / (1000000 / RT_TICK_PER_SECOND); + told = SysTick->VAL; + while (1) + { + tnow = SysTick->VAL; + if (tnow != told) + { + if (tnow < told) + { + tcnt += told - tnow; + } + else + { + tcnt += reload - tnow + told; + } + told = tnow; + if (tcnt >= ticks) + { + break; + } + } + } +} + +/** + * This function will initial FT32 board. + */ +rt_weak void rt_hw_board_init() +{ + SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND); + /* Heap initialization */ +#if defined(RT_USING_HEAP) + rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END); +#endif + + /* Pin driver initialization is open by default */ +#ifdef RT_USING_PIN + rt_hw_pin_init(); +#endif + + /* USART driver initialization is open by default */ +#ifdef RT_USING_SERIAL + rt_hw_usart_init(); +#endif + + /* Set the shell console output device */ +#if defined(RT_USING_CONSOLE) && defined(RT_USING_DEVICE) + rt_console_set_device(RT_CONSOLE_DEVICE_NAME); +#endif + + /* Board underlying hardware initialization */ +#ifdef RT_USING_COMPONENTS_INIT + rt_components_board_init(); +#endif +} + + diff --git a/bsp/ft32/ft32f407xe-starter/board/board.h b/bsp/ft32/ft32f407xe-starter/board/board.h new file mode 100644 index 00000000000..b8611133be1 --- /dev/null +++ b/bsp/ft32/ft32f407xe-starter/board/board.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-03-02 FMD-AE first version + */ + +#ifndef __BOARD_H__ +#define __BOARD_H__ + +#include +#include +#include "drv_gpio.h" +#include +#include +#include +#include +#include +#include +#include +#ifdef RT_USING_DEVICE + #include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#define FT32_FLASH_START_ADRESS ((uint32_t)0x08000000) +#define FT32_FLASH_SIZE (128 * 1024) +#define FT32_FLASH_END_ADDRESS ((uint32_t)(FT32_FLASH_START_ADRESS + FT32_FLASH_SIZE)) + +/* Internal SRAM memory size[Kbytes] <8-64>, Default: 64*/ +#define FT32_SRAM_SIZE 24 +#define FT32_SRAM_END (0x20000000 + FT32_SRAM_SIZE * 1024) + +#if defined(__ARMCC_VERSION) +extern int Image$$RW_IRAM1$$ZI$$Limit; +#define HEAP_BEGIN ((void *)&Image$$RW_IRAM1$$ZI$$Limit) +#elif __ICCARM__ +#pragma section="CSTACK" +#define HEAP_BEGIN (__segment_end("CSTACK")) +#else +extern int __bss_end; +#define HEAP_BEGIN ((void *)&__bss_end) +#endif + +#define HEAP_END FT32_SRAM_END + +#ifdef __cplusplus +} +#endif + +#endif /* __BOARD_H__ */ diff --git a/bsp/ft32/ft32f407xe-starter/board/linker_scripts/link.icf b/bsp/ft32/ft32f407xe-starter/board/linker_scripts/link.icf new file mode 100644 index 00000000000..ae5a7f57f86 --- /dev/null +++ b/bsp/ft32/ft32f407xe-starter/board/linker_scripts/link.icf @@ -0,0 +1,34 @@ +/*###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__ = 0x0807FFFF; +define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; +define symbol __ICFEDIT_region_RAM_end__ = 0x2001FFFF; +define symbol __ICFEDIT_region_CCMRAM_start__ = 0x10000000; +define symbol __ICFEDIT_region_CCMRAM_end__ = 0x1000FFFF; +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 0x400; +define symbol __ICFEDIT_size_heap__ = 0x200; +/**** End of ICF editor section. ###ICF###*/ + + +define memory mem with size = 4G; +define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; +define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; +define region CCMRAM_region = mem:[from __ICFEDIT_region_CCMRAM_start__ to __ICFEDIT_region_CCMRAM_end__]; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + +initialize by copy { readwrite }; +do not initialize { section .noinit }; + +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; + +place in ROM_region { readonly }; +place in RAM_region { readwrite, + block CSTACK, block HEAP }; \ No newline at end of file diff --git a/bsp/ft32/ft32f407xe-starter/board/linker_scripts/link.lds b/bsp/ft32/ft32f407xe-starter/board/linker_scripts/link.lds new file mode 100644 index 00000000000..cbe152d39f5 --- /dev/null +++ b/bsp/ft32/ft32f407xe-starter/board/linker_scripts/link.lds @@ -0,0 +1,157 @@ +/* + * linker script for STM32F10x with GNU ld + */ + +/* Program Entry, set to mark it as "used" and avoid gc */ +MEMORY +{ + ROM (rx) : ORIGIN = 0x08000000, LENGTH = 512k /* 512KB flash */ + RAM (rw) : ORIGIN = 0x20000000, LENGTH = 128k /* 128K sram */ +} +ENTRY(Reset_Handler) +_system_stack_size = 0x400; + +SECTIONS +{ + .text : + { + . = ALIGN(4); + _stext = .; + KEEP(*(.isr_vector)) /* Startup code */ + + . = ALIGN(4); + *(.text) /* remaining code */ + *(.text.*) /* remaining code */ + *(.rodata) /* read-only data (constants) */ + *(.rodata*) + *(.glue_7) + *(.glue_7t) + *(.gnu.linkonce.t*) + + /* section information for finsh shell */ + . = ALIGN(4); + __fsymtab_start = .; + KEEP(*(FSymTab)) + __fsymtab_end = .; + + . = ALIGN(4); + __vsymtab_start = .; + KEEP(*(VSymTab)) + __vsymtab_end = .; + + /* section information for initial. */ + . = ALIGN(4); + __rt_init_start = .; + KEEP(*(SORT(.rti_fn*))) + __rt_init_end = .; + + . = ALIGN(4); + + PROVIDE(__ctors_start__ = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + PROVIDE(__ctors_end__ = .); + + . = ALIGN(4); + + _etext = .; + } > ROM = 0 + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + + /* This is used by the startup in order to initialize the .data secion */ + _sidata = .; + } > ROM + __exidx_end = .; + + /* .data section which is used for initialized data */ + + .data : AT (_sidata) + { + . = ALIGN(4); + /* This is used by the startup in order to initialize the .data secion */ + _sdata = . ; + + *(.data) + *(.data.*) + *(.gnu.linkonce.d*) + + + PROVIDE(__dtors_start__ = .); + KEEP(*(SORT(.dtors.*))) + KEEP(*(.dtors)) + PROVIDE(__dtors_end__ = .); + + . = ALIGN(4); + /* This is used by the startup in order to initialize the .data secion */ + _edata = . ; + } >RAM + + .stack : + { + . = ALIGN(4); + _sstack = .; + . = . + _system_stack_size; + . = ALIGN(4); + _estack = .; + } >RAM + + __bss_start = .; + .bss : + { + . = ALIGN(4); + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; + + *(.bss) + *(.bss.*) + *(COMMON) + + . = ALIGN(4); + /* This is used by the startup in order to initialize the .bss secion */ + _ebss = . ; + + *(.bss.init) + } > RAM + __bss_end = .; + + _end = .; + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + /* DWARF debug sections. + * Symbols in the DWARF debugging sections are relative to the beginning + * of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } +} diff --git a/bsp/ft32/ft32f407xe-starter/board/linker_scripts/link.sct b/bsp/ft32/ft32f407xe-starter/board/linker_scripts/link.sct new file mode 100644 index 00000000000..5d1e3e6c008 --- /dev/null +++ b/bsp/ft32/ft32f407xe-starter/board/linker_scripts/link.sct @@ -0,0 +1,15 @@ +; ************************************************************* +; *** Scatter-Loading Description File generated by uVision *** +; ************************************************************* + +LR_IROM1 0x08000000 0x00080000 { ; load region size_region + ER_IROM1 0x08000000 0x00080000 { ; load address = execution address + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + } + RW_IRAM1 0x20000000 0x00020000 { ; RW data + .ANY (+RW +ZI) + } +} + diff --git a/bsp/ft32/ft32f407xe-starter/figures/ft32f407xe-starter.jpg b/bsp/ft32/ft32f407xe-starter/figures/ft32f407xe-starter.jpg new file mode 100644 index 0000000000000000000000000000000000000000..444e0ac9f2fdf6d73271bfabbafe5fe34e5e8cfe GIT binary patch literal 831855 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

V)k~s&BwaX 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�@adnOV!9@|F2Ik1|K)ahj5WJw!0 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 z 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�QBzgOqiSDSxbQ1eNoA$C1y>2nlqH%Ok+Cau>z1;y!=1448^Q zJ%#iJzQ;41-=jvg=iUF@CmC6&``vQDQ<+jIQqGXoMfC>0beh8s4@!`DjSoFIP5Kn) z9wrYGe`u`u=bqrKWOoIHL=?;d{YXrvpG-GHrdxoX{ys8I?~xA!j~yfGtYe={|^4SQhy;CdwkgWnPegPGMcPaXk>4(*Xyd8(m)t>cQLi zH3P!Lrwb+lE|?S{1u%Ea8z8Wc+LVTR?QSSv^S(9hzodnE;8`m&cx*8;>?A8D-7n}1 zEB}U94L;HysI}otzT9cYo|xe`!^M}IepbF$SHpGJzkg8aYq1g z-z*8pDa1e$$$Zd9Sc7k#%8;K50Eg{cyMkwlzDjc8)zfMVw=pYL!I5j7K@Jw$x39Tx z@$=L+q<6L7A*f>xZtSew{MY)BzpWB#*fTLwx>c|A0n!pZ^cSA}z$VYt2oYiZ60i^) zb#X7Zc>^s}ZkWR4-U)CRylLSUXeQOx|Newe_~N(UjiATrp3)2dJ_Qj5SJe2JDzJ7j zr)0%x*iG_->AGQ7%xRA6H|Y4t6OH`dZ@Wf%-n`8fg*l+5r;i5(_hzXz1=uzNgCB1< z%>T{t!!Om@(G!>*`8i^G`1y!(^@RdMKC*9VY@y6rhp1a=!rqCt4CCY*gkKXDwfezl z9V;wIajPCMt3>SqK}XJp?%%`WJWq+|sWcZ#-!p}rtwTqzug>tTB57e)CzXw}6_O-c zUt)-Dt_~^cK#+F81QR0cM+kJkbyo}hm{mY`@%y$Ke=cBZ$j$&5nm2Z;UFH?KU*Ze2 zdzJo`u9iKrF_>3*ooJ+8qW?xS9RX#bX~6ZLLXbe*k|et_je^IV2>l8<-BNaOf#f) zX^sYB6Q2AWNW0r(^5*d`!7+xnO}!Mb&*j$P-HFF#lx#Y;B79Zrs5M^Q?+f}XWqe0c zxCf80+*G2`6}X}XPLibPU@x5uUrogK7n(TCf|fQfw&9E5 zKQEwI)kH{YX=Tj8+S#+PA4&OMkEm&Or@scOJqz1h6*&?i)5R3il4+s#2hOC(ush}k zACmJN{hq*&opbykVHfJM50-CcT#dUIS6!g zVHUXhKpDldE$zSL%W-lgLA=A2WbqLH@*I4$_aPWw(SL{(=X(*{0-BsDBAEuL3bk$u z&VTDieHHmrr6J_d6np9Rx;oe3LwLBEP@B`rP%VSJsx3CTZo(BPSk}$$SZKG@`yj%d zlgA6xzGFKql8bMtb$BoA%h!BdXV(fCdP+v@EHg!3^|0>l?pvl5tA&GQKL)b|PmWpk zNyP{)q>h~T(r6+agmtd?Ot3xgQa?Rii(k%Wv-ULo5UZJ_qmtSdA3WkY8ymV zq%Pad3Z$stK4zPQJ9KGbA2FPAmMmz;)ODx8!Wn_<*5?6dQJzqWt)|S7$6Aln_E$3l ze`v^JH7QAU3&)zGf?vd|S)4wMflj{aqom4PNqJf{{>_UOfxOpzF3ZF6u+iQp@+k3A zINgQ)QOp4XdDi@#Jv8xZ(gsqEPHC ziX;bOSD1jbD1d*5*X#wMUn-}q<}J9)=K-8G*vxBS>a$e3W)}`p1D2)=ZIZyd$O_!+ zMX%ip;2z14KWbq(nnPI*EzYHLGiTu9(~pXGKc79iAb*TfE0^0GqNnh3;3ZwvMyb9~S!ouy-n#N?U0rcDR5y(^ECPqTt*Y*^* zO+R4YKBpQg1+9*t6>#ejloDCv%^oAtA1)0Y1hW>VKujBe-8i}KL zuBsKZk_93idK1^iKYd^*e`fB_1K6^k9?P}YdF)5eVk>X>T$q53YHaB&OSjLo;2D$y ze;tNj*Mb35B8FZhP=^}2V1a$L4p4c7gSVx~;n{JjA$?K5-5R0--R*)&6o=E(CsU!378LI1#S`o2ed`qeXp*Ncd4Z-fKVSAxk7M;iT<+1y z!D*Se3)T4^{-(Ys1|Iv`w{qpC+%Yy0wC`Riyr1{l!iWs(v)bT^;ROaaoK_%$1%zeq zCafN~>au$@$#nP5PY0>xr;3N2iLZ{fZD`aN2>|*zFN&esRlM20`RPD?3@R2IhCfqa8b;_ndW`@Q$l zmni>{`S7T?)&M-HbD1gOWt$e>J3*8r_+CQDxa;5U-WQ5$

N=>y!y+*f|mtvqu)k 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 + + + 2.1 + +

### uVision Project, (C) Keil Software
+ + + + rt-thread + 0x4 + ARM-ADS + 5060528::V5.06 update 5 (build 528)::.\ARMCC + 0 + + + FT32F407VEA2 + FMD + FMD.FT32F4xx_DFP.1.0.0 + https://www.fremontmicro.com/upload/tools/pack/ + IRAM(0x20000000,0x00020000) IRAM2(0x10000000,0x00010000) IROM(0x08000000,0x00080000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0FT32F4xx_512 -FS08000000 -FL080000 -FP0($$Device:FT32F407VEA2$Flash\FT32F4xx_512.FLM)) + 0 + + + + + + + + + + + $$Device:FT32F407VEA2$SVD\FT32F407x.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\build\keil\Obj\ + rt-thread + 1 + 0 + 0 + 1 + 0 + .\build\keil\List\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 1 + 0 + fromelf --bin !L --output rtthread.bin + + 0 + 0 + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + -REMAP -MPU + DCM.DLL + -pCM4 + SARMCM3.DLL + -MPU + TCM.DLL + -pCM4 + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4096 + + 1 + BIN\UL2CM3.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-M4" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 2 + 0 + 0 + 0 + 1 + 0 + 8 + 1 + 0 + 0 + 0 + 3 + 4 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x20000 + + + 1 + 0x8000000 + 0x80000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x8000000 + 0x80000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x20000 + + + 0 + 0x10000000 + 0x10000 + + + + + + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 2 + 0 + 0 + 1 + 1 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + + + FT32F407xE, RT_USING_LIBC, __STDC_LIMIT_MACROS, __RTTHREAD__, __CLK_TCK=RT_TICK_PER_SECOND, RT_USING_ARMLIBC + + ..\..\..\components\libc\posix\ipc;..\..\..\components\libc\compilers\common\extension\fcntl\octal;..\..\..\libcpu\arm\cortex-m4;..\..\..\components\libc\posix\io\eventfd;..\..\..\components\drivers\include;..\..\..\components\finsh;..\..\..\components\libc\posix\io\poll;..\..\..\components\drivers\include;..\..\..\components\drivers\smp_call;board;..\libraries\Drivers;..\..\..\components\libc\compilers\common\include;..\..\..\components\drivers\phy;..\..\..\components\libc\compilers\common\extension;..\..\..\components\drivers\include;..\libraries\FT32F4xx\FT32F4xx_Driver\inc;..\..\..\components\drivers\include;applications;..\libraries\FT32F4xx\FT32F4xx_Driver\templates\inc;.;..\..\..\include;..\..\..\components\libc\posix\io\epoll;..\..\..\libcpu\arm\common;..\..\..\components\drivers\include;..\libraries\FT32F4xx\CMSIS\FT32F4xx\include + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 4 + + + + + + + + + 0 + 0 + 0 + 0 + 1 + 0 + 0x08000000 + 0x20000000 + + .\board\linker_scripts\link.sct + + + + + + + + + + + Applications + + + main.c + 1 + .\applications\main.c + + + + + Compiler + + + syscall_mem.c + 1 + ..\..\..\components\libc\compilers\armlibc\syscall_mem.c + + + syscalls.c + 1 + ..\..\..\components\libc\compilers\armlibc\syscalls.c + + + cctype.c + 1 + ..\..\..\components\libc\compilers\common\cctype.c + + + cstdlib.c + 1 + ..\..\..\components\libc\compilers\common\cstdlib.c + + + cstring.c + 1 + ..\..\..\components\libc\compilers\common\cstring.c + + + ctime.c + 1 + ..\..\..\components\libc\compilers\common\ctime.c + + + cunistd.c + 1 + ..\..\..\components\libc\compilers\common\cunistd.c + + + cwchar.c + 1 + ..\..\..\components\libc\compilers\common\cwchar.c + + + + + DeviceDrivers + + + device.c + 1 + ..\..\..\components\drivers\core\device.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + __RT_IPC_SOURCE__ + + + + + + + + + completion_comm.c + 1 + ..\..\..\components\drivers\ipc\completion_comm.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + __RT_IPC_SOURCE__ + + + + + + + + + completion_up.c + 1 + ..\..\..\components\drivers\ipc\completion_up.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + __RT_IPC_SOURCE__ + + + + + + + + + condvar.c + 1 + ..\..\..\components\drivers\ipc\condvar.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + __RT_IPC_SOURCE__ + + + + + + + + + dataqueue.c + 1 + ..\..\..\components\drivers\ipc\dataqueue.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + __RT_IPC_SOURCE__ + + + + + + + + + pipe.c + 1 + ..\..\..\components\drivers\ipc\pipe.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + __RT_IPC_SOURCE__ + + + + + + + + + ringblk_buf.c + 1 + ..\..\..\components\drivers\ipc\ringblk_buf.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + __RT_IPC_SOURCE__ + + + + + + + + + ringbuffer.c + 1 + ..\..\..\components\drivers\ipc\ringbuffer.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + __RT_IPC_SOURCE__ + + + + + + + + + waitqueue.c + 1 + ..\..\..\components\drivers\ipc\waitqueue.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + __RT_IPC_SOURCE__ + + + + + + + + + workqueue.c + 1 + ..\..\..\components\drivers\ipc\workqueue.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + __RT_IPC_SOURCE__ + + + + + + + + + dev_pin.c + 1 + ..\..\..\components\drivers\pin\dev_pin.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + __RT_IPC_SOURCE__ + + + + + + + + + dev_serial.c + 1 + ..\..\..\components\drivers\serial\dev_serial.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + __RT_IPC_SOURCE__ + + + + + + + + + + + Drivers + + + board.c + 1 + .\board\board.c + + + startup_ft32f407xe.s + 2 + ..\libraries\FT32F4xx\CMSIS\FT32F4xx\source\arm\startup_ft32f407xe.s + + + drv_gpio.c + 1 + ..\libraries\Drivers\drv_gpio.c + + + drv_usart.c + 1 + ..\libraries\Drivers\drv_usart.c + + + + + Finsh + + + cmd.c + 1 + ..\..\..\components\finsh\cmd.c + + + msh_parse.c + 1 + ..\..\..\components\finsh\msh_parse.c + + + shell.c + 1 + ..\..\..\components\finsh\shell.c + + + msh.c + 1 + ..\..\..\components\finsh\msh.c + + + + + Kernel + + + clock.c + 1 + ..\..\..\src\clock.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + __RT_KERNEL_SOURCE__ + + + + + + + + + components.c + 1 + ..\..\..\src\components.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + __RT_KERNEL_SOURCE__ + + + + + + + + + cpu_up.c + 1 + ..\..\..\src\cpu_up.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + __RT_KERNEL_SOURCE__ + + + + + + + + + defunct.c + 1 + ..\..\..\src\defunct.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + __RT_KERNEL_SOURCE__ + + + + + + + + + idle.c + 1 + ..\..\..\src\idle.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + __RT_KERNEL_SOURCE__ + + + + + + + + + ipc.c + 1 + ..\..\..\src\ipc.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + __RT_KERNEL_SOURCE__ + + + + + + + + + irq.c + 1 + ..\..\..\src\irq.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + __RT_KERNEL_SOURCE__ + + + + + + + + + kservice.c + 1 + ..\..\..\src\kservice.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + __RT_KERNEL_SOURCE__ + + + + + + + + + mem.c + 1 + ..\..\..\src\mem.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + __RT_KERNEL_SOURCE__ + + + + + + + + + mempool.c + 1 + ..\..\..\src\mempool.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + __RT_KERNEL_SOURCE__ + + + + + + + + + object.c + 1 + ..\..\..\src\object.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + __RT_KERNEL_SOURCE__ + + + + + + + + + scheduler_comm.c + 1 + ..\..\..\src\scheduler_comm.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + __RT_KERNEL_SOURCE__ + + + + + + + + + scheduler_up.c + 1 + ..\..\..\src\scheduler_up.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + __RT_KERNEL_SOURCE__ + + + + + + + + + thread.c + 1 + ..\..\..\src\thread.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + __RT_KERNEL_SOURCE__ + + + + + + + + + timer.c + 1 + ..\..\..\src\timer.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + __RT_KERNEL_SOURCE__ + + + + + + + + + + + klibc + + + kstring.c + 1 + ..\..\..\src\klibc\kstring.c + + + kerrno.c + 1 + ..\..\..\src\klibc\kerrno.c + + + rt_vsnprintf_tiny.c + 1 + ..\..\..\src\klibc\rt_vsnprintf_tiny.c + + + rt_vsscanf.c + 1 + ..\..\..\src\klibc\rt_vsscanf.c + + + kstdio.c + 1 + ..\..\..\src\klibc\kstdio.c + + + + + libcpu + + + div0.c + 1 + ..\..\..\libcpu\arm\common\div0.c + + + showmem.c + 1 + ..\..\..\libcpu\arm\common\showmem.c + + + context_rvds.S + 2 + ..\..\..\libcpu\arm\cortex-m4\context_rvds.S + + + cpuport.c + 1 + ..\..\..\libcpu\arm\cortex-m4\cpuport.c + + + + + Libraries + + + ft32f4xx_adc.c + 1 + ..\libraries\FT32F4xx\FT32F4xx_Driver\src\ft32f4xx_adc.c + + + ft32f4xx_comp.c + 1 + ..\libraries\FT32F4xx\FT32F4xx_Driver\src\ft32f4xx_comp.c + + + ft32f4xx_crc.c + 1 + ..\libraries\FT32F4xx\FT32F4xx_Driver\src\ft32f4xx_crc.c + + + ft32f4xx_crs.c + 1 + ..\libraries\FT32F4xx\FT32F4xx_Driver\src\ft32f4xx_crs.c + + + ft32f4xx_dac.c + 1 + ..\libraries\FT32F4xx\FT32F4xx_Driver\src\ft32f4xx_dac.c + + + ft32f4xx_debug.c + 1 + ..\libraries\FT32F4xx\FT32F4xx_Driver\src\ft32f4xx_debug.c + + + ft32f4xx_dma.c + 1 + ..\libraries\FT32F4xx\FT32F4xx_Driver\src\ft32f4xx_dma.c + + + ft32f4xx_ecap.c + 1 + ..\libraries\FT32F4xx\FT32F4xx_Driver\src\ft32f4xx_ecap.c + + + ft32f4xx_epwm.c + 1 + ..\libraries\FT32F4xx\FT32F4xx_Driver\src\ft32f4xx_epwm.c + + + ft32f4xx_eqep.c + 1 + ..\libraries\FT32F4xx\FT32F4xx_Driver\src\ft32f4xx_eqep.c + + + ft32f4xx_eth.c + 1 + ..\libraries\FT32F4xx\FT32F4xx_Driver\src\ft32f4xx_eth.c + + + ft32f4xx_exti.c + 1 + ..\libraries\FT32F4xx\FT32F4xx_Driver\src\ft32f4xx_exti.c + + + ft32f4xx_fdcan.c + 1 + ..\libraries\FT32F4xx\FT32F4xx_Driver\src\ft32f4xx_fdcan.c + + + ft32f4xx_flash.c + 1 + ..\libraries\FT32F4xx\FT32F4xx_Driver\src\ft32f4xx_flash.c + + + ft32f4xx_fmc.c + 1 + ..\libraries\FT32F4xx\FT32F4xx_Driver\src\ft32f4xx_fmc.c + + + ft32f4xx_gpio.c + 1 + ..\libraries\FT32F4xx\FT32F4xx_Driver\src\ft32f4xx_gpio.c + + + ft32f4xx_i2c.c + 1 + ..\libraries\FT32F4xx\FT32F4xx_Driver\src\ft32f4xx_i2c.c + + + ft32f4xx_i2s.c + 1 + ..\libraries\FT32F4xx\FT32F4xx_Driver\src\ft32f4xx_i2s.c + + + ft32f4xx_iwdg.c + 1 + ..\libraries\FT32F4xx\FT32F4xx_Driver\src\ft32f4xx_iwdg.c + + + ft32f4xx_lptim.c + 1 + ..\libraries\FT32F4xx\FT32F4xx_Driver\src\ft32f4xx_lptim.c + + + ft32f4xx_misc.c + 1 + ..\libraries\FT32F4xx\FT32F4xx_Driver\src\ft32f4xx_misc.c + + + ft32f4xx_opamp.c + 1 + ..\libraries\FT32F4xx\FT32F4xx_Driver\src\ft32f4xx_opamp.c + + + ft32f4xx_pwr.c + 1 + ..\libraries\FT32F4xx\FT32F4xx_Driver\src\ft32f4xx_pwr.c + + + ft32f4xx_qspi.c + 1 + ..\libraries\FT32F4xx\FT32F4xx_Driver\src\ft32f4xx_qspi.c + + + ft32f4xx_rcc.c + 1 + ..\libraries\FT32F4xx\FT32F4xx_Driver\src\ft32f4xx_rcc.c + + + ft32f4xx_rng.c + 1 + ..\libraries\FT32F4xx\FT32F4xx_Driver\src\ft32f4xx_rng.c + + + ft32f4xx_rtc.c + 1 + ..\libraries\FT32F4xx\FT32F4xx_Driver\src\ft32f4xx_rtc.c + + + ft32f4xx_sdio.c + 1 + ..\libraries\FT32F4xx\FT32F4xx_Driver\src\ft32f4xx_sdio.c + + + ft32f4xx_spdif.c + 1 + ..\libraries\FT32F4xx\FT32F4xx_Driver\src\ft32f4xx_spdif.c + + + ft32f4xx_spi.c + 1 + ..\libraries\FT32F4xx\FT32F4xx_Driver\src\ft32f4xx_spi.c + + + ft32f4xx_ssi.c + 1 + ..\libraries\FT32F4xx\FT32F4xx_Driver\src\ft32f4xx_ssi.c + + + ft32f4xx_syscfg.c + 1 + ..\libraries\FT32F4xx\FT32F4xx_Driver\src\ft32f4xx_syscfg.c + + + ft32f4xx_tim.c + 1 + ..\libraries\FT32F4xx\FT32F4xx_Driver\src\ft32f4xx_tim.c + + + ft32f4xx_uart.c + 1 + ..\libraries\FT32F4xx\FT32F4xx_Driver\src\ft32f4xx_uart.c + + + ft32f4xx_usart.c + 1 + ..\libraries\FT32F4xx\FT32F4xx_Driver\src\ft32f4xx_usart.c + + + ft32f4xx_wwdg.c + 1 + ..\libraries\FT32F4xx\FT32F4xx_Driver\src\ft32f4xx_wwdg.c + + + system_ft32f4xx.c + 1 + ..\libraries\FT32F4xx\CMSIS\FT32F4xx\source\system_ft32f4xx.c + + + + + + + + + + + + + + + + + project + 1 + + + + + diff --git a/bsp/ft32/ft32f407xe-starter/rtconfig.h b/bsp/ft32/ft32f407xe-starter/rtconfig.h new file mode 100644 index 00000000000..5942ded4c8d --- /dev/null +++ b/bsp/ft32/ft32f407xe-starter/rtconfig.h @@ -0,0 +1,413 @@ +#ifndef RT_CONFIG_H__ +#define RT_CONFIG_H__ + +/* RT-Thread Kernel */ + +/* klibc options */ + +/* rt_vsnprintf options */ + +/* end of rt_vsnprintf options */ + +/* rt_vsscanf options */ + +/* end of rt_vsscanf options */ + +/* rt_memset options */ + +/* end of rt_memset options */ + +/* rt_memcpy options */ + +/* end of rt_memcpy options */ + +/* rt_memmove options */ + +/* end of rt_memmove options */ + +/* rt_memcmp options */ + +/* end of rt_memcmp options */ + +/* rt_strstr options */ + +/* end of rt_strstr options */ + +/* rt_strcasecmp options */ + +/* end of rt_strcasecmp options */ + +/* rt_strncpy options */ + +/* end of rt_strncpy options */ + +/* rt_strcpy options */ + +/* end of rt_strcpy options */ + +/* rt_strncmp options */ + +/* end of rt_strncmp options */ + +/* rt_strcmp options */ + +/* end of rt_strcmp options */ + +/* rt_strlen options */ + +/* end of rt_strlen options */ + +/* rt_strnlen options */ + +/* end of rt_strnlen options */ +/* end of klibc options */ +#define RT_NAME_MAX 12 +#define RT_CPUS_NR 1 +#define RT_ALIGN_SIZE 8 +#define RT_THREAD_PRIORITY_32 +#define RT_THREAD_PRIORITY_MAX 32 +#define RT_TICK_PER_SECOND 1000 +#define RT_USING_OVERFLOW_CHECK +#define RT_USING_HOOK +#define RT_HOOK_USING_FUNC_PTR +#define RT_USING_IDLE_HOOK +#define RT_IDLE_HOOK_LIST_SIZE 4 +#define IDLE_THREAD_STACK_SIZE 256 + +/* kservice options */ + +/* end of kservice options */ +#define RT_USING_DEBUG +#define RT_DEBUGING_ASSERT +#define RT_DEBUGING_COLOR +#define RT_DEBUGING_CONTEXT + +/* Inter-Thread communication */ + +#define RT_USING_SEMAPHORE +#define RT_USING_MUTEX +#define RT_USING_EVENT +#define RT_USING_MAILBOX +#define RT_USING_MESSAGEQUEUE +/* end of Inter-Thread communication */ + +/* Memory Management */ + +#define RT_USING_MEMPOOL +#define RT_USING_SMALL_MEM +#define RT_USING_SMALL_MEM_AS_HEAP +#define RT_USING_HEAP +/* end of Memory Management */ +#define RT_USING_DEVICE +#define RT_USING_CONSOLE +#define RT_CONSOLEBUF_SIZE 128 +#define RT_CONSOLE_DEVICE_NAME "uart2" +#define RT_VER_NUM 0x50201 +#define RT_BACKTRACE_LEVEL_MAX_NR 32 +/* end of RT-Thread Kernel */ +#define ARCH_ARM +#define ARCH_ARM_CORTEX_M +#define ARCH_ARM_CORTEX_M0 + +/* RT-Thread Components */ + +#define RT_USING_COMPONENTS_INIT +#define RT_USING_USER_MAIN +#define RT_MAIN_THREAD_STACK_SIZE 2048 +#define RT_MAIN_THREAD_PRIORITY 10 +#define RT_USING_MSH +#define RT_USING_FINSH +#define FINSH_USING_MSH +#define FINSH_THREAD_NAME "tshell" +#define FINSH_THREAD_PRIORITY 20 +#define FINSH_THREAD_STACK_SIZE 4096 +#define FINSH_USING_HISTORY +#define FINSH_HISTORY_LINES 5 +#define FINSH_USING_SYMTAB +#define FINSH_CMD_SIZE 80 +#define MSH_USING_BUILT_IN_COMMANDS +#define FINSH_USING_DESCRIPTION +#define FINSH_ARG_MAX 10 +#define FINSH_USING_OPTION_COMPLETION + +/* DFS: device virtual file system */ + +/* end of DFS: device virtual file system */ + +/* Device Drivers */ + +#define RT_USING_DEVICE_IPC +#define RT_UNAMED_PIPE_NUMBER 64 +#define RT_USING_SERIAL +#define RT_USING_SERIAL_V1 +#define RT_SERIAL_RB_BUFSZ 64 +#define RT_USING_PIN +/* end of Device Drivers */ + +/* C/C++ and POSIX layer */ + +/* ISO-ANSI C layer */ + +/* Timezone and Daylight Saving Time */ + +#define RT_LIBC_USING_LIGHT_TZ_DST +#define RT_LIBC_TZ_DEFAULT_HOUR 8 +#define RT_LIBC_TZ_DEFAULT_MIN 0 +#define RT_LIBC_TZ_DEFAULT_SEC 0 +/* end of Timezone and Daylight Saving Time */ +/* end of ISO-ANSI C layer */ + +/* POSIX (Portable Operating System Interface) layer */ + + +/* Interprocess Communication (IPC) */ + + +/* Socket is in the 'Network' category */ + +/* end of Interprocess Communication (IPC) */ +/* end of POSIX (Portable Operating System Interface) layer */ +/* end of C/C++ and POSIX layer */ + +/* Network */ + +/* end of Network */ + +/* Memory protection */ + +/* end of Memory protection */ + +/* Utilities */ + +/* end of Utilities */ + +/* Using USB legacy version */ + +/* end of Using USB legacy version */ +/* end of RT-Thread Components */ + +/* RT-Thread Utestcases */ + +/* end of RT-Thread Utestcases */ + +/* RT-Thread online packages */ + +/* IoT - internet of things */ + + +/* Wi-Fi */ + +/* Marvell WiFi */ + +/* end of Marvell WiFi */ + +/* Wiced WiFi */ + +/* end of Wiced WiFi */ + +/* CYW43012 WiFi */ + +/* end of CYW43012 WiFi */ + +/* BL808 WiFi */ + +/* end of BL808 WiFi */ + +/* CYW43439 WiFi */ + +/* end of CYW43439 WiFi */ +/* end of Wi-Fi */ + +/* IoT Cloud */ + +/* end of IoT Cloud */ +/* end of IoT - internet of things */ + +/* security packages */ + +/* end of security packages */ + +/* language packages */ + +/* JSON: JavaScript Object Notation, a lightweight data-interchange format */ + +/* end of JSON: JavaScript Object Notation, a lightweight data-interchange format */ + +/* XML: Extensible Markup Language */ + +/* end of XML: Extensible Markup Language */ +/* end of language packages */ + +/* multimedia packages */ + +/* LVGL: powerful and easy-to-use embedded GUI library */ + +/* end of LVGL: powerful and easy-to-use embedded GUI library */ + +/* u8g2: a monochrome graphic library */ + +/* end of u8g2: a monochrome graphic library */ +/* end of multimedia packages */ + +/* tools packages */ + +/* end of tools packages */ + +/* system packages */ + +/* enhanced kernel services */ + +/* end of enhanced kernel services */ + +/* acceleration: Assembly language or algorithmic acceleration packages */ + +/* end of acceleration: Assembly language or algorithmic acceleration packages */ + +/* CMSIS: ARM Cortex-M Microcontroller Software Interface Standard */ + +/* end of CMSIS: ARM Cortex-M Microcontroller Software Interface Standard */ + +/* Micrium: Micrium software products porting for RT-Thread */ + +/* end of Micrium: Micrium software products porting for RT-Thread */ +/* end of system packages */ + +/* peripheral libraries and drivers */ + +/* HAL & SDK Drivers */ + +/* STM32 HAL & SDK Drivers */ + +/* end of STM32 HAL & SDK Drivers */ + +/* Infineon HAL Packages */ + +/* end of Infineon HAL Packages */ + +/* Kendryte SDK */ + +/* end of Kendryte SDK */ + +/* WCH HAL & SDK Drivers */ + +/* end of WCH HAL & SDK Drivers */ + +/* AT32 HAL & SDK Drivers */ + +/* end of AT32 HAL & SDK Drivers */ + +/* HC32 DDL Drivers */ + +/* end of HC32 DDL Drivers */ + +/* NXP HAL & SDK Drivers */ + +/* end of NXP HAL & SDK Drivers */ + +/* NUVOTON Drivers */ + +/* end of NUVOTON Drivers */ + +/* GD32 Drivers */ + +/* end of GD32 Drivers */ +/* end of HAL & SDK Drivers */ + +/* sensors drivers */ + +/* end of sensors drivers */ + +/* touch drivers */ + +/* end of touch drivers */ +/* end of peripheral libraries and drivers */ + +/* AI packages */ + +/* end of AI packages */ + +/* Signal Processing and Control Algorithm Packages */ + +/* end of Signal Processing and Control Algorithm Packages */ + +/* miscellaneous packages */ + +/* project laboratory */ + +/* end of project laboratory */ + +/* samples: kernel and components samples */ + +/* end of samples: kernel and components samples */ + +/* entertainment: terminal games and other interesting software packages */ + +/* end of entertainment: terminal games and other interesting software packages */ +/* end of miscellaneous packages */ + +/* Arduino libraries */ + + +/* Projects and Demos */ + +/* end of Projects and Demos */ + +/* Sensors */ + +/* end of Sensors */ + +/* Display */ + +/* end of Display */ + +/* Timing */ + +/* end of Timing */ + +/* Data Processing */ + +/* end of Data Processing */ + +/* Data Storage */ + +/* Communication */ + +/* end of Communication */ + +/* Device Control */ + +/* end of Device Control */ + +/* Other */ + +/* end of Other */ + +/* Signal IO */ + +/* end of Signal IO */ + +/* Uncategorized */ + +/* end of Arduino libraries */ +/* end of RT-Thread online packages */ +#define SOC_FAMILY_FT32 +#define SOC_SERIES_FT32F4 + +/* Hardware Drivers Config */ + +#define SOC_FT32F407VE + +/* Onboard Peripheral Drivers */ + +/* On-chip Peripheral Drivers */ + +#define BSP_USING_GPIO +#define BSP_USING_UART2 + +/* end of On-chip Peripheral Drivers */ + +/* Board extended module Drivers */ + +/* end of Hardware Drivers Config */ + +#endif diff --git a/bsp/ft32/ft32f407xe-starter/rtconfig.py b/bsp/ft32/ft32f407xe-starter/rtconfig.py new file mode 100644 index 00000000000..5ad587f65a2 --- /dev/null +++ b/bsp/ft32/ft32f407xe-starter/rtconfig.py @@ -0,0 +1,185 @@ +import os + +# toolchains options +ARCH='arm' +CPU='cortex-m4' +CROSS_TOOL='gcc' + +# bsp lib config +BSP_LIBRARY_TYPE = None + +if os.getenv('RTT_CC'): + CROSS_TOOL = os.getenv('RTT_CC') +if os.getenv('RTT_ROOT'): + RTT_ROOT = os.getenv('RTT_ROOT') + +# cross_tool provides the cross compiler +# EXEC_PATH is the compiler execute path, for example, CodeSourcery, Keil MDK, IAR +if CROSS_TOOL == 'gcc': + PLATFORM = 'gcc' + EXEC_PATH = r'C:\Users\XXYYZZ' +elif CROSS_TOOL == 'keil': + PLATFORM = 'armcc' + EXEC_PATH = r'C:/Keil_v5' +elif CROSS_TOOL == 'iar': + PLATFORM = 'iccarm' + EXEC_PATH = r'C:/Program Files (x86)/IAR Systems/Embedded Workbench 8.3' + +if os.getenv('RTT_EXEC_PATH'): + EXEC_PATH = os.getenv('RTT_EXEC_PATH') + +BUILD = 'debug' + +if PLATFORM == 'gcc': + # toolchains + PREFIX = 'arm-none-eabi-' + CC = PREFIX + 'gcc' + AS = PREFIX + 'gcc' + AR = PREFIX + 'ar' + CXX = PREFIX + 'g++' + LINK = PREFIX + 'gcc' + TARGET_EXT = 'elf' + SIZE = PREFIX + 'size' + OBJDUMP = PREFIX + 'objdump' + OBJCPY = PREFIX + 'objcopy' + + DEVICE = ' -mcpu=cortex-m4 -mthumb -ffunction-sections -fdata-sections' + CFLAGS = DEVICE + ' -Dgcc' + AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp -Wa,-mimplicit-it=thumb ' + LFLAGS = DEVICE + ' -Wl,--gc-sections,-Map=rt-thread.map,-cref,-u,Reset_Handler -T board/linker_scripts/link.lds' + + CPATH = '' + LPATH = '' + + if BUILD == 'debug': + CFLAGS += ' -O0 -gdwarf-2 -g' + AFLAGS += ' -gdwarf-2' + else: + CFLAGS += ' -O2' + + CXXFLAGS = CFLAGS + + POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread.bin\n' + SIZE + ' $TARGET \n' + +elif PLATFORM == 'armcc': + # toolchains + CC = 'armcc' + CXX = 'armcc' + AS = 'armasm' + AR = 'armar' + LINK = 'armlink' + TARGET_EXT = 'axf' + + DEVICE = ' --cpu Cortex-M4 ' + CFLAGS = '-c ' + DEVICE + ' --apcs=interwork --c99' + AFLAGS = DEVICE + ' --apcs=interwork ' + LFLAGS = DEVICE + ' --scatter "board\linker_scripts\link.sct" --info sizes --info totals --info unused --info veneers --list rt-thread.map --strict' + CFLAGS += ' -I' + EXEC_PATH + '/ARM/ARMCC/include' + LFLAGS += ' --libpath=' + EXEC_PATH + '/ARM/ARMCC/lib' + + CFLAGS += ' -D__MICROLIB ' + AFLAGS += ' --pd "__MICROLIB SETA 1" ' + LFLAGS += ' --library_type=microlib ' + EXEC_PATH += '/ARM/ARMCC/bin/' + + if BUILD == 'debug': + CFLAGS += ' -g -O0' + AFLAGS += ' -g' + else: + CFLAGS += ' -O2' + + CXXFLAGS = CFLAGS + CFLAGS += ' -std=c99' + + POST_ACTION = 'fromelf --bin $TARGET --output rtthread.bin \nfromelf -z $TARGET' + +elif PLATFORM == 'armclang': + # toolchains + CC = 'armclang' + CXX = 'armclang' + AS = 'armasm' + AR = 'armar' + LINK = 'armlink' + TARGET_EXT = 'axf' + + DEVICE = ' --cpu Cortex-M4 ' + CFLAGS = ' --target=arm-arm-none-eabi -mcpu=cortex-m4 ' + CFLAGS += ' -mcpu=cortex-m4 ' + CFLAGS += ' -c -fno-rtti -funsigned-char -fshort-enums -fshort-wchar ' + CFLAGS += ' -gdwarf-3 -ffunction-sections ' + AFLAGS = DEVICE + ' --apcs=interwork ' + LFLAGS = DEVICE + ' --info sizes --info totals --info unused --info veneers ' + LFLAGS += ' --list rt-thread.map ' + LFLAGS += r' --strict --scatter "board\linker_scripts\link.sct" ' + CFLAGS += ' -I' + EXEC_PATH + '/ARM/ARMCLANG/include' + LFLAGS += ' --libpath=' + EXEC_PATH + '/ARM/ARMCLANG/lib' + + EXEC_PATH += '/ARM/ARMCLANG/bin/' + + if BUILD == 'debug': + CFLAGS += ' -g -O1' # armclang recommend + AFLAGS += ' -g' + else: + CFLAGS += ' -O2' + + CXXFLAGS = CFLAGS + CFLAGS += ' -std=c99' + + POST_ACTION = 'fromelf --bin $TARGET --output rtthread.bin \nfromelf -z $TARGET' + +elif PLATFORM == 'iccarm': + # toolchains + CC = 'iccarm' + CXX = 'iccarm' + AS = 'iasmarm' + AR = 'iarchive' + LINK = 'ilinkarm' + TARGET_EXT = 'out' + + DEVICE = '-Dewarm' + + CFLAGS = DEVICE + CFLAGS += ' --diag_suppress Pa050' + CFLAGS += ' --no_cse' + CFLAGS += ' --no_unroll' + CFLAGS += ' --no_inline' + CFLAGS += ' --no_code_motion' + CFLAGS += ' --no_tbaa' + CFLAGS += ' --no_clustering' + CFLAGS += ' --no_scheduling' + CFLAGS += ' --endian=little' + CFLAGS += ' --cpu=Cortex-M4' + CFLAGS += ' -e' + CFLAGS += ' --fpu=None' + CFLAGS += ' --dlib_config "' + EXEC_PATH + '/arm/INC/c/DLib_Config_Normal.h"' + CFLAGS += ' --silent' + + AFLAGS = DEVICE + AFLAGS += ' -s+' + AFLAGS += ' -w+' + AFLAGS += ' -r' + AFLAGS += ' --cpu Cortex-M4' + AFLAGS += ' --fpu None' + AFLAGS += ' -S' + + if BUILD == 'debug': + CFLAGS += ' --debug' + CFLAGS += ' -On' + else: + CFLAGS += ' -Oh' + + LFLAGS = ' --config "board/linker_scripts/link.icf"' + LFLAGS += ' --entry __iar_program_start' + + CXXFLAGS = CFLAGS + + EXEC_PATH = EXEC_PATH + '/arm/bin/' + POST_ACTION = 'ielftool --bin $TARGET rtthread.bin' + +def dist_handle(BSP_ROOT, dist_dir): + import sys + cwd_path = os.getcwd() + sys.path.append(os.path.join(os.path.dirname(BSP_ROOT), 'tools')) + from sdk_dist import dist_do_building + dist_do_building(BSP_ROOT, dist_dir) + diff --git a/bsp/ft32/ft32f407xe-starter/template.uvprojx b/bsp/ft32/ft32f407xe-starter/template.uvprojx new file mode 100644 index 00000000000..695d59daa2b --- /dev/null +++ b/bsp/ft32/ft32f407xe-starter/template.uvprojx @@ -0,0 +1,397 @@ + + + + 2.1 + +
### uVision Project, (C) Keil Software
+ + + + rt-thread + 0x4 + ARM-ADS + 5060528::V5.06 update 5 (build 528)::.\ARMCC + 0 + + + FT32F407VEA2 + FMD + FMD.FT32F4xx_DFP.1.0.0 + https://www.fremontmicro.com/upload/tools/pack/ + IRAM(0x20000000,0x00020000) IRAM2(0x10000000,0x00010000) IROM(0x08000000,0x00080000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0FT32F4xx_512 -FS08000000 -FL080000 -FP0($$Device:FT32F407VEA2$Flash\FT32F4xx_512.FLM)) + 0 + + + + + + + + + + + $$Device:FT32F407VEA2$SVD\FT32F407x.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\build\keil\Obj\ + rt-thread + 1 + 0 + 0 + 1 + 0 + .\build\keil\List\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 1 + 0 + fromelf --bin !L --output rtthread.bin + + 0 + 0 + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + -REMAP -MPU + DCM.DLL + -pCM4 + SARMCM3.DLL + -MPU + TCM.DLL + -pCM4 + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4096 + + 1 + BIN\UL2CM3.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-M4" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 2 + 0 + 0 + 0 + 1 + 0 + 8 + 0 + 0 + 0 + 0 + 3 + 4 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x20000 + + + 1 + 0x8000000 + 0x80000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x8000000 + 0x80000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x20000 + + + 0 + 0x10000000 + 0x10000 + + + + + + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 2 + 0 + 0 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + + + + + + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 4 + + + + + + + + + 0 + 0 + 0 + 0 + 1 + 0 + 0x08000000 + 0x20000000 + + .\board\linker_scripts\link.sct + + + + + + + + + + + Source Group 1 + + + + + + + + + + + +
diff --git a/bsp/ft32/libraries/Drivers/drv_config.h b/bsp/ft32/libraries/Drivers/drv_config.h index 8b0c854f8ab..eca48e4f5c4 100644 --- a/bsp/ft32/libraries/Drivers/drv_config.h +++ b/bsp/ft32/libraries/Drivers/drv_config.h @@ -23,6 +23,11 @@ extern "C" { #include "uart_config.h" #endif +#if defined(SOC_SERIES_FT32F4) +#include "dma_config.h" +#include "uart_config.h" +#endif + #ifdef __cplusplus } #endif diff --git a/bsp/ft32/libraries/Drivers/drv_dma.h b/bsp/ft32/libraries/Drivers/drv_dma.h index fe455f958f7..cc1e39c6c91 100644 --- a/bsp/ft32/libraries/Drivers/drv_dma.h +++ b/bsp/ft32/libraries/Drivers/drv_dma.h @@ -22,6 +22,10 @@ extern "C" { #define DMA_INSTANCE_TYPE DMA_Channel_TypeDef #endif +#if defined(SOC_SERIES_FT32F4) +#define DMA_INSTANCE_TYPE DMA_Channel_TypeDef +#endif + struct dma_config { DMA_INSTANCE_TYPE *Instance; rt_uint32_t dma_rcc; diff --git a/bsp/ft32/libraries/Drivers/drv_gpio.c b/bsp/ft32/libraries/Drivers/drv_gpio.c index 479294a3d03..94b03b5c651 100644 --- a/bsp/ft32/libraries/Drivers/drv_gpio.c +++ b/bsp/ft32/libraries/Drivers/drv_gpio.c @@ -6,6 +6,7 @@ * Change Logs: * Date Author Notes * 2022-03-02 FMD-AE first version + * 2025-12-31 FMD-AE add ft32f4 support */ #include @@ -59,6 +60,24 @@ static const struct pin_irq_map pin_irq_map[] = {GPIO_Pin_14, EXTI4_15_IRQn}, {GPIO_Pin_15, EXTI4_15_IRQn}, #endif +#if defined(SOC_SERIES_FT32F4) + {GPIO_Pin_0, EXTI0_IRQn}, + {GPIO_Pin_1, EXTI1_IRQn}, + {GPIO_Pin_2, EXTI2_IRQn}, + {GPIO_Pin_3, EXTI3_IRQn}, + {GPIO_Pin_4, EXTI4_IRQn}, + {GPIO_Pin_5, EXTI9_5_IRQn}, + {GPIO_Pin_6, EXTI9_5_IRQn}, + {GPIO_Pin_7, EXTI9_5_IRQn}, + {GPIO_Pin_8, EXTI9_5_IRQn}, + {GPIO_Pin_9, EXTI9_5_IRQn}, + {GPIO_Pin_10, EXTI15_10_IRQn}, + {GPIO_Pin_11, EXTI15_10_IRQn}, + {GPIO_Pin_12, EXTI15_10_IRQn}, + {GPIO_Pin_13, EXTI15_10_IRQn}, + {GPIO_Pin_14, EXTI15_10_IRQn}, + {GPIO_Pin_15, EXTI15_10_IRQn}, +#endif }; static struct rt_pin_irq_hdr pin_irq_hdr_tab[] = @@ -339,12 +358,18 @@ static void rt_gpio_deinit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin) /* Deactivate the Pull-up and Pull-down resistor for the current IO */ GPIOx->PUPDR &= ~(GPIO_PUPDR_PUPDR0 << (position * 2u)); +#if defined (SOC_SERIES_FT32F0) /* Configure the default value IO Output Type */ GPIOx->OTYPER &= ~(GPIO_OTYPER_OT_0 << position) ; - /* Configure the default value for IO Speed */ GPIOx->OSPEEDR &= ~(GPIO_OSPEEDER_OSPEEDR0 << (position * 2u)); - +#endif +#if defined (SOC_SERIES_FT32F4) + /* Configure the default value IO Output Type */ + GPIOx->OTYPER &= ~(GPIO_OTYPER_OT0 << position) ; + /* Configure the default value for IO Speed */ + GPIOx->OSPEEDR &= ~(GPIO_OSPEEDR_OSPEEDR0 << (position * 2u)); +#endif } position++; @@ -416,6 +441,7 @@ static rt_err_t ft32_pin_irq_enable(struct rt_device *device, rt_base_t pin, break; } GPIO_Init(PIN_FTPORT(pin), &GPIO_InitStruct); + EXTI_Init(&EXTI_InitStructure); NVIC_SetPriority(irqmap->irqno, 5); @@ -438,7 +464,6 @@ static rt_err_t ft32_pin_irq_enable(struct rt_device *device, rt_base_t pin, pin_irq_enable_mask &= ~irqmap->pinbit; - #if defined(SOC_SERIES_FT32F0) if ((irqmap->pinbit >= GPIO_Pin_0) && (irqmap->pinbit <= GPIO_Pin_1)) { @@ -467,6 +492,26 @@ static rt_err_t ft32_pin_irq_enable(struct rt_device *device, rt_base_t pin, NVIC_DisableIRQ(irqmap->irqno); } +#endif +#if defined(SOC_SERIES_FT32F4) + if ((irqmap->pinbit >= GPIO_Pin_5) && (irqmap->pinbit <= GPIO_Pin_9)) + { + if (!(pin_irq_enable_mask & (GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9))) + { + NVIC_DisableIRQ(irqmap->irqno); + } + } + else if ((irqmap->pinbit >= GPIO_Pin_10) && (irqmap->pinbit <= GPIO_Pin_15)) + { + if (!(pin_irq_enable_mask & (GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15))) + { + NVIC_DisableIRQ(irqmap->irqno); + } + } + else + { + NVIC_DisableIRQ(irqmap->irqno); + } #endif rt_hw_interrupt_enable(level); } @@ -546,15 +591,84 @@ void EXTI4_15_IRQHandler(void) rt_interrupt_leave(); } #endif +#if defined(SOC_SERIES_FT32F4) +void EXTI0_Handler(void) +{ + rt_interrupt_enter(); + GPIO_EXTI_IRQHandler(GPIO_Pin_0); + rt_interrupt_leave(); +} + +void EXTI1_Handler(void) +{ + rt_interrupt_enter(); + GPIO_EXTI_IRQHandler(GPIO_Pin_1); + rt_interrupt_leave(); +} + +void EXTI2_Handler(void) +{ + rt_interrupt_enter(); + GPIO_EXTI_IRQHandler(GPIO_Pin_2); + rt_interrupt_leave(); +} + +void EXTI3_Handler(void) +{ + rt_interrupt_enter(); + GPIO_EXTI_IRQHandler(GPIO_Pin_3); + rt_interrupt_leave(); +} + +void EXTI4_Handler(void) +{ + rt_interrupt_enter(); + GPIO_EXTI_IRQHandler(GPIO_Pin_4); + rt_interrupt_leave(); +} + +void EXTI5_9_Handler(void) +{ + rt_interrupt_enter(); + GPIO_EXTI_IRQHandler(GPIO_Pin_5); + GPIO_EXTI_IRQHandler(GPIO_Pin_6); + GPIO_EXTI_IRQHandler(GPIO_Pin_7); + GPIO_EXTI_IRQHandler(GPIO_Pin_8); + GPIO_EXTI_IRQHandler(GPIO_Pin_9); + rt_interrupt_leave(); +} + +void EXTI10_15_Handler(void) +{ + rt_interrupt_enter(); + GPIO_EXTI_IRQHandler(GPIO_Pin_10); + GPIO_EXTI_IRQHandler(GPIO_Pin_11); + GPIO_EXTI_IRQHandler(GPIO_Pin_12); + GPIO_EXTI_IRQHandler(GPIO_Pin_13); + GPIO_EXTI_IRQHandler(GPIO_Pin_14); + GPIO_EXTI_IRQHandler(GPIO_Pin_15); + rt_interrupt_leave(); +} +#endif int rt_hw_pin_init(void) { +#if defined(SOC_SERIES_FT32F0) RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOF, ENABLE); return rt_device_pin_register("pin", &_ft32_pin_ops, RT_NULL); +#endif +#if defined(SOC_SERIES_FT32F4) + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE); + return rt_device_pin_register("pin", &_ft32_pin_ops, RT_NULL); +#endif } #endif /* RT_USING_PIN */ diff --git a/bsp/ft32/libraries/Drivers/drv_gpio.h b/bsp/ft32/libraries/Drivers/drv_gpio.h index c571f35bea3..4e124e45f51 100644 --- a/bsp/ft32/libraries/Drivers/drv_gpio.h +++ b/bsp/ft32/libraries/Drivers/drv_gpio.h @@ -6,6 +6,7 @@ * Change Logs: * Date Author Notes * 2022-03-02 FMD-AE first version + * 2025-12-31 FMD-AE add ft32f4 support */ #ifndef __DRV_GPIO_H__ @@ -17,11 +18,21 @@ extern "C" { #endif +#if defined(SOC_SERIES_FT32F0) #define GPIO_GET_INDEX(__GPIOx__) (((__GPIOx__) == (GPIOA))? 0U :\ ((__GPIOx__) == (GPIOB))? 1U :\ ((__GPIOx__) == (GPIOC))? 2U :\ ((__GPIOx__) == (GPIOD))? 3U :\ ((__GPIOx__) == (GPIOF))? 5U : 4U) +#elif defined(SOC_SERIES_FT32F4) +#define GPIO_GET_INDEX(__GPIOx__) (((__GPIOx__) == (GPIOA))? 0U :\ + ((__GPIOx__) == (GPIOB))? 1U :\ + ((__GPIOx__) == (GPIOC))? 2U :\ + ((__GPIOx__) == (GPIOD))? 3U :\ + ((__GPIOx__) == (GPIOE))? 4U : 5U) +#else +#error "Unsupported SOC series" +#endif #define __GPIO_EXTI_GET_IT(__EXTI_LINE__) (EXTI->PR & (__EXTI_LINE__)) diff --git a/bsp/ft32/libraries/Drivers/drv_usart.c b/bsp/ft32/libraries/Drivers/drv_usart.c index 5cbd353ea02..a31d27fae78 100644 --- a/bsp/ft32/libraries/Drivers/drv_usart.c +++ b/bsp/ft32/libraries/Drivers/drv_usart.c @@ -23,10 +23,6 @@ /* this driver can be disabled at menuconfig -> RT-Thread Components -> Device Drivers */ #endif -#ifdef RT_SERIAL_USING_DMA - static void ft32_dma_config(struct rt_serial_device *serial, rt_ubase_t flag); -#endif - enum { #ifdef BSP_USING_UART1 @@ -54,7 +50,12 @@ void UART_MspInit(USART_TypeDef *USARTx) GPIO_InitTypeDef GPIO_InitStruct; if (USARTx == USART1) { +#if defined(SOC_SERIES_FT32F0) RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); +#endif +#if defined(SOC_SERIES_FT32F4) + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); +#endif RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); /*GPIO INIT*/ @@ -64,17 +65,28 @@ void UART_MspInit(USART_TypeDef *USARTx) GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOA, &GPIO_InitStruct); +#if defined(SOC_SERIES_FT32F0) GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_1); GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_1); - +#endif +#if defined(SOC_SERIES_FT32F4) + GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_7); + GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_7); +#endif /* USART1 interrupt Init */ NVIC_SetPriority(USART1_IRQn, 5); NVIC_EnableIRQ(USART1_IRQn); } else if (USARTx == USART2) { +#if defined(SOC_SERIES_FT32F0) RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); +#endif +#if defined(SOC_SERIES_FT32F4) + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); + RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART2, ENABLE); +#endif /*GPIO INIT*/ GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3; @@ -83,8 +95,14 @@ void UART_MspInit(USART_TypeDef *USARTx) GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOA, &GPIO_InitStruct); +#if defined(SOC_SERIES_FT32F0) GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_1); GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_1); +#endif +#if defined(SOC_SERIES_FT32F4) + GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_7); + GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_7); +#endif /* USART2 interrupt Init */ NVIC_SetPriority(USART2_IRQn, 5); @@ -100,15 +118,24 @@ static rt_err_t ft32_configure(struct rt_serial_device *serial, struct serial_co uart = rt_container_of(serial, struct ft32_uart, serial); uart->Init.USART_BaudRate = cfg->baud_rate; +#if defined(SOC_SERIES_FT32F0) uart->Init.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; - +#endif +#if defined(SOC_SERIES_FT32F4) + uart->Init.USART_Mode = USART_MODE_TX_RX; +#endif switch (cfg->flowcontrol) { case RT_SERIAL_FLOWCONTROL_NONE: uart->Init.USART_HardwareFlowControl = USART_HardwareFlowControl_None; break; case RT_SERIAL_FLOWCONTROL_CTSRTS: +#if defined(SOC_SERIES_FT32F0) uart->Init.USART_HardwareFlowControl = USART_HardwareFlowControl_RTS_CTS; +#endif +#if defined(SOC_SERIES_FT32F4) + uart->Init.USART_HardwareFlowControl = USART_HardwareFlowControl_RTS_DTR; +#endif break; default: uart->Init.USART_HardwareFlowControl = USART_HardwareFlowControl_None; @@ -117,6 +144,7 @@ static rt_err_t ft32_configure(struct rt_serial_device *serial, struct serial_co switch (cfg->data_bits) { +#if defined(SOC_SERIES_FT32F0) case DATA_BITS_8: if (cfg->parity == PARITY_ODD || cfg->parity == PARITY_EVEN) uart->Init.USART_WordLength = USART_WordLength_9b; @@ -129,10 +157,32 @@ static rt_err_t ft32_configure(struct rt_serial_device *serial, struct serial_co default: uart->Init.USART_WordLength = USART_WordLength_8b; break; +#endif +#if defined(SOC_SERIES_FT32F4) + case DATA_BITS_9: + uart->Init.USART_WordLength = USART_CHAR_LENGTH9_ENABLE; + break; + case DATA_BITS_8: + uart->Init.USART_WordLength = USART_CHAR_LENGTH_8BIT; + break; + case DATA_BITS_7: + uart->Init.USART_WordLength = USART_CHAR_LENGTH_7BIT; + break; + case DATA_BITS_6: + uart->Init.USART_WordLength = USART_CHAR_LENGTH_6BIT; + break; + case DATA_BITS_5: + uart->Init.USART_WordLength = USART_CHAR_LENGTH_5BIT; + break; + default: + uart->Init.USART_WordLength = USART_CHAR_LENGTH_8BIT; + break; +#endif } switch (cfg->stop_bits) { +#if defined(SOC_SERIES_FT32F0) case STOP_BITS_1: uart->Init.USART_StopBits = USART_StopBits_1; break; @@ -142,10 +192,23 @@ static rt_err_t ft32_configure(struct rt_serial_device *serial, struct serial_co default: uart->Init.USART_StopBits = USART_StopBits_1; break; +#endif +#if defined(SOC_SERIES_FT32F4) + case STOP_BITS_1: + uart->Init.USART_StopBits = USART_STOPBITS_1; + break; + case STOP_BITS_2: + uart->Init.USART_StopBits = USART_STOPBITS_2; + break; + default: + uart->Init.USART_StopBits = USART_STOPBITS_1; + break; +#endif } switch (cfg->parity) { +#if defined(SOC_SERIES_FT32F0) case PARITY_NONE: uart->Init.USART_Parity = USART_Parity_No; break; @@ -158,11 +221,23 @@ static rt_err_t ft32_configure(struct rt_serial_device *serial, struct serial_co default: uart->Init.USART_Parity = USART_Parity_No; break; +#endif +#if defined(SOC_SERIES_FT32F4) + case PARITY_NONE: + uart->Init.USART_Parity = USART_PARITY_NONE; + break; + case PARITY_ODD: + uart->Init.USART_Parity = USART_PARITY_ODD; + break; + case PARITY_EVEN: + uart->Init.USART_Parity = USART_PARITY_EVEN; + break; + default: + uart->Init.USART_Parity = USART_PARITY_NONE; + break; +#endif } -#ifdef RT_SERIAL_USING_DMA - uart->dma_rx.last_index = 0; -#endif UART_MspInit(uart->config->Instance); USART_Init(uart->config->Instance, &(uart->Init)); USART_Cmd(uart->config->Instance, ENABLE); @@ -172,9 +247,6 @@ static rt_err_t ft32_configure(struct rt_serial_device *serial, struct serial_co static rt_err_t ft32_control(struct rt_serial_device *serial, int cmd, void *arg) { struct ft32_uart *uart; -#ifdef RT_SERIAL_USING_DMA - rt_ubase_t ctrl_arg = (rt_ubase_t)arg; -#endif RT_ASSERT(serial != RT_NULL); uart = rt_container_of(serial, struct ft32_uart, serial); @@ -186,21 +258,17 @@ static rt_err_t ft32_control(struct rt_serial_device *serial, int cmd, void *arg /* disable rx irq */ NVIC_DisableIRQ(uart->config->irq_type); /* disable interrupt */ +#if defined(SOC_SERIES_FT32F0) + /* enable interrupt */ USART_ITConfig(uart->config->Instance, USART_IT_RXNE, DISABLE); - -#ifdef RT_SERIAL_USING_DMA - /* disable DMA */ - if (ctrl_arg == RT_DEVICE_FLAG_DMA_RX) - { - NVIC_DisableIRQ(uart->config->dma_rx->dma_irq); - DMA_DeInit(uart->dma_rx.Instance); - } - else if (ctrl_arg == RT_DEVICE_FLAG_DMA_TX) - { - NVIC_DisableIRQ(uart->config->dma_tx->dma_irq); - DMA_DeInit(uart->dma_rx.Instance); - } + break; +#endif +#if defined(SOC_SERIES_FT32F4) + /* enable interrupt */ + USART_ITConfig(uart->config->Instance, USART_IT_RXRDY, DISABLE); + break; #endif + break; /* enable interrupt */ @@ -208,15 +276,17 @@ static rt_err_t ft32_control(struct rt_serial_device *serial, int cmd, void *arg /* enable rx irq */ NVIC_SetPriority(uart->config->irq_type, 1); NVIC_EnableIRQ(uart->config->irq_type); +#if defined(SOC_SERIES_FT32F0) /* enable interrupt */ USART_ITConfig(uart->config->Instance, USART_IT_RXNE, ENABLE); break; - -#ifdef RT_SERIAL_USING_DMA - case RT_DEVICE_CTRL_CONFIG: - ft32_dma_config(serial, ctrl_arg); +#endif +#if defined(SOC_SERIES_FT32F4) + /* enable interrupt */ + USART_ITConfig(uart->config->Instance, USART_IT_RXRDY, ENABLE); break; #endif + break; case RT_DEVICE_CTRL_CLOSE: USART_DeInit(uart->config->Instance); @@ -226,6 +296,7 @@ static rt_err_t ft32_control(struct rt_serial_device *serial, int cmd, void *arg return RT_EOK; } +#if defined(SOC_SERIES_FT32F0) rt_uint32_t ft32_uart_get_mask(rt_uint32_t word_length, rt_uint32_t parity) { rt_uint32_t mask; @@ -269,6 +340,7 @@ rt_uint32_t ft32_uart_get_mask(rt_uint32_t word_length, rt_uint32_t parity) } return mask; } +#endif static int ft32_putc(struct rt_serial_device *serial, char c) { @@ -276,13 +348,20 @@ static int ft32_putc(struct rt_serial_device *serial, char c) RT_ASSERT(serial != RT_NULL); uart = rt_container_of(serial, struct ft32_uart, serial); - UART_INSTANCE_CLEAR_FUNCTION(uart->config->Instance, USART_FLAG_TC); #if defined(SOC_SERIES_FT32F0) + UART_INSTANCE_CLEAR_FUNCTION(uart->config->Instance, USART_FLAG_TC); uart->config->Instance->TDR = c; +#elif defined(SOC_SERIES_FT32F4) + USART_Transmit(uart->config->Instance, c); #else uart->config->Instance->DR = c; #endif +#if defined(SOC_SERIES_FT32F0) while (USART_GetFlagStatus(uart->config->Instance, USART_FLAG_TC) == RESET); +#endif +#if defined(SOC_SERIES_FT32F4) + while (USART_GetFlagStatus(uart->config->Instance, USART_FLAG_TXRDY) == RESET); +#endif return 1; } @@ -294,14 +373,21 @@ static int ft32_getc(struct rt_serial_device *serial) uart = rt_container_of(serial, struct ft32_uart, serial); ch = -1; +#if defined(SOC_SERIES_FT32F0) if (USART_GetFlagStatus(uart->config->Instance, USART_FLAG_RXNE) != RESET) - { +#endif +#if defined(SOC_SERIES_FT32F4) + if (USART_GetFlagStatus(uart->config->Instance, USART_FLAG_RXRDY) != RESET) +#endif + { #if defined(SOC_SERIES_FT32F0) - ch = uart->config->Instance->RDR & ft32_uart_get_mask(uart->Init.USART_WordLength, uart->Init.USART_Parity); + ch = uart->config->Instance->RDR & ft32_uart_get_mask(uart->Init.USART_WordLength, uart->Init.USART_Parity); +#elif defined(SOC_SERIES_FT32F4) + ch = USART_Receive(uart->config->Instance); #else - ch = uart->config->Instance->DR & ft32_uart_get_mask(uart->Init.USART_WordLength, uart->Init.USART_Parity); + ch = uart->config->Instance->DR & ft32_uart_get_mask(uart->Init.USART_WordLength, uart->Init.USART_Parity); #endif - } + } return ch; } @@ -329,43 +415,24 @@ static rt_ssize_t ft32_dma_transmit(struct rt_serial_device *serial, rt_uint8_t static void uart_isr(struct rt_serial_device *serial) { struct ft32_uart *uart; -#ifdef RT_SERIAL_USING_DMA - rt_size_t recv_total_index, recv_len; - rt_base_t level; -#endif RT_ASSERT(serial != RT_NULL); uart = rt_container_of(serial, struct ft32_uart, serial); - +#if defined(SOC_SERIES_FT32F0) /* UART in mode Receiver -------------------------------------------------*/ if (USART_GetFlagStatus(uart->config->Instance, USART_FLAG_RXNE) != RESET) { rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND); } -#ifdef RT_SERIAL_USING_DMA - else if ((uart->uart_dma_flag) && (USART_GetFlagStatus(uart->config->Instance, USART_FLAG_RXNE) != RESET)) - { - level = rt_hw_interrupt_disable(); - recv_total_index = serial->config.bufsz - DMA_GetCurrDataCounter(&(uart->dma_rx.Instance)); - recv_len = recv_total_index - uart->dma_rx.last_index; - uart->dma_rx.last_index = recv_total_index; - rt_hw_interrupt_enable(level); - - if (recv_len) - { - rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_DMADONE | (recv_len << 8)); - } - USART_ClearFlag(uart->config->Instance, USART_IT_IDLE); - } - else if (USART_GetFlagStatus(uart->config->Instance, USART_FLAG_TC) != RESET) +#endif +#if defined(SOC_SERIES_FT32F4) + /* UART in mode Receiver -------------------------------------------------*/ + if (USART_GetFlagStatus(uart->config->Instance, USART_FLAG_RXRDY) != RESET) { - if ((serial->parent.open_flag & RT_DEVICE_FLAG_DMA_TX) != 0) - { - - } - UART_INSTANCE_CLEAR_FUNCTION(uart->config->Instance, USART_FLAG_TC); + rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND); } #endif +#if defined (SOC_SERIES_FT32F0) else { if (USART_GetFlagStatus(uart->config->Instance, USART_FLAG_ORE) != RESET) @@ -384,12 +451,6 @@ static void uart_isr(struct rt_serial_device *serial) { USART_ClearFlag(uart->config->Instance, USART_FLAG_PE); } -#if !defined(SOC_SERIES_FT32F0) - if (USART_GetFlagStatus(uart->config->Instance, USART_FLAG_LBD) != RESET) - { - UART_INSTANCE_CLEAR_FUNCTION(uart->config->Instance, USART_FLAG_LBD); - } -#endif if (USART_GetFlagStatus(uart->config->Instance, USART_FLAG_CTS) != RESET) { UART_INSTANCE_CLEAR_FUNCTION(uart->config->Instance, USART_FLAG_CTS); @@ -407,42 +468,16 @@ static void uart_isr(struct rt_serial_device *serial) UART_INSTANCE_CLEAR_FUNCTION(uart->config->Instance, USART_FLAG_RXNE); } } -} - -#ifdef RT_SERIAL_USING_DMA -static void dma_isr(struct rt_serial_device *serial) -{ - struct ft32_uart *uart; - rt_size_t recv_total_index, recv_len; - rt_base_t level; - - RT_ASSERT(serial != RT_NULL); - uart = rt_container_of(serial, struct ft32_uart, serial); - - if ((DMA_GetITStatus(uart->dma_rx.Instance, DMA_IT_TC) != RESET) || - (DMA_GetITStatus(uart->dma_rx.Instance, DMA_IT_HT) != RESET)) +#endif +#if defined (SOC_SERIES_FT32F4) + else { - level = rt_hw_interrupt_disable(); - recv_total_index = serial->config.bufsz - DMA_GetCurrDataCounter(uart->dma_rx.Instance); - if (recv_total_index == 0) - { - recv_len = serial->config.bufsz - uart->dma_rx.last_index; - } - else - { - recv_len = recv_total_index - uart->dma_rx.last_index; - } - uart->dma_rx.last_index = recv_total_index; - rt_hw_interrupt_enable(level); - if (recv_len) - { - rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_DMADONE | (recv_len << 8)); - } } -} #endif +} +#if defined(SOC_SERIES_FT32F0) #if defined(BSP_USING_UART1) void USART1_IRQHandler(void) { @@ -454,30 +489,7 @@ void USART1_IRQHandler(void) /* leave interrupt */ rt_interrupt_leave(); } -#if defined(RT_SERIAL_USING_DMA) && defined(BSP_UART1_RX_USING_DMA) -void UART1_DMA_RX_IRQHandler(void) -{ - /* enter interrupt */ - rt_interrupt_enter(); - - __DMA_IRQHandler(uart_obj[UART1_INDEX].dma_rx.Instance); - - /* leave interrupt */ - rt_interrupt_leave(); -} -#endif /* defined(RT_SERIAL_USING_DMA) && defined(BSP_UART1_RX_USING_DMA) */ -#if defined(RT_SERIAL_USING_DMA) && defined(BSP_UART1_TX_USING_DMA) -void UART1_DMA_TX_IRQHandler(void) -{ - /* enter interrupt */ - rt_interrupt_enter(); - - __DMA_IRQHandler(uart_obj[UART1_INDEX].dma_tx.Instance); - /* leave interrupt */ - rt_interrupt_leave(); -} -#endif /* defined(RT_SERIAL_USING_DMA) && defined(BSP_UART1_TX_USING_DMA) */ #endif /* BSP_USING_UART1 */ #if defined(BSP_USING_UART2) @@ -491,170 +503,51 @@ void USART2_IRQHandler(void) /* leave interrupt */ rt_interrupt_leave(); } -#if defined(RT_SERIAL_USING_DMA) && defined(BSP_UART2_RX_USING_DMA) -void UART2_DMA_RX_IRQHandler(void) + +#endif /* BSP_USING_UART2 */ +#endif + +#if defined(SOC_SERIES_FT32F4) +#if defined(BSP_USING_UART1) +void USART1_Handler(void) { /* enter interrupt */ rt_interrupt_enter(); - __DMA_IRQHandler(uart_obj[UART2_INDEX].dma_rx.Instance); + uart_isr(&(uart_obj[UART1_INDEX].serial)); /* leave interrupt */ rt_interrupt_leave(); } -#endif /* defined(RT_SERIAL_USING_DMA) && defined(BSP_UART2_RX_USING_DMA) */ -#if defined(RT_SERIAL_USING_DMA) && defined(BSP_UART2_TX_USING_DMA) -void UART2_DMA_TX_IRQHandler(void) + +#endif /* BSP_USING_UART1 */ + +#if defined(BSP_USING_UART2) +void USART2_Handler(void) { /* enter interrupt */ rt_interrupt_enter(); - __DMA_IRQHandler(uart_obj[UART2_INDEX].dma_tx.Instance); + uart_isr(&(uart_obj[UART2_INDEX].serial)); /* leave interrupt */ rt_interrupt_leave(); } -#endif /* defined(RT_SERIAL_USING_DMA) && defined(BSP_UART2_TX_USING_DMA) */ -#endif /* BSP_USING_UART2 */ +#endif /* BSP_USING_UART2 */ +#endif static void ft32_uart_get_dma_config(void) { #ifdef BSP_USING_UART1 uart_obj[UART1_INDEX].uart_dma_flag = 0; -#ifdef BSP_UART1_RX_USING_DMA - uart_obj[UART1_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX; - static struct dma_config uart1_dma_rx = UART1_DMA_RX_CONFIG; - uart_config[UART1_INDEX].dma_rx = &uart1_dma_rx; -#endif -#ifdef BSP_UART1_TX_USING_DMA - uart_obj[UART1_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_TX; - static struct dma_config uart1_dma_tx = UART1_DMA_TX_CONFIG; - uart_config[UART1_INDEX].dma_tx = &uart1_dma_tx; -#endif #endif #ifdef BSP_USING_UART2 uart_obj[UART2_INDEX].uart_dma_flag = 0; -#ifdef BSP_UART2_RX_USING_DMA - uart_obj[UART2_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX; - static struct dma_config uart2_dma_rx = UART2_DMA_RX_CONFIG; - uart_config[UART2_INDEX].dma_rx = &uart2_dma_rx; -#endif -#ifdef BSP_UART2_TX_USING_DMA - uart_obj[UART2_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_TX; - static struct dma_config uart2_dma_tx = UART2_DMA_TX_CONFIG; - uart_config[UART2_INDEX].dma_tx = &uart2_dma_tx; #endif -#endif -} - -#ifdef RT_SERIAL_USING_DMA -static void ft32_dma_config(struct rt_serial_device *serial, rt_ubase_t flag) -{ - struct rt_serial_rx_fifo *rx_fifo; - - DMA_InitTypeDef Init; - struct dma_config *dma_config; - struct ft32_uart *uart; - - RT_ASSERT(serial != RT_NULL); - RT_ASSERT(flag == RT_DEVICE_FLAG_DMA_TX || flag == RT_DEVICE_FLAG_DMA_RX); - uart = rt_container_of(serial, struct ft32_uart, serial); - - if (RT_DEVICE_FLAG_DMA_RX == flag) - { - Init = &uart->dma_rx.Init; - dma_config = uart->config->dma_rx; - } - else /* RT_DEVICE_FLAG_DMA_TX == flag */ - { - Init = &uart->dma_tx.Init; - dma_config = uart->config->dma_tx; - } - LOG_D("%s dma config start", uart->config->name); - - { - rt_uint32_t tmpreg = 0x00U; -#if defined(SOC_SERIES_FT32F0) - /* enable DMA clock && Delay after an RCC peripheral clock enabling*/ - SET_BIT(RCC->AHBENR, dma_config->dma_rcc); - tmpreg = READ_BIT(RCC->AHBENR, dma_config->dma_rcc); -#endif - - (void)(tmpreg); /* To avoid compiler warnings */ - } - - if (RT_DEVICE_FLAG_DMA_RX == flag) - { - } - else if (RT_DEVICE_FLAG_DMA_TX == flag) - { - } - - Init.DMA_PeripheralInc = DMA_PeripheralInc_Disable; - Init.MemInc = DMA_MemoryInc_Enable; - Init.PeriphDataAlignment = DMA_PeripheralDataSize_Byte; - Init.MemDataAlignment = DMA_MemoryDataSize_Byte; - - if (RT_DEVICE_FLAG_DMA_RX == flag) - { - Init.Direction = DMA_DIR_PeripheralSRC; - Init.Mode = DMA_Mode_Circular; - } - else if (RT_DEVICE_FLAG_DMA_TX == flag) - { - Init.Direction = DMA_DIR_PeripheralDST; - Init.Mode = DMA_Mode_Normal; - } - - Init.Priority = DMA_Priority_Medium; - DMA_DeInit(dma_config->Instance); - DMA_Init(dma_config->Instance); - - /* enable interrupt */ - if (flag == RT_DEVICE_FLAG_DMA_RX) - { - rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx; - /* Start DMA transfer */ - UART_Receive_DMA(uart->config->Instance, rx_fifo->buffer, serial->config.bufsz); - CLEAR_BIT(uart->handle.Instance->CR3, USART_CR3_EIE); - USART_ITConfig(uart->config->Instance, USART_IT_IDLE, ENABLE); - } - - /* DMA irq should set in DMA TX mode, or HAL_UART_TxCpltCallback function will not be called */ - NVIC_SetPriority(dma_config->dma_irq, 0, 0); - NVIC_EnableIRQ(dma_config->dma_irq); - - NVIC_SetPriority(uart->config->irq_type, 1, 0); - NVIC_EnableIRQ(uart->config->irq_type); - - LOG_D("%s dma %s instance: %x", uart->config->name, flag == RT_DEVICE_FLAG_DMA_RX ? "RX" : "TX", DMA_Handle->Instance); - LOG_D("%s dma config done", uart->config->name); } -static void _dma_tx_complete(struct rt_serial_device *serial) -{ - struct ft32_uart *uart; - rt_size_t trans_total_index; - rt_base_t level; - - RT_ASSERT(serial != RT_NULL); - uart = rt_container_of(serial, struct ft32_uart, serial); - - level = rt_hw_interrupt_disable(); - trans_total_index = DMA_GetCurrDataCounter(uart->dma_tx.Instance); - rt_hw_interrupt_enable(level); - - if (trans_total_index == 0) - { - rt_hw_serial_isr(serial, RT_SERIAL_EVENT_TX_DMADONE); - } -} - - -#endif /* RT_SERIAL_USING_DMA */ - static const struct rt_uart_ops ft32_uart_ops = { .configure = ft32_configure, diff --git a/bsp/ft32/libraries/Drivers/drv_usart.h b/bsp/ft32/libraries/Drivers/drv_usart.h index ae0462f407c..0530ddcfe0e 100644 --- a/bsp/ft32/libraries/Drivers/drv_usart.h +++ b/bsp/ft32/libraries/Drivers/drv_usart.h @@ -25,6 +25,9 @@ int rt_hw_usart_init(void); #if defined(SOC_SERIES_FT32F0) #define UART_INSTANCE_CLEAR_FUNCTION USART_ClearITPendingBit #endif +#if defined(SOC_SERIES_FT32F4) + #define UART_INSTANCE_CLEAR_FUNCTION USART_ClearFlag +#endif #define USART_TX_Pin GPIO_PIN_2 #define USART_TX_GPIO_Port GPIOA @@ -46,20 +49,6 @@ struct ft32_uart { USART_InitTypeDef Init; struct ft32_uart_config *config; - -#ifdef RT_SERIAL_USING_DMA - struct - { - DMA_InitTypeDef Init; - DMA_Channel_TypeDef *Instance; - rt_size_t last_index; - } dma_rx; - struct - { - DMA_InitTypeDef Init; - DMA_Channel_TypeDef *Instance; - } dma_tx; -#endif rt_uint16_t uart_dma_flag; struct rt_serial_device serial; }; diff --git a/bsp/ft32/libraries/Drivers/uart_config.h b/bsp/ft32/libraries/Drivers/uart_config.h index 19a9ab79739..febb31f71da 100644 --- a/bsp/ft32/libraries/Drivers/uart_config.h +++ b/bsp/ft32/libraries/Drivers/uart_config.h @@ -28,17 +28,6 @@ extern "C" { #endif /* UART1_CONFIG */ #endif /* BSP_USING_UART1 */ -#if defined(BSP_UART1_RX_USING_DMA) -#ifndef UART1_DMA_RX_CONFIG -#define UART1_DMA_RX_CONFIG \ - { \ - .Instance = UART1_RX_DMA_INSTANCE, \ - .dma_rcc = UART1_RX_DMA_RCC, \ - .dma_irq = UART1_RX_DMA_IRQ, \ - } -#endif /* UART1_DMA_RX_CONFIG */ -#endif /* BSP_UART1_RX_USING_DMA */ - #if defined(BSP_USING_UART2) #ifndef UART2_CONFIG #define UART2_CONFIG \ @@ -50,17 +39,6 @@ extern "C" { #endif /* UART2_CONFIG */ #endif /* BSP_USING_UART2 */ -#if defined(BSP_UART2_RX_USING_DMA) -#ifndef UART2_DMA_RX_CONFIG -#define UART2_DMA_RX_CONFIG \ - { \ - .Instance = UART2_RX_DMA_INSTANCE, \ - .dma_rcc = UART2_RX_DMA_RCC, \ - .dma_irq = UART2_RX_DMA_IRQ, \ - } -#endif /* UART2_DMA_RX_CONFIG */ -#endif /* BSP_UART2_RX_USING_DMA */ - #ifdef __cplusplus } #endif diff --git a/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/cachel1_armv7.h b/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/cachel1_armv7.h new file mode 100644 index 00000000000..abebc95f946 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/cachel1_armv7.h @@ -0,0 +1,411 @@ +/****************************************************************************** + * @file cachel1_armv7.h + * @brief CMSIS Level 1 Cache API for Armv7-M and later + * @version V1.0.1 + * @date 19. April 2021 + ******************************************************************************/ +/* + * 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) + 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/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/cmsis_armcc.h b/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/cmsis_armcc.h new file mode 100644 index 00000000000..55f87a0995f --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/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/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/cmsis_armclang.h b/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/cmsis_armclang.h new file mode 100644 index 00000000000..69114177477 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/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/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/cmsis_armclang_ltm.h b/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/cmsis_armclang_ltm.h new file mode 100644 index 00000000000..1e255d5907f --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/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/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/cmsis_compiler.h b/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/cmsis_compiler.h new file mode 100644 index 00000000000..cf1b6e4c6ec --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/cmsis_compiler.h @@ -0,0 +1,292 @@ +/**************************************************************************//** + * @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/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/cmsis_gcc.h b/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/cmsis_gcc.h new file mode 100644 index 00000000000..67bda4ef3c3 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/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/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/cmsis_iccarm.h b/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/cmsis_iccarm.h new file mode 100644 index 00000000000..65b824b009c --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/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/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/cmsis_version.h b/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/cmsis_version.h new file mode 100644 index 00000000000..8a74531e8de --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/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/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/core_armv81mml.h b/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/core_armv81mml.h new file mode 100644 index 00000000000..94128a1a709 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/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/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/core_armv8mbl.h b/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/core_armv8mbl.h new file mode 100644 index 00000000000..932d3d188bf --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/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/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/core_armv8mml.h b/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/core_armv8mml.h new file mode 100644 index 00000000000..c119fbf2424 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/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/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/core_cm4.h b/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/core_cm4.h new file mode 100644 index 00000000000..2b1f4633d2b --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/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/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/ft32f407xe.h b/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/ft32f407xe.h new file mode 100644 index 00000000000..b46f626fa68 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/ft32f407xe.h @@ -0,0 +1,20900 @@ +/**************************************************************************//** + * @file ft32f407xe.h + * @brief CMSIS Cortex-M4 Core Peripheral Access Layer Header File for + * Device CMSDK_CM4 + * @version V3.01 + * @date 06. March 2012 + * + * @note + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * @par + * ARM Limited (ARM) is supplying this software for use with Cortex-M + * processor based microcontrollers. This file can be freely distributed + * within development tools that are supporting such ARM based processors. + * + * @par + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR + * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + * + ******************************************************************************/ + + +#ifndef __FT32F407XE_H +#define __FT32F407XE_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/** @addtogroup Library_configuration_section + * @{ + */ + +/* Uncomment the line below according to the target FT32F0 device used in your + application + */ + +#if !defined (FT32F407XE) +#define FT32F407XE +#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_STDPERIPH_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_STDPERIPH_DRIVER*/ +#endif /* USE_STDPERIPH_DRIVER */ + +/** + * @brief In the following line adjust the value of External High Speed oscillator (HSE) + used in your application + + 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. + */ +#if !defined (HSE_VALUE) +#define HSE_VALUE ((uint32_t)8000000) /*!< Value of the External oscillator in Hz*/ +#endif /* HSE_VALUE */ + +/** + * @brief In the following line adjust the External High Speed oscillator (HSE) Startup + Timeout value + */ +#if !defined (HSE_STARTUP_TIMEOUT) +#define HSE_STARTUP_TIMEOUT ((uint32_t)0x00005000) /*!< Time out for HSE start up */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief In the following line adjust the Internal High Speed oscillator (HSI) Startup + Timeout value + */ +#if !defined (HSI_STARTUP_TIMEOUT) +#define HSI_STARTUP_TIMEOUT ((uint32_t)0x00005000) /*!< Time out for HSI start up */ +#endif /* HSI_STARTUP_TIMEOUT */ + +#if !defined (HSI48_STARTUP_TIMEOUT) +#define HSI48_STARTUP_TIMEOUT ((uint32_t)0x00005000) /*!< Time out for HSI48 start up */ +#endif /* HSI48_STARTUP_TIMEOUT */ + +#if !defined (LSE_STARTUP_TIMEOUT) +#define LSE_STARTUP_TIMEOUT ((uint32_t)0x00005000) /*!< Time out for LSE start up */ +#endif /* LSE_STARTUP_TIMEOUT */ + +#if !defined (LSI_STARTUP_TIMEOUT) +#define LSI_STARTUP_TIMEOUT ((uint32_t)0x00005000) /*!< Time out for LSI start up */ +#endif /* LSI_STARTUP_TIMEOUT */ + +#if !defined (PLL_STARTUP_TIMEOUT) +#define PLL_STARTUP_TIMEOUT ((uint32_t)0x00005000) /*!< Time out for PLL start up */ +#endif /* PLL_STARTUP_TIMEOUT */ + +#if !defined (PLL2_STARTUP_TIMEOUT) +#define PLL2_STARTUP_TIMEOUT ((uint32_t)0x00005000) /*!< Time out for PLL2 start up */ +#endif /* PLL2_STARTUP_TIMEOUT */ + +#if !defined (HSI_VALUE) +#define HSI_VALUE ((uint32_t)16000000) /*!< Value of the Internal High Speed oscillator for ADC in Hz. + The real value may vary depending on the variations + in voltage and temperature. */ +#endif /* HSI_VALUE */ + +#if !defined (HSE_VALUE) +#define HSE_VALUE ((uint32_t)16000000) /*!< Value of the Internal High Speed oscillator for ADC in Hz. + The real value may vary depending on the variations + in voltage and temperature. */ +#endif /* HSE_VALUE */ + +#if !defined (HSI48_VALUE) +#define HSI48_VALUE ((uint32_t)48000000) /*!< Value of the Internal High Speed oscillator for USB in Hz. + The real value may vary depending on the variations + in voltage and temperature. */ +#endif /* HSI48_VALUE */ + +#if !defined (LSI_VALUE) +#define LSI_VALUE ((uint32_t)32000) /*!< 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 */ + +#if !defined (LSE_VALUE) +#define LSE_VALUE ((uint32_t)32768) /*!< Value of the External Low Speed oscillator in Hz */ +#endif /* LSE_VALUE */ + +/** + * @brief FT32F0XX Standard Peripheral Library version number V1.4.0 + */ +#define __FT32F4XX_STDPERIPH_VERSION_MAIN (0x01) /*!< [31:24] main version */ +#define __FT32F4XX_STDPERIPH_VERSION_SUB1 (0x05) /*!< [23:16] sub1 version */ +#define __FT32F4XX_STDPERIPH_VERSION_SUB2 (0x00) /*!< [15:8] sub2 version */ +#define __FT32F4XX_STDPERIPH_VERSION_RC (0x00) /*!< [7:0] release candidate */ +#define __FT32F4XX_STDPERIPH_VERSION ((__FT32F4XX_STDPERIPH_VERSION_MAIN << 24)\ + |(__FT32F4XX_STDPERIPH_VERSION_SUB1 << 16)\ + |(__FT32F4XX_STDPERIPH_VERSION_SUB2 << 8)\ + |(__FT32F4XX_STDPERIPH_VERSION_RC)) + + +/** @addtogroup CMSDK_CM4_Definitions CMSDK_CM4 Definitions + This file defines all structures and symbols for CMSDK_CM4: + - registers and bitfields + - peripheral base address + - peripheral ID + - Peripheral definitions + @{ +*/ + + +/******************************************************************************/ +/* Processor and Core Peripherals */ +/******************************************************************************/ +/** @addtogroup CMSDK_CM4_CMSIS Device CMSIS Definitions + Configuration of the Cortex-M4 Processor and Core Peripherals + @{ +*/ + +/* + * ========================================================================== + * ---------- Interrupt Number Definition ----------------------------------- + * ========================================================================== + */ + +typedef enum IRQn +{ + /****** Cortex-M4 Processor Exceptions Numbers ***************************************************/ + NonMaskableInt_IRQn = -14, /*!< 2 Cortex-M4 Non Maskable Interrupt */ + HardFault_IRQn = -13, /*!< 3 Cortex-M4 Hard Fault Interrupt */ + MemoryManagement_IRQn = -12, /*!< 4 Cortex-M4 Memory Management Interrupt */ + BusFault_IRQn = -11, /*!< 5 Cortex-M4 Bus Fault Interrupt */ + UsageFault_IRQn = -10, /*!< 6 Cortex-M4 Usage Fault Interrupt */ + SVCall_IRQn = -5, /*!< 11 Cortex-M4 SV Call Interrupt */ + DebugMonitor_IRQn = -4, /*!< 12 Cortex-M4 Debug Monitor Interrupt */ + PendSV_IRQn = -2, /*!< 14 Cortex-M4 Pend SV Interrupt */ + SysTick_IRQn = -1, /*!< 15 Cortex-M4 System Tick Interrupt */ + + /****** CMSDK Specific Interrupt Numbers *******************************************************/ + WWDG_IRQn = 0, + PVD_IRQn = 1, + TAMP_STAMP_IRQn = 2, + RTC_IRQn = 3, + FLASH_IRQn = 4, + RCC_IRQn = 5, + EXTI0_IRQn = 6, + EXTI1_IRQn = 7, + EXTI2_IRQn = 8, + EXTI3_IRQn = 9, + EXTI4_IRQn = 10, + DMA1_CH0_IRQn = 11, + DMA1_CH1_IRQn = 12, + DMA1_CH2_IRQn = 13, + DMA1_CH3_IRQn = 14, + DMA1_CH4_IRQn = 15, + DMA1_CH5_IRQn = 16, + DMA1_CH6_IRQn = 17, + ADC_IRQn = 18, + CAN1_IRQn = 19, + CAN2_IRQn = 20, + CAN3_IRQn = 21, + CAN4_IRQn = 22, + EXTI9_5_IRQn = 23, + TIM1_BRK_TIM9_IRQn = 24, + TIM1_UP_TIM1O_IRQn = 25, + TIM1_TRG_COM_TIM11_IRQn = 26, + TIM1_CC_IRQn = 27, + TIM2_IRQn = 28, + TIM3_IRQn = 29, + TIM4_IRQn = 30, + I2C1_IRQn = 31, + I2C2_IRQn = 32, + QSPI_IRQn = 33, + SPI1_IRQn = 34, + SPI2_IRQn = 35, + USART1_IRQn = 36, + USART2_IRQn = 37, + USART3_IRQn = 38, + EXTI15_10_IRQn = 39, + RTCAlarm_IRQn = 40, + OTG_FS_WKUP_IRQn = 41, + TIM8_BRK_TIM12_IRQn = 42, + TIM8_UP_TIM13_IRQn = 43, + TIM8_TRG_COM_TIM14_IRQn = 44, + TIM8_CC_IRQn = 45, + DMA1_CH7_IRQn = 46, + FMC_IRQn = 47, + SDIO_IRQn = 48, + TIM5_IRQn = 49, + SPI3_IRQn = 50, + UART4_IRQn = 51, + UART5_IRQn = 52, + TIM6_DAC_IRQn = 53, + TIM7_IRQn = 54, + DMA2_CH0_IRQn = 55, + DMA2_CH1_IRQn = 56, + DMA2_CH2_IRQn = 57, + DMA2_CH3_IRQn = 58, + DMA2_CH4_IRQn = 59, + OTG_FS_IRQn = 60, + DMA2_CH5_IRQn = 61, + DMA2_CH6_IRQn = 62, + DMA2_CH7_IRQn = 63, + USART6_IRQn = 64, + I2C3_IRQn = 65, + OTG_HS_EP1_OUT_IRQn = 66, + OTG_HS_EP1_IN_IRQn = 67, + OTG_HS_WKUP_IRQn = 68, + OTG_HS_IRQn = 69, + RNG_IRQn = 70, + FPU_IRQn = 71, + CRS_IRQn = 72, + SPDIF_IRQn = 73, + SSI_AC97_IRQn = 74, + ETH_WKUP_IRQn = 75, + LPUART_IRQn = 76, + LPTIM_IRQn = 77, + ETH_SBD_IRQn = 78, + ETH_PERCHTX_IRQn = 79, + ETH_PERCHRX_IRQn = 80, + EPWM1_IRQn = 81, + EPWM1_TZ_IRQn = 82, + EPWM2_IRQn = 83, + EPWM2_TZ_IRQn = 84, + EPWM3_IRQn = 85, + EPWM3_TZ_IRQn = 86, + EPWM4_IRQn = 87, + EPWM4_TZ_IRQn = 88, + ECAP_IRQn = 89, + EQEP_IRQn = 90, + DLL_CAL_IRQn = 91, + COMP1_IRQn = 92, + COMP2_IRQn = 93, + COMP3_IRQn = 94, + COMP4_IRQn = 95, + COMP5_IRQn = 96, + COMP6_IRQn = 97, + ICACHE_IRQn = 98, + DCACHE_IRQn = 99, + UART7_IRQn = 100 +} IRQn_Type; + + +/* + * ========================================================================== + * ----------- Processor and Core Peripheral Section ------------------------ + * ========================================================================== + */ + +/* Configuration of the Cortex-M4 Processor and Core Peripherals */ +#define __CM4_REV 0x0001 /*!< Core Revision r0p1 */ +#define __NVIC_PRIO_BITS 4 /*!< Number of Bits used for Priority Levels */ +#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ +#define __MPU_PRESENT 1 /*!< MPU present or not */ +#define __FPU_PRESENT 1 /*!< FPU present or not */ + +/*@}*/ /* end of group CMSDK_CM4_CMSIS */ + +#include "core_cm4.h" /* Cortex-M4 processor and core peripherals */ +#include "ft32f4xx.h" +#include "system_ft32f4xx.h" /* CMSDK_CM4 System include file */ +#include +#include +#include +#include + + +/** @addtogroup Exported_types + * @{ + */ +/** @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 +{ + ERROR = 0, + SUCCESS = !ERROR +} ErrorStatus; + + +/******************************************************************************/ +/* Device Specific Peripheral registers structures */ +/******************************************************************************/ +/** @addtogroup CMSDK_CM4_Peripherals CMSDK_CM4 Peripherals + CMSDK_CM4 Device Specific Peripheral registers structures + @{ +*/ + +//#if defined ( __CC_ARM ) +//#pragma anon_unions +//#endif + +typedef struct +{ + __IO uint32_t TIM1_CR1 ; + __IO uint32_t TIM1_CR2 ; + __IO uint32_t TIM1_SMCR ; + __IO uint32_t TIM1_DIER ; + __IO uint32_t TIM1_SR ; + __IO uint32_t TIM1_EGR ; + __IO uint32_t TIM1_CCMR1 ; + __IO uint32_t TIM1_CCMR2 ; + __IO uint32_t TIM1_CCER ; + __IO uint32_t TIM1_CNT ; + __IO uint32_t TIM1_PSC ; + __IO uint32_t TIM1_ARR ; + __IO uint32_t TIM1_RCR ; + __IO uint32_t TIM1_CCR1 ; + __IO uint32_t TIM1_CCR2 ; + __IO uint32_t TIM1_CCR3 ; + __IO uint32_t TIM1_CCR4 ; + __IO uint32_t TIM1_BDTR ; + __IO uint32_t TIM1_DCR ; + __IO uint32_t TIM1_DMAR ; + __IO uint32_t TIM1_OR1 ; //0x50, added by yqiu + __IO uint32_t TIM1_CCMR3 ; //0x54, added by yqiu + __IO uint32_t TIM1_CCR5 ; //0x58, added by yqiu + __IO uint32_t TIM1_CCR6 ; //0x5c, added by yqiu + __IO uint32_t TIM1_AF ; //0x60, added by yqiu + __IO uint32_t TIM1_AF2 ; //0x64, added by yqiu + __IO uint32_t TIM1_TISEL ; //0x68, added by yqiu +} TIM1_TypeDef; + + +typedef struct +{ + __IO uint32_t TBCTL ; + __IO uint32_t TBSTS ; + __IO uint32_t TBPHSHR ; + __IO uint32_t TBPHS ; + __IO uint32_t TBCTR ; + __IO uint32_t TBPRD ; + __IO uint32_t TBPRDHR ; + __IO uint32_t CMPCTL ; + __IO uint32_t CMPAHR ; + __IO uint32_t CMPA ; + __IO uint32_t CMPB ; + __IO uint32_t AQCTLA ; + __IO uint32_t AQCTLB ; + __IO uint32_t AQSFRC ; + __IO uint32_t AQCSFRC ; + __IO uint32_t DBCTL ; + __IO uint32_t DBRED ; + __IO uint32_t DBFED ; + __IO uint32_t PCCTL ; + __IO uint32_t TZSEL ; + __IO uint32_t TZDCSEL ; + __IO uint32_t TZCTL ; + __IO uint32_t TZEINT ; + __IO uint32_t TZFLG ; + __IO uint32_t TZCLR ; + __IO uint32_t TZFRC ; + __IO uint32_t ETSEL ; + __IO uint32_t ETPS ; + __IO uint32_t ETFLG ; + __IO uint32_t ETCLR ; + __IO uint32_t ETFRC ; + __IO uint32_t DCTRIPSEL ; + __IO uint32_t DCACTL ; + __IO uint32_t DCBCTL ; + __IO uint32_t DCFCTL ; + __IO uint32_t DCCAPCTL ; + __IO uint32_t DCFOFFSET ; + __IO uint32_t DCFOFFSETCNT ; + __IO uint32_t DCFWINDOW ; + __IO uint32_t DCFWINDOWCNT ; + __IO uint32_t DCCAP ; + __IO uint32_t HRCNFG ; + __IO uint32_t HRPWR ; + __IO uint32_t HRMSTEP ; + __IO uint32_t HRPCTL ; + __IO uint32_t MEPINT ; + __IO uint32_t MEPFLG ; + __IO uint32_t MEPCLR ; +} EPWM_TypeDef; + + +typedef struct +{ + __IO uint32_t TSCTR ; + __IO uint32_t CTRPHS ; + __IO uint32_t CAP1 ; + __IO uint32_t CAP2 ; + __IO uint32_t CAP3 ; + __IO uint32_t CAP4 ; + __IO uint32_t ECCTL1 ; + __IO uint32_t ECCTL2 ; + __IO uint32_t ECEINT ; + __IO uint32_t ECFLG ; + __IO uint32_t ECCLR ; + __IO uint32_t ECFRC ; +} ECAP_TypeDef; + + +typedef struct +{ + __IO uint32_t QPOSCNT ; + __IO uint32_t QPOSINIT ; + __IO uint32_t QPOSMAX ; + __IO uint32_t QPOSCMP ; + __IO uint32_t QPOSILAT ; + __IO uint32_t QPOSSLAT ; + __IO uint32_t QPOSLAT ; + __IO uint32_t QUTMR ; + __IO uint32_t QUPRD ; + __IO uint32_t QWDTMR ; + __IO uint32_t QWDPRD ; + __IO uint32_t QDECCTL ; + __IO uint32_t QEPCTL ; + __IO uint32_t QCAPCTL ; + __IO uint32_t QPOSCTL ; + __IO uint32_t QEINT ; + __IO uint32_t QFLG ; + __IO uint32_t QCLR ; + __IO uint32_t QFRC ; + __IO uint32_t QEPSTS ; + __IO uint32_t QCTMR ; + __IO uint32_t QCPRD ; + __IO uint32_t QCTMRLAT ; + __IO uint32_t QCPRDLAT ; +} EQEP_TypeDef; + + +typedef struct +{ + __IO uint32_t ISR ; + __IO uint32_t IER ; + __IO uint32_t CR ; + __IO uint32_t CFGR1 ; + __IO uint32_t CFGR2 ; + __IO uint32_t SMPR1 ; + __IO uint32_t SMPR2 ; + __IO uint32_t SMPR3 ; + __IO uint32_t TR1 ; + __IO uint32_t TR2 ; + __IO uint32_t TR3 ; + uint32_t RESERVED1 ; + __IO uint32_t SQR1 ; + __IO uint32_t SQR2 ; + __IO uint32_t SQR3 ; + __IO uint32_t SQR4 ; + __IO uint32_t DR ; + uint32_t RESERVED2[2] ; + __IO uint32_t JSQR ; + uint32_t RESERVED3[4] ; + __IO uint32_t OFR1 ; + __IO uint32_t OFR2 ; + __IO uint32_t OFR3 ; + __IO uint32_t OFR4 ; + uint32_t RESERVED4[4] ; + __IO uint32_t JDR1 ; + __IO uint32_t JDR2 ; + __IO uint32_t JDR3 ; + __IO uint32_t JDR4 ; + uint32_t RESERVED5[4] ; + __IO uint32_t AWD2CR ; + __IO uint32_t AWD3CR ; + uint32_t RESERVED6[2] ; + __IO uint32_t DIFSEL ; + __IO uint32_t CALFACT ; + uint32_t RESERVED7[2] ; + __IO uint32_t GCOMP ; +} ADC_TypeDef; + + +typedef struct +{ + __IO uint32_t CSR1 ; + __IO uint32_t CSR2 ; + __IO uint32_t CCR ; + __IO uint32_t CDR ; +} ADC_Common_TypeDef; + + +//------------------- added by yqiu ------------------ +/*------------- DMA --------------------------------------*/ +/** @addtogroup DMA controller + @{ +*/ +typedef struct +{ + __IO uint64_t SAR; /*!< Offset: 0x000 Channel Source Address Register (R/W) */ + __IO uint64_t DAR; /*!< Offset: 0x008 Channel Destination Address Register (R/W) */ + uint64_t RESERVED0[1]; + //__IO uint64_t LLP; /*!< Offset: 0x010 Channel Linked List Pointer Register (R/W) */ + __IO uint64_t CTL; /*!< Offset: 0x018 Channel Control Register (R/W) */ + uint64_t RESERVED1[4]; + //__IO uint64_t SSTAT; /*!< Offset: 0x020 Channel Source Status Register (R/W) */ + //__IO uint64_t DSTAT; /*!< Offset: 0x028 Channel Destination Status Register (R/W) */ + //__IO uint64_t SSTATAR; /*!< Offset: 0x030 Channel Source Status Address Register (R/W) */ + //__IO uint64_t DSTATAR; /*!< Offset: 0x038 Channel Destination Status Address Register (R/W) */ + __IO uint64_t CFG; /*!< Offset: 0x040 Channel Configuration Register (R/W) */ + //__IO uint64_t SGR; /*!< Offset: 0x048 Channel Source Gather Register (R/W) */ + //__IO uint64_t DSR; /*!< Offset: 0x050 Channel Destination Scatter Register (R/W) */ +} DMA_Channel_TypeDef; + +typedef struct +{ + __IO uint64_t RAWTFR; /*!< Offset: 0x2c0 Raw Status for IntTfr Interrupt Register (R/W) */ + __IO uint64_t RAWBLOCK; /*!< Offset: 0x2c8 Raw Status for IntBlock Interrupt Register (R/W) */ + __IO uint64_t RAWSRCTRAN; /*!< Offset: 0x2d0 Raw Status for IntSrcTran Interrupt Register (R/W) */ + __IO uint64_t RAWDSTTRAN; /*!< Offset: 0x2d8 Raw Status for IntDstTran Interrupt Register (R/W) */ + __IO uint64_t RAWERR; /*!< Offset: 0x2e0 Raw Status for IntErr Interrupt Register (R/W) */ + __I uint64_t STATUSTFR; /*!< Offset: 0x2e8 Status for IntTfr Interrupt Register (R/ ) */ + __I uint64_t STATUSBLOCK; /*!< Offset: 0x2f0 Status for IntBlock Interrupt Register (R/ ) */ + __I uint64_t STATUSSRCTRAN; /*!< Offset: 0x2f8 Status for IntSrcTran Interrupt Register (R/ ) */ + __I uint64_t STATUSDSTTRAN; /*!< Offset: 0x300 Status for IntDstTran Interrupt Register (R/ ) */ + __I uint64_t STATUSERR; /*!< Offset: 0x308 Status for IntErr Interrupt Register (R/ ) */ + __IO uint64_t MASKTFR; /*!< Offset: 0x310 Mask for IntTfr Interrupt Register (R/W) */ + __IO uint64_t MASKBLOCK; /*!< Offset: 0x318 Mask for IntBlock Interrupt Register (R/W) */ + __IO uint64_t MASKSRCTRAN; /*!< Offset: 0x320 Mask for IntSrcTran Interrupt Register (R/W) */ + __IO uint64_t MASKDSTTRAN; /*!< Offset: 0x328 Mask for IntDstTran Interrupt Register (R/W) */ + __IO uint64_t MASKERR; /*!< Offset: 0x330 Mask for IntErr Interrupt Register (R/W) */ + __O uint64_t CLEARTFR; /*!< Offset: 0x338 Clear for IntTfr Interrupt Register ( /W) */ + __O uint64_t CLEARBLOCK; /*!< Offset: 0x340 Clear for IntBlock Interrupt Register ( /W) */ + __O uint64_t CLEARSRCTRAN; /*!< Offset: 0x348 Clear for IntSrcTran Interrupt Register ( /W) */ + __O uint64_t CLEARDSTTRAN; /*!< Offset: 0x350 Clear for IntDstTran Interrupt Register ( /W) */ + __O uint64_t CLEARERR; /*!< Offset: 0x358 Clear for IntErr Interrupt Register ( /W) */ + __I uint64_t STATUSINT; /*!< Offset: 0x360 Status for Each Interrupt Type Register (R/ ) */ + + __IO uint64_t REQSRC; /*!< Offset: 0x368 Source Software Transaction Request Register (R/W) */ + __IO uint64_t REQDST; /*!< Offset: 0x370 Destination Software Transaction Request Register (R/W) */ + __IO uint64_t SGLRQSRC; /*!< Offset: 0x378 Source Single Transaction Request Register (R/W) */ + __IO uint64_t SGLRQDST; /*!< Offset: 0x380 Destination Single Transaction Request Register (R/W) */ + __IO uint64_t LSTSRC; /*!< Offset: 0x388 Source Last Transaction Request Register (R/W) */ + __IO uint64_t LSTDST; /*!< Offset: 0x390 Destination Last Transaction Request Register (R/W) */ + + __IO uint64_t DMACFG; /*!< Offset: 0x398 DMA Configuration Register (R/W) */ + __IO uint64_t CHEN; /*!< Offset: 0x3a0 DMA Channel Enable Register (R/W) */ + __I uint64_t ID; /*!< Offset: 0x3a8 DMA ID Register (R/ ) */ + __IO uint64_t TEST; /*!< Offset: 0x3b0 DMA Test Register (R/W) */ + __IO uint64_t LPTIMEOUT; /*!< Offset: 0x3b8 DMA Low Power Timeout Register (R/W) */ + __IO uint64_t CHSEL; /*!< Offset: 0x3c0 DMA Channel Request Select Register (R/W) */ + __I uint64_t COMPPARAMS6; /*!< Offset: 0x3c8 DMA Component Parameters Register 6 (R/ ) */ + __I uint64_t COMPPARAMS5; /*!< Offset: 0x3d0 DMA Component Parameters Register 5 (R/ ) */ + __I uint64_t COMPPARAMS4; /*!< Offset: 0x3d8 DMA Component Parameters Register 4 (R/ ) */ + __I uint64_t COMPPARAMS3; /*!< Offset: 0x3e0 DMA Component Parameters Register 3 (R/ ) */ + __I uint64_t COMPPARAMS2; /*!< Offset: 0x3e8 DMA Component Parameters Register 2 (R/ ) */ + __I uint64_t COMPPARAMS1; /*!< Offset: 0x3f0 DMA Component Parameters Register 1 (R/ ) */ + __I uint64_t COMPSID; /*!< Offset: 0x3f8 DMA Component ID Register (R/ ) */ + +} DMA_TypeDef; + +/*@}*/ /* end of group DMA */ +//---------------------------------------------------- + + +#if defined ( __CC_ARM ) +#pragma no_anon_unions +#endif + +//******************** flash register define******************************* +typedef struct +{ + __IO uint32_t RDC; //Address offset : 0000H + __IO uint32_t KEYR; //Address offset : 0004H + __IO uint32_t OPTKEYR; //Address offset : 0008H + __IO uint32_t FR; //Address offset : 000cH + __IO uint32_t WRC; //Address offset : 0010H + __IO uint32_t OPBC; //Address offset : 0014H + __IO uint32_t WRPR; //Address offset : 0018H + uint32_t RESERVED0[185]; //Address offset : 001cH -- 02FCH + __IO uint32_t FLAC_KEYR; //Address offset : 0300H + __IO uint32_t FLAC_CR; //Address offset : 0304H + __IO uint32_t FLAC_ITEST; //Address offset : 0308H + __IO uint32_t FLAC_DUMMY; //Address offset : 030cH + __IO uint32_t FLAC_FCFG0; //Address offset : 0310H + __IO uint32_t FLAC_FCFG1; //Address offset : 0314H + __IO uint32_t FLAC_FCFG2; //Address offset : 0318H + __IO uint32_t FLAC_FCFG3; //Address offset : 031cH + __IO uint32_t FLAC_FCFG4; //Address offset : 0320H + __IO uint32_t FLAC_FCFG5; //Address offset : 0324H + __IO uint32_t FLAC_FCFG6; //Address offset : 0328H + __IO uint32_t FLAC_FCFG7; //Address offset : 032cH + __IO uint32_t FLAC_FUNC0; //Address offset : 0330H + __IO uint32_t FLAC_FUNC1; //Address offset : 0334H + __IO uint32_t FLAC_FUNC2; //Address offset : 0338H + __IO uint32_t FLAC_FUNC3; //Address offset : 033cH + __IO uint32_t FLAC_PID0123; //Address offset : 0340H + __IO uint32_t FLAC_PID4; //Address offset : 0344H + __IO uint32_t FLAC_BDSCID; //Address offset : 0348H + __IO uint32_t FLAC_DBGMCU; //Address offset : 0348H 34C + __IO uint32_t FLAC_INFO10; //Address offset : 0348H 350 + __IO uint32_t FLAC_INFO11; //Address offset : 034cH 354 + __IO uint32_t FLAC_INFO12; //Address offset : 034cH 358 + __IO uint32_t FLAC_INFO13; //Address offset : 034cH 35C + __IO uint32_t FLAC_CHIPV; //Address offset : 0350H 360 +} FLASH_TypeDef; + + +//******************** rcc register define******************************* +typedef struct +{ + __IO uint32_t CR; // Clock control register Address offset : 0000H + __IO uint32_t PLLCFGR; // PLL configuration register Address offset : 0004H + __IO uint32_t PLL2CFGR; // PLL2 configuration register Address offset : 0008H + __IO uint32_t CFGR; // Clock configuration register Address offset : 000CH + __IO uint32_t CIR; // Clock interrupt register Address offset : 0010H + __IO uint32_t AHB1RSTR; // AHB1 peripheral reset register Address offset : 0014H + __IO uint32_t AHB2RSTR; // AHB2 peripheral reset register Address offset : 0018H + __IO uint32_t AHB3RSTR; // AHB3 peripheral reset register Address offset : 001CH + __IO uint32_t APB1RSTR; // APB1 peripheral reset register Address offset : 0020H + __IO uint32_t APB2RSTR; // APB2 peripheral reset register Address offset : 0024H + __IO uint32_t AHB1ENR; // AHB1 peripheral clock enable register Address offset : 0028H + __IO uint32_t AHB2ENR; // AHB2 peripheral clock enable register Address offset : 002CH + __IO uint32_t AHB3ENR; // AHB3 peripheral clock enable register Address offset : 0030H + __IO uint32_t APB1ENR; // APB1 peripheral clock enable register Address offset : 0034H + __IO uint32_t APB2ENR; // APB2 peripheral clock enable register Address offset : 0038H + __IO uint32_t AHB1LPENR; // AHB1 peripheral clock enable in low power register Address offset : 003CH + __IO uint32_t AHB2LPENR; // AHB2 peripheral clock enable in low power register Address offset : 0040H + __IO uint32_t AHB3LPENR; // AHB3 peripheral clock enable in low power register Address offset : 0044H + __IO uint32_t APB1LPENR; // APB1 peripheral clock enable in low power register Address offset : 0048H + __IO uint32_t APB2LPENR; // APB2 peripheral clock enable in low power register Address offset : 004CH + __IO uint32_t CCIPR; // Peripheral independent clock configuration register Address offset : 0050H + __IO uint32_t CR2; // Clock control register Address offset : 0054H + __IO uint32_t BDCR; // Backup domain control register Address offset : 0058H + __IO uint32_t CSR; // Clock control & status register Address offset : 005CH + uint32_t RESERVED0[40]; // Address offset : 0060H -- 00FCH + __IO uint32_t RAMCTL; // CACHE SDIO USB CAN ETH RAM control register Address offset : 0100H +} RCC_TypeDef; + + +//******************** crs register define******************************* +typedef struct +{ + __IO uint32_t CR; // control register Address offset : 0000H + __IO uint32_t CFGR; // configuration register Address offset : 0004H + __IO uint32_t ISR; // interrupt status register Address offset : 0008H + __IO uint32_t ICR; // interrupt clear register Address offset : 000CH +} CRS_TypeDef; + + +//******************** SYSCFG register define******************************* +typedef struct +{ + __IO uint32_t MEMRMP; // memory remap register Address offset : 0000H + __IO uint32_t PMC; // peripheral mode configuration register Address offset : 0004H + __IO uint32_t EXTICR[4]; // external interrupt configuration register Address offset : 0008H ~ 0014H + __IO uint32_t RESERVED0; // Address offset : 0018H + __IO uint32_t CFGR; // configuration register Address offset : 001CH +} SYSCFG_TypeDef; + + +//******************** usb_fs_otg register define******************************* +typedef struct +{ + __IO uint8_t FADDR; // function address register Address offset : 0000H + __IO uint8_t POWER; // power management register Address offset : 0001H + __IO uint8_t INTRTX1; // interrupt register for enapoint 0 and tx1~7 Address offset : 0002H + uint8_t RESERVED0; // Address offset : 0003H + __IO uint8_t INTRRX1; // interrupt register for rx enapoint 1~7 Address offset : 0004H + uint8_t RESERVED1; // Address offset : 0005H + __IO uint8_t INTRUSB; // interrupt register for common USB interrupt Address offset : 0006H + __IO uint8_t INTRTX1E; // interrupt enable register for INTRTX1 Address offset : 0007H + uint8_t RESERVED2; // Address offset : 0008H + __IO uint8_t INTRRX1E; // interrupt enable register for INTRRX1 Address offset : 0009H + uint8_t RESERVED3; // Address offset : 000AH + __IO uint8_t INTRUSBE; // interrupt enable register for INTRUSBE Address offset : 000BH + __IO uint8_t FRAME1; // frame number bits 0 to 7 Address offset : 000CH + __IO uint8_t FRAME2; // frame number bits 8 to 10 Address offset : 000DH + __IO uint8_t INDEX; // index register for selecting the endpoint Address offset : 000EH + __IO uint8_t DEVCTL; // usb device control register Address offset : 000FH + __IO uint8_t TXMAXP; // maximum packet size for IN/OUT endpoint(except ep0) Address offset : 0010H + union // Address offset : 0011H + { + __IO uint8_t CSR0; // main control status register for ep0 + __IO uint8_t TXCSR1; // control status register 1 for IN/HOST OUT endpoint1~15 + }; + union // Address offset : 0012H + { + __IO uint8_t CSR02; // subsidiary control status register for ep0 + __IO uint8_t TXCSR2; // control status register 2 for IN/OUT endpoint1~15 + }; + __IO uint8_t RXMAXP; // maximum packet size for OUT/IN endpoint(except ep0) Address offset : 0013H + __IO uint8_t RXCSR1; // control status register 1 for OUT/HOST IN endpoint Address offset : 0014H + __IO uint8_t RXCSR2; // control status rehister 2 for OUT/HOST IN endpoint Address offset : 0015H + union // Address offset : 0016H + { + __IO uint8_t COUNT0; // number received bytes in ep0 fifo + __IO uint8_t RXCOUNT1; // number of bytes in OUT/HOST IN endpoint fifo(lower byte) + }; + __IO uint8_t RXCOUNT2; // number of bytes in OUT/HOST IN endpoint fifo(upper byte) Address offset : 0017H + __IO uint8_t TXTYPE; // set the transaction type and ep number for host out Address offset : 0018H + union // Address offset : 0019H + { + __IO uint8_t NAKLMT0; // set nak response timeout on endpoint + __IO uint8_t TXINTERVAL; // set polling interval for an out interrupt/iso endpoint + }; + __IO uint8_t RXTYPE; // set the transaction type and ep number for host in Address offset : 001AH + __IO uint8_t RXINTERVAL; // set polling interval for in endpoint Address offset : 001BH + __IO uint8_t TXFIFO1; // txfifox configuration1 Address offset : 001CH + __IO uint8_t TXFIFO2; // txfifox configuration2 Address offset : 001DH + __IO uint8_t RXFIFO1; // rxfifox configuration1 Address offset : 001EH + __IO uint8_t RXFIFO2; // rxfifox configuration2 Address offset : 001FH + __IO uint32_t FIFO0; // fifos for endpoint0 Address offset : 0020H + __IO uint32_t FIFO1; // fifos for endpoint1 Address offset : 0024H + __IO uint32_t FIFO2; // fifos for endpoint2 Address offset : 0028H + __IO uint32_t FIFO3; // fifos for endpoint3 Address offset : 002CH + +} OTG_FS_TypeDef; + + +/** + *@brief USB_OTG_HS_Core_register + */ + +typedef struct +{ + __IO uint32_t GOTGCTL; // OTG control and status register Address offset : 0000H + __IO uint32_t GOTGINT; // OTG interrupt register Address offset : 0004H + __IO uint32_t GAHBCFG; // AHB configuration register Address offset : 0008H + __IO uint32_t GUSBCFG; // USB configuration register Address offset : 000CH + __IO uint32_t GRSTCTL; // Reset register Address offset : 0010H + __IO uint32_t GINTSTS; // Interrupt register Address offset : 0014H + __IO uint32_t GINTMSK; // Interrupt mask register Address offset : 0018H + __IO uint32_t GRXSTSR; // Recieve status read register Address offset : 001CH + __IO uint32_t GRXSTSP; // Recieve status read/pop register Address offset : 0020H + __IO uint32_t GRXFSIZ; // Receice FIFO size register Address offset : 0024H + __IO uint32_t DIEPTXF0_HNPTXFSIZ; // Non-periodic transmit FIFO size register Address offset : 0028H + __IO uint32_t HNPTXSTS; // Non-periodic transmit FIFO/queue status register Address offset : 002CH + uint32_t RESERVED0[3]; // Address offset : 0030H -- 003BH + __IO uint32_t GUID; // User ID register Address offset : 003CH + uint32_t RESERVED1[7]; // Address offset : 0040H -- 005BH + __IO uint32_t GDFIFOCFG; // Global DFIFO configuration register Address offset : 005CH + uint32_t RESERVED3[40]; // Address offset : 0060H -- 00FFH + __IO uint32_t HPTXFSIZ; // Host periodic transmit FIFO size register Address offset : 0100H + __IO uint32_t DIEPTXF[0x0F]; // Device IN endpoint transmit FIFO size register Address offset : 0104H +} USB_OTG_HS_GlobalTypeDef; + +/** + *@brief USB_OTG_HS_Device_register + */ +typedef struct +{ + __IO uint32_t DCFG; // Device configuration register Address offset : 0800H + __IO uint32_t DCTL; // Device control register Address offset : 0804H + __IO uint32_t DSTS; // Device status register Address offset : 0808H + uint32_t RESERVED19; // Address offset : 080CH + __IO uint32_t DIEPMSK; // Device IN endpoint common interrupt mask register Address offset : 0810H + __IO uint32_t DOEPMSK; // Device OUT endpoint common interrupt mask register Address offset : 0814H + __IO uint32_t DAINT; // Device all endpoints interrupt register Address offset : 0818H + __IO uint32_t DAINTMSK; // Device all endpoints interrupt mask register Address offset : 081CH + uint32_t RESERVED20[2]; // Address offset : 0820H -- 0824H + __IO uint32_t DVBUSDIS; // Device VBUS discharge time register Address offset : 0828H + __IO uint32_t DVBUSPULSE; // Device VBUS pulsing time register Address offset : 082CH + __IO uint32_t DTHRCTL; // Device threshold control register Address offset : 0830H + __IO uint32_t DIEPEMPMSK; // Device IN endpoint FIFO empty interrupt mask register Address offset : 0834H + __IO uint32_t DEACHINT; // Device each endpoints interrupt register Address offset : 0838H + __IO uint32_t DEACHMSK; // Device each endpoints interrupt mask register Address offset : 083CH + uint32_t RESERVED21; // Address offset : 0840H + __IO uint32_t DINEP1MSK; // Device each IN endpoint 1 interrupt register Address offset : 0844H + uint32_t RESERVED22[15]; // Address offset : 0848H -- 0880H + __IO uint32_t DOUTEP1MSK; // Device each OUT endpoint 1 interrupt register Address offset : 0884H +} USB_OTG_HS_DeviceTypeDef; +/** + *@brief USB_OTG_HS_IN_Endpoint_specific_register + */ +typedef struct +{ + __IO uint32_t DIEPCTL; // Device control IN endpoint control register Address offset : 0900H + ep_num*20h + uint32_t RESERVED24; // Address offset : 0904H + ep_num*20h + __IO uint32_t DIEPINT; // Device IN endpoint interrupt register Address offset : 0908H + ep_num*20h + uint32_t RESERVED25; // Address offset : 090CH + ep_num*20h + __IO uint32_t DIEPTSIZ; // Device IN endpoint transfer size register Address offset : 0910H + ep_num*20h + __IO uint32_t DIEPDMA; // Device IN endpoint DMA address register Address offset : 0914H + ep_num*20h + __IO uint32_t DTXFSTS; // Device IN endpoint transmit FIFO status register Address offset : 0918H + ep_num*20h + uint32_t RESERVED26; // Address offset : 091CH + ep_num*20h +} USB_OTG_HS_INEndpointTypeDef; + +/** + *@brief USB_OTG_HS_OUT_Endpoint_specific_register + */ +typedef struct +{ + __IO uint32_t DOEPCTL; // Device control OUT endpoint control register Address offset : 0B00H + ep_num*20h + uint32_t RESERVED42; // Address offset : 0B04H + ep_num*20h + __IO uint32_t DOEPINT; // Device OUT endpoint interrupt register Address offset : 0B08H + ep_num*20h + uint32_t RESERVED43; // Address offset : 0B0CH + ep_num*20h + __IO uint32_t DOEPTSIZ; // Device OUT endpoint transfer size register Address offset : 0B10H + ep_num*20h + __IO uint32_t DOEPDMA; // Device OUT endpoint DMA address register Address offset : 0B14H + ep_num*20h + uint32_t RESERVED44[2]; // Address offset : 0B18H -- 0B1CH + ep_num*20h +} USB_OTG_HS_OUTEndpointTypeDef; + +/** + *@brief USB_OTG_HS_HOST_MODE_register + */ +typedef struct +{ + __IO uint32_t HCFG; // Host configuration register Address offset : 0400H + __IO uint32_t HFIR; // Host frame interval register Address offset : 0404H + __IO uint32_t HFNUM; // Host frame number/frame time remaining register Address offset : 0408H + uint32_t RESERVED4; // Address offset : 040CH + __IO uint32_t HPTXSTS; // Host periodic transmit FIFO/queue status register Address offset : 0410H + __IO uint32_t HAINT; // Host all channels interrupt register Address offset : 0414H + __IO uint32_t HAINTMSK; // Host all channels interrupt mask register Address offset : 0418H +} USB_OTG_HS_HostTypeDef; + +/** + *@brief USB_OTG_HS_HOST_Channel_specific_register + */ +typedef struct +{ + __IO uint32_t HCCHAR; // Host channel characteristics register Address offset : 0500H + ch_num*20h + __IO uint32_t HCSPLT; // Host channel split control register Address offset : 0504H + ch_num*20h + __IO uint32_t HCINT; // Host channel interrupt register Address offset : 0508H + ch_num*20h + __IO uint32_t HCINTMSK; // Host channel interrupt mask register Address offset : 050CH + ch_num*20h + __IO uint32_t HCTSIZ; // Host channel transfer size register Address offset : 0510H + ch_num*20h + __IO uint32_t HCDMA; // Host channel DMA address register Address offset : 0514H + ch_num*20h + uint32_t RESERVED7[2]; // Address offset : 0518H -- 051CH + ch_num*20h +} USB_OTG_HS_HostChannelTypeDef; + +// *************************************************************************** +//******************** i2c register define******************************* +typedef struct +{ + __IO uint32_t CR1; + __IO uint32_t CR2; + __IO uint32_t OAR1; + __IO uint32_t OAR2; + __IO uint32_t TIMINGR; + __IO uint32_t TIMEOUTR; + __IO uint32_t ISR; + __IO uint32_t ICR; + __IO uint32_t PECR; + __IO uint32_t RXDR; + __IO uint32_t TXDR; +} I2C_TypeDef; + + +// *************************************************************************** +//******************** ucpd register define******************************* +typedef struct +{ + __IO uint32_t UCPD_CFG; + __IO uint32_t UCPD_CR; + __IO uint32_t UCPD_TX; + __IO uint32_t UCPD_TX_DR; + __IO uint32_t UCPD_IE; + __IO uint32_t UCPD_SR; + __IO uint32_t UCPD_ICR; + __IO uint32_t UCPD_TX_ORDSET; + __IO uint32_t UCPD_TX_PAYSZ; + __IO uint32_t UCPD_RX_ORDSET; + __IO uint32_t UCPD_RX_PAYSZ; + __IO uint32_t UCPD_RXRD; +} UCPD_TypeDef; + + +typedef struct +{ + __IO uint32_t CAN_RECEIVE_BUFFER0; + __IO uint32_t CAN_RECEIVE_BUFFER1; + __IO uint32_t CAN_RECEIVE_BUFFER[16]; + __IO uint32_t CAN_RECEIVE_BUFFER_RTS[2]; + __IO uint32_t CAN_TRANSMIT_BUFFER0; + __IO uint32_t CAN_TRANSMIT_BUFFER1; + __IO uint32_t CAN_TRANSMIT_BUFFER[16]; + __IO uint32_t CAN_TRANSMISION_TS[2]; + __IO uint32_t CAN_CMD_CTRL; //0xA0 + __IO uint32_t CAN_INT_FLAG1; //0xA4 + __IO uint32_t CAN_S_SEG_UNIT_SET; //0xA8 + __IO uint32_t CAN_F_SEG_UNIT_SET; //0xAC + __IO uint32_t CAN_ERR_CNT; //0xB0 + __IO uint32_t CAN_FILTER_CTRL; //0xB4 + __IO uint32_t CAN_ACF; //0xB8 + __IO uint32_t CAN_INT_FLAG2; //0xBC + __IO uint32_t CAN_REF_MSG; //0xC0 + __IO uint32_t CAN_TRIG_CFG; //0xC4 + __IO uint32_t CAN_TRANS_INT_STAT; //0xC8 + __IO uint32_t CAN_MEM_ES; //0xCC + __IO uint32_t CAN_SCFG; //0xD0 + __IO uint32_t CAN_INIT_CFG_OFFSET; //0xD4 +} FDCAN_TypeDef; + +/******************* Bit definition for FDCAN_ISR register ******************/ +#define FDCAN_ISR_RACTIVE ((uint32_t)0x00000004) /*!< Reception ACTIVE */ +#define FDCAN_ISR_TACTIVE ((uint32_t)0x00000002) /*!< Transmission ACTIVE */ +#define FDCAN_ISR_TSSTAT ((uint32_t)0x00030000) /*!< Tansmission Secondary Status */ +#define FDCAN_ISR_RSTAT ((uint32_t)0x03000010) /*!< Receive Buffer Overflow */ +#define FDCAN_ISR_ROV ((uint32_t)0x20000000) /*!< Receive Buffer OverRun Error */ +// *************************************************************************** +//******************** spi register define******************************* +typedef struct +{ + __IO uint32_t CR1 ; //0x00 + __IO uint32_t CR2 ; //0x04 + __IO uint32_t SR ; //0x08 + __IO uint32_t DR ; //0x0c + __IO uint32_t CRCPR ; //0x10 + __IO uint32_t RXCRCR ; //0x14 + __IO uint32_t TXCRCR ; //0x18 + __IO uint32_t SSPR ; //0x1c +} SPI_TypeDef; + + +// *************************************************************************** +//******************** qspi register define******************************* +typedef struct +{ + __IO uint32_t CTRLR0 ; // 0x0 Control Register 0 + __IO uint32_t CTRLR1 ; // 0x4 Control Register 1 + __IO uint32_t SSIENR ; // 0x8 SSI Enable Register + __IO uint32_t MWCR ; // 0xc Microwire Control Register + __IO uint32_t SER ; // 0x10 Target Enable Register + __IO uint32_t BAUDR ; // 0x14 Baud Rate Select + __IO uint32_t TXFTLR ; // 0x18 Transmit FIFO Threshold Level + __IO uint32_t RXFTLR ; // 0x1c Receive FIFO Threshold Level + __IO uint32_t TXFLR ; // 0x20 Transmit FIFO Level Register + __IO uint32_t RXFLR ; // 0x24 Receive FIFO Level Register + __IO uint32_t SR ; // 0x28 Status Register + __IO uint32_t IMR ; // 0x2c Interrupt Mask Register + __IO uint32_t ISR ; // 0x30 Interrupt Status Register + __IO uint32_t RISR ; // 0x34 Raw Interrupt Status Register + __IO uint32_t TXEICR ; // 0x38 Transmit FIFO Error Interrupt Clear Register Register + __IO uint32_t RXOICR ; // 0x3c Receive FIFO Overflow Interrupt Clear Register + __IO uint32_t RXUICR ; // 0x40 Receive FIFO Underflow Interrupt Clear Register + __IO uint32_t MSTICR ; // 0x44 Multi-Controller Interrupt Clear Register + __IO uint32_t ICR ; // 0x48 Interrupt Clear Register + __IO uint32_t DMACR ; // 0x4c DMA Control Register + __IO uint32_t DMATDLR ; // 0x50 DMA Transmit Data Level + __IO uint32_t DMARDLR ; // 0x54 DMA Receive Data Level + __IO uint32_t IDR ; // 0x58 Identification Register + __IO uint32_t SSIC_VERSION_ID ; // 0x5c DWC_ssi component version +// __IO uint32_t DR0 ; // 0x60 DWC_ssi Data Register +// __IO uint32_t DR1 ; // 0x64 DWC_ssi Data Register +// __IO uint32_t DR2 ; // 0x68 DWC_ssi Data Register +// __IO uint32_t DR3 ; // 0x6c DWC_ssi Data Register +// __IO uint32_t DR4 ; // 0x70 DWC_ssi Data Register +// __IO uint32_t DR5 ; // 0x74 DWC_ssi Data Register +// __IO uint32_t DR6 ; // 0x78 DWC_ssi Data Register +// __IO uint32_t DR7 ; // 0x7c DWC_ssi Data Register +// __IO uint32_t DR8 ; // 0x80 DWC_ssi Data Register +// __IO uint32_t DR9 ; // 0x84 DWC_ssi Data Register +// __IO uint32_t DR10 ; // 0x88 DWC_ssi Data Register +// __IO uint32_t DR11 ; // 0x8c DWC_ssi Data Register +// __IO uint32_t DR12 ; // 0x90 DWC_ssi Data Register +// __IO uint32_t DR13 ; // 0x94 DWC_ssi Data Register +// __IO uint32_t DR14 ; // 0x98 DWC_ssi Data Register +// __IO uint32_t DR15 ; // 0x9c DWC_ssi Data Register +// __IO uint32_t DR16 ; // 0xa0 DWC_ssi Data Register +// __IO uint32_t DR17 ; // 0xa4 DWC_ssi Data Register +// __IO uint32_t DR18 ; // 0xa8 DWC_ssi Data Register +// __IO uint32_t DR19 ; // 0xac DWC_ssi Data Register +// __IO uint32_t DR20 ; // 0xb0 DWC_ssi Data Register +// __IO uint32_t DR21 ; // 0xb4 DWC_ssi Data Register +// __IO uint32_t DR22 ; // 0xb8 DWC_ssi Data Register +// __IO uint32_t DR23 ; // 0xbc DWC_ssi Data Register +// __IO uint32_t DR24 ; // 0xc0 DWC_ssi Data Register +// __IO uint32_t DR25 ; // 0xc4 DWC_ssi Data Register +// __IO uint32_t DR26 ; // 0xc8 DWC_ssi Data Register +// __IO uint32_t DR27 ; // 0xcc DWC_ssi Data Register +// __IO uint32_t DR28 ; // 0xd0 DWC_ssi Data Register +// __IO uint32_t DR29 ; // 0xd4 DWC_ssi Data Register +// __IO uint32_t DR30 ; // 0xd8 DWC_ssi Data Register +// __IO uint32_t DR31 ; // 0xdc DWC_ssi Data Register +// __IO uint32_t DR32 ; // 0xe0 DWC_ssi Data Register +// __IO uint32_t DR33 ; // 0xe4 DWC_ssi Data Register +// __IO uint32_t DR34 ; // 0xe8 DWC_ssi Data Register +// __IO uint32_t DR35 ; // 0xec DWC_ssi Data Register + __IO uint32_t DR[16] ; // 0x60 DWC_ssi Data Register + __IO uint32_t RES0[20] ; // 0xa0 ~ 0xec,Reserved. + __IO uint32_t RX_SAMPLE_DELAY ; // 0xf0 RX Sample Delay Register + __IO uint32_t SPI_CTRLR0 ; // 0xf4 SPI_CTRLR0 - SPI Control Register + __IO uint32_t DDR_DRIVE_EDGE ; // 0xf8 DDR_DRIVE_EDGE - Transmit Drive Edge Register + __IO uint32_t XIP_MODE_BITS ; // 0xfc eXecute in Place - Mode bits + __IO uint32_t XIP_INCR_INST ; // 0x100 XIP_INCR_INST - XIP INCR transfer opcode + __IO uint32_t XIP_WRAP_INST ; // 0x104 XIP_WRAP_INST - XIP WRAP transfer opcode + __IO uint32_t RES[3] ; // 0x108 ~ 110 Reserved. //XIP_CTRL ; // 0x108 XIP_CTRL - XIP Control Register +// __IO uint32_t XIP_SER ; // 0x10c Target Enable Register +// __IO uint32_t XRXOICR ; // 0x110 XIP Receive FIFO Overflow Interrupt Clear Register + __IO uint32_t XIP_CNT_TIME_OUT ; // 0x114 XIP time out register for continuous transfers + __IO uint32_t SPI_CTRLR1 ; // 0x118 SPI_CTRLR1 Control 1 register +// __IO uint32_t XIP_WRITE_INCR_INST ; // 0x140 XIP_WRITE_INCR_INST - XIP Write INCR transfer opcode +// __IO uint32_t XIP_WRITE_WRAP_INST ; // 0x144 XIP_WRITE_WRAP_INST - XIP Write WRAP transfer opcode +// __IO uint32_t XIP_WRITE_CTRL ; // 0x148 XIP_WRITE_CTRL - XIP Write Control Register +} QSPI_TypeDef; + + +// *************************************************************************** +//******************** usart register define******************************* +typedef struct +{ + __IO uint32_t CR ; //0x0 + __IO uint32_t MR ; //0x4 + __IO uint32_t IER ; //0x8 + __IO uint32_t IDR ; //0xc + __IO uint32_t IMR ; //0x10 + __IO uint32_t CSR ; //0x14 + __IO uint32_t RHR ; //0x18 + __IO uint32_t THR ; //0x1c + __IO uint32_t BRGR ; //0x20 + __IO uint32_t RTOR ; //0x24 + __IO uint32_t TTGR ; //0x28 + __IO uint32_t RES1 ; //0x2c + __IO uint32_t RES2 ; //0x30 + __IO uint32_t RES3 ; //0x34 + __IO uint32_t RES4 ; //0x38 + __IO uint32_t RES5 ; //0x3c + __IO uint32_t FIDI ; //0x40 + __IO uint32_t NER ; //0x44 + __IO uint32_t XON_XOFF ; //RES6 //0x48 + __IO uint32_t IF ; //0x4c +// __IO uint32_t MAN ; //0x50 + __IO uint32_t RES7 ; //0x50 + __IO uint32_t LINMR ; //0x54 + __IO uint32_t LINIR ; //0x58 + __IO uint32_t LINBRR ; //0x5c +// __IO uint32_t LONMR ; //0x60, not has function, this regster is reserved +// __IO uint32_t LONPR ; //0x64, not has function, this regster is reserved +// __IO uint32_t LONDL ; //0x68, not has function, this regster is reserved +// __IO uint32_t LONL2HDR ; //0x6c, not has function, this regster is reserved +// __IO uint32_t LONBL ; //0x70, not has function, this regster is reserved +// __IO uint32_t LONB1TX ; //0x74, not has function, this regster is reserved +// __IO uint32_t LONB1RX ; //0x78, not has function, this regster is reserved +// __IO uint32_t LONPRIO ; //0x7c, not has function, this regster is reserved +// __IO uint32_t IDTTX ; //0x80, not has function, this regster is reserved +// __IO uint32_t IDTRX ; //0x84, not has function, this regster is reserved +// __IO uint32_t ICDIFF ; //0x88, not has function, this regster is reserved +} USART_TypeDef; + + +typedef struct +{ + __IO uint32_t WPMR ; + __IO uint32_t WPSR ; +} USART_WP_TypeDef; + + +// *************************************************************************** +//******************** FMC register define******************************* +typedef struct +{ + __IO uint32_t BTCR[8]; // 0x00-0x1C +} FMC_Bank1_TypeDef; + + +typedef struct +{ + __IO uint32_t BWTR[7]; // 0x104-0x11C +} FMC_Bank1E_TypeDef; + +typedef struct +{ + __IO uint32_t PCR2; // 0x60 + __IO uint32_t SR2; // 0x64 + __IO uint32_t PMEM2; // 0x68 + __IO uint32_t PATT2; // 0x6c + uint32_t RESERVED0; + __IO uint32_t ECCR2; // 0x74 + uint32_t RESERVED1[2]; + __IO uint32_t PCR3; // 0x80 + __IO uint32_t SR3; // 0x84 + __IO uint32_t PMEM3; // 0x88 + __IO uint32_t PATT3; // 0x8c + uint32_t RESERVED2; + __IO uint32_t ECCR3; // 0x94 +} FMC_Bank2_3_TypeDef; + +typedef struct +{ + __IO uint32_t SDCR[2]; // 0x140-0x144 + __IO uint32_t SDTR[2]; // 0x148-0x14c + __IO uint32_t SDCMR; // 0x150 + __IO uint32_t SDRTR; // 0x154 + __IO uint32_t SDSR; // 0x158 +} FMC_Bank5_6_TypeDef; + +// *************************************************************************** +// ******************** CRC register define*********************************** +typedef struct +{ + __IO uint32_t DR; // 0x00 + __IO uint32_t IDR; // 0x04 + __IO uint32_t CR; // 0x08 + __IO uint32_t RESERVED0; // 0x0c + __IO uint32_t INIT; // 0x10 +} CRC_TypeDef; + + +// *************************************************************************** +// *********************** gpio register define******************************* +typedef struct +{ + __IO uint32_t MODER; // 0x00 + __IO uint32_t OTYPER; // 0x04 + __IO uint32_t OSPEEDR; // 0x08 + __IO uint32_t PUPDR; // 0x0c + __IO uint32_t IDR; // 0x10 + __IO uint32_t ODR; // 0x14 + __IO uint32_t BSRR; // 0x18 + __IO uint32_t LCKR; // 0x1c + __IO uint32_t AFR[2]; // 0x20-0x24 +} GPIO_TypeDef; + + +// *************************************************************************** +//******************** SDIO register define******************************* +typedef struct +{ + __IO uint32_t CTRL ; // 0x0 Control register + __IO uint32_t PWREN ; // 0x4 Power Enable Register + __IO uint32_t CLKDIV ; // 0x8 Clock Divider Register + __IO uint32_t CLKSRC ; // 0xc Clock Source Register + __IO uint32_t CLKENA ; // 0x10 Clock Enable Register + __IO uint32_t TMOUT ; // 0x14 Timeout Register + __IO uint32_t CTYPE ; // 0x18 Card Type Register + __IO uint32_t BLKSIZ ; // 0x1c Block Size Register + __IO uint32_t BYTCNT ; // 0x20 Byte Count Register + __IO uint32_t INTMASK ; // 0x24 Interrupt Mask Register + __IO uint32_t CMDARG ; // 0x28 Command Argument Register + __IO uint32_t CMD ; // 0x2c Command Register + __IO uint32_t RESP0 ; // 0x30 Response Register 0 + __IO uint32_t RESP1 ; // 0x34 Response Register 1 + __IO uint32_t RESP2 ; // 0x38 Response Register 2 + __IO uint32_t RESP3 ; // 0x3c Response Register 3 + __IO uint32_t MINTSTS ; // 0x40 Masked Interrupt Status Register Size: 32 bits Address Offset: 0x40 Read/write access: read MISTATS... + __IO uint32_t RINTSTS ; // 0x44 Raw Interrupt Status Register Size: 32 bits Address Offset: 0x44 Read/write access:... + __IO uint32_t STATUS ; // 0x48 Status Register Size: 32 bits Address Offset: 0x48 Read/write access: read + __IO uint32_t FIFOTH ; // 0x4c FIFO Threshold Watermark Register Size: 32 bits Address Offset: 0x4C Read/write access:... + __IO uint32_t CDETECT ; // 0x50 Card Detect Register Size: 32 bits Address Offset: 0x50 Read/write access: read-only + __IO uint32_t WRTPRT ; // 0x54 Write Protect Register Size: 32 bits Address Offset: 0x54 Read/write access: read-only + __IO uint32_t GPIO ; // 0x58 General Purpose Input/Output Register Size: 32 bits Address Offset: 0x58 Read/write access:... + __IO uint32_t TCBCNT ; // 0x5c Transferred CIU Card Byte Count Register Size: 32 bits Address Offset: 0x5C Read/write access:... + __IO uint32_t TBBCNT ; // 0x60 Transferred Host to BIU-FIFO Byte Count Register Size: 32 bits Address Offset: 0x60 Read/write... + __IO uint32_t DEBNCE ; // 0x64 Debounce Count Register Size: 32 bits Address Offset: 0x64 Read/write access:... + __IO uint32_t USRID ; // 0x68 User ID Register Size: 32 bits Address Offset: 0x68 Read/write access: write/readUser ID... + __IO uint32_t VERID ; // 0x6c Version ID Register Size: 32 bits Address Offset: 0x6C Read/write access: read + __IO uint32_t HCON ; // 0x70 Hardware Configuration Register Size: 32 bits Address Offset: 0x70 Read/Write access: readHardware... + __IO uint32_t UHS_REG ; // 0x74 UHS-1 Register Size: 32 bits Address Offset: 0x74 Read/write access: write/read + __IO uint32_t RST_N ; // 0x78 H/W Reset Size: 32 bits Address Offset: 0x78 Read/write access: write/read + __IO uint32_t RES[33] ; // 0x7C ~ FF Reserved + __IO uint32_t CARDTHRCTL ; // 0x100 Card Threshold Control Register Size: 32 bits Address Offset: 0x100 Read/Write access:... + __IO uint32_t BACK_END_POWER_R ; // 0x104 Back End Power Register Size: 32 bits Address Offset: 0x104 Read/Write access:... + __IO uint32_t UHS_REG_EXT ; // 0x108 UHS Register Extention Size: 32 bits Address Offset: 0x108 Read/Write access:... + __IO uint32_t EMMC_DDR_REG ; // 0x10c EMMC DDR Register Size: 32 bits Address Offset: 0x10C Read/Write access: read/write + __IO uint32_t ENABLE_SHIFT ; // 0x110 Enable Phase Shift Register Address Offset: 0x110 Read/Write access: read/write +} SDIO_TypeDef; + + +typedef struct +{ + __IO uint32_t DATA ; // 0x200 SDIO FIFO, depth = 32 Words = 128 Bytes +} SDIO_DATA_TypeDef; + + +typedef struct +{ + __IO uint32_t SPDIF_CTRL ; + __IO uint32_t INT ; + __IO uint32_t FIFO_CTRL ; + __IO uint32_t STAT ; + __IO uint32_t DATA ; //FIFO address +} SPDIF_TypeDef; + + +// SSI/I2S/AC97 registers +typedef struct +{ + __IO uint32_t STX0 ; //0x00 + __IO uint32_t STX1 ; //0x04 + __IO uint32_t SRX0 ; //0x08 + __IO uint32_t SRX1 ; //0x0C + __IO uint32_t SCR ; //0x10 + __IO uint32_t SISR ; //0x14 + __IO uint32_t SIER ; //0x18 + __IO uint32_t STCR ; //0x1C + __IO uint32_t SRCR ; //0x20 + __IO uint32_t STCCR ; //0x24 + __IO uint32_t SRCCR ; //0x28 + __IO uint32_t SFCSR ; //0x2C + __IO uint32_t STR ; //0x30 + __IO uint32_t SOR ; //0x34 + __IO uint32_t SACNT ; //0x38 + __IO uint32_t SACADD ; //0x3C + __IO uint32_t SACDAT ; //0x40 + __IO uint32_t SATAG ; //0x44 + __IO uint32_t STMSK ; //0x48 + __IO uint32_t SRMSK ; //0x4C + __IO uint32_t SACCST ; //0x50 + __IO uint32_t SACCEN ; //0x54 + __IO uint32_t SACCDIS ; //0x58 +} SSI_TypeDef; + + +typedef struct +{ + __O uint32_t KR; // Independent watchdog key reg + __IO uint32_t PR; // Independent watchdog prescaler reg + __IO uint32_t RLR; // Independent watchdog reload reg + __I uint32_t SR; // Independent watchdog status reg + __IO uint32_t WINR; // Independent watchdog window reg +} IWDG_TypeDef; + +#define IWDG_KR_Pos 0 +#define IWDG_KR_Msk (0x0ul << IWDG_KR_Pos) + +#define IWDG_PR_Pos 0 +#define IWDG_PR_Msk (0x0ul << IWDG_PR_Pos) + +#define IWDG_RLR_Pos 0 +#define IWDG_RLR_Msk (0xFFFFFFFFul << IWDG_RLR_Pos) + +#define IWDG_SR_Pos 0 +#define IWDG_SR_Msk (0x0ul << IWDG_SR_Pos) + +#define IWDG_WINR_Pos 0 +#define IWDG_WINR_Msk (0xFFFFFFFFul << IWDG_WINR_Pos) + +/******************* Bit definition for IWDG_KR register ********************/ +#define IWDG_KR_KEY ((uint16_t)0xFFFF) /*!< Key value (write only, read 0000h) */ + +/******************* Bit definition for IWDG_PR register ********************/ +#define IWDG_PR_PR ((uint8_t)0x07) /*!< PR[2:0] (Prescaler divider) */ +#define IWDG_PR_PR_0 ((uint8_t)0x01) /*!< Bit 0 */ +#define IWDG_PR_PR_1 ((uint8_t)0x02) /*!< Bit 1 */ +#define IWDG_PR_PR_2 ((uint8_t)0x04) /*!< Bit 2 */ + +/******************* Bit definition for IWDG_RLR register *******************/ +#define IWDG_RLR_RL ((uint16_t)0x0FFF) /*!< Watchdog counter reload value */ + +/******************* Bit definition for IWDG_SR register ********************/ +#define IWDG_SR_PVU ((uint8_t)0x01) /*!< Watchdog prescaler value update */ +#define IWDG_SR_RVU ((uint8_t)0x02) /*!< Watchdog counter reload value update */ +#define IWDG_SR_WVU ((uint8_t)0x04) /*!< Watchdog counter window value update */ + +/******************* Bit definition for IWDG_KR register ********************/ +#define IWDG_WINR_WIN ((uint16_t)0x0FFF) /*!< Watchdog counter window value */ + +/*------------------- Window Watchdog -----------------------------------------*/ +typedef struct +{ + __IO uint32_t CR; // Window watchdog control reg + __IO uint32_t CFR; // Window watchdog configure reg + __IO uint32_t SR; // Window watchdog status reg +} WWDG_TypeDef; + +#define WWDG_CR_WDGA_Pos 7 +#define WWDG_CR_WDGA_Msk (0x1ul << WWDG_CR_WDGA_Pos) +#define WWDG_CR_T_Pos 0 +#define WWDG_CR_T_Msk (0x7Ful << WWDG_CR_T_Pos) + +#define WWDG_CFR_EWI_Pos 9 +#define WWDG_CFR_EWI_Msk (0x1ul << WWDG_CFR_EWI_Pos) +#define WWDG_CFR_WDGTB_Pos 7 +#define WWDG_CFR_WDGTB_Msk (0x3ul << WWDG_CFR_WDGTB_Pos) +#define WWDG_CFR_W_Pos 0 +#define WWDG_CFR_W_Msk (0x7Ful << WWDG_CFR_W_Pos) + +#define WWDG_SR_EWIF_Pos 0 +#define WWDG_SR_EWIF_Msk (0x0ul << WWDG_SR_EWIF_Pos) + +/******************* Bit definition for WWDG_CR register ********************/ +#define WWDG_CR_T ((uint8_t)0x7F) /*!< T[6:0] bits (7-Bit counter (MSB to LSB)) */ +#define WWDG_CR_T0 ((uint8_t)0x01) /*!< Bit 0 */ +#define WWDG_CR_T1 ((uint8_t)0x02) /*!< Bit 1 */ +#define WWDG_CR_T2 ((uint8_t)0x04) /*!< Bit 2 */ +#define WWDG_CR_T3 ((uint8_t)0x08) /*!< Bit 3 */ +#define WWDG_CR_T4 ((uint8_t)0x10) /*!< Bit 4 */ +#define WWDG_CR_T5 ((uint8_t)0x20) /*!< Bit 5 */ +#define WWDG_CR_T6 ((uint8_t)0x40) /*!< Bit 6 */ + +#define WWDG_CR_WDGA ((uint8_t)0x80) /*!< Activation bit */ + +/******************* Bit definition for WWDG_CFR register *******************/ +#define WWDG_CFR_W ((uint16_t)0x007F) /*!< W[6:0] bits (7-bit window value) */ +#define WWDG_CFR_W0 ((uint16_t)0x0001) /*!< Bit 0 */ +#define WWDG_CFR_W1 ((uint16_t)0x0002) /*!< Bit 1 */ +#define WWDG_CFR_W2 ((uint16_t)0x0004) /*!< Bit 2 */ +#define WWDG_CFR_W3 ((uint16_t)0x0008) /*!< Bit 3 */ +#define WWDG_CFR_W4 ((uint16_t)0x0010) /*!< Bit 4 */ +#define WWDG_CFR_W5 ((uint16_t)0x0020) /*!< Bit 5 */ +#define WWDG_CFR_W6 ((uint16_t)0x0040) /*!< Bit 6 */ + +#define WWDG_CFR_WDGTB ((uint16_t)0x0180) /*!< WDGTB[1:0] bits (Timer Base) */ +#define WWDG_CFR_WDGTB0 ((uint16_t)0x0080) /*!< Bit 0 */ +#define WWDG_CFR_WDGTB1 ((uint16_t)0x0100) /*!< Bit 1 */ + +#define WWDG_CFR_EWI ((uint16_t)0x0200) /*!< Early Wakeup Interrupt */ + +/******************* Bit definition for WWDG_SR register ********************/ +#define WWDG_SR_EWIF ((uint8_t)0x01) /*!< Early Wakeup Interrupt Flag */ + + +typedef struct +{ + __IO uint32_t IMR; + __IO uint32_t EMR; + __IO uint32_t RTSR; + __IO uint32_t FTSR; + __IO uint32_t SWIER; + __IO uint32_t PR; +} EXTI_TypeDef; + + +typedef struct +{ + __IO uint32_t CR1 ; + __IO uint32_t CR2 ; + __IO uint32_t SMCR ; + __IO uint32_t DIER ; + __IO uint32_t SR ; + __IO uint32_t EGR ; + __IO uint32_t CCMR1 ; + __IO uint32_t CCMR2 ; + __IO uint32_t CCER ; + __IO uint32_t CNT ; + __IO uint32_t PSC ; + __IO uint32_t ARR ; + __IO uint32_t RCR ; + __IO uint32_t CCR1 ; + __IO uint32_t CCR2 ; + __IO uint32_t CCR3 ; + __IO uint32_t CCR4 ; + __IO uint32_t BDTR ; + __IO uint32_t DCR ; + __IO uint32_t DMAR ; + __IO uint32_t OR ; + __IO uint32_t CCMR3 ; + __IO uint32_t CCR5 ; + __IO uint32_t CCR6 ; + __IO uint32_t AF1 ; + __IO uint32_t AF2 ; + __IO uint32_t TISEL ; +} TIM_TypeDef; + + +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 IER ; /*!< 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 CMP ; /*!< LPTIM Compare register, 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 OR ; /*!< LPTIM Option register, Address offset: 0x20 */ +} LPTIM_TypeDef; + + +/******************************************************************************/ +/* */ +/* Low Power Timer (LPTIM) */ +/* */ +/******************************************************************************/ +/****************** Bit definition for LPTIM_ISR register *******************/ +#define LPTIM_ISR_CMPM_Pos (0U) +#define LPTIM_ISR_CMPM_Msk (0x1UL << LPTIM_ISR_CMPM_Pos) /*!< 0x00000001 */ +#define LPTIM_ISR_CMPM LPTIM_ISR_CMPM_Msk /*!< Compare match */ +#define LPTIM_ISR_ARRM_Pos (1U) +#define LPTIM_ISR_ARRM_Msk (0x1UL << LPTIM_ISR_ARRM_Pos) /*!< 0x00000002 */ +#define LPTIM_ISR_ARRM LPTIM_ISR_ARRM_Msk /*!< Autoreload match */ +#define LPTIM_ISR_EXTTRIG_Pos (2U) +#define LPTIM_ISR_EXTTRIG_Msk (0x1UL << LPTIM_ISR_EXTTRIG_Pos) /*!< 0x00000004 */ +#define LPTIM_ISR_EXTTRIG LPTIM_ISR_EXTTRIG_Msk /*!< External trigger edge event */ +#define LPTIM_ISR_CMPOK_Pos (3U) +#define LPTIM_ISR_CMPOK_Msk (0x1UL << LPTIM_ISR_CMPOK_Pos) /*!< 0x00000008 */ +#define LPTIM_ISR_CMPOK LPTIM_ISR_CMPOK_Msk /*!< Compare register update OK */ +#define LPTIM_ISR_ARROK_Pos (4U) +#define LPTIM_ISR_ARROK_Msk (0x1UL << LPTIM_ISR_ARROK_Pos) /*!< 0x00000010 */ +#define LPTIM_ISR_ARROK LPTIM_ISR_ARROK_Msk /*!< Autoreload register update OK */ +#define LPTIM_ISR_UP_Pos (5U) +#define LPTIM_ISR_UP_Msk (0x1UL << LPTIM_ISR_UP_Pos) /*!< 0x00000020 */ +#define LPTIM_ISR_UP LPTIM_ISR_UP_Msk /*!< Counter direction change down to up */ +#define LPTIM_ISR_DOWN_Pos (6U) +#define LPTIM_ISR_DOWN_Msk (0x1UL << LPTIM_ISR_DOWN_Pos) /*!< 0x00000040 */ +#define LPTIM_ISR_DOWN LPTIM_ISR_DOWN_Msk /*!< Counter direction change up to down */ + +/****************** Bit definition for LPTIM_ICR register *******************/ +#define LPTIM_ICR_CMPMCF_Pos (0U) +#define LPTIM_ICR_CMPMCF_Msk (0x1UL << LPTIM_ICR_CMPMCF_Pos) /*!< 0x00000001 */ +#define LPTIM_ICR_CMPMCF LPTIM_ICR_CMPMCF_Msk /*!< Compare match Clear Flag */ +#define LPTIM_ICR_ARRMCF_Pos (1U) +#define LPTIM_ICR_ARRMCF_Msk (0x1UL << LPTIM_ICR_ARRMCF_Pos) /*!< 0x00000002 */ +#define LPTIM_ICR_ARRMCF LPTIM_ICR_ARRMCF_Msk /*!< Autoreload match Clear Flag */ +#define LPTIM_ICR_EXTTRIGCF_Pos (2U) +#define LPTIM_ICR_EXTTRIGCF_Msk (0x1UL << LPTIM_ICR_EXTTRIGCF_Pos) /*!< 0x00000004 */ +#define LPTIM_ICR_EXTTRIGCF LPTIM_ICR_EXTTRIGCF_Msk /*!< External trigger edge event Clear Flag */ +#define LPTIM_ICR_CMPOKCF_Pos (3U) +#define LPTIM_ICR_CMPOKCF_Msk (0x1UL << LPTIM_ICR_CMPOKCF_Pos) /*!< 0x00000008 */ +#define LPTIM_ICR_CMPOKCF LPTIM_ICR_CMPOKCF_Msk /*!< Compare register update OK Clear Flag */ +#define LPTIM_ICR_ARROKCF_Pos (4U) +#define LPTIM_ICR_ARROKCF_Msk (0x1UL << LPTIM_ICR_ARROKCF_Pos) /*!< 0x00000010 */ +#define LPTIM_ICR_ARROKCF LPTIM_ICR_ARROKCF_Msk /*!< Autoreload register update OK Clear Flag */ +#define LPTIM_ICR_UPCF_Pos (5U) +#define LPTIM_ICR_UPCF_Msk (0x1UL << LPTIM_ICR_UPCF_Pos) /*!< 0x00000020 */ +#define LPTIM_ICR_UPCF LPTIM_ICR_UPCF_Msk /*!< Counter direction change down to up Clear Flag */ +#define LPTIM_ICR_DOWNCF_Pos (6U) +#define LPTIM_ICR_DOWNCF_Msk (0x1UL << LPTIM_ICR_DOWNCF_Pos) /*!< 0x00000040 */ +#define LPTIM_ICR_DOWNCF LPTIM_ICR_DOWNCF_Msk /*!< Counter direction change up to down Clear Flag */ + +/****************** Bit definition for LPTIM_IER register ********************/ +#define LPTIM_IER_CMPMIE_Pos (0U) +#define LPTIM_IER_CMPMIE_Msk (0x1UL << LPTIM_IER_CMPMIE_Pos) /*!< 0x00000001 */ +#define LPTIM_IER_CMPMIE LPTIM_IER_CMPMIE_Msk /*!< Compare match Interrupt Enable */ +#define LPTIM_IER_ARRMIE_Pos (1U) +#define LPTIM_IER_ARRMIE_Msk (0x1UL << LPTIM_IER_ARRMIE_Pos) /*!< 0x00000002 */ +#define LPTIM_IER_ARRMIE LPTIM_IER_ARRMIE_Msk /*!< Autoreload match Interrupt Enable */ +#define LPTIM_IER_EXTTRIGIE_Pos (2U) +#define LPTIM_IER_EXTTRIGIE_Msk (0x1UL << LPTIM_IER_EXTTRIGIE_Pos) /*!< 0x00000004 */ +#define LPTIM_IER_EXTTRIGIE LPTIM_IER_EXTTRIGIE_Msk /*!< External trigger edge event Interrupt Enable */ +#define LPTIM_IER_CMPOKIE_Pos (3U) +#define LPTIM_IER_CMPOKIE_Msk (0x1UL << LPTIM_IER_CMPOKIE_Pos) /*!< 0x00000008 */ +#define LPTIM_IER_CMPOKIE LPTIM_IER_CMPOKIE_Msk /*!< Compare register update OK Interrupt Enable */ +#define LPTIM_IER_ARROKIE_Pos (4U) +#define LPTIM_IER_ARROKIE_Msk (0x1UL << LPTIM_IER_ARROKIE_Pos) /*!< 0x00000010 */ +#define LPTIM_IER_ARROKIE LPTIM_IER_ARROKIE_Msk /*!< Autoreload register update OK Interrupt Enable */ +#define LPTIM_IER_UPIE_Pos (5U) +#define LPTIM_IER_UPIE_Msk (0x1UL << LPTIM_IER_UPIE_Pos) /*!< 0x00000020 */ +#define LPTIM_IER_UPIE LPTIM_IER_UPIE_Msk /*!< Counter direction change down to up Interrupt Enable */ +#define LPTIM_IER_DOWNIE_Pos (6U) +#define LPTIM_IER_DOWNIE_Msk (0x1UL << LPTIM_IER_DOWNIE_Pos) /*!< 0x00000040 */ +#define LPTIM_IER_DOWNIE LPTIM_IER_DOWNIE_Msk /*!< Counter direction change up to down Interrupt Enable */ + +/****************** Bit definition for LPTIM_CFGR register *******************/ +#define LPTIM_CFGR_CKSEL_Pos (0U) +#define LPTIM_CFGR_CKSEL_Msk (0x1UL << LPTIM_CFGR_CKSEL_Pos) /*!< 0x00000001 */ +#define LPTIM_CFGR_CKSEL LPTIM_CFGR_CKSEL_Msk /*!< Clock selector */ + +#define LPTIM_CFGR_CKPOL_Pos (1U) +#define LPTIM_CFGR_CKPOL_Msk (0x3UL << LPTIM_CFGR_CKPOL_Pos) /*!< 0x00000006 */ +#define LPTIM_CFGR_CKPOL LPTIM_CFGR_CKPOL_Msk /*!< CKPOL[1:0] bits (Clock polarity) */ +#define LPTIM_CFGR_CKPOL_0 (0x1UL << LPTIM_CFGR_CKPOL_Pos) /*!< 0x00000002 */ +#define LPTIM_CFGR_CKPOL_1 (0x2UL << LPTIM_CFGR_CKPOL_Pos) /*!< 0x00000004 */ + +#define LPTIM_CFGR_CKFLT_Pos (3U) +#define LPTIM_CFGR_CKFLT_Msk (0x3UL << LPTIM_CFGR_CKFLT_Pos) /*!< 0x00000018 */ +#define LPTIM_CFGR_CKFLT LPTIM_CFGR_CKFLT_Msk /*!< CKFLT[1:0] bits (Configurable digital filter for external clock) */ +#define LPTIM_CFGR_CKFLT_0 (0x1UL << LPTIM_CFGR_CKFLT_Pos) /*!< 0x00000008 */ +#define LPTIM_CFGR_CKFLT_1 (0x2UL << LPTIM_CFGR_CKFLT_Pos) /*!< 0x00000010 */ + +#define LPTIM_CFGR_TRGFLT_Pos (6U) +#define LPTIM_CFGR_TRGFLT_Msk (0x3UL << LPTIM_CFGR_TRGFLT_Pos) /*!< 0x000000C0 */ +#define LPTIM_CFGR_TRGFLT LPTIM_CFGR_TRGFLT_Msk /*!< TRGFLT[1:0] bits (Configurable digital filter for trigger) */ +#define LPTIM_CFGR_TRGFLT_0 (0x1UL << LPTIM_CFGR_TRGFLT_Pos) /*!< 0x00000040 */ +#define LPTIM_CFGR_TRGFLT_1 (0x2UL << LPTIM_CFGR_TRGFLT_Pos) /*!< 0x00000080 */ + +#define LPTIM_CFGR_PRESC_Pos (9U) +#define LPTIM_CFGR_PRESC_Msk (0x7UL << LPTIM_CFGR_PRESC_Pos) /*!< 0x00000E00 */ +#define LPTIM_CFGR_PRESC LPTIM_CFGR_PRESC_Msk /*!< PRESC[2:0] bits (Clock prescaler) */ +#define LPTIM_CFGR_PRESC_0 (0x1UL << LPTIM_CFGR_PRESC_Pos) /*!< 0x00000200 */ +#define LPTIM_CFGR_PRESC_1 (0x2UL << LPTIM_CFGR_PRESC_Pos) /*!< 0x00000400 */ +#define LPTIM_CFGR_PRESC_2 (0x4UL << LPTIM_CFGR_PRESC_Pos) /*!< 0x00000800 */ + +#define LPTIM_CFGR_TRIGSEL_Pos (13U) +#define LPTIM_CFGR_TRIGSEL_Msk (0x7UL << LPTIM_CFGR_TRIGSEL_Pos) /*!< 0x0000E000 */ +#define LPTIM_CFGR_TRIGSEL LPTIM_CFGR_TRIGSEL_Msk /*!< TRIGSEL[2:0]] bits (Trigger selector) */ +#define LPTIM_CFGR_TRIGSEL_0 (0x1UL << LPTIM_CFGR_TRIGSEL_Pos) /*!< 0x00002000 */ +#define LPTIM_CFGR_TRIGSEL_1 (0x2UL << LPTIM_CFGR_TRIGSEL_Pos) /*!< 0x00004000 */ +#define LPTIM_CFGR_TRIGSEL_2 (0x4UL << LPTIM_CFGR_TRIGSEL_Pos) /*!< 0x00008000 */ +#define LPTIM_CFGR_TRIGSEL_3 (0x1UL << 29) /*!< 0x20000000 */ + + +#define LPTIM_CFGR_TRIGEN_Pos (17U) +#define LPTIM_CFGR_TRIGEN_Msk (0x3UL << LPTIM_CFGR_TRIGEN_Pos) /*!< 0x00060000 */ +#define LPTIM_CFGR_TRIGEN LPTIM_CFGR_TRIGEN_Msk /*!< TRIGEN[1:0] bits (Trigger enable and polarity) */ +#define LPTIM_CFGR_TRIGEN_0 (0x1UL << LPTIM_CFGR_TRIGEN_Pos) /*!< 0x00020000 */ +#define LPTIM_CFGR_TRIGEN_1 (0x2UL << LPTIM_CFGR_TRIGEN_Pos) /*!< 0x00040000 */ + +#define LPTIM_CFGR_TIMOUT_Pos (19U) +#define LPTIM_CFGR_TIMOUT_Msk (0x1UL << LPTIM_CFGR_TIMOUT_Pos) /*!< 0x00080000 */ +#define LPTIM_CFGR_TIMOUT LPTIM_CFGR_TIMOUT_Msk /*!< Timeout enable */ +#define LPTIM_CFGR_WAVE_Pos (20U) +#define LPTIM_CFGR_WAVE_Msk (0x1UL << LPTIM_CFGR_WAVE_Pos) /*!< 0x00100000 */ +#define LPTIM_CFGR_WAVE LPTIM_CFGR_WAVE_Msk /*!< Waveform shape */ +#define LPTIM_CFGR_WAVPOL_Pos (21U) +#define LPTIM_CFGR_WAVPOL_Msk (0x1UL << LPTIM_CFGR_WAVPOL_Pos) /*!< 0x00200000 */ +#define LPTIM_CFGR_WAVPOL LPTIM_CFGR_WAVPOL_Msk /*!< Waveform shape polarity */ +#define LPTIM_CFGR_PRELOAD_Pos (22U) +#define LPTIM_CFGR_PRELOAD_Msk (0x1UL << LPTIM_CFGR_PRELOAD_Pos) /*!< 0x00400000 */ +#define LPTIM_CFGR_PRELOAD LPTIM_CFGR_PRELOAD_Msk /*!< Reg update mode */ +#define LPTIM_CFGR_COUNTMODE_Pos (23U) +#define LPTIM_CFGR_COUNTMODE_Msk (0x1UL << LPTIM_CFGR_COUNTMODE_Pos) /*!< 0x00800000 */ +#define LPTIM_CFGR_COUNTMODE LPTIM_CFGR_COUNTMODE_Msk /*!< Counter mode enable */ +#define LPTIM_CFGR_ENC_Pos (24U) +#define LPTIM_CFGR_ENC_Msk (0x1UL << LPTIM_CFGR_ENC_Pos) /*!< 0x01000000 */ +#define LPTIM_CFGR_ENC LPTIM_CFGR_ENC_Msk /*!< Encoder mode enable */ + +/****************** Bit definition for LPTIM_CR register ********************/ +#define LPTIM_CR_ENABLE_Pos (0U) +#define LPTIM_CR_ENABLE_Msk (0x1UL << LPTIM_CR_ENABLE_Pos) /*!< 0x00000001 */ +#define LPTIM_CR_ENABLE LPTIM_CR_ENABLE_Msk /*!< LPTIMer enable */ +#define LPTIM_CR_SNGSTRT_Pos (1U) +#define LPTIM_CR_SNGSTRT_Msk (0x1UL << LPTIM_CR_SNGSTRT_Pos) /*!< 0x00000002 */ +#define LPTIM_CR_SNGSTRT LPTIM_CR_SNGSTRT_Msk /*!< Timer start in single mode */ +#define LPTIM_CR_CNTSTRT_Pos (2U) +#define LPTIM_CR_CNTSTRT_Msk (0x1UL << LPTIM_CR_CNTSTRT_Pos) /*!< 0x00000004 */ +#define LPTIM_CR_CNTSTRT LPTIM_CR_CNTSTRT_Msk /*!< Timer start in continuous mode */ +#define LPTIM_CR_COUNTRST_Pos (3U) +#define LPTIM_CR_COUNTRST_Msk (0x1UL << LPTIM_CR_COUNTRST_Pos) /*!< 0x00000008 */ +#define LPTIM_CR_COUNTRST LPTIM_CR_COUNTRST_Msk /*!< Counter reset */ +#define LPTIM_CR_RSTARE_Pos (4U) +#define LPTIM_CR_RSTARE_Msk (0x1UL << LPTIM_CR_RSTARE_Pos) /*!< 0x00000010 */ +#define LPTIM_CR_RSTARE LPTIM_CR_RSTARE_Msk /*!< Reset after read enable */ + +/****************** Bit definition for LPTIM_CMP register *******************/ +#define LPTIM_CMP_CMP_Pos (0U) +#define LPTIM_CMP_CMP_Msk (0xFFFFUL << LPTIM_CMP_CMP_Pos) /*!< 0x0000FFFF */ +#define LPTIM_CMP_CMP LPTIM_CMP_CMP_Msk /*!< Compare register */ + +/****************** Bit definition for LPTIM_ARR register *******************/ +#define LPTIM_ARR_ARR_Pos (0U) +#define LPTIM_ARR_ARR_Msk (0xFFFFUL << LPTIM_ARR_ARR_Pos) /*!< 0x0000FFFF */ +#define LPTIM_ARR_ARR LPTIM_ARR_ARR_Msk /*!< Auto reload register */ + +/****************** Bit definition for LPTIM_CNT register *******************/ +#define LPTIM_CNT_CNT_Pos (0U) +#define LPTIM_CNT_CNT_Msk (0xFFFFUL << LPTIM_CNT_CNT_Pos) /*!< 0x0000FFFF */ +#define LPTIM_CNT_CNT LPTIM_CNT_CNT_Msk /*!< Counter register */ + +/****************** Bit definition for LPTIM_OR register *******************/ +#define LPTIM_OR_IN1_Pos (0U) +#define LPTIM_OR_IN1_Msk (0xDUL << LPTIM_OR_IN1_Pos) /*!< 0x0000000D */ +#define LPTIM_OR_IN1 LPTIM_OR_IN1_Msk /*!< OR[3:2],OR[0] bits (INPUT1 selection) */ +#define LPTIM_OR_IN1_0 0x00000001UL +#define LPTIM_OR_IN1_1 0x00000004UL +#define LPTIM_OR_IN1_2 0x00000008UL + +#define LPTIM_OR_IN2_Pos (1U) +#define LPTIM_OR_IN2_Msk (0x32UL << LPTIM_OR_IN2_Pos) /*!< 0x00000032 */ +#define LPTIM_OR_IN2 LPTIM_OR_IN2_Msk /*!< OR[5:4],OR[1] bits (INPUT2 selection) */ +#define LPTIM_OR_IN2_0 0x00000002UL +#define LPTIM_OR_IN2_1 0x00000010UL +#define LPTIM_OR_IN2_2 0x00000020UL + +//******************** ETHERNET register define******************************* +typedef struct +{ +//Ethernet mac + __IO uint32_t ETH_MAC_CFG; // 0x0000 Ethernet mac configuration register + __IO uint32_t ETH_MAC_EXTDCFG; // 0x0004 Ethernet mac extended configuration register + __IO uint32_t ETH_MAC_PKTFILT; // 0x0008 Ethernet mac packet filter register + __IO uint32_t ETH_MAC_WTDTO; // 0x000c Ethernet mac watch dog timeout register + __IO uint32_t ETH_MAC_HASHTB0; // 0x0010 Ethernet mac Hash table register 0 + __IO uint32_t ETH_MAC_HASHTB1; // 0x0014 Ethernet mac Hash table register 1 + __IO uint32_t RESERVED0[14]; // 0x0018 - 0x004c + __IO uint32_t ETH_MAC_VLANT; // 0x0050 Ethernet mac VLAN tag register + __IO uint32_t RESERVED1[7]; // 0x0054 - 0x006c + __IO uint32_t ETH_MAC_TXFLCTL; // 0x0070 Ethernet mac Tx FLow control register + __IO uint32_t RESERVED2[7]; // 0x0074 - 0x008c + __IO uint32_t ETH_MAC_RXFLCTL; // 0x0090 Ethernet mac Rx Flow control register + __IO uint32_t RESERVED3[7]; // 0x0094 - 0x00ac + __IO uint32_t ETH_MAC_IRSTU; // 0x00b0 Ethernet mac interrupt status register + __IO uint32_t ETH_MAC_IREN; // 0x00b4 Ethernet mac interrupt enable register + __IO uint32_t ETH_MAC_RXTXSTU; // 0x00b8 Ethernet mac receive tranmit status register + __IO uint32_t RESERVED4[1]; // 0x00bc + __IO uint32_t ETH_MAC_PMTCTLSTU; // 0x00c0 Ethernet mac PMT control and status register + __IO uint32_t ETH_MAC_RWKPKTFILT; // 0x00c4 Ethernet mac remote wakeup filter register + __IO uint32_t RESERVED5[19]; // 0X00c8 - 0x0110 + __IO uint32_t ETH_MAC_DBG; // 0x0114 Ethernet mac debug register + __IO uint32_t RESERVED6[58]; // 0x0118 - 0x01fc + __IO uint32_t ETH_MAC_MDIOADDR; // 0x0200 Ethernet mac MDIO address register + __IO uint32_t ETH_MAC_MDIODATA; // 0x0204 Ethernet MDIO data register + __IO uint32_t RESERVED7[10]; // 0x0208 - 0x022c + __IO uint32_t ETH_MAC_SWCTL; // 0x0230 Ethernet mac software programmable control + __IO uint32_t RESERVED8[51]; // 0x0234 - 0x02fc + __IO uint32_t ETH_MAC_ADDRH0; // 0x0300 Ethernet mac address0 high register + __IO uint32_t ETH_MAC_ADDRL0; // 0x0304 Ethernet mac address0 low register + __IO uint32_t ETH_MAC_ADDRH1; // 0x0308 Ethernet mac address1 high register + __IO uint32_t ETH_MAC_ADDRL1; // 0x030c Ethernet mac address1 low register + __IO uint32_t ETH_MAC_ADDRH2; // 0x0310 Ethernet mac address2 high register + __IO uint32_t ETH_MAC_ADDRL2; // 0x0314 Ethernet mac address2 low register + __IO uint32_t ETH_MAC_ADDRH3; // 0x0318 Ethernet mac address3 high register + __IO uint32_t ETH_MAC_ADDRL3; // 0x031c Ethernet mac address3 low register + __IO uint32_t RESERVED9[248]; // 0x0320 - 0x06fc + + //Ethernet mmc + __IO uint32_t ETH_MMC_CTL; // 0x0700 Ethernet mmc control refister + __IO uint32_t ETH_MMC_RXIR; // 0x0704 Ethernet mmc receive statistics counters interrupt + __IO uint32_t ETH_MMC_TXIR; // 0x0708 Ethernet mmc transmit statistics counters interrupt + __IO uint32_t ETH_MMC_RXIRMSK; // 0x070c Ethernet mmc masks for receive statistics counters + __IO uint32_t ETH_MMC_TXIRMSK; // 0x0710 Ethernet mmc masks for transmit statistic counters + __IO uint32_t RESERVED10[14]; // 0x0714 - 0x0748 + __IO uint32_t ETH_MMC_TXSCGP; // 0x074c Ethernet mmc transmit number of single collision good packets + __IO uint32_t ETH_MMC_TXMCGP; // 0x0750 Ethernet mmc transmit number of multiple collision good packets + __IO uint32_t RESERVED11[5]; // 0x0754 - 0x0764 + __IO uint32_t ETH_MMC_TXGP; // 0x0768 Ethernet mmc transmit number of good packets + __IO uint32_t RESERVED12[10]; // 0x076C - 0x0790 + __IO uint32_t ETH_MMC_RXCRCERRP; // 0x0794 Ethernet mmc receive number of packets with CRC error + __IO uint32_t ETH_MMC_RXALGERRP; // 0x0798 Ethernet mmc receive number of packets with alignment error + __IO uint32_t RESERVED13[10]; // 0x079c - 0x07c0 + __IO uint32_t ETH_MMC_RXUCASTP; // 0x07c4 Ethernet mmc receive number of good unicast packets + __IO uint32_t RESERVED14[206]; // 0x07c8 - 0x0afc + + //Ethernet ptp + __IO uint32_t ETH_PTP_TSCTL; // 0x0b00 Ethernet mac PTP pkt timstamp control register + __IO uint32_t ETH_PTP_SUBSECINR; // 0x0b04 Ethernet mac sub second increment + __IO uint32_t ETH_PTP_SYSTMSEC; // 0x0b08 Ethernet mac system time seconds register + __IO uint32_t ETH_PTP_SYSTMNSEC; // 0x0b0c Ethernet mac system time nanoseconds register + __IO uint32_t ETH_PTP_SYSTMSECUPDT; // 0x0b10 Etherner mac system time seconds updata register + __IO uint32_t ETH_PTP_SYSTMNSECUPDT; // 0x0b14 Ethernet mac system time nanoseconds updata register + __IO uint32_t ETH_PTP_TSADD; // 0x0b18 Ethernet mac timestamp addend register + __IO uint32_t RESERVED15[1]; // 0x0b1c + __IO uint32_t ETH_PTP_TSSTU; // 0x0b20 Ethernet mac timestamp status register + __IO uint32_t RESERVED16[3]; // 0x0b24 - 0x0b2c + __IO uint32_t ETH_PTP_TXTSSTUNSEC; // 0x0b30 Ethernet mac nanosecond part of timestamp status + __IO uint32_t ETH_PTP_TXTSSTUSEC; // 0x0b34 Ethernet mac higher 32 bits of timestamp captured when PTP is transmit + __IO uint32_t RESERVED17[6]; // 0x0b38 - 0x0b4c + __IO uint32_t ETH_PTP_TSINGASMCOR; // 0x0b50 Ethernet Timestamp Ingress Asymmetry Correction register + __IO uint32_t ETH_PTP_TSEGASMCOR; // 0x0b54 Ethernet Timestamp Egress Asymmetry Correction register + __IO uint32_t ETH_PTP_TSINGCORNSEC; // 0x0b58 Ethernet nanoseconds correction value with captured timestamp value in the ingress path + __IO uint32_t ETH_PTP_TSEGCORNSEC; // 0x0b5C Ethernet nanoseconds correction value with captured timestamp value in the egress path + __IO uint32_t RESERVED18[2]; // 0x0b60 - 0x0b64 + __IO uint32_t ETH_PTP_TSINGLAT; // 0x0b68 Ethernet mac ingress latency + __IO uint32_t ETH_PTP_TSEGLAT; // 0x0b6c Ethernet mac egress latency + __IO uint32_t ETH_PTP_PPSCTL; // 0x0b70 Ethernet PPS control register + __IO uint32_t RESERVED19[3]; // 0x0b74 - 0x0b7c + __IO uint32_t ETH_PTP_TRGTTMSEC; // 0x0b80 Ethernet PPS target time seconds register + __IO uint32_t ETH_PTP_TRGTTMNSEC; // 0x0b84 Ethernet PPS target time nanoseconds register + __IO uint32_t RESERVED20[30]; // 0x0b88 - 0x0bfc + + //Ethernet MTL + __IO uint32_t ETH_MTL_OPMODE; // 0x0c00 Ethernet transmit and receive operation mode + __IO uint32_t RESERVED21[7]; // 0x0c04 - 0x0c1c + __IO uint32_t ETH_MTL_INTRSTU; // 0x0c20 Ethernet app reads during interrupt service routing or polling to determine interrupt status + __IO uint32_t RESERVED22[55]; // 0x0c24 - 0x0cfc; + __IO uint32_t ETH_MTL_TXQOPMODE; // 0x0d00 Ethernet queue 0 transmit operation mode register + __IO uint32_t ETH_MTL_TXQUDFLW; // 0x0d04 Ethernet queue 0 underflow counter register + __IO uint32_t ETH_MTL_TXQDBG; // 0x0d08 Ethernet queue 0 transmit debug register + __IO uint32_t RESERVED23[8]; // 0x0d0c - 0x0d28 + __IO uint32_t ETH_MTL_QINTRCTRLSTU; // 0x0d2c Ethernet queue 0 interrupt enable and status + __IO uint32_t ETH_MTL_RXQOPMODE; // 0x0d30 Ethernet queue 0 receive operation mode register + __IO uint32_t ETH_MTL_RXQMISPKTOVFLWCNT; // 0X0d34 Ethernet queue 0 missed packet and overflow counter register + __IO uint32_t ETH_MTL_RXQDBG; // 0x0d38 Ethernet queue 0 receive debug register + __IO uint32_t RESERVED24[177]; // 0x0d3c - 0x0ffc + + //Ethernet DMA + __IO uint32_t ETH_DMA_OPMODE; // 0x1000 Ethernet BUS mode register + __IO uint32_t ETH_DMA_SYSBUSMODE; // 0x1004 Ethernet system bus mode register + __IO uint32_t ETH_DMA_INTRSTU; // 0x1008 Ethernet DMA channel interrupt status + __IO uint32_t ETH_DMA_DBGSTU; // 0x100c Ethernet DMA channel receive and transmit process status + __IO uint32_t RESERVED25[60]; // 0x1010-0x10fc + __IO uint32_t ETH_DMA_CTL; // 0x1100 Ethernet DMA channel0 control register + __IO uint32_t ETH_DMA_TXCTL; // 0x1104 Ethernet DMA channel0 transmit control register + __IO uint32_t ETH_DMA_RXCTL; // 0x1108 Ethernet DMA channel0 receive control register + __IO uint32_t RESERVED26[2]; // 0x110C - 0x1110 + __IO uint32_t ETH_DMA_TXDESCLSTADDR; // 0x1114 Ethernet DMA channel0 TX descriptor list address register + __IO uint32_t RESERVED27[1]; // 0x1118 + __IO uint32_t ETH_DMA_RXDESCLSTADDR; // 0x111c Ethernet DMA channel0 RX descriptor list address register + __IO uint32_t ETH_DMA_TXDESCTAILPTR; // 0x1120 Ethernet DMA channel0 TX descriptor tail pointer register + __IO uint32_t RESERVED28[1]; // 0x1124 + __IO uint32_t ETH_DMA_RXDESCTAILPTR; // 0x1128 Ethernet DMA channel0 RX descriptor tail pointer register + __IO uint32_t ETH_DMA_TXDESCRINGLEN; // 0x112c Ethernet DMA descriptor ring length reister + __IO uint32_t ETH_DMA_RXCTL2; // 0x1130 Ethernet DMA channel0 receive control register + __IO uint32_t ETH_DMA_INTRENA; // 0x1134 Ethernet DMA channel0 interrupt enable register + __IO uint32_t ETH_DMA_RXINTRWDGTMR; // 0x1138 Ethernet DMA channel0 receive interrupt watchdog timer register + __IO uint32_t RESERVED29[2]; // 0x113c - 0x1140 + __IO uint32_t ETH_DMA_CURAPPTXDESC; // 0x1144 Ethernet DMA channel0 current application transmit descriptor register + __IO uint32_t RESERVED30[1]; // 0x1148 + __IO uint32_t ETH_DMA_CURAPPRXDESC; // 0x114c Ethernet DMA channel0 current application receive descriptor register + __IO uint32_t RESERVED31[1]; // 0X1150 + __IO uint32_t ETH_DMA_CURAPPTXBUF; // 0x1154 Ethernet DMA channel0 current application transmit buffer address register + __IO uint32_t RESERVED32[1]; // 0x1158 + __IO uint32_t ETH_DMA_CURAPPRXBUF; // 0x115c Ethernet DMA channel0 current application receive buffer address register + __IO uint32_t ETH_DMA_STU; // 0x1160 Ethernet DMA channel0 status + __IO uint32_t ETH_DMA_MISFRMCNT; // 0x1164 Ethernet DMA channel0 number of packet counter that got dropped by the DMA + __IO uint32_t RESERVED33[1]; // 0x1168 + __IO uint32_t ETH_DMA_RXERICNT; // 0x116c Ethernet DMA channel0 provides the count of the number of times ERI was asserted + +} ETH_TypeDef; + + + +//******************** DBGMCU register define******************************* +typedef struct +{ + __IO uint32_t IDCODE; // 0xE0042000 + __IO uint32_t CR; // 0xE0042004 + __IO uint32_t APB1FZ; // 0xE0042008 + __IO uint32_t APB2FZ; // 0xE004200C + +} DBG_TypeDef; + + +//******************** COMP_OPAM_DAC register define******************************* +typedef struct +{ + //---DAC + __IO uint32_t DAC_CR ; // 0x40007400 + __IO uint32_t DAC_SWTRIGR ; // 0x40007404 + __IO uint32_t DAC_DHR12R1 ; // 0x40007408 + __IO uint32_t DAC_DHR12L1 ; // 0x4000740C + __IO uint32_t DAC_DHR8R1 ; // 0x40007410 + __IO uint32_t DAC_DHR12R2 ; // 0x40007414 + __IO uint32_t DAC_DHR12L2 ; // 0x40007418 + __IO uint32_t DAC_DHR8R2 ; // 0x4000741c + __IO uint32_t DAC_DHR12RD ; // 0x40007420 + __IO uint32_t DAC_DHR12LD ; // 0x40007424 + __IO uint32_t DAC_DHR8RD ; // 0x40007428 + __IO uint32_t DAC_DOR1 ; // 0x4000742c + __IO uint32_t DAC_DOR2 ; // 0x40007430 + __IO uint32_t DAC_SR ; // 0x40007434 + + //---OPAMP + __IO uint32_t OPAMP1_CSR ; // 0x40007438 + __IO uint32_t OPAMP2_CSR ; // 0X4000743C + __IO uint32_t OPAMP3_CSR ; // 0x40007440 + __IO uint32_t OPAMP1_TCMR ; // 0x40007444 + __IO uint32_t OPAMP2_TCMR ; // 0x40007448 + __IO uint32_t OPAMP3_TCMR ; // 0x4000744c + + //---COMP + __IO uint32_t COMP1_CSR ; // 0x40007450 + __IO uint32_t COMP2_CSR ; // 0x40007454 + __IO uint32_t COMP1_RAMPMAXREF_SHADOW; // 0x40007458 + __IO uint32_t COMP1_RAMPMAXREF_ACTIV ; // 0x4000745c + __IO uint32_t COMP1_RAMPDECVAL_SHADOW; // 0x40007460 + __IO uint32_t COMP1_RAMPDECVAL_ACTIV ; // 0x40007464 + __IO uint32_t COMP2_RAMPMAXREF_SHADOW; // 0x40007468 + __IO uint32_t COMP2_RAMPMAXREF_ACTIV ; // 0x4000746c + __IO uint32_t COMP2_RAMPDECVAL_SHADOW; // 0x40007470 + __IO uint32_t COMP2_RAMPDECVAL_ACTIV ; // 0x40007474 + __IO uint32_t COMP1_RAMPSTS ; // 0x40007478 + __IO uint32_t COMP2_RAMPSTS ; // 0x4000747c + __IO uint32_t COMP3_CSR ; // 0x40007480 + __IO uint32_t COMP4_CSR ; // 0x40007480 + __IO uint32_t COMP5_CSR ; // 0x40007480 + __IO uint32_t COMP6_CSR ; // 0x40007480 + + +} COMP_OPAM_DAC_TypeDef; + +//******************** CACHE register define******************************* +typedef struct +{ + //---ICACHE + __IO uint32_t ICACHE_CTRL ; // 0x4002E000 + __IO uint32_t ICACHE_SR ; // 0x4002E004 + __IO uint32_t ICACHE_IRQMASK ; // 0X4002E008 + __IO uint32_t ICACHE_IRQSTAT ; // 0X4002E00c + __IO uint32_t ICACHE_TYPE ; // 0x4002E010 + __IO uint32_t ICACHE_CSHR ; // 0x4002E014 + __IO uint32_t ICACHE_CSMR ; // 0x4002E018 +} ICACHE_TypeDef; + +typedef struct +{ + //---DCACHE + __IO uint32_t DCACHE_CTRL ; // 0x4003E020 + __IO uint32_t DCACHE_SR ; // 0x4003E024 + __IO uint32_t DCACHE_IRQMASK ; // 0X4003E028 + __IO uint32_t DCACHE_IRQSTAT ; // 0X4003E02c + __IO uint32_t DCACHE_TYPE ; // 0x4003E030 + __IO uint32_t DCACHE_CSHR ; // 0x4003E034 + __IO uint32_t DCACHE_CSMR ; // 0x4003E038 +} DCACHE_TypeDef; + +//******************** RNG register define******************************* +typedef struct +{ + //---RNG + __IO uint32_t RNG_CR ; // 0x50060800 + __IO uint32_t RNG_SR ; // 0X50060804 + __IO uint32_t RNG_DR ; // 0x50060808 +} RNG_TypeDef; + +//******************** VREFBUF register define******************************* +typedef struct +{ + __IO uint32_t VREFBUF_CSR ; // 0x40016400 + __IO uint32_t VREFBUF_CCR ; // 0X40016404 + +} VREFBUF_TypeDef; + + +/******************************************************************************/ +/* pwr_register_typedef */ +/******************************************************************************/ +typedef struct +{ + __IO uint32_t CR; // 0x0000 pwr configuration register + __IO uint32_t CSR; // 0x0004 pwr configuration register +} PWR_TypeDef; +/******************************************************************************/ +/* rtc_register_typedef */ +/******************************************************************************/ +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 CR; /*!< RTC control register, Address offset: 0x08 */ + __IO uint32_t ISR; /*!< RTC initialization and status register, Address offset: 0x0C */ + __IO uint32_t PRER; /*!< RTC prescaler register, Address offset: 0x10 */ + __IO uint32_t WUTR; /*!< RTC wkup timing register, Address offset: 0x14 */ + __IO uint32_t CALIBR; /*!< RTC rough calibration, Address offset: 0x18 */ + __IO uint32_t ALRMAR; /*!< RTC alram A register, Address offset: 0x1C */ + __IO uint32_t ALRMBR; /*!< RTC alarm B register, Address offset: 0x20 */ + __IO uint32_t WPR; /*!< RTC write protection register, Address offset: 0x24 */ + __IO uint32_t SSR; /*!< RTC sub second 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 */ + __IO uint32_t CALR; /*!< RTC calibration register, Address offset: 0x3C */ + __IO uint32_t TAFCR; /*!< RTC tamper and alternate funtion configuration register, Address offset: 0x40 */ + __IO uint32_t ALRMASSR; /*!< RTC alram A sub second register, Address offset: 0x44 */ + __IO uint32_t ALRMBSSR; /*!< RTC alram B sub second register, Address offset: 0x48 */ + uint32_t RESERVES; /*!< RTC reserves register, Address offset: 0x4C */ + __IO uint32_t BKP0R; /*!< RTC backup register, Address offset: 0x50 */ + __IO uint32_t BKP1R; /*!< RTC backup register, Address offset: 0x54 */ + __IO uint32_t BKP2R; /*!< RTC backup register, Address offset: 0x58 */ + __IO uint32_t BKP3R; /*!< RTC backup register, Address offset: 0x5c */ + __IO uint32_t BKP4R; /*!< RTC backup register, Address offset: 0x60 */ + __IO uint32_t BKP5R; /*!< RTC backup register, Address offset: 0x64 */ + __IO uint32_t BKP6R; /*!< RTC backup register, Address offset: 0x68 */ + __IO uint32_t BKP7R; /*!< RTC backup register, Address offset: 0x6c */ + __IO uint32_t BKP8R; /*!< RTC backup register, Address offset: 0x70 */ + __IO uint32_t BKP9R; /*!< RTC backup register, Address offset: 0x74 */ + __IO uint32_t BKP10R; /*!< RTC backup register, Address offset: 0x78 */ + __IO uint32_t BKP11R; /*!< RTC backup register, Address offset: 0x7c */ + __IO uint32_t BKP12R; /*!< RTC backup register, Address offset: 0x80 */ + __IO uint32_t BKP13R; /*!< RTC backup register, Address offset: 0x84 */ + __IO uint32_t BKP14R; /*!< RTC backup register, Address offset: 0x88 */ + __IO uint32_t BKP15R; /*!< RTC backup register, Address offset: 0x8c */ + __IO uint32_t BKP16R; /*!< RTC backup register, Address offset: 0x90 */ + __IO uint32_t BKP17R; /*!< RTC backup register, Address offset: 0x94 */ + __IO uint32_t BKP18R; /*!< RTC backup register, Address offset: 0x98 */ + __IO uint32_t BKP19R; /*!< RTC backup register, Address offset: 0x9c */ +} RTC_TypeDef; + +//*************************************************************************** +//******************** i2s register define*********************************** +typedef struct +{ + __IO uint32_t CTRL ; //0x00 + __IO uint32_t INTR_STAT ; //0x04 + __IO uint32_t SRR ; //0x08 + __IO uint32_t CID_CTRL ; //0x0C + __I uint32_t TFIFO_STAT ; //0x10 + __I uint32_t RFIFO_STAT ; //0x14 + __IO uint32_t TFIFO_CTRL ; //0x18 + __IO uint32_t RFIFO_CTRL ; //0x1C + __IO uint32_t DEV_CONF ; //0x20 + __I uint32_t POLL_STAT ; //0x24 + __IO uint32_t RESERVED0[5] ; //0x28 + __IO uint32_t FIFO ; //0x3C +} I2S_TypeDef; + + +/******************************************************************************/ +/* Peripheral memory map */ +/******************************************************************************/ +/** @addtogroup CM4_MemoryMap CM4 Memory Mapping + @{ +*/ + +/* Peripheral and SRAM base address */ +//#define FLASH_BASE (0x00000000UL) /*!< (FLASH ) Base Address */ +#define SRAM_BASE (0x20000000UL) /*!< (SRAM ) Base Address */ +#define PERIPH_BASE (0x40000000UL) /*!< (Peripheral) Base Address */ +#define FMC_R_BASE (0xA0000000UL) /*!< FMC register Base Address */ + +/* Base addresses */ +#define RAM_BASE (0x20000000UL) +#define APB1_BASE (0x40000000UL) +#define APB2_BASE (0x40010000UL) +#define AHB1_BASE (0x40020000UL) +#define AHB2_BASE (0x50000000UL) +#define AHB3_BASE (0x60000000UL) +#define FLASH_BASE (0x08000000UL) +#define FLASH_CTL_BASE (AHB1_BASE + 0x3C00UL) +#define RCC_BASE (AHB1_BASE + 0x3800UL) +#define CRS_BASE (APB1_BASE + 0x8000UL) +#define SYSCFG_BASE (APB2_BASE + 0x3800UL) +#define PWR_BASE (APB1_BASE + 0x7000UL) +#define RTC_BASE (APB1_BASE + 0x2800UL) +#define VREFBUF_BASE (APB2_BASE + 0x6400UL) + + +/* APB peripherals */ +#define I2C1_BASE (APB1_BASE + 0x5400UL) +#define I2C2_BASE (APB1_BASE + 0x5800UL) +#define I2C3_BASE (APB1_BASE + 0x5C00UL) + +#define USART1_BASE (APB2_BASE + 0x1000UL) +#define USART6_BASE (APB2_BASE + 0x1400UL) +#define USART1_WP_BASE (USART1_BASE + 0xE4UL) +#define USART6_WP_BASE (USART6_BASE + 0xE4UL) +#define SDIO_BASE (APB2_BASE + 0x2C00UL) +#define SDIO_DATA_BASE (SDIO_BASE + 0x200UL) +#define SPI1_BASE (APB2_BASE + 0x3000UL) + +#define USART2_BASE (APB1_BASE + 0x4000UL) +#define USART3_BASE (APB1_BASE + 0x4400UL) +#define UART4_BASE (APB1_BASE + 0x4800UL) +#define UART5_BASE (APB1_BASE + 0x4C00UL) +#define UART7_BASE (APB1_BASE + 0x7800UL) +#define LPUART_BASE (APB1_BASE + 0x5000UL) +#define USART2_WP_BASE (USART2_BASE + 0xE4UL) +#define USART3_WP_BASE (USART3_BASE + 0xE4UL) +#define UART4_WP_BASE (UART4_BASE + 0xE4UL) +#define UART5_WP_BASE (UART5_BASE + 0xE4UL) +#define UART7_WP_BASE (UART7_BASE + 0xE4UL) +#define LPUART_WP_BASE (LPUART_BASE + 0xE4UL) +#define SPI2_BASE (APB1_BASE + 0x3800UL) +#define SPI3_BASE (APB1_BASE + 0x3C00UL) +#define SPDIF_BASE (APB2_BASE + 0x2400UL) +#define SSI_BASE (APB1_BASE + 0x3400UL) +#define IWDG_BASE (APB1_BASE + 0x3000UL) +#define WWDG_BASE (APB1_BASE + 0x2C00UL) +#define EXTI_BASE (APB2_BASE + 0x3C00UL) +#define TIM2_BASE (APB1_BASE + 0x0000UL) +#define TIM3_BASE (APB1_BASE + 0x0400UL) +#define TIM4_BASE (APB1_BASE + 0x0800UL) +#define TIM5_BASE (APB1_BASE + 0x0c00UL) +#define TIM6_BASE (APB1_BASE + 0x1000UL) +#define TIM7_BASE (APB1_BASE + 0x1400UL) +#define TIM9_BASE (APB2_BASE + 0x4000UL) +#define TIM10_BASE (APB2_BASE + 0x4400UL) +#define TIM11_BASE (APB2_BASE + 0x4800UL) +#define TIM12_BASE (APB1_BASE + 0x1800UL) +#define TIM13_BASE (APB1_BASE + 0x1c00UL) +#define TIM14_BASE (APB1_BASE + 0x2000UL) +#define LPTIM_BASE (APB2_BASE + 0x5400UL) +#define CAN1_BASE (APB1_BASE + 0x6000UL) +#define CAN2_BASE (APB1_BASE + 0x6400UL) +#define CAN3_BASE (APB1_BASE + 0x6800UL) +#define CAN4_BASE (APB1_BASE + 0x6C00UL) +#define TIM1_BASE (APB2_BASE + 0x0000UL) +#define TIM8_BASE (APB2_BASE + 0x0400UL) +#define EPWM1_BASE (APB2_BASE + 0x4C00UL) +#define EPWM2_BASE (APB2_BASE + 0x5800UL) +#define EPWM3_BASE (APB2_BASE + 0x5C00UL) +#define EPWM4_BASE (APB2_BASE + 0x6000UL) +#define ECAP_BASE (APB2_BASE + 0x0800UL) +#define EQEP_BASE (APB2_BASE + 0x0C00UL) +#define UCPD_BASE (APB1_BASE + 0x7C00UL) +#define DBGMCU_BASE (0xE0042000UL) +#define COMP_OPAM_DAC_BASE (APB1_BASE + 0x7400UL) +#define RNG_BASE (AHB2_BASE + 0x060800L) +#define I2S2_BASE (SPI2_BASE + 0x200UL) +#define I2S3_BASE (SPI3_BASE + 0x200UL) + +/* AHB peripherals */ +#define OTG_FS_BASE (AHB2_BASE + 0UL) +#define OTG_HS_BASE (AHB1_BASE + 0x20000UL) +#define ETH_BASE (AHB1_BASE + 0x8000UL) +#define ICACHE_BASE (AHB1_BASE + 0xE000UL) +#define DCACHE_BASE (AHB1_BASE + 0xE020UL) + +#define DMA1_BASE (AHB1_BASE + 0x6000UL) +#define DMA2_BASE (AHB1_BASE + 0x6400UL) +#define QSPI_BASE (0xA0000000UL + 0x1000UL) +#define QSPI_BANK (AHB3_BASE + 0x30000000UL) + +/*!< FMC Bankx registers base address */ +#define FMC_Bank1_R_BASE (FMC_R_BASE + 0x0000UL) +#define FMC_Bank1E_R_BASE (FMC_R_BASE + 0x0104UL) +#define FMC_Bank2_3_R_BASE (FMC_R_BASE + 0x0060UL) +#define FMC_Bank5_6_R_BASE (FMC_R_BASE + 0x0140UL) + + +#define FMC_BASE (AHB3_BASE + 0x40000000UL) +#define FMC_BANK1 (AHB3_BASE) +#define FMC_BANK1_1 (FMC_BANK1) +#define FMC_BANK1_2 (FMC_BANK1 + 0x04000000UL) +#define FMC_BANK1_3 (FMC_BANK1 + 0x08000000UL) +#define FMC_BANK1_4 (FMC_BANK1 + 0x0C000000UL) + +#define FMC_BANK2 (AHB3_BASE + 0x10000000UL) +#define FMC_BANK3 (AHB3_BASE + 0x20000000UL) + +#ifdef SWP_FMC +#define NAND2_MEM_DATA_BASE (AHB3_BASE + 0x60000000UL) +#define NAND2_MEM_CMD_BASE (AHB3_BASE + 0x60010000UL) +#define NAND2_MEM_ADDR_BASE (AHB3_BASE + 0x60020000UL) + +#define NAND2_ATT_DATA_BASE (AHB3_BASE + 0x68000000UL) +#define NAND2_ATT_CMD_BASE (AHB3_BASE + 0x68010000UL) +#define NAND2_ATT_ADDR_BASE (AHB3_BASE + 0x68020000UL) + +#define NAND3_MEM_DATA_BASE (AHB3_BASE + 0x70000000UL) +#define NAND3_MEM_CMD_BASE (AHB3_BASE + 0x70010000UL) +#define NAND3_MEM_ADDR_BASE (AHB3_BASE + 0x70020000UL) + +#define NAND3_ATT_DATA_BASE (AHB3_BASE + 0x78000000UL) +#define NAND3_ATT_CMD_BASE (AHB3_BASE + 0x78010000UL) +#define NAND3_ATT_ADDR_BASE (AHB3_BASE + 0x78020000UL) + +#define FMC_BANK5 (FMC_BANK1 + 0x10000000UL) +#define FMC_BANK6 (FMC_BANK1 + 0x20000000UL) +#else +#define NAND2_MEM_DATA_BASE (AHB3_BASE + 0x10000000UL) +#define NAND2_MEM_CMD_BASE (AHB3_BASE + 0x10010000UL) +#define NAND2_MEM_ADDR_BASE (AHB3_BASE + 0x10020000UL) + +#define NAND2_ATT_DATA_BASE (AHB3_BASE + 0x18000000UL) +#define NAND2_ATT_CMD_BASE (AHB3_BASE + 0x18010000UL) +#define NAND2_ATT_ADDR_BASE (AHB3_BASE + 0x18020000UL) + +#define NAND3_MEM_DATA_BASE (AHB3_BASE + 0x20000000UL) +#define NAND3_MEM_CMD_BASE (AHB3_BASE + 0x20010000UL) +#define NAND3_MEM_ADDR_BASE (AHB3_BASE + 0x20020000UL) + +#define NAND3_ATT_DATA_BASE (AHB3_BASE + 0x28000000UL) +#define NAND3_ATT_CMD_BASE (AHB3_BASE + 0x28010000UL) +#define NAND3_ATT_ADDR_BASE (AHB3_BASE + 0x28020000UL) + +#define PCCARD4_MEM_BASE (AHB3_BASE + 0x30000000UL) +#define PCCARD4_ATT_BASE (AHB3_BASE + 0x38000000UL) +#define PCCARD4_IO_BASE (AHB3_BASE + 0x3C000000UL) + +#define FMC_BANK5 (FMC_BANK1 + 0x60000000UL) +#define FMC_BANK6 (FMC_BANK1 + 0x70000000UL) +#endif + +#define GPIO_BASE (AHB1_BASE) +#define GPIOA_BASE (GPIO_BASE + 0x0000UL) +#define GPIOB_BASE (GPIO_BASE + 0x0400UL) +#define GPIOC_BASE (GPIO_BASE + 0x0800UL) +#define GPIOD_BASE (GPIO_BASE + 0x0C00UL) +#define GPIOE_BASE (GPIO_BASE + 0x1000UL) +#define GPIOH_BASE (GPIO_BASE + 0x1C00UL) +#define CRC_BASE (AHB1_BASE + 0x3000UL) +#define CRC ((CRC_TypeDef *) CRC_BASE) + + +#define USB_OTG_HS_GLOBAL_BASE 0x0000UL +#define USB_OTG_HS_DEVICE_BASE 0x0800UL +#define USB_OTG_HS_IN_ENDPOINT_BASE 0x0900UL +#define USB_OTG_HS_OUT_ENDPOINT_BASE 0x0B00UL +#define USB_OTG_HS_EP_REG_SIZE 0x0020UL +#define USB_OTG_HS_HOST_BASE 0x0400UL +#define USB_OTG_HS_HOST_PORT_BASE 0x0440UL +#define USB_OTG_HS_HOST_CHANNEL_BASE 0x0500UL +#define USB_OTG_HS_HOST_CHANNEL_SIZE 0x0020UL +#define USB_OTG_HS_PCGCCTL_BASE 0x0E00UL +#define USB_OTG_HS_FIFO_BASE 0x1000UL +#define USB_OTG_HS_FIFO_SIZE 0x1000UL +#define USB_OTG_HS_PKEY_BASE 0x0E20UL +#define USB_OTG_HS_PREG_BASE 0x0E18UL + +/*@}*/ /* end of group CM4_MemoryMap */ + + +/******************************************************************************/ +/* Peripheral declaration */ +/******************************************************************************/ +/** @addtogroup CM4_PeripheralDecl CM4 Peripheral Declaration + @{ +*/ + +#define TIM1 ((TIM_TypeDef *) TIM1_BASE ) +#define TIM8 ((TIM_TypeDef *) TIM8_BASE ) + +#define EPWM1 ((EPWM_TypeDef *) EPWM1_BASE) +#define EPWM2 ((EPWM_TypeDef *) EPWM2_BASE) +#define EPWM3 ((EPWM_TypeDef *) EPWM3_BASE) +#define EPWM4 ((EPWM_TypeDef *) EPWM4_BASE) +#define ECAP ((ECAP_TypeDef *) ECAP_BASE ) +#define EQEP ((EQEP_TypeDef *) EQEP_BASE ) + + +//DMA1 Registers Address +#define DMA1_channel0_BASE (DMA1_BASE + 0x00000000) +#define DMA1_channel1_BASE (DMA1_BASE + 0x00000058) +#define DMA1_channel2_BASE (DMA1_BASE + 0x000000B0) +#define DMA1_channel3_BASE (DMA1_BASE + 0x00000108) +#define DMA1_channel4_BASE (DMA1_BASE + 0x00000160) +#define DMA1_channel5_BASE (DMA1_BASE + 0x000001B8) +#define DMA1_channel6_BASE (DMA1_BASE + 0x00000210) +#define DMA1_channel7_BASE (DMA1_BASE + 0x00000268) +#define DMA1_CFG_BASE (DMA1_BASE + 0x000002C0) + +//DMA2 Registers Address +#define DMA2_channel0_BASE (DMA2_BASE + 0x00000000) +#define DMA2_channel1_BASE (DMA2_BASE + 0x00000058) +#define DMA2_channel2_BASE (DMA2_BASE + 0x000000B0) +#define DMA2_channel3_BASE (DMA2_BASE + 0x00000108) +#define DMA2_channel4_BASE (DMA2_BASE + 0x00000160) +#define DMA2_channel5_BASE (DMA2_BASE + 0x000001B8) +#define DMA2_channel6_BASE (DMA2_BASE + 0x00000210) +#define DMA2_channel7_BASE (DMA2_BASE + 0x00000268) +#define DMA2_CFG_BASE (DMA2_BASE + 0x000002C0) + +//DMA1 Registers Define +#define DMA1_Channel0 ((DMA_Channel_TypeDef *) DMA1_channel0_BASE) +#define DMA1_Channel1 ((DMA_Channel_TypeDef *) DMA1_channel1_BASE) +#define DMA1_Channel2 ((DMA_Channel_TypeDef *) DMA1_channel2_BASE) +#define DMA1_Channel3 ((DMA_Channel_TypeDef *) DMA1_channel3_BASE) +#define DMA1_Channel4 ((DMA_Channel_TypeDef *) DMA1_channel4_BASE) +#define DMA1_Channel5 ((DMA_Channel_TypeDef *) DMA1_channel5_BASE) +#define DMA1_Channel6 ((DMA_Channel_TypeDef *) DMA1_channel6_BASE) +#define DMA1_Channel7 ((DMA_Channel_TypeDef *) DMA1_channel7_BASE) +#define DMA1 ((DMA_TypeDef *) DMA1_CFG_BASE ) + +//DMA2 Registers Define +#define DMA2_Channel0 ((DMA_Channel_TypeDef *) DMA2_channel0_BASE) +#define DMA2_Channel1 ((DMA_Channel_TypeDef *) DMA2_channel1_BASE) +#define DMA2_Channel2 ((DMA_Channel_TypeDef *) DMA2_channel2_BASE) +#define DMA2_Channel3 ((DMA_Channel_TypeDef *) DMA2_channel3_BASE) +#define DMA2_Channel4 ((DMA_Channel_TypeDef *) DMA2_channel4_BASE) +#define DMA2_Channel5 ((DMA_Channel_TypeDef *) DMA2_channel5_BASE) +#define DMA2_Channel6 ((DMA_Channel_TypeDef *) DMA2_channel6_BASE) +#define DMA2_Channel7 ((DMA_Channel_TypeDef *) DMA2_channel7_BASE) +#define DMA2 ((DMA_TypeDef *) DMA2_CFG_BASE ) + + +#define DMA1_CH0 ((DMA_Channel_TypeDef *) DMA1_channel0_BASE) +#define DMA1_CH1 ((DMA_Channel_TypeDef *) DMA1_channel1_BASE) +#define DMA1_CH2 ((DMA_Channel_TypeDef *) DMA1_channel2_BASE) +#define DMA1_CH3 ((DMA_Channel_TypeDef *) DMA1_channel3_BASE) +#define DMA1_CH4 ((DMA_Channel_TypeDef *) DMA1_channel4_BASE) +#define DMA1_CH5 ((DMA_Channel_TypeDef *) DMA1_channel5_BASE) +#define DMA1_CH6 ((DMA_Channel_TypeDef *) DMA1_channel6_BASE) +#define DMA1_CH7 ((DMA_Channel_TypeDef *) DMA1_channel7_BASE) + +#define DMA2_CH0 ((DMA_Channel_TypeDef *) DMA2_channel0_BASE) +#define DMA2_CH1 ((DMA_Channel_TypeDef *) DMA2_channel1_BASE) +#define DMA2_CH2 ((DMA_Channel_TypeDef *) DMA2_channel2_BASE) +#define DMA2_CH3 ((DMA_Channel_TypeDef *) DMA2_channel3_BASE) +#define DMA2_CH4 ((DMA_Channel_TypeDef *) DMA2_channel4_BASE) +#define DMA2_CH5 ((DMA_Channel_TypeDef *) DMA2_channel5_BASE) +#define DMA2_CH6 ((DMA_Channel_TypeDef *) DMA2_channel6_BASE) +#define DMA2_CH7 ((DMA_Channel_TypeDef *) DMA2_channel7_BASE) + +#define I2C1 ((I2C_TypeDef *) I2C1_BASE) +#define I2C2 ((I2C_TypeDef *) I2C2_BASE) +#define I2C3 ((I2C_TypeDef *) I2C3_BASE) +#define FLASH ((FLASH_TypeDef *) FLASH_CTL_BASE) +#define RCC ((RCC_TypeDef *) RCC_BASE) +#define PWR ((PWR_TypeDef *) PWR_BASE) +#define RTC ((RTC_TypeDef *) RTC_BASE) +#define CRS ((CRS_TypeDef *) CRS_BASE) +#define SYSCFG ((SYSCFG_TypeDef *) SYSCFG_BASE) +#define OTG_FS ((OTG_FS_TypeDef *) OTG_FS_BASE) +#define USB_FS ((OTG_FS_TypeDef *) OTG_FS_BASE) +#define OTG_HS ((USB_OTG_HS_GlobalTypeDef *) OTG_HS_BASE) +#define USB_HS ((USB_OTG_HS_GlobalTypeDef *) OTG_HS_BASE) +#define VREFBUF ((VREFBUF_TypeDef *) VREFBUF_BASE) +#define UCPD ((UCPD_TypeDef *) UCPD_BASE) +#define USART1 ((USART_TypeDef *) USART1_BASE) +#define USART2 ((USART_TypeDef *) USART2_BASE) +#define USART3 ((USART_TypeDef *) USART3_BASE) +#define USART6 ((USART_TypeDef *) USART6_BASE) +#define UART4 ((USART_TypeDef *) UART4_BASE) +#define UART5 ((USART_TypeDef *) UART5_BASE) +#define UART7 ((USART_TypeDef *) UART7_BASE) +#define LPUART ((USART_TypeDef *) LPUART_BASE) +#define USART1_WP ((USART_WP_TypeDef *) USART1_WP_BASE) +#define USART2_WP ((USART_WP_TypeDef *) USART2_WP_BASE) +#define USART3_WP ((USART_WP_TypeDef *) USART3_WP_BASE) +#define USART6_WP ((USART_WP_TypeDef *) USART6_WP_BASE) +#define UART4_WP ((USART_WP_TypeDef *) UART4_WP_BASE) +#define UART5_WP ((USART_WP_TypeDef *) UART5_WP_BASE) +#define UART7_WP ((USART_WP_TypeDef *) UART7_WP_BASE) +#define LPUART_WP ((USART_WP_TypeDef *) LPUART_WP_BASE) +#define SPI1 ((SPI_TypeDef *) SPI1_BASE) +#define SPI2 ((SPI_TypeDef *) SPI2_BASE) +#define SPI3 ((SPI_TypeDef *) SPI3_BASE) +#define QSPI ((QSPI_TypeDef *) QSPI_BASE) +#define SDIO ((SDIO_TypeDef *) SDIO_BASE) +#define SDIO_DATA ((SDIO_DATA_TypeDef *) SDIO_DATA_BASE) +#define SPDIF ((SPDIF_TypeDef *) SPDIF_BASE) +#define SSI ((SSI_TypeDef *) SSI_BASE) +#define WWDG ((WWDG_TypeDef *) WWDG_BASE) +#define IWDG ((IWDG_TypeDef *) IWDG_BASE ) +#define EXTI ((EXTI_TypeDef *) EXTI_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 TIM10 ((TIM_TypeDef *) TIM10_BASE) +#define TIM11 ((TIM_TypeDef *) TIM11_BASE) +#define TIM12 ((TIM_TypeDef *) TIM12_BASE) +#define TIM13 ((TIM_TypeDef *) TIM13_BASE) +#define TIM14 ((TIM_TypeDef *) TIM14_BASE) +#define LPTIM ((LPTIM_TypeDef *) LPTIM_BASE) +#define LPTIM1 ((LPTIM_TypeDef *) LPTIM_BASE) +#define FDCAN1 ((FDCAN_TypeDef *) CAN1_BASE) +#define FDCAN2 ((FDCAN_TypeDef *) CAN2_BASE) +#define FDCAN3 ((FDCAN_TypeDef *) CAN3_BASE) +#define FDCAN4 ((FDCAN_TypeDef *) CAN4_BASE) +#define DBGMCU ((DBG_TypeDef *) DBGMCU_BASE) +#define COMP_OPAM_DAC ((COMP_OPAM_DAC_TypeDef *) COMP_OPAM_DAC_BASE) +#define ICACHE ((ICACHE_TypeDef *) ICACHE_BASE) +#define DCACHE ((DCACHE_TypeDef *) DCACHE_BASE) +#define RNG ((RNG_TypeDef *) RNG_BASE) +#define FMC_Bank1 ((FMC_Bank1_TypeDef *) FMC_Bank1_R_BASE) +#define FMC_Bank1E ((FMC_Bank1E_TypeDef *) FMC_Bank1E_R_BASE) +#define FMC_Bank2_3 ((FMC_Bank2_3_TypeDef *) FMC_Bank2_3_R_BASE) +#define FMC_Bank5_6 ((FMC_Bank5_6_TypeDef *) FMC_Bank5_6_R_BASE) +#define ETH ((ETH_TypeDef *) ETH_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 GPIOH ((GPIO_TypeDef *) GPIOH_BASE) +#define CRC ((CRC_TypeDef *) CRC_BASE) +#define I2S2 ((I2S_TypeDef *) I2S2_BASE) +#define I2S3 ((I2S_TypeDef *) I2S3_BASE) + +//****************** ADC Registers Address ****************** +//added by cpf +#define ADC1_BASE (APB2_BASE + 0x2000) +#define ADC2_BASE (APB2_BASE + 0x2100) +#define ADC3_BASE (APB2_BASE + 0x2200) +#define ADC_Common_BASE (APB2_BASE + 0x2300) + +#define ADC1 ((ADC_TypeDef *) ADC1_BASE) +#define ADC2 ((ADC_TypeDef *) ADC2_BASE) +#define ADC3 ((ADC_TypeDef *) ADC3_BASE) +#define ADC_Common ((ADC_Common_TypeDef *) ADC_Common_BASE) + + + +/*@}*/ /* end of group CM4_PeripheralDecl */ + + + +/** @addtogroup Peripheral_Registers_Bits_Definition +* @{ +*/ +/******************************************************************************/ +/* Peripheral Registers Bits Definition */ +/******************************************************************************/ +/******************************************************************************/ +/* */ +/* USB High-speed On-The-Go (OTG_HS) */ +/* */ +/******************************************************************************/ +/******************** Bit definition for OTG_HS_GOTGCTL register *******************/ +#define OTG_HS_GOTGCTL_SRQSCS_Pos (0U) +#define OTG_HS_GOTGCTL_SRQSCS_Msk (0x1UL << OTG_HS_GOTGCTL_SRQSCS_Pos) /*!< 0x00000001 */ +#define OTG_HS_GOTGCTL_SRQSCS OTG_HS_GOTGCTL_SRQSCS_Msk /*! */ + +#define CACHE_SR_POWST_Pos (4U) +#define CACHE_SR_POWST_Msk (0x1UL << CACHE_SR_POWST_Pos) /*! 0x00000010 */ +#define POWST CACHE_SR_POWST_Msk /*< SRAM power acknowledges */ + +/**************** Bit definition for I/D CACHE_IRQMASK register ****************/ +#define CACHE_IRQMASK_POWERR_Pos (0U) +#define CACHE_IRQMASK_POWERR_Msk (0x1UL << CACHE_TRQMASK_POWERR_Pos) /*! 0x00000001 */ +#define MASK_POWERR CACHE_IRQMASK_POWERR_Msk /*< Mask interrupt request on power error indication >*/ + +#define CACHE_IRQMASK_MANINVERR_Pos (1U) +#define CACHE_IRQMASK_MANINVERR_Msk (0x2UL << CACHE_IRQMASK_MANINVERR_Pos) /*! 0x00000002 */ +#define MASK_MANINVERR CACHE_IRQMASK_MANINVERR_Msk /*< Mask interrupt request on manual invalidation error indication >*/ + + + +/**************** Bit definition for I/D CACHE_IRQSTAT register ****************/ +#define CACHE_IRQSTAT_POWERR_Pos (0U) +#define CACHE_IRQSTAT_POWERR_Msk (0x1UL << CACHE_IRQSTAT_POWERR_Pos) /*! 0x00000001 */ +#define POWERR CACHE_IRQSTAT_POWERR_Msk /*< SRAM power error status , write 1 to clear */ + +#define CACHE_IRQSTAT_MANINVERR_Pos (1U) +#define CACHE_IRQSTAT_MANINVERR_Msk (0x1UL << CACHE_IRQSTAT_MANINVERR_Pos) /*! 0x00000002 */ +#define MANINVERR CACHE_IRQSTAT_MANINVERR_Msk /*< Manual invalidation error status , write 1 to clear */ + + +/**************** Bit definition for I/D CACHE_TYPE register ****************/ +#define CACHE_TYPE_AW_Pos (0U) +#define CACHE_TYPE_AW_Msk (0x1fUL << CACHE_TYPE_AW_Pos) +#define AW_0 (0x1UL << CACHE_TYPE_AW_Pos) +#define AW_1 (0x2UL << CACHE_TYPE_AW_Pos) +#define AW_2 (0x4UL << CACHE_TYPE_AW_Pos) +#define AW_3 (0x8UL << CACHE_TYPE_AW_Pos) +#define AW_4 (0x10UL << CACHE_TYPE_AW_Pos) + +#define CACHE_TYPE_CW_Pos (5U) +#define CACHE_TYPE_CW_Msk (0x1fUL << CACHE_TYPE_CW_Pos) +#define CW_0 (0x1UL << CACHE_TYPE_CW_Pos) +#define CW_1 (0x2UL << CACHE_TYPE_CW_Pos) +#define CW_2 (0x4UL << CACHE_TYPE_CW_Pos) +#define CW_3 (0x8UL << CACHE_TYPE_CW_Pos) +#define CW_4 (0x10UL << CACHE_TYPE_CW_Pos) + +#define CACHE_TYPE_WAY_Pos (10U) +#define CACHE_TYPE_WAY_Msk (0x1fUL << CACHE_TYPE_WAY_Pos) +#define WAY_0 (0x1UL << CACHE_TYPE_WAY_Pos) +#define WAY_1 (0x2UL << CACHE_TYPE_WAY_Pos) + +#define CACHE_TYPE_RSTALLREG_Pos (12U) +#define CACHE_TYPE_RSTALLREG_Msk (0x1UL << CACHE_TYPE_RSTALLREG_Pos) +#define RSTALLREG CACHE_TYPE_RSTALLREG_Msk + +#define CACHE_TYPE_GENSTATLOGIC_Pos (13U) +#define CACHE_TYPE_GENSTATLOGIC_Msk (0x1UL << CACHE_TYPE_GENSTATLOGIC_Pos) +#define GENSTATLOGIC CACHE_TYPE_GENSTATLOGIC_Msk + + +/******************************************************************************/ +/* */ +/* RNG */ +/* */ +/******************************************************************************/ + +/**************** Bit definition for RNG RNG_CR register ****************/ +#define RNG_EN_Pos (2U) +#define RNG_EN_Msk (0x1UL << RNG_EN_Pos) /*! 0x00000004 */ +#define RNG_EN RNG_EN_Msk /*< RNG enbable */ + +#define RNG_IE_Pos (3U) +#define RNG_IE_Msk (0x1UL << RNG_IE_Pos) /*! 0x00000008 */ +#define RNG_IE RNG_IE_Msk /*< RNG interrupt enable */ + + +/**************** Bit definition for RNG RNG_SR register ****************/ +#define RNG_DRDY_Pos (0U) +#define RNG_DRDY_Msk (0x1UL << RNG_DRDY_Pos) /*! 0x00000001 */ +#define RNG_DRDY RNG_DRDY_Msk /*< RNG DATA READY */ + +#define RNG_CECS_Pos (1U) +#define RNG_CECS_Msk (0x1UL << RNG_CECS_Pos) /*! 0x00000002 */ +#define RNG_CECS RNG_CECS_Msk /*< RNG CLK ERROR CURRENT STATUS*/ + +#define RNG_SECS_Pos (2U) +#define RNG_SECS_Msk (0x1UL << RNG_SECS_Pos) /*! 0x00000004 */ +#define RNG_SECS RNG_SECS_Msk /*< RNG SEED ERROR CURRENT STATUS */ + +#define RNG_CEIS_Pos (5U) +#define RNG_CEIS_Msk (0x1UL << RNG_CEIS_Pos) /*! 0x00000020 */ +#define RNG_CEIS RNG_CEIS_Msk /*< RNG CLK ERROR INTR STATUS */ + +#define RNG_SEIS_Pos (6U) +#define RNG_SEIS_Msk (0x1UL << RNG_SEIS_Pos) /*! 0x00000040 */ +#define RNG_SEIS RNG_SEIS_Msk /*< RNG SEED ERROR INTR STATUS */ + +/******************************************************************************/ +/* */ +/* VREFBUF */ +/* */ +/******************************************************************************/ + + +/**************** Bit definition for VREFBUF_CSR register ****************/ +#define VREFBUF_ENVR_Pos (0U) +#define VREFBUF_ENVR_Msk (0x1UL << VREFBUF_ENVR_Pos) /*! 0x00000001 */ +#define VREFBUF_ENVR VREFBUF_ENVR_Msk /*< Voltage reference buffer mode enable */ + +#define VREFBUF_HIZ_Pos (1U) +#define VREFBUF_HIZ_Msk (0x1UL << VREFBUF_HIZ_Pos) /*! 0x00000002 */ +#define VREFBUF_HIZ VREFBUF_HIZ_Msk /*< High impedance mode */ + +#define VREFBUF_VRS_Pos (2U) +#define VREFBUF_VRS_Msk (0x1UL << VREFBUF_VRS_Pos) /*! 0x00000004*/ +#define VREFBUF_VRS VREFBUF_VRS_Msk /*< Voltage reference scale */ + +#define VREFBUF_VRR_Pos (3U) +#define VREFBUF_VRR_Msk (0x1UL << VREFBUF_VRR_Pos) /*! 0x00000008*/ +#define VREFBUF_VRR VREFBUF_VRR_Msk /*!< Voltage reference buffer ready */ + +/**************** Bit definition for VREFBUF_CCR register ****************/ +#define VREFBUF_TRIM_Pos (0U) +#define VREFBUF_TRIM_Msk (0x3fUL << VREFBUF_TRIM_Pos) /*! 0x0000003f */ +#define VREFBUF_TRIM_0 (0x1UL << VREFBUF_TRIM_Pos) /*! 0x00000001 */ +#define VREFBUF_TRIM_1 (0x2UL << VREFBUF_TRIM_Pos) /*! 0x00000002 */ +#define VREFBUF_TRIM_2 (0x4UL << VREFBUF_TRIM_Pos) /*! 0x00000004 */ +#define VREFBUF_TRIM_3 (0x8UL << VREFBUF_TRIM_Pos) /*! 0x00000008 */ +#define VREFBUF_TRIM_4 (0x10UL << VREFBUF_TRIM_Pos) /*! 0x00000010 */ +#define VREFBUF_TRIM_5 (0x20UL << VREFBUF_TRIM_Pos) /*! 0x00000020 */ + + + + + +/******************************************************************************/ +/* */ +/* ADC */ +/* */ +/******************************************************************************/ + +/**************** Bit definition for ADC_ISR register ****************/ +#define ADC_ISR_Pos (0U) +#define ADC_ISR_Msk (0x7FFUL << ADC_ISR_Pos) +#define ADC_ISR_ADRDY (0x1UL << ADC_ISR_Pos) /*! 0x00000001 */ +#define ADC_ISR_EOSMP (0x2UL << ADC_ISR_Pos) /*! 0x00000002 */ +#define ADC_ISR_EOC (0x4UL << ADC_ISR_Pos) /*! 0x00000004 */ +#define ADC_ISR_EOS (0x8UL << ADC_ISR_Pos) /*! 0x00000008 */ +#define ADC_ISR_OVR (0x10UL << ADC_ISR_Pos) /*! 0x00000010 */ +#define ADC_ISR_JEOC (0x20UL << ADC_ISR_Pos) /*! 0x00000020 */ +#define ADC_ISR_JEOS (0x40UL << ADC_ISR_Pos) /*! 0x00000040 */ +#define ADC_ISR_AWD1 (0x80UL << ADC_ISR_Pos) /*! 0x00000080 */ +#define ADC_ISR_AWD2 (0x100UL << ADC_ISR_Pos) /*! 0x00000100 */ +#define ADC_ISR_AWD3 (0x200UL << ADC_ISR_Pos) /*! 0x00000200 */ +#define ADC_ISR_JQOVF (0x400UL << ADC_ISR_Pos) /*! 0x00000400 */ + +/**************** Bit definition for ADC_IER register ****************/ +#define ADC_IER_Pos (0U) +#define ADC_IER_Msk (0x7FFUL << ADC_IER_Pos) +#define ADC_IER_ADRDYIE (0x1UL << ADC_IER_Pos) /*! 0x00000001 */ +#define ADC_IER_EOSMPIE (0x2UL << ADC_IER_Pos) /*! 0x00000002 */ +#define ADC_IER_EOCIE (0x4UL << ADC_IER_Pos) /*! 0x00000004 */ +#define ADC_IER_EOSIE (0x8UL << ADC_IER_Pos) /*! 0x00000008 */ +#define ADC_IER_OVRIE (0x10UL << ADC_IER_Pos) /*! 0x00000010 */ +#define ADC_IER_JEOCIE (0x20UL << ADC_IER_Pos) /*! 0x00000020 */ +#define ADC_IER_JEOSIE (0x40UL << ADC_IER_Pos) /*! 0x00000040 */ +#define ADC_IER_AWD1IE (0x80UL << ADC_IER_Pos) /*! 0x00000080 */ +#define ADC_IER_AWD2IE (0x100UL << ADC_IER_Pos) /*! 0x00000100 */ +#define ADC_IER_AWD3IE (0x200UL << ADC_IER_Pos) /*! 0x00000200 */ +#define ADC_IER_JQOVIE (0x400UL << ADC_IER_Pos) /*! 0x00000400 */ + +/**************** Bit definition for ADC_CR register ****************/ +#define ADC_CR_Pos (0U) +#define ADC_CR_Msk (0xFFFFFFFFUL << ADC_CR_Pos) +#define ADC_CR_ADEN (0x1UL << ADC_CR_Pos) /*!< 0x00000001 */ +#define ADC_CR_ADDIS (0x2UL << ADC_CR_Pos) /*!< 0x00000002 */ +#define ADC_CR_ADSTART (0x4UL << ADC_CR_Pos) /*!< 0x00000004 */ +#define ADC_CR_JADSTART (0x8UL << ADC_CR_Pos) /*!< 0x00000008 */ +#define ADC_CR_ADSTP (0x10UL << ADC_CR_Pos) /*!< 0x00000010 */ +#define ADC_CR_JADSTP (0x20UL << ADC_CR_Pos) /*!< 0x00000020 */ +#define ADC_CR_SELREFLDO (0x4000000UL << ADC_CR_Pos) /*!< 0x04000000 */ +#define ADC_CR_SELRANGELDO (0x8000000UL << ADC_CR_Pos) /*!< 0x08000000 */ +#define ADC_CR_ADVREGEN (0x10000000UL << ADC_CR_Pos) /*!< 0x10000000 */ +#define ADC_CR_DEEPPWD (0x20000000UL << ADC_CR_Pos) /*!< 0x20000000 */ +#define ADC_CR_ADCALDIF (0x40000000UL << ADC_CR_Pos) /*!< 0x40000000 */ +#define ADC_CR_ADCAL (0x80000000UL << ADC_CR_Pos) /*!< 0x80000000 */ + +/**************** Bit definition for ADC_CFGR1 register ****************/ +#define ADC_CFGR1_Pos (0U) +#define ADC_CFGR1_Msk (0xFFFFFFFDUL << ADC_CFGR1_Pos) +#define ADC_CFGR1_DMAEN (0x1UL << ADC_CFGR1_Pos) /*!< 0x00000001 */ +#define ADC_CFGR1_DMACFG (0x2UL << ADC_CFGR1_Pos) /*!< 0x00000002 */ +#define ADC_CFGR1_RES_0 (0x8UL << ADC_CFGR1_Pos) /*!< 0x00000008 */ +#define ADC_CFGR1_RES_1 (0x10UL << ADC_CFGR1_Pos) /*!< 0x00000010 */ +#define ADC_CFGR1_RES (0x18UL << ADC_CFGR1_Pos) /*!< 0x00000018 */ +#define ADC_CFGR1_EXTSEL_0 (0x20UL << ADC_CFGR1_Pos) /*!< 0x00000020 */ +#define ADC_CFGR1_EXTSEL_1 (0x40UL << ADC_CFGR1_Pos) /*!< 0x00000040 */ +#define ADC_CFGR1_EXTSEL_2 (0x80UL << ADC_CFGR1_Pos) /*!< 0x00000080 */ +#define ADC_CFGR1_EXTSEL_3 (0x100UL << ADC_CFGR1_Pos) /*!< 0x00000100 */ +#define ADC_CFGR1_EXTSEL_4 (0x200UL << ADC_CFGR1_Pos) /*!< 0x00000200 */ +#define ADC_CFGR1_EXTSEL (0x3E0UL << ADC_CFGR1_Pos) /*!< 0x000003E0 */ +#define ADC_CFGR1_EXTEN_0 (0x400UL << ADC_CFGR1_Pos) /*!< 0x00000400 */ +#define ADC_CFGR1_EXTEN_1 (0x800UL << ADC_CFGR1_Pos) /*!< 0x00000800 */ +#define ADC_CFGR1_EXTEN (0xC00UL << ADC_CFGR1_Pos) /*!< 0x00000C00 */ +#define ADC_CFGR1_OVRMOD (0x1000UL << ADC_CFGR1_Pos) /*!< 0x00001000 */ +#define ADC_CFGR1_CONT (0x2000UL << ADC_CFGR1_Pos) /*!< 0x00002000 */ +#define ADC_CFGR1_AUTDLY (0x4000UL << ADC_CFGR1_Pos) /*!< 0x00004000 */ +#define ADC_CFGR1_ALIGN (0x8000UL << ADC_CFGR1_Pos) /*!< 0x00008000 */ +#define ADC_CFGR1_DISCEN (0x10000UL << ADC_CFGR1_Pos) /*!< 0x00010000 */ +#define ADC_CFGR1_DISCNUM_0 (0x20000UL << ADC_CFGR1_Pos) /*!< 0x00020000 */ +#define ADC_CFGR1_DISCNUM_1 (0x40000UL << ADC_CFGR1_Pos) /*!< 0x00040000 */ +#define ADC_CFGR1_DISCNUM_2 (0x80000UL << ADC_CFGR1_Pos) /*!< 0x00080000 */ +#define ADC_CFGR1_DISCNUM (0xE0000UL << ADC_CFGR1_Pos) /*!< 0x000E0000 */ +#define ADC_CFGR1_JDISCEN (0x100000UL << ADC_CFGR1_Pos) /*!< 0x00100000 */ +#define ADC_CFGR1_JQM (0x200000UL << ADC_CFGR1_Pos) /*!< 0x00200000 */ +#define ADC_CFGR1_AWD1SGL (0x400000UL << ADC_CFGR1_Pos) /*!< 0x00400000 */ +#define ADC_CFGR1_AWD1EN (0x800000UL << ADC_CFGR1_Pos) /*!< 0x00800000 */ +#define ADC_CFGR1_JAWD1EN (0x1000000UL << ADC_CFGR1_Pos) /*!< 0x01000000 */ +#define ADC_CFGR1_JAUTO (0x2000000UL << ADC_CFGR1_Pos) /*!< 0x02000000 */ +#define ADC_CFGR1_AWD1CH_0 (0x4000000UL << ADC_CFGR1_Pos) /*!< 0x04000000 */ +#define ADC_CFGR1_AWD1CH_1 (0x8000000UL << ADC_CFGR1_Pos) /*!< 0x08000000 */ +#define ADC_CFGR1_AWD1CH_2 (0x10000000UL << ADC_CFGR1_Pos) /*!< 0x10000000 */ +#define ADC_CFGR1_AWD1CH_3 (0x20000000UL << ADC_CFGR1_Pos) /*!< 0x20000000 */ +#define ADC_CFGR1_AWD1CH_4 (0x40000000UL << ADC_CFGR1_Pos) /*!< 0x40000000 */ +#define ADC_CFGR1_AWD1CH (0x7C000000UL << ADC_CFGR1_Pos) /*!< 0x7C000000 */ +#define ADC_CFGR1_JQDIS (0x80000000UL << ADC_CFGR1_Pos) /*!< 0x80000000 */ + + +/**************** Bit definition for ADC_CFGR2 register ****************/ +#define ADC_CFGR2_Pos (0U) +#define ADC_CFGR2_Msk (0xE003FFFUL << ADC_CFGR2_Pos) +#define ADC_CFGR2_ROVSE (0x1UL << ADC_CFGR2_Pos) /*!< 0x00000001 */ +#define ADC_CFGR2_JOVSE (0x2UL << ADC_CFGR2_Pos) /*!< 0x00000002 */ +#define ADC_CFGR2_OVSR_0 (0x4UL << ADC_CFGR2_Pos) /*!< 0x00000004 */ +#define ADC_CFGR2_OVSR_1 (0x8UL << ADC_CFGR2_Pos) /*!< 0x00000008 */ +#define ADC_CFGR2_OVSR_2 (0x10UL << ADC_CFGR2_Pos) /*!< 0x00000010 */ +#define ADC_CFGR2_OVSR (0x1CUL << ADC_CFGR2_Pos) /*!< 0x0000001C */ +#define ADC_CFGR2_OVSS_0 (0x20UL << ADC_CFGR2_Pos) /*!< 0x00000020 */ +#define ADC_CFGR2_OVSS_1 (0x40UL << ADC_CFGR2_Pos) /*!< 0x00000040 */ +#define ADC_CFGR2_OVSS_2 (0x80UL << ADC_CFGR2_Pos) /*!< 0x00000080 */ +#define ADC_CFGR2_OVSS_3 (0x100UL << ADC_CFGR2_Pos) /*!< 0x00000100 */ +#define ADC_CFGR2_OVSS (0x1E0UL << ADC_CFGR2_Pos) /*!< 0x000001E0 */ +#define ADC_CFGR2_TROVS (0x200UL << ADC_CFGR2_Pos) /*!< 0x00000200 */ +#define ADC_CFGR2_ROVSM (0x400UL << ADC_CFGR2_Pos) /*!< 0x00000400 */ +#define ADC_CFGR2_OP1SEL (0x800UL << ADC_CFGR2_Pos) /*!< 0x00000800 */ +#define ADC_CFGR2_OP2SEL (0x1000UL << ADC_CFGR2_Pos) /*!< 0x00001000 */ +#define ADC_CFGR2_OP3SEL (0x2000UL << ADC_CFGR2_Pos) /*!< 0x00002000 */ +#define ADC_CFGR2_GCOMP (0x10000UL << ADC_CFGR2_Pos) /*!< 0x00010000 */ +#define ADC_CFGR2_SWTRIG (0x2000000UL << ADC_CFGR2_Pos) /*!< 0x02000000 */ +#define ADC_CFGR2_BULB (0x4000000UL << ADC_CFGR2_Pos) /*!< 0x04000000 */ +#define ADC_CFGR2_SMPTRIG (0x8000000UL << ADC_CFGR2_Pos) /*!< 0x08000000 */ + + +/**************** Bit definition for ADC_SMPR1 register ****************/ +#define ADC_SMPR1_Pos (0U) +#define ADC_SMPR1_Msk (0xDFFFFFFFUL << ADC_SMPR1_Pos) +#define ADC_SMPR1_SMP0_0 (0x1UL << ADC_SMPR1_Pos) /*!< 0x00000001 */ +#define ADC_SMPR1_SMP0_1 (0x2UL << ADC_SMPR1_Pos) /*!< 0x00000002 */ +#define ADC_SMPR1_SMP0_2 (0x4UL << ADC_SMPR1_Pos) /*!< 0x00000004 */ +#define ADC_SMPR1_SMP1_0 (0x8UL << ADC_SMPR1_Pos) /*!< 0x00000008 */ +#define ADC_SMPR1_SMP1_1 (0x10UL << ADC_SMPR1_Pos) /*!< 0x00000010 */ +#define ADC_SMPR1_SMP1_2 (0x20UL << ADC_SMPR1_Pos) /*!< 0x00000020 */ +#define ADC_SMPR1_SMP2_0 (0x40UL << ADC_SMPR1_Pos) /*!< 0x00000040 */ +#define ADC_SMPR1_SMP2_1 (0x80UL << ADC_SMPR1_Pos) /*!< 0x00000080 */ +#define ADC_SMPR1_SMP2_2 (0x100UL << ADC_SMPR1_Pos) /*!< 0x00000100 */ +#define ADC_SMPR1_SMP3_0 (0x200UL << ADC_SMPR1_Pos) /*!< 0x00000200 */ +#define ADC_SMPR1_SMP3_1 (0x400UL << ADC_SMPR1_Pos) /*!< 0x00000400 */ +#define ADC_SMPR1_SMP3_2 (0x800UL << ADC_SMPR1_Pos) /*!< 0x00000800 */ +#define ADC_SMPR1_SMP4_0 (0x1000UL << ADC_SMPR1_Pos) /*!< 0x00001000 */ +#define ADC_SMPR1_SMP4_1 (0x2000UL << ADC_SMPR1_Pos) /*!< 0x00002000 */ +#define ADC_SMPR1_SMP4_2 (0x4000UL << ADC_SMPR1_Pos) /*!< 0x00004000 */ +#define ADC_SMPR1_SMP5_0 (0x8000UL << ADC_SMPR1_Pos) /*!< 0x00008000 */ +#define ADC_SMPR1_SMP5_1 (0x10000UL << ADC_SMPR1_Pos) /*!< 0x00010000 */ +#define ADC_SMPR1_SMP5_2 (0x20000UL << ADC_SMPR1_Pos) /*!< 0x00020000 */ +#define ADC_SMPR1_SMP6_0 (0x40000UL << ADC_SMPR1_Pos) /*!< 0x00040000 */ +#define ADC_SMPR1_SMP6_1 (0x80000UL << ADC_SMPR1_Pos) /*!< 0x00080000 */ +#define ADC_SMPR1_SMP6_2 (0x100000UL << ADC_SMPR1_Pos) /*!< 0x00100000 */ +#define ADC_SMPR1_SMP7_0 (0x200000UL << ADC_SMPR1_Pos) /*!< 0x00200000 */ +#define ADC_SMPR1_SMP7_1 (0x400000UL << ADC_SMPR1_Pos) /*!< 0x00400000 */ +#define ADC_SMPR1_SMP7_2 (0x800000UL << ADC_SMPR1_Pos) /*!< 0x00800000 */ +#define ADC_SMPR1_SMP8_0 (0x1000000UL << ADC_SMPR1_Pos) /*!< 0x01000000 */ +#define ADC_SMPR1_SMP8_1 (0x2000000UL << ADC_SMPR1_Pos) /*!< 0x02000000 */ +#define ADC_SMPR1_SMP8_2 (0x4000000UL << ADC_SMPR1_Pos) /*!< 0x04000000 */ +#define ADC_SMPR1_SMP9_0 (0x8000000UL << ADC_SMPR1_Pos) /*!< 0x08000000 */ +#define ADC_SMPR1_SMP9_1 (0x10000000UL << ADC_SMPR1_Pos) /*!< 0x10000000 */ +#define ADC_SMPR1_SMP9_2 (0x20000000UL << ADC_SMPR1_Pos) /*!< 0x20000000 */ +#define ADC_SMPR1_SMPLUS_0 (0x40000000UL << ADC_SMPR1_Pos) /*!< 0x40000000 */ +#define ADC_SMPR1_SMPLUS_1 (0x80000000UL << ADC_SMPR1_Pos) /*!< 0x80000000 */ +#define ADC_SMPR1_SMPLUS (0xC0000000UL << ADC_SMPR1_Pos) /*!< 0xC0000000 */ + + +/**************** Bit definition for ADC_SMPR2 register ****************/ +#define ADC_SMPR2_Pos (0U) +#define ADC_SMPR2_Msk (0x7FFFFFFUL << ADC_SMPR2_Pos) +#define ADC_SMPR2_SMP10_0 (0x1UL << ADC_SMPR2_Pos) /*!< 0x00000001 */ +#define ADC_SMPR2_SMP10_1 (0x2UL << ADC_SMPR2_Pos) /*!< 0x00000002 */ +#define ADC_SMPR2_SMP10_2 (0x4UL << ADC_SMPR2_Pos) /*!< 0x00000004 */ +#define ADC_SMPR2_SMP11_0 (0x8UL << ADC_SMPR2_Pos) /*!< 0x00000008 */ +#define ADC_SMPR2_SMP11_1 (0x10UL << ADC_SMPR2_Pos) /*!< 0x00000010 */ +#define ADC_SMPR2_SMP11_2 (0x20UL << ADC_SMPR2_Pos) /*!< 0x00000020 */ +#define ADC_SMPR2_SMP12_0 (0x40UL << ADC_SMPR2_Pos) /*!< 0x00000040 */ +#define ADC_SMPR2_SMP12_1 (0x80UL << ADC_SMPR2_Pos) /*!< 0x00000080 */ +#define ADC_SMPR2_SMP12_2 (0x100UL << ADC_SMPR2_Pos) /*!< 0x00000100 */ +#define ADC_SMPR2_SMP13_0 (0x200UL << ADC_SMPR2_Pos) /*!< 0x00000200 */ +#define ADC_SMPR2_SMP13_1 (0x400UL << ADC_SMPR2_Pos) /*!< 0x00000400 */ +#define ADC_SMPR2_SMP13_2 (0x800UL << ADC_SMPR2_Pos) /*!< 0x00000800 */ +#define ADC_SMPR2_SMP14_0 (0x1000UL << ADC_SMPR2_Pos) /*!< 0x00001000 */ +#define ADC_SMPR2_SMP14_1 (0x2000UL << ADC_SMPR2_Pos) /*!< 0x00002000 */ +#define ADC_SMPR2_SMP14_2 (0x4000UL << ADC_SMPR2_Pos) /*!< 0x00004000 */ +#define ADC_SMPR2_SMP15_0 (0x8000UL << ADC_SMPR2_Pos) /*!< 0x00008000 */ +#define ADC_SMPR2_SMP15_1 (0x10000UL << ADC_SMPR2_Pos) /*!< 0x00010000 */ +#define ADC_SMPR2_SMP15_2 (0x20000UL << ADC_SMPR2_Pos) /*!< 0x00020000 */ +#define ADC_SMPR2_SMP16_0 (0x40000UL << ADC_SMPR2_Pos) /*!< 0x00040000 */ +#define ADC_SMPR2_SMP16_1 (0x80000UL << ADC_SMPR2_Pos) /*!< 0x00080000 */ +#define ADC_SMPR2_SMP16_2 (0x100000UL << ADC_SMPR2_Pos) /*!< 0x00100000 */ +#define ADC_SMPR2_SMP17_0 (0x200000UL << ADC_SMPR2_Pos) /*!< 0x00200000 */ +#define ADC_SMPR2_SMP17_1 (0x400000UL << ADC_SMPR2_Pos) /*!< 0x00400000 */ +#define ADC_SMPR2_SMP17_2 (0x800000UL << ADC_SMPR2_Pos) /*!< 0x00800000 */ +#define ADC_SMPR2_SMP18_0 (0x1000000UL << ADC_SMPR2_Pos) /*!< 0x01000000 */ +#define ADC_SMPR2_SMP18_1 (0x2000000UL << ADC_SMPR2_Pos) /*!< 0x02000000 */ +#define ADC_SMPR2_SMP18_2 (0x4000000UL << ADC_SMPR2_Pos) /*!< 0x04000000 */ + + +/**************** Bit definition for ADC_SMPR3 register ****************/ +#define ADC_SMPR3_Pos (0U) +#define ADC_SMPR3_Msk (0x7FFFFFFUL << ADC_SMPR2_Pos) +#define ADC_SMPR3_SMP19_0 (0x1UL << ADC_SMPR2_Pos) /*!< 0x00000001 */ +#define ADC_SMPR3_SMP19_1 (0x2UL << ADC_SMPR2_Pos) /*!< 0x00000002 */ +#define ADC_SMPR3_SMP19_2 (0x4UL << ADC_SMPR2_Pos) /*!< 0x00000004 */ +#define ADC_SMPR3_SMP20_0 (0x8UL << ADC_SMPR2_Pos) /*!< 0x00000008 */ +#define ADC_SMPR3_SMP20_1 (0x10UL << ADC_SMPR2_Pos) /*!< 0x00000010 */ +#define ADC_SMPR3_SMP20_2 (0x20UL << ADC_SMPR2_Pos) /*!< 0x00000020 */ +#define ADC_SMPR3_SMP21_0 (0x40UL << ADC_SMPR2_Pos) /*!< 0x00000040 */ +#define ADC_SMPR3_SMP21_1 (0x80UL << ADC_SMPR2_Pos) /*!< 0x00000080 */ +#define ADC_SMPR3_SMP21_2 (0x100UL << ADC_SMPR2_Pos) /*!< 0x00000100 */ + + + + + +/**************** Bit definition for ADC_TR1 register ****************/ +#define ADC_TR1_Pos (0U) +#define ADC_TR1_Msk (0xFFF7FFFUL << ADC_TR1_Pos) +#define ADC_TR1_LT1_0 (0x1UL << ADC_TR1_Pos) /*!< 0x00000001 */ +#define ADC_TR1_LT1_1 (0x2UL << ADC_TR1_Pos) /*!< 0x00000002 */ +#define ADC_TR1_LT1_2 (0x4UL << ADC_TR1_Pos) /*!< 0x00000004 */ +#define ADC_TR1_LT1_3 (0x8UL << ADC_TR1_Pos) /*!< 0x00000008 */ +#define ADC_TR1_LT1_4 (0x10UL << ADC_TR1_Pos) /*!< 0x00000010 */ +#define ADC_TR1_LT1_5 (0x20UL << ADC_TR1_Pos) /*!< 0x00000020 */ +#define ADC_TR1_LT1_6 (0x40UL << ADC_TR1_Pos) /*!< 0x00000040 */ +#define ADC_TR1_LT1_7 (0x80UL << ADC_TR1_Pos) /*!< 0x00000080 */ +#define ADC_TR1_LT1_8 (0x100UL << ADC_TR1_Pos) /*!< 0x00000100 */ +#define ADC_TR1_LT1_9 (0x200UL << ADC_TR1_Pos) /*!< 0x00000200 */ +#define ADC_TR1_LT1_10 (0x400UL << ADC_TR1_Pos) /*!< 0x00000400 */ +#define ADC_TR1_LT1_11 (0x800UL << ADC_TR1_Pos) /*!< 0x00000800 */ +#define ADC_TR1_LT1 (0xFFFUL << ADC_TR1_Pos) /*!< 0x00000FFF */ +#define ADC_TR1_AWDFILT_0 (0x1000UL << ADC_TR1_Pos) /*!< 0x00001000 */ +#define ADC_TR1_AWDFILT_1 (0x2000UL << ADC_TR1_Pos) /*!< 0x00002000 */ +#define ADC_TR1_AWDFILT_2 (0x4000UL << ADC_TR1_Pos) /*!< 0x00004000 */ +#define ADC_TR1_AWDFILT (0x7000UL << ADC_TR1_Pos) /*!< 0x00007000 */ +#define ADC_TR1_HT1_0 (0x10000UL << ADC_TR1_Pos) /*!< 0x00010000 */ +#define ADC_TR1_HT1_1 (0x20000UL << ADC_TR1_Pos) /*!< 0x00020000 */ +#define ADC_TR1_HT1_2 (0x40000UL << ADC_TR1_Pos) /*!< 0x00040000 */ +#define ADC_TR1_HT1_3 (0x80000UL << ADC_TR1_Pos) /*!< 0x00080000 */ +#define ADC_TR1_HT1_4 (0x100000UL << ADC_TR1_Pos) /*!< 0x00100000 */ +#define ADC_TR1_HT1_5 (0x200000UL << ADC_TR1_Pos) /*!< 0x00200000 */ +#define ADC_TR1_HT1_6 (0x400000UL << ADC_TR1_Pos) /*!< 0x00400000 */ +#define ADC_TR1_HT1_7 (0x800000UL << ADC_TR1_Pos) /*!< 0x00800000 */ +#define ADC_TR1_HT1_8 (0x1000000UL << ADC_TR1_Pos) /*!< 0x01000000 */ +#define ADC_TR1_HT1_9 (0x2000000UL << ADC_TR1_Pos) /*!< 0x02000000 */ +#define ADC_TR1_HT1_10 (0x4000000UL << ADC_TR1_Pos) /*!< 0x04000000 */ +#define ADC_TR1_HT1_11 (0x8000000UL << ADC_TR1_Pos) /*!< 0x08000000 */ +#define ADC_TR1_HT1 (0xFFF0000UL << ADC_TR1_Pos) /*!< 0x0FFF0000 */ + + +/**************** Bit definition for ADC_TR2 register ****************/ +#define ADC_TR2_Pos (0U) +#define ADC_TR2_Msk (0xFF00FFUL << ADC_TR2_Pos) +#define ADC_TR2_LT2_0 (0x1UL << ADC_TR2_Pos) /*!< 0x00000001 */ +#define ADC_TR2_LT2_1 (0x2UL << ADC_TR2_Pos) /*!< 0x00000002 */ +#define ADC_TR2_LT2_2 (0x4UL << ADC_TR2_Pos) /*!< 0x00000004 */ +#define ADC_TR2_LT2_3 (0x8UL << ADC_TR2_Pos) /*!< 0x00000008 */ +#define ADC_TR2_LT2_4 (0x10UL << ADC_TR2_Pos) /*!< 0x00000010 */ +#define ADC_TR2_LT2_5 (0x20UL << ADC_TR2_Pos) /*!< 0x00000020 */ +#define ADC_TR2_LT2_6 (0x40UL << ADC_TR2_Pos) /*!< 0x00000040 */ +#define ADC_TR2_LT2_7 (0x80UL << ADC_TR2_Pos) /*!< 0x00000080 */ +#define ADC_TR2_LT2 (0xFFUL << ADC_TR2_Pos) /*!< 0x000000FF */ +#define ADC_TR2_HT2_0 (0x10000UL << ADC_TR2_Pos) /*!< 0x00010000 */ +#define ADC_TR2_HT2_1 (0x20000UL << ADC_TR2_Pos) /*!< 0x00020000 */ +#define ADC_TR2_HT2_2 (0x40000UL << ADC_TR2_Pos) /*!< 0x00040000 */ +#define ADC_TR2_HT2_3 (0x80000UL << ADC_TR2_Pos) /*!< 0x00080000 */ +#define ADC_TR2_HT2_4 (0x100000UL << ADC_TR2_Pos) /*!< 0x00100000 */ +#define ADC_TR2_HT2_5 (0x200000UL << ADC_TR2_Pos) /*!< 0x00200000 */ +#define ADC_TR2_HT2_6 (0x400000UL << ADC_TR2_Pos) /*!< 0x00400000 */ +#define ADC_TR2_HT2_7 (0x800000UL << ADC_TR2_Pos) /*!< 0x00800000 */ +#define ADC_TR2_HT2 (0xFF0000UL << ADC_TR2_Pos) /*!< 0x00FF0000 */ + + +/**************** Bit definition for ADC_TR3 register ****************/ +#define ADC_TR3_Pos (0U) +#define ADC_TR3_Msk (0xFF00FFUL << ADC_TR3_Pos) +#define ADC_TR3_LT3_0 (0x1UL << ADC_TR3_Pos) /*!< 0x00000001 */ +#define ADC_TR3_LT3_1 (0x2UL << ADC_TR3_Pos) /*!< 0x00000002 */ +#define ADC_TR3_LT3_2 (0x4UL << ADC_TR3_Pos) /*!< 0x00000004 */ +#define ADC_TR3_LT3_3 (0x8UL << ADC_TR3_Pos) /*!< 0x00000008 */ +#define ADC_TR3_LT3_4 (0x10UL << ADC_TR3_Pos) /*!< 0x00000010 */ +#define ADC_TR3_LT3_5 (0x20UL << ADC_TR3_Pos) /*!< 0x00000020 */ +#define ADC_TR3_LT3_6 (0x40UL << ADC_TR3_Pos) /*!< 0x00000040 */ +#define ADC_TR3_LT3_7 (0x80UL << ADC_TR3_Pos) /*!< 0x00000080 */ +#define ADC_TR3_LT3 (0xFFUL << ADC_TR3_Pos) /*!< 0x000000FF */ +#define ADC_TR3_HT3_0 (0x10000UL << ADC_TR3_Pos) /*!< 0x00010000 */ +#define ADC_TR3_HT3_1 (0x20000UL << ADC_TR3_Pos) /*!< 0x00020000 */ +#define ADC_TR3_HT3_2 (0x40000UL << ADC_TR3_Pos) /*!< 0x00040000 */ +#define ADC_TR3_HT3_3 (0x80000UL << ADC_TR3_Pos) /*!< 0x00080000 */ +#define ADC_TR3_HT3_4 (0x100000UL << ADC_TR3_Pos) /*!< 0x00100000 */ +#define ADC_TR3_HT3_5 (0x200000UL << ADC_TR3_Pos) /*!< 0x00200000 */ +#define ADC_TR3_HT3_6 (0x400000UL << ADC_TR3_Pos) /*!< 0x00400000 */ +#define ADC_TR3_HT3_7 (0x800000UL << ADC_TR3_Pos) /*!< 0x00800000 */ +#define ADC_TR3_HT3 (0xFF0000UL << ADC_TR3_Pos) /*!< 0x00FF0000 */ + + +/**************** Bit definition for ADC_SQR1 register ****************/ +#define ADC_SQR1_Pos (0U) +#define ADC_SQR1_Msk (0x1F7DF7CFUL << ADC_SQR1_Pos) +#define ADC_SQR1_L (0xF << ADC_SQR1_Pos) +#define ADC_SQR1_L_0 (0x1UL << ADC_SQR1_Pos) /*!< 0x00000001 */ +#define ADC_SQR1_L_1 (0x2UL << ADC_SQR1_Pos) /*!< 0x00000002 */ +#define ADC_SQR1_L_2 (0x4UL << ADC_SQR1_Pos) /*!< 0x00000004 */ +#define ADC_SQR1_L_3 (0x8UL << ADC_SQR1_Pos) /*!< 0x00000008 */ +#define ADC_SQR1_SQ1_0 (0x40UL << ADC_SQR1_Pos) /*!< 0x00000040 */ +#define ADC_SQR1_SQ1_1 (0x80UL << ADC_SQR1_Pos) /*!< 0x00000080 */ +#define ADC_SQR1_SQ1_2 (0x100UL << ADC_SQR1_Pos) /*!< 0x00000100 */ +#define ADC_SQR1_SQ1_3 (0x200UL << ADC_SQR1_Pos) /*!< 0x00000200 */ +#define ADC_SQR1_SQ1_4 (0x400UL << ADC_SQR1_Pos) /*!< 0x00000400 */ +#define ADC_SQR1_SQ1 (0x7C0UL << ADC_SQR1_Pos) /*!< 0x000007C0 */ +#define ADC_SQR1_SQ2_0 (0x1000UL << ADC_SQR1_Pos) /*!< 0x00001000 */ +#define ADC_SQR1_SQ2_1 (0x2000UL << ADC_SQR1_Pos) /*!< 0x00002000 */ +#define ADC_SQR1_SQ2_2 (0x4000UL << ADC_SQR1_Pos) /*!< 0x00004000 */ +#define ADC_SQR1_SQ2_3 (0x8000UL << ADC_SQR1_Pos) /*!< 0x00008000 */ +#define ADC_SQR1_SQ2_4 (0x10000UL << ADC_SQR1_Pos) /*!< 0x00010000 */ +#define ADC_SQR1_SQ2 (0x1F000UL << ADC_SQR1_Pos) /*!< 0x0001F000 */ +#define ADC_SQR1_SQ3_0 (0x40000UL << ADC_SQR1_Pos) /*!< 0x00040000 */ +#define ADC_SQR1_SQ3_1 (0x80000UL << ADC_SQR1_Pos) /*!< 0x00080000 */ +#define ADC_SQR1_SQ3_2 (0x100000UL << ADC_SQR1_Pos) /*!< 0x00100000 */ +#define ADC_SQR1_SQ3_3 (0x200000UL << ADC_SQR1_Pos) /*!< 0x00200000 */ +#define ADC_SQR1_SQ3_4 (0x400000UL << ADC_SQR1_Pos) /*!< 0x00400000 */ +#define ADC_SQR1_SQ3 (0x7C0000UL << ADC_SQR1_Pos) /*!< 0x007C0000 */ +#define ADC_SQR1_SQ4_0 (0x1000000UL << ADC_SQR1_Pos) /*!< 0x01000000 */ +#define ADC_SQR1_SQ4_1 (0x2000000UL << ADC_SQR1_Pos) /*!< 0x02000000 */ +#define ADC_SQR1_SQ4_2 (0x4000000UL << ADC_SQR1_Pos) /*!< 0x04000000 */ +#define ADC_SQR1_SQ4_3 (0x8000000UL << ADC_SQR1_Pos) /*!< 0x08000000 */ +#define ADC_SQR1_SQ4_4 (0x10000000UL << ADC_SQR1_Pos) /*!< 0x10000000 */ +#define ADC_SQR1_SQ4 (0x1F000000UL << ADC_SQR1_Pos) /*!< 0x1F000000 */ + + +/**************** Bit definition for ADC_SQR2 register ****************/ +#define ADC_SQR2_Pos (0U) +#define ADC_SQR2_Msk (0xFFFFFFFFUL << ADC_SQR2_Pos) +#define ADC_SQR2_SQ5_0 (0x1UL << ADC_SQR2_Pos) /*!< 0x00000001 */ +#define ADC_SQR2_SQ5_1 (0x2UL << ADC_SQR2_Pos) /*!< 0x00000002 */ +#define ADC_SQR2_SQ5_2 (0x4UL << ADC_SQR2_Pos) /*!< 0x00000004 */ +#define ADC_SQR2_SQ5_3 (0x8UL << ADC_SQR2_Pos) /*!< 0x00000008 */ +#define ADC_SQR2_SQ5_4 (0x10UL << ADC_SQR2_Pos) /*!< 0x00000040 */ +#define ADC_SQR2_SQ6_0 (0x40UL << ADC_SQR2_Pos) /*!< 0x00000040 */ +#define ADC_SQR2_SQ6_1 (0x80UL << ADC_SQR2_Pos) /*!< 0x00000080 */ +#define ADC_SQR2_SQ6_2 (0x100UL << ADC_SQR2_Pos) /*!< 0x00000100 */ +#define ADC_SQR2_SQ6_3 (0x200UL << ADC_SQR2_Pos) /*!< 0x00000200 */ +#define ADC_SQR2_SQ6_4 (0x400UL << ADC_SQR2_Pos) /*!< 0x00000400 */ +#define ADC_SQR2_SQ7_0 (0x1000UL << ADC_SQR2_Pos) /*!< 0x00001000 */ +#define ADC_SQR2_SQ7_1 (0x2000UL << ADC_SQR2_Pos) /*!< 0x00002000 */ +#define ADC_SQR2_SQ7_2 (0x4000UL << ADC_SQR2_Pos) /*!< 0x00004000 */ +#define ADC_SQR2_SQ7_3 (0x8000UL << ADC_SQR2_Pos) /*!< 0x00008000 */ +#define ADC_SQR2_SQ7_4 (0x10000UL << ADC_SQR2_Pos) /*!< 0x00010000 */ +#define ADC_SQR2_SQ8_0 (0x40000UL << ADC_SQR2_Pos) /*!< 0x00040000 */ +#define ADC_SQR2_SQ8_1 (0x80000UL << ADC_SQR2_Pos) /*!< 0x00080000 */ +#define ADC_SQR2_SQ8_2 (0x100000UL << ADC_SQR2_Pos) /*!< 0x00100000 */ +#define ADC_SQR2_SQ8_3 (0x200000UL << ADC_SQR2_Pos) /*!< 0x00200000 */ +#define ADC_SQR2_SQ8_4 (0x400000UL << ADC_SQR2_Pos) /*!< 0x00400000 */ +#define ADC_SQR2_SQ9_0 (0x1000000UL << ADC_SQR2_Pos) /*!< 0x01000000 */ +#define ADC_SQR2_SQ9_1 (0x2000000UL << ADC_SQR2_Pos) /*!< 0x02000000 */ +#define ADC_SQR2_SQ9_2 (0x4000000UL << ADC_SQR2_Pos) /*!< 0x04000000 */ +#define ADC_SQR2_SQ9_3 (0x8000000UL << ADC_SQR2_Pos) /*!< 0x08000000 */ +#define ADC_SQR2_SQ9_4 (0x10000000UL << ADC_SQR2_Pos) /*!< 0x10000000 */ + + +/**************** Bit definition for ADC_SQR3 register ****************/ +#define ADC_SQR3_Pos (0U) +#define ADC_SQR3_Msk (0xFFFFFFFFUL << ADC_SQR3_Pos) +#define ADC_SQR3_SQ10_0 (0x1UL << ADC_SQR3_Pos) /*!< 0x00000001 */ +#define ADC_SQR3_SQ10_1 (0x2UL << ADC_SQR3_Pos) /*!< 0x00000002 */ +#define ADC_SQR3_SQ10_2 (0x4UL << ADC_SQR3_Pos) /*!< 0x00000004 */ +#define ADC_SQR3_SQ10_3 (0x8UL << ADC_SQR3_Pos) /*!< 0x00000008 */ +#define ADC_SQR3_SQ10_4 (0x10UL << ADC_SQR3_Pos) /*!< 0x00000040 */ +#define ADC_SQR3_SQ11_0 (0x40UL << ADC_SQR3_Pos) /*!< 0x00000040 */ +#define ADC_SQR3_SQ11_1 (0x80UL << ADC_SQR3_Pos) /*!< 0x00000080 */ +#define ADC_SQR3_SQ11_2 (0x100UL << ADC_SQR3_Pos) /*!< 0x00000100 */ +#define ADC_SQR3_SQ11_3 (0x200UL << ADC_SQR3_Pos) /*!< 0x00000200 */ +#define ADC_SQR3_SQ11_4 (0x400UL << ADC_SQR3_Pos) /*!< 0x00000400 */ +#define ADC_SQR3_SQ12_0 (0x1000UL << ADC_SQR3_Pos) /*!< 0x00001000 */ +#define ADC_SQR3_SQ12_1 (0x2000UL << ADC_SQR3_Pos) /*!< 0x00002000 */ +#define ADC_SQR3_SQ12_2 (0x4000UL << ADC_SQR3_Pos) /*!< 0x00004000 */ +#define ADC_SQR3_SQ12_3 (0x8000UL << ADC_SQR3_Pos) /*!< 0x00008000 */ +#define ADC_SQR3_SQ12_4 (0x10000UL << ADC_SQR3_Pos) /*!< 0x00010000 */ +#define ADC_SQR3_SQ13_0 (0x40000UL << ADC_SQR3_Pos) /*!< 0x00040000 */ +#define ADC_SQR3_SQ13_1 (0x80000UL << ADC_SQR3_Pos) /*!< 0x00080000 */ +#define ADC_SQR3_SQ13_2 (0x100000UL << ADC_SQR3_Pos) /*!< 0x00100000 */ +#define ADC_SQR3_SQ13_3 (0x200000UL << ADC_SQR3_Pos) /*!< 0x00200000 */ +#define ADC_SQR3_SQ13_4 (0x400000UL << ADC_SQR3_Pos) /*!< 0x00400000 */ +#define ADC_SQR3_SQ14_0 (0x1000000UL << ADC_SQR3_Pos) /*!< 0x01000000 */ +#define ADC_SQR3_SQ14_1 (0x2000000UL << ADC_SQR3_Pos) /*!< 0x02000000 */ +#define ADC_SQR3_SQ14_2 (0x4000000UL << ADC_SQR3_Pos) /*!< 0x04000000 */ +#define ADC_SQR3_SQ14_3 (0x8000000UL << ADC_SQR3_Pos) /*!< 0x08000000 */ +#define ADC_SQR3_SQ14_4 (0x10000000UL << ADC_SQR3_Pos) /*!< 0x10000000 */ + + +/**************** Bit definition for ADC_SQR4 register ****************/ +#define ADC_SQR4_Pos (0U) +#define ADC_SQR4_Msk (0xFFFFFFFFUL << ADC_SQR4_Pos) +#define ADC_SQR4_SQ15_0 (0x1UL << ADC_SQR4_Pos) /*!< 0x00000001 */ +#define ADC_SQR4_SQ15_1 (0x2UL << ADC_SQR4_Pos) /*!< 0x00000002 */ +#define ADC_SQR4_SQ15_2 (0x4UL << ADC_SQR4_Pos) /*!< 0x00000004 */ +#define ADC_SQR4_SQ15_3 (0x8UL << ADC_SQR4_Pos) /*!< 0x00000008 */ +#define ADC_SQR4_SQ15_4 (0x10UL << ADC_SQR4_Pos) /*!< 0x00000040 */ +#define ADC_SQR4_SQ16_0 (0x40UL << ADC_SQR4_Pos) /*!< 0x00000040 */ +#define ADC_SQR4_SQ16_1 (0x80UL << ADC_SQR4_Pos) /*!< 0x00000080 */ +#define ADC_SQR4_SQ16_2 (0x100UL << ADC_SQR4_Pos) /*!< 0x00000100 */ +#define ADC_SQR4_SQ16_3 (0x200UL << ADC_SQR4_Pos) /*!< 0x00000200 */ +#define ADC_SQR4_SQ16_4 (0x400UL << ADC_SQR4_Pos) /*!< 0x00000400 */ + + +/**************** Bit definition for ADC_DR register ****************/ +#define ADC_DR_Pos (0U) +#define ADC_DR_Msk (0xFFFFFFFFUL << ADC_DR_Pos) +#define ADC_DR_RDATA_0 (0x1UL << ADC_DR_Pos) /*!< 0x00000001 */ +#define ADC_DR_RDATA_1 (0x2UL << ADC_DR_Pos) /*!< 0x00000002 */ +#define ADC_DR_RDATA_2 (0x4UL << ADC_DR_Pos) /*!< 0x00000004 */ +#define ADC_DR_RDATA_3 (0x8UL << ADC_DR_Pos) /*!< 0x00000008 */ +#define ADC_DR_RDATA_4 (0x10UL << ADC_DR_Pos) /*!< 0x00000010 */ +#define ADC_DR_RDATA_5 (0x20UL << ADC_DR_Pos) /*!< 0x00000020 */ +#define ADC_DR_RDATA_6 (0x40UL << ADC_DR_Pos) /*!< 0x00000040 */ +#define ADC_DR_RDATA_7 (0x80UL << ADC_DR_Pos) /*!< 0x00000080 */ +#define ADC_DR_RDATA_8 (0x100UL << ADC_DR_Pos) /*!< 0x00000100 */ +#define ADC_DR_RDATA_9 (0x200UL << ADC_DR_Pos) /*!< 0x00000200 */ +#define ADC_DR_RDATA_10 (0x400UL << ADC_DR_Pos) /*!< 0x00000400 */ +#define ADC_DR_RDATA_11 (0x800UL << ADC_DR_Pos) /*!< 0x00000800 */ +#define ADC_DR_RDATA_12 (0x1000UL << ADC_DR_Pos) /*!< 0x00001000 */ +#define ADC_DR_RDATA_13 (0x2000UL << ADC_DR_Pos) /*!< 0x00002000 */ +#define ADC_DR_RDATA_14 (0x4000UL << ADC_DR_Pos) /*!< 0x00004000 */ +#define ADC_DR_RDATA_15 (0x8000UL << ADC_DR_Pos) /*!< 0x00008000 */ + + +/**************** Bit definition for ADC_JSQR register ****************/ +#define ADC_JSQR_Pos (0U) +#define ADC_JSQR_Msk (0xFFFFFFFFUL << ADC_JSQR_Pos) +#define ADC_JSQR_JL_0 (0x1UL << ADC_JSQR_Pos) /*!< 0x00000001 */ +#define ADC_JSQR_JL_1 (0x2UL << ADC_JSQR_Pos) /*!< 0x00000002 */ +#define ADC_JSQR_JL (0x3UL << ADC_JSQR_Pos) /*!< 0x00000003 */ +#define ADC_JSQR_JEXTSEL_0 (0x4UL << ADC_JSQR_Pos) /*!< 0x00000004 */ +#define ADC_JSQR_JEXTSEL_1 (0x8UL << ADC_JSQR_Pos) /*!< 0x00000008 */ +#define ADC_JSQR_JEXTSEL_2 (0x10UL << ADC_JSQR_Pos) /*!< 0x00000010 */ +#define ADC_JSQR_JEXTSEL_3 (0x20UL << ADC_JSQR_Pos) /*!< 0x00000020 */ +#define ADC_JSQR_JEXTSEL_4 (0x40UL << ADC_JSQR_Pos) /*!< 0x00000040 */ +#define ADC_JSQR_JEXTSEL (0x7C0UL << ADC_JSQR_Pos) /*!< 0x0000007C */ +#define ADC_JSQR_JEXTEN_0 (0x80UL << ADC_JSQR_Pos) /*!< 0x00000080 */ +#define ADC_JSQR_JEXTEN_1 (0x100UL << ADC_JSQR_Pos) /*!< 0x00000100 */ +#define ADC_JSQR_JEXTEN (0x180UL << ADC_JSQR_Pos) /*!< 0x00000180 */ +#define ADC_JSQR_JSQ1_0 (0x200UL << ADC_JSQR_Pos) /*!< 0x00000200 */ +#define ADC_JSQR_JSQ1_1 (0x400UL << ADC_JSQR_Pos) /*!< 0x00000400 */ +#define ADC_JSQR_JSQ1_2 (0x800UL << ADC_JSQR_Pos) /*!< 0x00000800 */ +#define ADC_JSQR_JSQ1_3 (0x1000UL << ADC_JSQR_Pos) /*!< 0x00001000 */ +#define ADC_JSQR_JSQ1_4 (0x2000UL << ADC_JSQR_Pos) /*!< 0x00002000 */ +#define ADC_JSQR_JSQ2_0 (0x8000UL << ADC_JSQR_Pos) /*!< 0x00008000 */ +#define ADC_JSQR_JSQ2_1 (0x10000UL << ADC_JSQR_Pos) /*!< 0x00010000 */ +#define ADC_JSQR_JSQ2_2 (0x20000UL << ADC_JSQR_Pos) /*!< 0x00020000 */ +#define ADC_JSQR_JSQ2_3 (0x40000UL << ADC_JSQR_Pos) /*!< 0x00040000 */ +#define ADC_JSQR_JSQ2_4 (0x80000UL << ADC_JSQR_Pos) /*!< 0x00080000 */ +#define ADC_JSQR_JSQ3_0 (0x200000UL << ADC_JSQR_Pos) /*!< 0x00200000 */ +#define ADC_JSQR_JSQ3_1 (0x400000UL << ADC_JSQR_Pos) /*!< 0x00400000 */ +#define ADC_JSQR_JSQ3_2 (0x800000UL << ADC_JSQR_Pos) /*!< 0x00800000 */ +#define ADC_JSQR_JSQ3_3 (0x1000000UL << ADC_JSQR_Pos) /*!< 0x01000000 */ +#define ADC_JSQR_JSQ3_4 (0x2000000UL << ADC_JSQR_Pos) /*!< 0x02000000 */ +#define ADC_JSQR_JSQ4_0 (0x8000000UL << ADC_JSQR_Pos) /*!< 0x08000000 */ +#define ADC_JSQR_JSQ4_1 (0x10000000UL << ADC_JSQR_Pos) /*!< 0x10000000 */ +#define ADC_JSQR_JSQ4_2 (0x20000000UL << ADC_JSQR_Pos) /*!< 0x20000000 */ +#define ADC_JSQR_JSQ4_3 (0x40000000UL << ADC_JSQR_Pos) /*!< 0x40000000 */ +#define ADC_JSQR_JSQ4_4 (0x80000000UL << ADC_JSQR_Pos) /*!< 0x80000000 */ + + +/**************** Bit definition for ADC_OFR1 register ****************/ +#define ADC_OFR1_Pos (0U) +#define ADC_OFR1_Msk (0xFFFFFFFFUL << ADC_OFR1_Pos) +#define ADC_OFR1_OFFSET_0 (0x1UL << ADC_OFR1_Pos) /*!< 0x00000001 */ +#define ADC_OFR1_OFFSET_1 (0x2UL << ADC_OFR1_Pos) /*!< 0x00000002 */ +#define ADC_OFR1_OFFSET_2 (0x4UL << ADC_OFR1_Pos) /*!< 0x00000004 */ +#define ADC_OFR1_OFFSET_3 (0x8UL << ADC_OFR1_Pos) /*!< 0x00000008 */ +#define ADC_OFR1_OFFSET_4 (0x10UL << ADC_OFR1_Pos) /*!< 0x00000010 */ +#define ADC_OFR1_OFFSET_5 (0x20UL << ADC_OFR1_Pos) /*!< 0x00000020 */ +#define ADC_OFR1_OFFSET_6 (0x40UL << ADC_OFR1_Pos) /*!< 0x00000040 */ +#define ADC_OFR1_OFFSET_7 (0x80UL << ADC_OFR1_Pos) /*!< 0x00000080 */ +#define ADC_OFR1_OFFSET_8 (0x100UL << ADC_OFR1_Pos) /*!< 0x00000100 */ +#define ADC_OFR1_OFFSET_9 (0x200UL << ADC_OFR1_Pos) /*!< 0x00000200 */ +#define ADC_OFR1_OFFSET_10 (0x400UL << ADC_OFR1_Pos) /*!< 0x00000400 */ +#define ADC_OFR1_OFFSET_11 (0x800UL << ADC_OFR1_Pos) /*!< 0x00000800 */ +#define ADC_OFR1_OFFSET (0xFFFUL << ADC_OFR1_Pos) /*!< 0x00000FFF */ +#define ADC_OFR1_OFFSETPOS (0x1000000UL << ADC_OFR1_Pos) /*!< 0x01000000 */ +#define ADC_OFR1_SATEN (0x2000000UL << ADC_OFR1_Pos) /*!< 0x02000000 */ +#define ADC_OFR1_OFFSET_CH_0 (0x4000000UL << ADC_OFR1_Pos) /*!< 0x04000000 */ +#define ADC_OFR1_OFFSET_CH_1 (0x8000000UL << ADC_OFR1_Pos) /*!< 0x08000000 */ +#define ADC_OFR1_OFFSET_CH_2 (0x10000000UL << ADC_OFR1_Pos) /*!< 0x10000000 */ +#define ADC_OFR1_OFFSET_CH_3 (0x20000000UL << ADC_OFR1_Pos) /*!< 0x20000000 */ +#define ADC_OFR1_OFFSET_CH_4 (0x40000000UL << ADC_OFR1_Pos) /*!< 0x40000000 */ +#define ADC_OFR1_OFFSET_EN (0x80000000UL << ADC_OFR1_Pos) /*!< 0x80000000 */ + + +/**************** Bit definition for ADC_OFR2 register ****************/ +#define ADC_OFR2_Pos (0U) +#define ADC_OFR2_Msk (0xFFFFFFFFUL << ADC_OFR2_Pos) +#define ADC_OFR2_OFFSET_0 (0x1UL << ADC_OFR2_Pos) /*!< 0x00000001 */ +#define ADC_OFR2_OFFSET_1 (0x2UL << ADC_OFR2_Pos) /*!< 0x00000002 */ +#define ADC_OFR2_OFFSET_2 (0x4UL << ADC_OFR2_Pos) /*!< 0x00000004 */ +#define ADC_OFR2_OFFSET_3 (0x8UL << ADC_OFR2_Pos) /*!< 0x00000008 */ +#define ADC_OFR2_OFFSET_4 (0x10UL << ADC_OFR2_Pos) /*!< 0x00000010 */ +#define ADC_OFR2_OFFSET_5 (0x20UL << ADC_OFR2_Pos) /*!< 0x00000020 */ +#define ADC_OFR2_OFFSET_6 (0x40UL << ADC_OFR2_Pos) /*!< 0x00000040 */ +#define ADC_OFR2_OFFSET_7 (0x80UL << ADC_OFR2_Pos) /*!< 0x00000080 */ +#define ADC_OFR2_OFFSET_8 (0x100UL << ADC_OFR2_Pos) /*!< 0x00000100 */ +#define ADC_OFR2_OFFSET_9 (0x200UL << ADC_OFR2_Pos) /*!< 0x00000200 */ +#define ADC_OFR2_OFFSET_10 (0x400UL << ADC_OFR2_Pos) /*!< 0x00000400 */ +#define ADC_OFR2_OFFSET_11 (0x800UL << ADC_OFR2_Pos) /*!< 0x00000800 */ +#define ADC_OFR2_OFFSET (0xFFFUL << ADC_OFR2_Pos) /*!< 0x00000FFF */ +#define ADC_OFR2_OFFSETPOS (0x1000000UL << ADC_OFR2_Pos) /*!< 0x01000000 */ +#define ADC_OFR2_SATEN (0x2000000UL << ADC_OFR2_Pos) /*!< 0x02000000 */ +#define ADC_OFR2_OFFSET_CH_0 (0x4000000UL << ADC_OFR2_Pos) /*!< 0x04000000 */ +#define ADC_OFR2_OFFSET_CH_1 (0x8000000UL << ADC_OFR2_Pos) /*!< 0x08000000 */ +#define ADC_OFR2_OFFSET_CH_2 (0x10000000UL << ADC_OFR2_Pos) /*!< 0x10000000 */ +#define ADC_OFR2_OFFSET_CH_3 (0x20000000UL << ADC_OFR2_Pos) /*!< 0x20000000 */ +#define ADC_OFR2_OFFSET_CH_4 (0x40000000UL << ADC_OFR2_Pos) /*!< 0x40000000 */ +#define ADC_OFR2_OFFSET_EN (0x80000000UL << ADC_OFR2_Pos) /*!< 0x80000000 */ + + + +/**************** Bit definition for ADC_OFR3 register ****************/ +#define ADC_OFR3_Pos (0U) +#define ADC_OFR3_Msk (0xFFFFFFFFUL << ADC_OFR3_Pos) +#define ADC_OFR3_OFFSET_0 (0x1UL << ADC_OFR3_Pos) /*!< 0x00000001 */ +#define ADC_OFR3_OFFSET_1 (0x2UL << ADC_OFR3_Pos) /*!< 0x00000002 */ +#define ADC_OFR3_OFFSET_2 (0x4UL << ADC_OFR3_Pos) /*!< 0x00000004 */ +#define ADC_OFR3_OFFSET_3 (0x8UL << ADC_OFR3_Pos) /*!< 0x00000008 */ +#define ADC_OFR3_OFFSET_4 (0x10UL << ADC_OFR3_Pos) /*!< 0x00000010 */ +#define ADC_OFR3_OFFSET_5 (0x20UL << ADC_OFR3_Pos) /*!< 0x00000020 */ +#define ADC_OFR3_OFFSET_6 (0x40UL << ADC_OFR3_Pos) /*!< 0x00000040 */ +#define ADC_OFR3_OFFSET_7 (0x80UL << ADC_OFR3_Pos) /*!< 0x00000080 */ +#define ADC_OFR3_OFFSET_8 (0x100UL << ADC_OFR3_Pos) /*!< 0x00000100 */ +#define ADC_OFR3_OFFSET_9 (0x200UL << ADC_OFR3_Pos) /*!< 0x00000200 */ +#define ADC_OFR3_OFFSET_10 (0x400UL << ADC_OFR3_Pos) /*!< 0x00000400 */ +#define ADC_OFR3_OFFSET_11 (0x800UL << ADC_OFR3_Pos) /*!< 0x00000800 */ +#define ADC_OFR3_OFFSET (0xFFFUL << ADC_OFR3_Pos) /*!< 0x00000FFF */ +#define ADC_OFR3_OFFSETPOS (0x1000000UL << ADC_OFR3_Pos) /*!< 0x01000000 */ +#define ADC_OFR3_SATEN (0x2000000UL << ADC_OFR3_Pos) /*!< 0x02000000 */ +#define ADC_OFR3_OFFSET_CH_0 (0x4000000UL << ADC_OFR3_Pos) /*!< 0x04000000 */ +#define ADC_OFR3_OFFSET_CH_1 (0x8000000UL << ADC_OFR3_Pos) /*!< 0x08000000 */ +#define ADC_OFR3_OFFSET_CH_2 (0x10000000UL << ADC_OFR3_Pos) /*!< 0x10000000 */ +#define ADC_OFR3_OFFSET_CH_3 (0x20000000UL << ADC_OFR3_Pos) /*!< 0x20000000 */ +#define ADC_OFR3_OFFSET_CH_4 (0x40000000UL << ADC_OFR3_Pos) /*!< 0x40000000 */ +#define ADC_OFR3_OFFSET_EN (0x80000000UL << ADC_OFR3_Pos) /*!< 0x80000000 */ + + +/**************** Bit definition for ADC_OFR4 register ****************/ +#define ADC_OFR4_Pos (0U) +#define ADC_OFR4_Msk (0xFFFFFFFFUL << ADC_OFR4_Pos) +#define ADC_OFR4_OFFSET_0 (0x1UL << ADC_OFR4_Pos) /*!< 0x00000001 */ +#define ADC_OFR4_OFFSET_1 (0x2UL << ADC_OFR4_Pos) /*!< 0x00000002 */ +#define ADC_OFR4_OFFSET_2 (0x4UL << ADC_OFR4_Pos) /*!< 0x00000004 */ +#define ADC_OFR4_OFFSET_3 (0x8UL << ADC_OFR4_Pos) /*!< 0x00000008 */ +#define ADC_OFR4_OFFSET_4 (0x10UL << ADC_OFR4_Pos) /*!< 0x00000010 */ +#define ADC_OFR4_OFFSET_5 (0x20UL << ADC_OFR4_Pos) /*!< 0x00000020 */ +#define ADC_OFR4_OFFSET_6 (0x40UL << ADC_OFR4_Pos) /*!< 0x00000040 */ +#define ADC_OFR4_OFFSET_7 (0x80UL << ADC_OFR4_Pos) /*!< 0x00000080 */ +#define ADC_OFR4_OFFSET_8 (0x100UL << ADC_OFR4_Pos) /*!< 0x00000100 */ +#define ADC_OFR4_OFFSET_9 (0x200UL << ADC_OFR4_Pos) /*!< 0x00000200 */ +#define ADC_OFR4_OFFSET_10 (0x400UL << ADC_OFR4_Pos) /*!< 0x00000400 */ +#define ADC_OFR4_OFFSET_11 (0x800UL << ADC_OFR4_Pos) /*!< 0x00000800 */ +#define ADC_OFR4_OFFSET (0xFFFUL << ADC_OFR4_Pos) /*!< 0x00000FFF */ +#define ADC_OFR4_OFFSETPOS (0x1000000UL << ADC_OFR4_Pos) /*!< 0x01000000 */ +#define ADC_OFR4_SATEN (0x2000000UL << ADC_OFR4_Pos) /*!< 0x02000000 */ +#define ADC_OFR4_OFFSET_CH_0 (0x4000000UL << ADC_OFR4_Pos) /*!< 0x04000000 */ +#define ADC_OFR4_OFFSET_CH_1 (0x8000000UL << ADC_OFR4_Pos) /*!< 0x08000000 */ +#define ADC_OFR4_OFFSET_CH_2 (0x10000000UL << ADC_OFR4_Pos) /*!< 0x10000000 */ +#define ADC_OFR4_OFFSET_CH_3 (0x20000000UL << ADC_OFR4_Pos) /*!< 0x20000000 */ +#define ADC_OFR4_OFFSET_CH_4 (0x40000000UL << ADC_OFR4_Pos) /*!< 0x40000000 */ +#define ADC_OFR4_OFFSET_EN (0x80000000UL << ADC_OFR4_Pos) /*!< 0x80000000 */ + + +/**************** Bit definition for ADC_JDR1 register ****************/ +#define ADC_JDR1_Pos (0U) +#define ADC_JDR1_Msk (0xDFFFFFFFUL << ADC_JDR1_Pos) +#define ADC_JDR1_JDATA_0 (0x1UL << ADC_JDR1_Pos) /*!< 0x00000001 */ +#define ADC_JDR1_JDATA_1 (0x2UL << ADC_JDR1_Pos) /*!< 0x00000002 */ +#define ADC_JDR1_JDATA_2 (0x4UL << ADC_JDR1_Pos) /*!< 0x00000004 */ +#define ADC_JDR1_JDATA_3 (0x8UL << ADC_JDR1_Pos) /*!< 0x00000008 */ +#define ADC_JDR1_JDATA_4 (0x10UL << ADC_JDR1_Pos) /*!< 0x00000010 */ +#define ADC_JDR1_JDATA_5 (0x20UL << ADC_JDR1_Pos) /*!< 0x00000020 */ +#define ADC_JDR1_JDATA_6 (0x40UL << ADC_JDR1_Pos) /*!< 0x00000040 */ +#define ADC_JDR1_JDATA_7 (0x80UL << ADC_JDR1_Pos) /*!< 0x00000080 */ +#define ADC_JDR1_JDATA_8 (0x100UL << ADC_JDR1_Pos) /*!< 0x00000100 */ +#define ADC_JDR1_JDATA_9 (0x200UL << ADC_JDR1_Pos) /*!< 0x00000200 */ +#define ADC_JDR1_JDATA_10 (0x400UL << ADC_JDR1_Pos) /*!< 0x00000400 */ +#define ADC_JDR1_JDATA_11 (0x800UL << ADC_JDR1_Pos) /*!< 0x00000800 */ +#define ADC_JDR1_JDATA_12 (0x1000UL << ADC_JDR1_Pos) /*!< 0x00001000 */ +#define ADC_JDR1_JDATA_13 (0x2000UL << ADC_JDR1_Pos) /*!< 0x00002000 */ +#define ADC_JDR1_JDATA_14 (0x4000UL << ADC_JDR1_Pos) /*!< 0x00004000 */ +#define ADC_JDR1_JDATA_15 (0x8000UL << ADC_JDR1_Pos) /*!< 0x00008000 */ + + +/**************** Bit definition for ADC_JDR2 register ****************/ +#define ADC_JDR2_Pos (0U) +#define ADC_JDR2_Msk (0xDFFFFFFFUL << ADC_JDR2_Pos) +#define ADC_JDR2_JDATA_0 (0x1UL << ADC_JDR2_Pos) /*!< 0x00000001 */ +#define ADC_JDR2_JDATA_1 (0x2UL << ADC_JDR2_Pos) /*!< 0x00000002 */ +#define ADC_JDR2_JDATA_2 (0x4UL << ADC_JDR2_Pos) /*!< 0x00000004 */ +#define ADC_JDR2_JDATA_3 (0x8UL << ADC_JDR2_Pos) /*!< 0x00000008 */ +#define ADC_JDR2_JDATA_4 (0x10UL << ADC_JDR2_Pos) /*!< 0x00000010 */ +#define ADC_JDR2_JDATA_5 (0x20UL << ADC_JDR2_Pos) /*!< 0x00000020 */ +#define ADC_JDR2_JDATA_6 (0x40UL << ADC_JDR2_Pos) /*!< 0x00000040 */ +#define ADC_JDR2_JDATA_7 (0x80UL << ADC_JDR2_Pos) /*!< 0x00000080 */ +#define ADC_JDR2_JDATA_8 (0x100UL << ADC_JDR2_Pos) /*!< 0x00000100 */ +#define ADC_JDR2_JDATA_9 (0x200UL << ADC_JDR2_Pos) /*!< 0x00000200 */ +#define ADC_JDR2_JDATA_10 (0x400UL << ADC_JDR2_Pos) /*!< 0x00000400 */ +#define ADC_JDR2_JDATA_11 (0x800UL << ADC_JDR2_Pos) /*!< 0x00000800 */ +#define ADC_JDR2_JDATA_12 (0x1000UL << ADC_JDR2_Pos) /*!< 0x00001000 */ +#define ADC_JDR2_JDATA_13 (0x2000UL << ADC_JDR2_Pos) /*!< 0x00002000 */ +#define ADC_JDR2_JDATA_14 (0x4000UL << ADC_JDR2_Pos) /*!< 0x00004000 */ +#define ADC_JDR2_JDATA_15 (0x8000UL << ADC_JDR2_Pos) /*!< 0x00008000 */ + + +/**************** Bit definition for ADC_JDR2 register ****************/ +#define ADC_JDR3_Pos (0U) +#define ADC_JDR3_Msk (0xDFFFFFFFUL << ADC_JDR3_Pos) +#define ADC_JDR3_JDATA_0 (0x1UL << ADC_JDR3_Pos) /*!< 0x00000001 */ +#define ADC_JDR3_JDATA_1 (0x2UL << ADC_JDR3_Pos) /*!< 0x00000002 */ +#define ADC_JDR3_JDATA_2 (0x4UL << ADC_JDR3_Pos) /*!< 0x00000004 */ +#define ADC_JDR3_JDATA_3 (0x8UL << ADC_JDR3_Pos) /*!< 0x00000008 */ +#define ADC_JDR3_JDATA_4 (0x10UL << ADC_JDR3_Pos) /*!< 0x00000010 */ +#define ADC_JDR3_JDATA_5 (0x20UL << ADC_JDR3_Pos) /*!< 0x00000020 */ +#define ADC_JDR3_JDATA_6 (0x40UL << ADC_JDR3_Pos) /*!< 0x00000040 */ +#define ADC_JDR3_JDATA_7 (0x80UL << ADC_JDR3_Pos) /*!< 0x00000080 */ +#define ADC_JDR3_JDATA_8 (0x100UL << ADC_JDR3_Pos) /*!< 0x00000100 */ +#define ADC_JDR3_JDATA_9 (0x200UL << ADC_JDR3_Pos) /*!< 0x00000200 */ +#define ADC_JDR3_JDATA_10 (0x400UL << ADC_JDR3_Pos) /*!< 0x00000400 */ +#define ADC_JDR3_JDATA_11 (0x800UL << ADC_JDR3_Pos) /*!< 0x00000800 */ +#define ADC_JDR3_JDATA_12 (0x1000UL << ADC_JDR3_Pos) /*!< 0x00001000 */ +#define ADC_JDR3_JDATA_13 (0x2000UL << ADC_JDR3_Pos) /*!< 0x00002000 */ +#define ADC_JDR3_JDATA_14 (0x4000UL << ADC_JDR3_Pos) /*!< 0x00004000 */ +#define ADC_JDR3_JDATA_15 (0x8000UL << ADC_JDR3_Pos) /*!< 0x00008000 */ + + +/**************** Bit definition for ADC_JDR4 register ****************/ +#define ADC_JDR4_Pos (0U) +#define ADC_JDR4_Msk (0xDFFFFFFFUL << ADC_JDR4_Pos) +#define ADC_JDR4_JDATA_0 (0x1UL << ADC_JDR4_Pos) /*!< 0x00000001 */ +#define ADC_JDR4_JDATA_1 (0x2UL << ADC_JDR4_Pos) /*!< 0x00000002 */ +#define ADC_JDR4_JDATA_2 (0x4UL << ADC_JDR4_Pos) /*!< 0x00000004 */ +#define ADC_JDR4_JDATA_3 (0x8UL << ADC_JDR4_Pos) /*!< 0x00000008 */ +#define ADC_JDR4_JDATA_4 (0x10UL << ADC_JDR4_Pos) /*!< 0x00000010 */ +#define ADC_JDR4_JDATA_5 (0x20UL << ADC_JDR4_Pos) /*!< 0x00000020 */ +#define ADC_JDR4_JDATA_6 (0x40UL << ADC_JDR4_Pos) /*!< 0x00000040 */ +#define ADC_JDR4_JDATA_7 (0x80UL << ADC_JDR4_Pos) /*!< 0x00000080 */ +#define ADC_JDR4_JDATA_8 (0x100UL << ADC_JDR4_Pos) /*!< 0x00000100 */ +#define ADC_JDR4_JDATA_9 (0x200UL << ADC_JDR4_Pos) /*!< 0x00000200 */ +#define ADC_JDR4_JDATA_10 (0x400UL << ADC_JDR4_Pos) /*!< 0x00000400 */ +#define ADC_JDR4_JDATA_11 (0x800UL << ADC_JDR4_Pos) /*!< 0x00000800 */ +#define ADC_JDR4_JDATA_12 (0x1000UL << ADC_JDR4_Pos) /*!< 0x00001000 */ +#define ADC_JDR4_JDATA_13 (0x2000UL << ADC_JDR4_Pos) /*!< 0x00002000 */ +#define ADC_JDR4_JDATA_14 (0x4000UL << ADC_JDR4_Pos) /*!< 0x00004000 */ +#define ADC_JDR4_JDATA_15 (0x8000UL << ADC_JDR4_Pos) /*!< 0x00008000 */ + + +/**************** Bit definition for ADC_AWD2CR register ****************/ +#define ADC_AWD2CR_Pos (0U) +#define ADC_AWD2CR_Msk (0xFFFFFFFFUL << ADC_AWD2CR_Pos) +#define ADC_AWD2CR_AWD2CH_0 (0x1UL << ADC_AWD2CR_Pos) /*!< 0x00000001 */ +#define ADC_AWD2CR_AWD2CH_1 (0x2UL << ADC_AWD2CR_Pos) /*!< 0x00000002 */ +#define ADC_AWD2CR_AWD2CH_2 (0x4UL << ADC_AWD2CR_Pos) /*!< 0x00000004 */ +#define ADC_AWD2CR_AWD2CH_3 (0x8UL << ADC_AWD2CR_Pos) /*!< 0x00000008 */ +#define ADC_AWD2CR_AWD2CH_4 (0x10UL << ADC_AWD2CR_Pos) /*!< 0x00000010 */ +#define ADC_AWD2CR_AWD2CH_5 (0x20UL << ADC_AWD2CR_Pos) /*!< 0x00000020 */ +#define ADC_AWD2CR_AWD2CH_6 (0x40UL << ADC_AWD2CR_Pos) /*!< 0x00000040 */ +#define ADC_AWD2CR_AWD2CH_7 (0x80UL << ADC_AWD2CR_Pos) /*!< 0x00000080 */ +#define ADC_AWD2CR_AWD2CH_8 (0x100UL << ADC_AWD2CR_Pos) /*!< 0x00000100 */ +#define ADC_AWD2CR_AWD2CH_9 (0x200UL << ADC_AWD2CR_Pos) /*!< 0x00000200 */ +#define ADC_AWD2CR_AWD2CH_10 (0x400UL << ADC_AWD2CR_Pos) /*!< 0x00000400 */ +#define ADC_AWD2CR_AWD2CH_11 (0x800UL << ADC_AWD2CR_Pos) /*!< 0x00000800 */ +#define ADC_AWD2CR_AWD2CH_12 (0x1000UL << ADC_AWD2CR_Pos) /*!< 0x00001000 */ +#define ADC_AWD2CR_AWD2CH_13 (0x2000UL << ADC_AWD2CR_Pos) /*!< 0x00002000 */ +#define ADC_AWD2CR_AWD2CH_14 (0x4000UL << ADC_AWD2CR_Pos) /*!< 0x00004000 */ +#define ADC_AWD2CR_AWD2CH_15 (0x8000UL << ADC_AWD2CR_Pos) /*!< 0x00008000 */ +#define ADC_AWD2CR_AWD2CH_16 (0x10000UL << ADC_AWD2CR_Pos) /*!< 0x00010000 */ +#define ADC_AWD2CR_AWD2CH_17 (0x20000UL << ADC_AWD2CR_Pos) /*!< 0x00020000 */ +#define ADC_AWD2CR_AWD2CH_18 (0x40000UL << ADC_AWD2CR_Pos) /*!< 0x00040000 */ + + +/**************** Bit definition for ADC_AWD3CR register ****************/ +#define ADC_AWD3CR_Pos (0U) +#define ADC_AWD3CR_Msk (0xFFFFFFFFUL << ADC_AWD3CR_Pos) +#define ADC_AWD3CR_AWD3CH_0 (0x1UL << ADC_AWD3CR_Pos) /*!< 0x00000001 */ +#define ADC_AWD3CR_AWD3CH_1 (0x2UL << ADC_AWD3CR_Pos) /*!< 0x00000002 */ +#define ADC_AWD3CR_AWD3CH_2 (0x4UL << ADC_AWD3CR_Pos) /*!< 0x00000004 */ +#define ADC_AWD3CR_AWD3CH_3 (0x8UL << ADC_AWD3CR_Pos) /*!< 0x00000008 */ +#define ADC_AWD3CR_AWD3CH_4 (0x10UL << ADC_AWD3CR_Pos) /*!< 0x00000010 */ +#define ADC_AWD3CR_AWD3CH_5 (0x20UL << ADC_AWD3CR_Pos) /*!< 0x00000020 */ +#define ADC_AWD3CR_AWD3CH_6 (0x40UL << ADC_AWD3CR_Pos) /*!< 0x00000040 */ +#define ADC_AWD3CR_AWD3CH_7 (0x80UL << ADC_AWD3CR_Pos) /*!< 0x00000080 */ +#define ADC_AWD3CR_AWD3CH_8 (0x100UL << ADC_AWD3CR_Pos) /*!< 0x00000100 */ +#define ADC_AWD3CR_AWD3CH_9 (0x200UL << ADC_AWD3CR_Pos) /*!< 0x00000200 */ +#define ADC_AWD3CR_AWD3CH_10 (0x400UL << ADC_AWD3CR_Pos) /*!< 0x00000400 */ +#define ADC_AWD3CR_AWD3CH_11 (0x800UL << ADC_AWD3CR_Pos) /*!< 0x00000800 */ +#define ADC_AWD3CR_AWD3CH_12 (0x1000UL << ADC_AWD3CR_Pos) /*!< 0x00001000 */ +#define ADC_AWD3CR_AWD3CH_13 (0x2000UL << ADC_AWD3CR_Pos) /*!< 0x00002000 */ +#define ADC_AWD3CR_AWD3CH_14 (0x4000UL << ADC_AWD3CR_Pos) /*!< 0x00004000 */ +#define ADC_AWD3CR_AWD3CH_15 (0x8000UL << ADC_AWD3CR_Pos) /*!< 0x00008000 */ +#define ADC_AWD3CR_AWD3CH_16 (0x10000UL << ADC_AWD3CR_Pos) /*!< 0x00010000 */ +#define ADC_AWD3CR_AWD3CH_17 (0x20000UL << ADC_AWD3CR_Pos) /*!< 0x00020000 */ +#define ADC_AWD3CR_AWD3CH_18 (0x40000UL << ADC_AWD3CR_Pos) /*!< 0x00040000 */ + + +/**************** Bit definition for ADC_DIFSEL register ****************/ +#define ADC_DIFSEL_Pos (0U) +#define ADC_DIFSEL_Msk (0xFFFFFFFFUL << ADC_DIFSEL_Pos) +#define ADC_DIFSEL_0 (0x1UL << ADC_DIFSEL_Pos) /*!< 0x00000001 */ +#define ADC_DIFSEL_1 (0x2UL << ADC_DIFSEL_Pos) /*!< 0x00000002 */ +#define ADC_DIFSEL_2 (0x4UL << ADC_DIFSEL_Pos) /*!< 0x00000004 */ +#define ADC_DIFSEL_3 (0x8UL << ADC_DIFSEL_Pos) /*!< 0x00000008 */ +#define ADC_DIFSEL_4 (0x10UL << ADC_DIFSEL_Pos) /*!< 0x00000010 */ +#define ADC_DIFSEL_5 (0x20UL << ADC_DIFSEL_Pos) /*!< 0x00000020 */ +#define ADC_DIFSEL_6 (0x40UL << ADC_DIFSEL_Pos) /*!< 0x00000040 */ +#define ADC_DIFSEL_7 (0x80UL << ADC_DIFSEL_Pos) /*!< 0x00000080 */ +#define ADC_DIFSEL_8 (0x100UL << ADC_DIFSEL_Pos) /*!< 0x00000100 */ +#define ADC_DIFSEL_9 (0x200UL << ADC_DIFSEL_Pos) /*!< 0x00000200 */ +#define ADC_DIFSEL_10 (0x400UL << ADC_DIFSEL_Pos) /*!< 0x00000400 */ +#define ADC_DIFSEL_11 (0x800UL << ADC_DIFSEL_Pos) /*!< 0x00000800 */ +#define ADC_DIFSEL_12 (0x1000UL << ADC_DIFSEL_Pos) /*!< 0x00001000 */ +#define ADC_DIFSEL_13 (0x2000UL << ADC_DIFSEL_Pos) /*!< 0x00002000 */ +#define ADC_DIFSEL_14 (0x4000UL << ADC_DIFSEL_Pos) /*!< 0x00004000 */ +#define ADC_DIFSEL_15 (0x8000UL << ADC_DIFSEL_Pos) /*!< 0x00008000 */ +#define ADC_DIFSEL_16 (0x10000UL << ADC_DIFSEL_Pos) /*!< 0x00010000 */ +#define ADC_DIFSEL_17 (0x20000UL << ADC_DIFSEL_Pos) /*!< 0x00020000 */ +#define ADC_DIFSEL_18 (0x40000UL << ADC_DIFSEL_Pos) /*!< 0x00040000 */ + + +/**************** Bit definition for ADC_CALFACT register ****************/ +#define ADC_CALFACT_Pos (0U) +#define ADC_CALFACT_Msk (0xFFFFFFFFUL << ADC_CALFACT_Pos) +#define ADC_CALFACT_S_0 (0x1UL << ADC_CALFACT_Pos) /*!< 0x00000001 */ +#define ADC_CALFACT_S_1 (0x2UL << ADC_CALFACT_Pos) /*!< 0x00000002 */ +#define ADC_CALFACT_S_2 (0x4UL << ADC_CALFACT_Pos) /*!< 0x00000004 */ +#define ADC_CALFACT_S_3 (0x8UL << ADC_CALFACT_Pos) /*!< 0x00000008 */ +#define ADC_CALFACT_S_4 (0x10UL << ADC_CALFACT_Pos) /*!< 0x00000010 */ +#define ADC_CALFACT_S_5 (0x20UL << ADC_CALFACT_Pos) /*!< 0x00000020 */ +#define ADC_CALFACT_S_6 (0x40UL << ADC_CALFACT_Pos) /*!< 0x00000040 */ +#define ADC_CALFACT_S (0x7FUL << ADC_CALFACT_Pos) /*!< 0x0000007F */ +#define ADC_CALFACT_D_0 (0x10000UL << ADC_CALFACT_Pos) /*!< 0x00010000 */ +#define ADC_CALFACT_D_1 (0x20000UL << ADC_CALFACT_Pos) /*!< 0x00020000 */ +#define ADC_CALFACT_D_2 (0x40000UL << ADC_CALFACT_Pos) /*!< 0x00040000 */ +#define ADC_CALFACT_D_3 (0x80000UL << ADC_CALFACT_Pos) /*!< 0x00080000 */ +#define ADC_CALFACT_D_4 (0x100000UL << ADC_CALFACT_Pos) /*!< 0x00100000 */ +#define ADC_CALFACT_D_5 (0x200000UL << ADC_CALFACT_Pos) /*!< 0x00200000 */ +#define ADC_CALFACT_D_6 (0x400000UL << ADC_CALFACT_Pos) /*!< 0x00400000 */ +#define ADC_CALFACT_D (0x7F0000UL << ADC_CALFACT_Pos) /*!< 0x007F0000 */ + + +/**************** Bit definition for ADC_GCOMP register ****************/ +#define ADC_GCOMP_Pos (0U) +#define ADC_GCOMP_Msk (0xFFFFFFFFUL << ADC_GCOMP_Pos) +#define ADC_GCOMP_GCOMPCOEFF_0 (0x1UL << ADC_GCOMP_Pos) /*!< 0x00000001 */ +#define ADC_GCOMP_GCOMPCOEFF_1 (0x2UL << ADC_GCOMP_Pos) /*!< 0x00000002 */ +#define ADC_GCOMP_GCOMPCOEFF_2 (0x4UL << ADC_GCOMP_Pos) /*!< 0x00000004 */ +#define ADC_GCOMP_GCOMPCOEFF_3 (0x8UL << ADC_GCOMP_Pos) /*!< 0x00000008 */ +#define ADC_GCOMP_GCOMPCOEFF_4 (0x10UL << ADC_GCOMP_Pos) /*!< 0x00000010 */ +#define ADC_GCOMP_GCOMPCOEFF_5 (0x20UL << ADC_GCOMP_Pos) /*!< 0x00000020 */ +#define ADC_GCOMP_GCOMPCOEFF_6 (0x40UL << ADC_GCOMP_Pos) /*!< 0x00000040 */ +#define ADC_GCOMP_GCOMPCOEFF_7 (0x80UL << ADC_GCOMP_Pos) /*!< 0x00000080 */ +#define ADC_GCOMP_GCOMPCOEFF_8 (0x100UL << ADC_GCOMP_Pos) /*!< 0x00000100 */ +#define ADC_GCOMP_GCOMPCOEFF_9 (0x200UL << ADC_GCOMP_Pos) /*!< 0x00000200 */ +#define ADC_GCOMP_GCOMPCOEFF_10 (0x400UL << ADC_GCOMP_Pos) /*!< 0x00000400 */ +#define ADC_GCOMP_GCOMPCOEFF_11 (0x800UL << ADC_GCOMP_Pos) /*!< 0x00000800 */ +#define ADC_GCOMP_GCOMPCOEFF_12 (0x1000UL << ADC_GCOMP_Pos) /*!< 0x00001000 */ +#define ADC_GCOMP_GCOMPCOEFF_13 (0x2000UL << ADC_GCOMP_Pos) /*!< 0x00002000 */ +#define ADC_GCOMP_GCOMPCOEFF (0x3FFFUL << ADC_GCOMP_Pos) /*!< 0x00003FFF */ + + +/**************** Bit definition for ADC_Common_CSR1 register ****************/ +#define ADC_CSR1_Pos (0U) +#define ADC_CSR1_Msk (0xDFFFFFFFUL << ADC_CSR1_Pos) +#define ADC_CSR1_ADRDY1 (0x1UL << ADC_CSR1_Pos) /*!< 0x00000001 */ +#define ADC_CSR1_EOSMP1 (0x2UL << ADC_CSR1_Pos) /*!< 0x00000002 */ +#define ADC_CSR1_EOC1 (0x4UL << ADC_CSR1_Pos) /*!< 0x00000004 */ +#define ADC_CSR1_EOS1 (0x8UL << ADC_CSR1_Pos) /*!< 0x00000008 */ +#define ADC_CSR1_OVR1 (0x10UL << ADC_CSR1_Pos) /*!< 0x00000010 */ +#define ADC_CSR1_JEOC1 (0x20UL << ADC_CSR1_Pos) /*!< 0x00000020 */ +#define ADC_CSR1_JEOS1 (0x40UL << ADC_CSR1_Pos) /*!< 0x00000040 */ +#define ADC_CSR1_AWD11 (0x80UL << ADC_CSR1_Pos) /*!< 0x00000080 */ +#define ADC_CSR1_AWD21 (0x100UL << ADC_CSR1_Pos) /*!< 0x00000100 */ +#define ADC_CSR1_AWD31 (0x200UL << ADC_CSR1_Pos) /*!< 0x00000200 */ +#define ADC_CSR1_JQOVF1 (0x400UL << ADC_CSR1_Pos) /*!< 0x00000400 */ +#define ADC_CSR1_ADRDY2 (0x10000UL << ADC_CSR1_Pos) /*!< 0x00010000 */ +#define ADC_CSR1_EOSMP2 (0x20000UL << ADC_CSR1_Pos) /*!< 0x00020000 */ +#define ADC_CSR1_EOC2 (0x40000UL << ADC_CSR1_Pos) /*!< 0x00040000 */ +#define ADC_CSR1_EOS2 (0x80000UL << ADC_CSR1_Pos) /*!< 0x00080000 */ +#define ADC_CSR1_OVR2 (0x100000UL << ADC_CSR1_Pos) /*!< 0x00100000 */ +#define ADC_CSR1_JEOC2 (0x200000UL << ADC_CSR1_Pos) /*!< 0x00200000 */ +#define ADC_CSR1_JEOS2 (0x400000UL << ADC_CSR1_Pos) /*!< 0x00400000 */ +#define ADC_CSR1_AWD12 (0x800000UL << ADC_CSR1_Pos) /*!< 0x00800000 */ +#define ADC_CSR1_AWD22 (0x1000000UL << ADC_CSR1_Pos) /*!< 0x01000000 */ +#define ADC_CSR1_AWD32 (0x2000000UL << ADC_CSR1_Pos) /*!< 0x02000000 */ +#define ADC_CSR1_JQOVF2 (0x4000000UL << ADC_CSR1_Pos) /*!< 0x04000000 */ + + +/**************** Bit definition for ADC_Common_CSR2 register ****************/ +#define ADC_CSR2_Pos (0U) +#define ADC_CSR2_Msk (0xDFFFFFFFUL << ADC_CSR2_Pos) +#define ADC_CSR2_ADRDY3 (0x1UL << ADC_CSR2_Pos) /*!< 0x00000001 */ +#define ADC_CSR2_EOSMP3 (0x2UL << ADC_CSR2_Pos) /*!< 0x00000002 */ +#define ADC_CSR2_EOC3 (0x4UL << ADC_CSR2_Pos) /*!< 0x00000004 */ +#define ADC_CSR2_EOS3 (0x8UL << ADC_CSR2_Pos) /*!< 0x00000008 */ +#define ADC_CSR2_OVR3 (0x10UL << ADC_CSR2_Pos) /*!< 0x00000010 */ +#define ADC_CSR2_JEOC3 (0x20UL << ADC_CSR2_Pos) /*!< 0x00000020 */ +#define ADC_CSR2_JEOS3 (0x40UL << ADC_CSR2_Pos) /*!< 0x00000040 */ +#define ADC_CSR2_AWD13 (0x80UL << ADC_CSR2_Pos) /*!< 0x00000080 */ +#define ADC_CSR2_AWD23 (0x100UL << ADC_CSR2_Pos) /*!< 0x00000100 */ +#define ADC_CSR2_AWD33 (0x200UL << ADC_CSR2_Pos) /*!< 0x00000200 */ +#define ADC_CSR2_JQOVF3 (0x400UL << ADC_CSR2_Pos) /*!< 0x00000400 */ + + +/**************** Bit definition for ADC_Common_CCR register ****************/ +#define ADC_CCR_Pos (0U) +#define ADC_CCR_Msk (0xDFFFFFFFUL << ADC_CCR_Pos) +#define ADC_CCR_MULTI_0 (0x1UL << ADC_CCR_Pos) /*!< 0x00000001 */ +#define ADC_CCR_MULTI_1 (0x2UL << ADC_CCR_Pos) /*!< 0x00000002 */ +#define ADC_CCR_MULTI_2 (0x4UL << ADC_CCR_Pos) /*!< 0x00000004 */ +#define ADC_CCR_MULTI_3 (0x8UL << ADC_CCR_Pos) /*!< 0x00000008 */ +#define ADC_CCR_MULTI_4 (0x10UL << ADC_CCR_Pos) /*!< 0x00000010 */ +#define ADC_CCR_MULTI (0x1FUL << ADC_CCR_Pos) /*!< 0x0000001F */ +#define ADC_CCR_DELAY_0 (0x100UL << ADC_CCR_Pos) /*!< 0x00000100 */ +#define ADC_CCR_DELAY_1 (0x200UL << ADC_CCR_Pos) /*!< 0x00000200 */ +#define ADC_CCR_DELAY_2 (0x400UL << ADC_CCR_Pos) /*!< 0x00000400 */ +#define ADC_CCR_DELAY_3 (0x800UL << ADC_CCR_Pos) /*!< 0x00000800 */ +#define ADC_CCR_DELAY (0xF00UL << ADC_CCR_Pos) /*!< 0x00000F00 */ +#define ADC_CCR_DMACFG (0x2000UL << ADC_CCR_Pos) /*!< 0x00002000 */ +#define ADC_CCR_MDMA_0 (0x4000UL << ADC_CCR_Pos) /*!< 0x00004000 */ +#define ADC_CCR_MDMA_1 (0x8000UL << ADC_CCR_Pos) /*!< 0x00008000 */ +#define ADC_CCR_MDMA (0xC000UL << ADC_CCR_Pos) /*!< 0x0000C000 */ +#define ADC_CCR_CKMODE_0 (0x10000UL << ADC_CCR_Pos) /*!< 0x00010000 */ +#define ADC_CCR_CKMODE_1 (0x20000UL << ADC_CCR_Pos) /*!< 0x00020000 */ +#define ADC_CCR_CKMODE (0x30000UL << ADC_CCR_Pos) /*!< 0x00030000 */ +#define ADC_CCR_PRESC_0 (0x40000UL << ADC_CCR_Pos) /*!< 0x00040000 */ +#define ADC_CCR_PRESC_1 (0x80000UL << ADC_CCR_Pos) /*!< 0x00080000 */ +#define ADC_CCR_PRESC_2 (0x100000UL << ADC_CCR_Pos) /*!< 0x00100000 */ +#define ADC_CCR_PRESC_3 (0x200000UL << ADC_CCR_Pos) /*!< 0x00200000 */ +#define ADC_CCR_PRESC (0x3C0000UL << ADC_CCR_Pos) /*!< 0x003C0000 */ +#define ADC_CCR_VREFEN (0x400000UL << ADC_CCR_Pos) /*!< 0x00400000 */ +#define ADC_CCR_VSENSESEL (0x800000UL << ADC_CCR_Pos) /*!< 0x00800000 */ +#define ADC_CCR_VBATSEL (0x1000000UL << ADC_CCR_Pos) /*!< 0x01000000 */ +#define ADC_CCR_VBEAUTO (0x2000000UL << ADC_CCR_Pos) /*!< 0x02000000 */ +#define ADC_CCR_AWDSEL (0x4000000UL << ADC_CCR_Pos) /*!< 0x04000000 */ + + +/**************** Bit definition for ADC_Common_CDR register ****************/ +#define ADC_CDR_Pos (0U) +#define ADC_CDR_Msk (0xDFFFFFFFUL << ADC_CDR_Pos) +#define ADC_CDR_DATA1_0 (0x1UL << ADC_CDR_Pos) /*!< 0x00000001 */ +#define ADC_CDR_DATA1_1 (0x2UL << ADC_CDR_Pos) /*!< 0x00000002 */ +#define ADC_CDR_DATA1_2 (0x4UL << ADC_CDR_Pos) /*!< 0x00000004 */ +#define ADC_CDR_DATA1_3 (0x8UL << ADC_CDR_Pos) /*!< 0x00000008 */ +#define ADC_CDR_DATA1_4 (0x10UL << ADC_CDR_Pos) /*!< 0x00000010 */ +#define ADC_CDR_DATA1_5 (0x20UL << ADC_CDR_Pos) /*!< 0x00000020 */ +#define ADC_CDR_DATA1_6 (0x40UL << ADC_CDR_Pos) /*!< 0x00000040 */ +#define ADC_CDR_DATA1_7 (0x80UL << ADC_CDR_Pos) /*!< 0x00000080 */ +#define ADC_CDR_DATA1_8 (0x100UL << ADC_CDR_Pos) /*!< 0x00000100 */ +#define ADC_CDR_DATA1_9 (0x200UL << ADC_CDR_Pos) /*!< 0x00000200 */ +#define ADC_CDR_DATA1_10 (0x400UL << ADC_CDR_Pos) /*!< 0x00000400 */ +#define ADC_CDR_DATA1_11 (0x800UL << ADC_CDR_Pos) /*!< 0x00000800 */ +#define ADC_CDR_DATA1_12 (0x1000UL << ADC_CDR_Pos) /*!< 0x00001000 */ +#define ADC_CDR_DATA1_13 (0x2000UL << ADC_CDR_Pos) /*!< 0x00002000 */ +#define ADC_CDR_DATA1_14 (0x4000UL << ADC_CDR_Pos) /*!< 0x00004000 */ +#define ADC_CDR_DATA1_15 (0x8000UL << ADC_CDR_Pos) /*!< 0x00008000 */ +#define ADC_CDR_DATA2_0 (0x10000UL << ADC_CDR_Pos) /*!< 0x00010000 */ +#define ADC_CDR_DATA2_1 (0x20000UL << ADC_CDR_Pos) /*!< 0x00020000 */ +#define ADC_CDR_DATA2_2 (0x40000UL << ADC_CDR_Pos) /*!< 0x00040000 */ +#define ADC_CDR_DATA2_3 (0x80000UL << ADC_CDR_Pos) /*!< 0x00080000 */ +#define ADC_CDR_DATA2_4 (0x100000UL << ADC_CDR_Pos) /*!< 0x00100000 */ +#define ADC_CDR_DATA2_5 (0x200000UL << ADC_CDR_Pos) /*!< 0x00200000 */ +#define ADC_CDR_DATA2_6 (0x400000UL << ADC_CDR_Pos) /*!< 0x00400000 */ +#define ADC_CDR_DATA2_7 (0x800000UL << ADC_CDR_Pos) /*!< 0x00800000 */ +#define ADC_CDR_DATA2_8 (0x1000000UL << ADC_CDR_Pos) /*!< 0x01000000 */ +#define ADC_CDR_DATA2_9 (0x2000000UL << ADC_CDR_Pos) /*!< 0x02000000 */ +#define ADC_CDR_DATA2_10 (0x4000000UL << ADC_CDR_Pos) /*!< 0x04000000 */ +#define ADC_CDR_DATA2_11 (0x8000000UL << ADC_CDR_Pos) /*!< 0x08000000 */ +#define ADC_CDR_DATA2_12 (0x10000000UL << ADC_CDR_Pos) /*!< 0x10000000 */ +#define ADC_CDR_DATA2_13 (0x20000000UL << ADC_CDR_Pos) /*!< 0x20000000 */ +#define ADC_CDR_DATA2_14 (0x40000000UL << ADC_CDR_Pos) /*!< 0x40000000 */ +#define ADC_CDR_DATA2_15 (0x80000000UL << ADC_CDR_Pos) /*!< 0x80000000 */ + + + +/******************************************************************************/ +/* */ +/* I2S */ +/* */ +/******************************************************************************/ + +/****************** Bit definition for I2S_CTRL register ***************************/ +#define I2S_CTRL_I2SEN0_Pos 0 +#define I2S_CTRL_I2SEN0_Msk (0x1UL << I2S_CTRL_I2SEN0_Pos) /*!< 0x00000001 */ +#define I2S_CTRL_I2SEN0 I2S_CTRL_I2SEN0_Msk /*!< Enable bit for I2S channel 0 */ + +#define I2S_CTRL_I2SEN1_Pos 1 +#define I2S_CTRL_I2SEN1_Msk (0x1UL << I2S_CTRL_I2SEN1_Pos) /*!< 0x00000002 */ +#define I2S_CTRL_I2SEN1 I2S_CTRL_I2SEN1_Msk /*!< Enable bit for I2S channel 1 */ + +#define I2S_CTRL_TRCFG0_Pos 8 +#define I2S_CTRL_TRCFG0_Msk (0x1UL << I2S_CTRL_TRCFG0_Pos) /*!< 0x00000100 */ +#define I2S_CTRL_TRCFG0 I2S_CTRL_TRCFG0_Msk /*!< Transmitter or recevier for I2S channel 0 */ + +#define I2S_CTRL_TRCFG1_Pos 9 +#define I2S_CTRL_TRCFG1_Msk (0x1UL << I2S_CTRL_TRCFG1_Pos) /*!< 0x00000100 */ +#define I2S_CTRL_TRCFG1 I2S_CTRL_TRCFG1_Msk /*!< Transmitter or recevier for I2S channel 1 */ + +#define I2S_CTRL_LOOPBACK01_Pos 16 +#define I2S_CTRL_LOOPBACK01_Msk (0x1UL << I2S_CTRL_LOOPBACK01_Pos) /*!< 0x00010000 */ +#define I2S_CTRL_LOOPBACK01 I2S_CTRL_LOOPBACK01_Msk /*!< Loop-back test configuration for I2S channel 0/1*/ + +#define I2S_CTRL_SFRRST_Pos 20 +#define I2S_CTRL_SFRRST_Msk (0x1UL << I2S_CTRL_SFRRST_Pos) /*!< 0x00100000 */ +#define I2S_CTRL_SFRRST I2S_CTRL_SFRRST_Msk /*!< SFR block synchronour reset */ + +#define I2S_CTRL_TMS_Pos 21 +#define I2S_CTRL_TMS_Msk (0x1UL << I2S_CTRL_TMS_Pos) /*!< 0x00200000 */ +#define I2S_CTRL_TMS I2S_CTRL_TMS_Msk /*!< Master or slave configuration for transmitter */ + +#define I2S_CTRL_RMS_Pos 22 +#define I2S_CTRL_RMS_Msk (0x1UL << I2S_CTRL_RMS_Pos) /*!< 0x00400000 */ +#define I2S_CTRL_RMS I2S_CTRL_RMS_Msk /*!< Master or slave configuration for receiver */ + +#define I2S_CTRL_TFIFORST_Pos 23 +#define I2S_CTRL_TFIFORST_Msk (0x1UL << I2S_CTRL_TFIFORST_Pos) /*!< 0x00800000 */ +#define I2S_CTRL_TFIFORST I2S_CTRL_TFIFORST_Msk /*!< Transmait fifo reset */ + +#define I2S_CTRL_RFIFORST_Pos 24 +#define I2S_CTRL_RFIFORST_Msk (0x1UL << I2S_CTRL_RFIFORST_Pos) /*!< 0x01000000 */ +#define I2S_CTRL_RFIFORST I2S_CTRL_RFIFORST_Msk /*!< Receive fifo reset */ + +#define I2S_CTRL_TSYNCRST_Pos 25 +#define I2S_CTRL_TSYNCRST_Msk (0x1UL << I2S_CTRL_TSYNCRST_Pos) /*!< 0x02000000 */ +#define I2S_CTRL_TSYNCRST I2S_CTRL_TSYNCRST_Msk /*!< Reset for transmitter synchronizing unit */ + +#define I2S_CTRL_RSYNCRST_Pos 26 +#define I2S_CTRL_RSYNCRST_Msk (0x1UL << I2S_CTRL_RSYNCRST_Pos) /*!< 0x04000000 */ +#define I2S_CTRL_RSYNCRST I2S_CTRL_RSYNCRST_Msk /*!< Reset for receiver synchronizing unit */ + +#define I2S_CTRL_TSYNCLOOPBACK_Pos 27 +#define I2S_CTRL_TSYNCLOOPBACK_Msk (0x1UL << I2S_CTRL_TSYNCLOOPBACK_Pos) /*!< 0x08000000 */ +#define I2S_CTRL_TSYNCLOOPBACK I2S_CTRL_TSYNCLOOPBACK_Msk /*!< Loop-back configuration for transmitter synchronization unit */ + +#define I2S_CTRL_RSYNCLOOPBACK_Pos 28 +#define I2S_CTRL_RSYNCLOOPBACK_Msk (0x1UL << I2S_CTRL_RSYNCLOOPBACK_Pos) /*!< 0x10000000 */ +#define I2S_CTRL_RSYNCLOOPBACK I2S_CTRL_RSYNCLOOPBACK_Msk /*!< Loop-back configuration for receiver synchronization unit */ + +/****************** Bit definition for INTR_STAT register **************************/ +#define I2S_INTR_STAT_TDATAUNDERR_Pos 0 +#define I2S_INTR_STAT_TDATAUNDERR_Msk (0x1UL << I2S_INTR_STAT_TDATAUNDERR_Pos) /*!< 0x00000001 */ +#define I2S_INTR_STAT_TDATAUNDERR I2S_INTR_STAT_TDATAUNDERR_Msk /*!< Transmitter data underrun event */ + +#define I2S_INTR_STAT_UNDERRCODE_Pos 1 +#define I2S_INTR_STAT_UNDERRCODE_Msk (0x1UL << I2S_INTR_STAT_UNDERRCODE_Pos) /*!< 0x00000002 */ +#define I2S_INTR_STAT_UNDERRCODE I2S_INTR_STAT_UNDERRCODE_Msk /*!< Code of the transmitter that caused underrun event */ + +#define I2S_INTR_STAT_RDATAOVRERR_Pos 4 +#define I2S_INTR_STAT_RDATAOVRERR_Msk (0x1UL << I2S_INTR_STAT_RDATAOVRERR_Pos) /*!< 0x00000010 */ +#define I2S_INTR_STAT_RDATAOVRERR I2S_INTR_STAT_RDATAOVRERR_Msk /*!< Receiver data overrun error */ + +#define I2S_INTR_STAT_OVRERRCODE_Pos 5 +#define I2S_INTR_STAT_OVRERRCODE_Msk (0x1UL << I2S_INTR_STAT_OVRERRCODE_Pos) /*!< 0x00000020 */ +#define I2S_INTR_STAT_OVRERRCODE I2S_INTR_STAT_OVRERRCODE_Msk /*!< Code of the receiver that caused overrun error */ + +#define I2S_INTR_STAT_TFIFOEMPTY_Pos 8 +#define I2S_INTR_STAT_TFIFOEMPTY_Msk (0x1UL << I2S_INTR_STAT_TFIFOEMPTY_Pos) /*!< 0x00000100 */ +#define I2S_INTR_STAT_TFIFOEMPTY I2S_INTR_STAT_TFIFOEMPTY_Msk /*!< Transmit fifo empty flag */ + +#define I2S_INTR_STAT_TFIFOAEMPTY_Pos 9 +#define I2S_INTR_STAT_TFIFOAEMPTY_Msk (0x1UL << I2S_INTR_STAT_TFIFOAEMPTY_Pos) /*!< 0x00000200 */ +#define I2S_INTR_STAT_TFIFOAEMPTY I2S_INTR_STAT_TFIFOAEMPTY_Msk /*!< Transmit fifo almost empty flag */ + +#define I2S_INTR_STAT_TFIFOFULL_Pos 10 +#define I2S_INTR_STAT_TFIFOFULL_Msk (0x1UL << I2S_INTR_STAT_TFIFOFULL_Pos) /*!< 0x00000400 */ +#define I2S_INTR_STAT_TFIFOFULL I2S_INTR_STAT_TFIFOFULL_Msk /*!< Transmit fifo full flag */ + +#define I2S_INTR_STAT_TFIFOAFULL_Pos 11 +#define I2S_INTR_STAT_TFIFOAFULL_Msk (0x1UL << I2S_INTR_STAT_TFIFOAFULL_Pos) /*!< 0x00000800 */ +#define I2S_INTR_STAT_TFIFOAFULL I2S_INTR_STAT_TFIFOAFULL_Msk /*!< Transmit fifo almost full flag */ + +#define I2S_INTR_STAT_RFIFOEMPTY_Pos 12 +#define I2S_INTR_STAT_RFIFOEMPTY_Msk (0x1UL << I2S_INTR_STAT_RFIFOEMPTY_Pos) /*!< 0x00001000 */ +#define I2S_INTR_STAT_RFIFOEMPTY I2S_INTR_STAT_RFIFOEMPTY_Msk /*!< Receive fifo empty flag */ + +#define I2S_INTR_STAT_RFIFOAEMPTY_Pos 13 +#define I2S_INTR_STAT_RFIFOAEMPTY_Msk (0x1UL << I2S_INTR_STAT_RFIFOAEMPTY_Pos) /*!< 0x00002000 */ +#define I2S_INTR_STAT_RFIFOAEMPTY I2S_INTR_STAT_RFIFOAEMPTY_Msk /*!< Receive fifo almost empty flag */ + +#define I2S_INTR_STAT_RFIFOFULL_Pos 14 +#define I2S_INTR_STAT_RFIFOFULL_Msk (0x1UL << I2S_INTR_STAT_RFIFOFULL_Pos) /*!< 0x00004000 */ +#define I2S_INTR_STAT_RFIFOFULL I2S_INTR_STAT_RFIFOFULL_Msk /*!< Receive fifo full flag */ + +#define I2S_INTR_STAT_RFIFOAFULL_Pos 15 +#define I2S_INTR_STAT_RFIFOAFULL_Msk (0x1UL << I2S_INTR_STAT_RFIFOAFULL_Pos) /*!< 0x00008000 */ +#define I2S_INTR_STAT_RFIFOAFULL I2S_INTR_STAT_RFIFOAFULL_Msk /*!< Receive fifo almost full flag */ + +/****************** Bit definition for SRR register ********************************/ +#define I2S_SRR_TSAMPLERATE_Pos 0 +#define I2S_SRR_TSAMPLERATE_Msk (0x7FFUL << I2S_SRR_TSAMPLERATE_Pos) /*!< 0x000007FF */ +#define I2S_SRR_TSAMPLERATE I2S_SRR_TSAMPLERATE_Msk /*!< Transmitter sample rate */ +#define I2S_SRR_TSAMPLERATE_0 (0x1UL << I2S_SRR_TSAMPLERATE_Pos) /*!< 0x00000001 */ +#define I2S_SRR_TSAMPLERATE_1 (0x2UL << I2S_SRR_TSAMPLERATE_Pos) /*!< 0x00000002 */ +#define I2S_SRR_TSAMPLERATE_2 (0x4UL << I2S_SRR_TSAMPLERATE_Pos) /*!< 0x00000004 */ +#define I2S_SRR_TSAMPLERATE_3 (0x8UL << I2S_SRR_TSAMPLERATE_Pos) /*!< 0x00000008 */ +#define I2S_SRR_TSAMPLERATE_4 (0x10UL << I2S_SRR_TSAMPLERATE_Pos) /*!< 0x00000010 */ +#define I2S_SRR_TSAMPLERATE_5 (0x20UL << I2S_SRR_TSAMPLERATE_Pos) /*!< 0x00000020 */ +#define I2S_SRR_TSAMPLERATE_6 (0x40UL << I2S_SRR_TSAMPLERATE_Pos) /*!< 0x00000040 */ +#define I2S_SRR_TSAMPLERATE_7 (0x80UL << I2S_SRR_TSAMPLERATE_Pos) /*!< 0x00000080 */ +#define I2S_SRR_TSAMPLERATE_8 (0x100UL << I2S_SRR_TSAMPLERATE_Pos) /*!< 0x00000100 */ +#define I2S_SRR_TSAMPLERATE_9 (0x200UL << I2S_SRR_TSAMPLERATE_Pos) /*!< 0x00000200 */ +#define I2S_SRR_TSAMPLERATE_10 (0x400UL << I2S_SRR_TSAMPLERATE_Pos) /*!< 0x00000400 */ + +#define I2S_SRR_TRESOLUTION_Pos 11 +#define I2S_SRR_TRESOLUTION_Msk (0x1FUL << I2S_SRR_TRESOLUTION_Pos) /*!< 0x0000001F */ +#define I2S_SRR_TRESOLUTION I2S_SRR_TRESOLUTION_Msk /*!< Transmitter sample resolution */ +#define I2S_SRR_TRESOLUTION_0 (0x1UL << I2S_SRR_TRESOLUTION_Pos) /*!< 0x00000800 */ +#define I2S_SRR_TRESOLUTION_1 (0x2UL << I2S_SRR_TRESOLUTION_Pos) /*!< 0x00001000 */ +#define I2S_SRR_TRESOLUTION_2 (0x4UL << I2S_SRR_TRESOLUTION_Pos) /*!< 0x00002000 */ +#define I2S_SRR_TRESOLUTION_3 (0x8UL << I2S_SRR_TRESOLUTION_Pos) /*!< 0x00004000 */ +#define I2S_SRR_TRESOLUTION_4 (0x10UL << I2S_SRR_TRESOLUTION_Pos) /*!< 0x00008000 */ + +#define I2S_SRR_RSAMPLERATE_Pos 16 +#define I2S_SRR_RSAMPLERATE_Msk (0x7FFUL << I2S_SRR_RSAMPLERATE_Pos) /*!< 0x07FF0000 */ +#define I2S_SRR_RSAMPLERATE I2S_SRR_RSAMPLERATE_Msk /*!< Transmitter sample rate */ +#define I2S_SRR_RSAMPLERATE_0 (0x1UL << I2S_SRR_RSAMPLERATE_Pos) /*!< 0x00010000 */ +#define I2S_SRR_RSAMPLERATE_1 (0x2UL << I2S_SRR_RSAMPLERATE_Pos) /*!< 0x00020000 */ +#define I2S_SRR_RSAMPLERATE_2 (0x4UL << I2S_SRR_RSAMPLERATE_Pos) /*!< 0x00040000 */ +#define I2S_SRR_RSAMPLERATE_3 (0x8UL << I2S_SRR_RSAMPLERATE_Pos) /*!< 0x00080000 */ +#define I2S_SRR_RSAMPLERATE_4 (0x10UL << I2S_SRR_RSAMPLERATE_Pos) /*!< 0x00100000 */ +#define I2S_SRR_RSAMPLERATE_5 (0x20UL << I2S_SRR_RSAMPLERATE_Pos) /*!< 0x00200000 */ +#define I2S_SRR_RSAMPLERATE_6 (0x40UL << I2S_SRR_RSAMPLERATE_Pos) /*!< 0x00400000 */ +#define I2S_SRR_RSAMPLERATE_7 (0x80UL << I2S_SRR_RSAMPLERATE_Pos) /*!< 0x00800000 */ +#define I2S_SRR_RSAMPLERATE_8 (0x100UL << I2S_SRR_RSAMPLERATE_Pos) /*!< 0x01000000 */ +#define I2S_SRR_RSAMPLERATE_9 (0x200UL << I2S_SRR_RSAMPLERATE_Pos) /*!< 0x02000000 */ +#define I2S_SRR_RSAMPLERATE_10 (0x400UL << I2S_SRR_RSAMPLERATE_Pos) /*!< 0x04000000 */ + +#define I2S_SRR_RRESOLUTION_Pos 27 +#define I2S_SRR_RRESOLUTION_Msk (0x1FUL << I2S_SRR_RRESOLUTION_Pos) /*!< 0x0000001F */ +#define I2S_SRR_RRESOLUTION I2S_SRR_RRESOLUTION_Msk /*!< Transmitter sample resolution */ +#define I2S_SRR_RRESOLUTION_0 (0x1UL << I2S_SRR_RRESOLUTION_Pos) /*!< 0x08000000 */ +#define I2S_SRR_RRESOLUTION_1 (0x2UL << I2S_SRR_RRESOLUTION_Pos) /*!< 0x01000000 */ +#define I2S_SRR_RRESOLUTION_2 (0x4UL << I2S_SRR_RRESOLUTION_Pos) /*!< 0x02000000 */ +#define I2S_SRR_RRESOLUTION_3 (0x8UL << I2S_SRR_RRESOLUTION_Pos) /*!< 0x04000000 */ +#define I2S_SRR_RRESOLUTION_4 (0x10UL << I2S_SRR_RRESOLUTION_Pos) /*!< 0x80000000 */ + +/****************** Bit definition for CID_CTRL register ***************************/ +#define I2S_CID_CTRL_I2SSTROBE0_Pos 0 +#define I2S_CID_CTRL_I2SSTROBE0_Msk (0x1UL << I2S_CID_CTRL_I2SSTROBE0_Pos) /*!< 0x00000001 */ +#define I2S_CID_CTRL_I2SSTROBE0 I2S_CID_CTRL_I2SSTROBE0_Msk /*!< Clock enable, channel 0 */ + +#define I2S_CID_CTRL_I2SSTROBE1_Pos 1 +#define I2S_CID_CTRL_I2SSTROBE1_Msk (0x1UL << I2S_CID_CTRL_I2SSTROBE1_Pos) /*!< 0x00000002 */ +#define I2S_CID_CTRL_I2SSTROBE1 I2S_CID_CTRL_I2SSTROBE1_Msk /*!< Clock enable, channel 1 */ + +#define I2S_CID_CTRL_STROBETS_Pos 8 +#define I2S_CID_CTRL_STROBETS_Msk (0x1UL << I2S_CID_CTRL_STROBETS_Pos) /*!< 0x00000100 */ +#define I2S_CID_CTRL_STROBETS I2S_CID_CTRL_STROBETS_Msk /*!< Clock enable for the unit synchronizing transmitters */ + +#define I2S_CID_CTRL_STROBERS_Pos 9 +#define I2S_CID_CTRL_STROBERS_Msk (0x1UL << I2S_CID_CTRL_STROBERS_Pos) /*!< 0x00000200 */ +#define I2S_CID_CTRL_STROBERS I2S_CID_CTRL_STROBERS_Msk /*!< Clock enable for the unit synchronizing receivers */ + +#define I2S_CID_CTRL_INTREQMASK_Pos 15 +#define I2S_CID_CTRL_INTREQMASK_Msk (0x1UL << I2S_CID_CTRL_INTREQMASK_Pos) /*!< 0x00008000 */ +#define I2S_CID_CTRL_INTREQMASK I2S_CID_CTRL_INTREQMASK_Msk /*!< Bit masking all interrupt requests */ + +#define I2S_CID_CTRL_I2SMASK0_Pos 16 +#define I2S_CID_CTRL_I2SMASK0_Msk (0x1UL << I2S_CID_CTRL_I2SMASK0_Pos) /*!< 0x00010000 */ +#define I2S_CID_CTRL_I2SMASK0 I2S_CID_CTRL_I2SMASK0_Msk /*!< Bit masking interrupt request genaration after underrun/overrun in I2S channle 0 */ + +#define I2S_CID_CTRL_I2SMASK1_Pos 17 +#define I2S_CID_CTRL_I2SMASK1_Msk (0x1UL << I2S_CID_CTRL_I2SMASK1_Pos) /*!< 0x00020000 */ +#define I2S_CID_CTRL_I2SMASK1 I2S_CID_CTRL_I2SMASK1_Msk /*!< Bit masking interrupt request genaration after underrun/overrun in I2S channle 1 */ + +#define I2S_CID_CTRL_TFIFOEMPTYMASK_Pos 24 +#define I2S_CID_CTRL_TFIFOEMPTYMASK_Msk (0x1UL << I2S_CID_CTRL_TFIFOEMPTYMASK_Pos) /*!< 0x01000000 */ +#define I2S_CID_CTRL_TFIFOEMPTYMASK I2S_CID_CTRL_TFIFOEMPTYMASK_Msk /*!< Bit masking interrupt request genaration after transmit fifo empty */ + +#define I2S_CID_CTRL_TFIFOAEMPTYMASK_Pos 25 +#define I2S_CID_CTRL_TFIFOAEMPTYMASK_Msk (0x1L << I2S_CID_CTRL_TFIFOAEMPTYMASK_Pos) /*!< 0x02000000 */ +#define I2S_CID_CTRL_TFIFOAEMPTYMASK I2S_CID_CTRL_TFIFOAEMPTYMASK_Msk /*!< Bit masking interrupt request genaration after transmit fifo almost empty */ + +#define I2S_CID_CTRL_TFIFOFULLMASK_Pos 26 +#define I2S_CID_CTRL_TFIFOFULLMASK_Msk (0x1UL << I2S_CID_CTRL_TFIFOFULLMASK_Pos) /*!< 0x04000000 */ +#define I2S_CID_CTRL_TFIFOFULLMASK I2S_CID_CTRL_TFIFOFULLMASK_Msk /*!< Bit masking interrupt request genaration after transmit fifo full */ + +#define I2S_CID_CTRL_TFIFOAFULLMASK_Pos 27 +#define I2S_CID_CTRL_TFIFOAFULLMASK_Msk (0x1UL << I2S_CID_CTRL_TFIFOAFULLMASK_Pos) /*!< 0x08000000 */ +#define I2S_CID_CTRL_TFIFOAFULLMASK I2S_CID_CTRL_TFIFOAFULLMASK_Msk /*!< Bit masking interrupt request genaration after transmit fifo almost full */ + +#define I2S_CID_CTRL_RFIFOEMPTYMASK_Pos 28 +#define I2S_CID_CTRL_RFIFOEMPTYMASK_Msk (0x1UL << I2S_CID_CTRL_RFIFOEMPTYMASK_Pos) /*!< 0x10000000 */ +#define I2S_CID_CTRL_RFIFOEMPTYMASK I2S_CID_CTRL_RFIFOEMPTYMASK_Msk /*!< Bit masking interrupt request genaration after receive fifo empty */ + +#define I2S_CID_CTRL_RFIFOAEMPTYMASK_Pos 29 +#define I2S_CID_CTRL_RFIFOAEMPTYMASK_Msk (0x1UL << I2S_CID_CTRL_RFIFOAEMPTYMASK_Pos) /*!< 0x20000000 */ +#define I2S_CID_CTRL_RFIFOAEMPTYMASK I2S_CID_CTRL_RFIFOAEMPTYMASK_Msk /*!< Bit masking interrupt request genaration after receive fifo almost empty */ + +#define I2S_CID_CTRL_RFIFOFULLMASK_Pos 30 +#define I2S_CID_CTRL_RFIFOFULLMASK_Msk (0x1UL << I2S_CID_CTRL_RFIFOFULLMASK_Pos) /*!< 0x40000000 */ +#define I2S_CID_CTRL_RFIFOFULLMASK I2S_CID_CTRL_RFIFOFULLMASK_Msk /*!< Bit masking interrupt request genaration after receive fifo full */ + +#define I2S_CID_CTRL_RFIFOAFULLMASK_Pos 31 +#define I2S_CID_CTRL_RFIFOAFULLMASK_Msk (0x1UL << I2S_CID_CTRL_RFIFOAFULLMASK_Pos) /*!< 0x80000000 */ +#define I2S_CID_CTRL_RFIFOAFULLMASK I2S_CID_CTRL_RFIFOAFULLMASK_Msk /*!< Bit masking interrupt request genaration after receive fifo almost full */ + +/****************** Bit definition for TFIFO_STAT register *************************/ +#define I2S_TFIFO_STAT_TLEVEL_Pos 0 +#define I2S_TFIFO_STAT_TLEVEL_Msk (0xFUL << I2S_TFIFO_STAT_TLEVEL_Pos) /*!< 0x0000000F */ +#define I2S_TFIFO_STAT_TLEVEL I2S_TFIFO_STAT_TLEVEL_Msk /*!< Transmit fifo level */ +#define I2S_TFIFO_STAT_TLEVEL_0 (0x1UL << I2S_TFIFO_STAT_TLEVEL_Pos) /*!< 0x00000001 */ +#define I2S_TFIFO_STAT_TLEVEL_1 (0x2UL << I2S_TFIFO_STAT_TLEVEL_Pos) /*!< 0x00000002 */ +#define I2S_TFIFO_STAT_TLEVEL_2 (0x4UL << I2S_TFIFO_STAT_TLEVEL_Pos) /*!< 0x00000004 */ +#define I2S_TFIFO_STAT_TLEVEL_3 (0x8UL << I2S_TFIFO_STAT_TLEVEL_Pos) /*!< 0x00000008 */ + +/****************** Bit definition for RFIFO_STAT register *************************/ +#define I2S_RFIFO_STAT_RLEVEL_Pos 0 +#define I2S_RFIFO_STAT_RLEVEL_Msk (0xFUL << I2S_RFIFO_STAT_RLEVEL_Pos) /*!< 0x0000000F */ +#define I2S_RFIFO_STAT_RLEVEL I2S_RFIFO_STAT_RLEVEL_Msk /*!< Receive fifo level */ +#define I2S_RFIFO_STAT_RLEVEL_0 (0x1UL << I2S_RFIFO_STAT_RLEVEL_Pos) /*!< 0x00000001 */ +#define I2S_RFIFO_STAT_RLEVEL_1 (0x2UL << I2S_RFIFO_STAT_RLEVEL_Pos) /*!< 0x00000002 */ +#define I2S_RFIFO_STAT_RLEVEL_2 (0x4UL << I2S_RFIFO_STAT_RLEVEL_Pos) /*!< 0x00000004 */ +#define I2S_RFIFO_STAT_RLEVEL_3 (0x8UL << I2S_RFIFO_STAT_RLEVEL_Pos) /*!< 0x00000008 */ + +/****************** Bit definition for TFIFO_CTRL register *************************/ +#define I2S_TFIFO_CTRL_TAEMPTYTHRESHOLD_Pos 0 +#define I2S_TFIFO_CTRL_TAEMPTYTHRESHOLD_Msk (0x7UL << I2S_TFIFO_CTRL_TAEMPTYTHRESHOLD_Pos) /*!< 0x00000007 */ +#define I2S_TFIFO_CTRL_TAEMPTYTHRESHOLD I2S_TFIFO_CTRL_TAEMPTYTHRESHOLD_Msk /*!< Transmit fifo almost empty threshold level */ +#define I2S_TFIFO_CTRL_TAEMPTYTHRESHOLD_0 (0x1UL << I2S_TFIFO_CTRL_TAEMPTYTHRESHOLD_Pos) /*!< 0x00000001 */ +#define I2S_TFIFO_CTRL_TAEMPTYTHRESHOLD_1 (0x2UL << I2S_TFIFO_CTRL_TAEMPTYTHRESHOLD_Pos) /*!< 0x00000002 */ +#define I2S_TFIFO_CTRL_TAEMPTYTHRESHOLD_2 (0x4UL << I2S_TFIFO_CTRL_TAEMPTYTHRESHOLD_Pos) /*!< 0x00000004 */ + +#define I2S_TFIFO_CTRL_TAFULLTHRESHOLD_Pos 16 +#define I2S_TFIFO_CTRL_TAFULLTHRESHOLD_Msk (0x7UL << I2S_TFIFO_CTRL_TAFULLTHRESHOLD_Pos) /*!< 0x00070000 */ +#define I2S_TFIFO_CTRL_TAFULLTHRESHOLD I2S_TFIFO_CTRL_TAFULLTHRESHOLD_Msk /*!< Transmit fifo almost full threshold level */ +#define I2S_TFIFO_CTRL_TAFULLTHRESHOLD_0 (0x1UL << I2S_TFIFO_CTRL_TAFULLTHRESHOLD_Pos) /*!< 0x00010000 */ +#define I2S_TFIFO_CTRL_TAFULLTHRESHOLD_1 (0x2UL << I2S_TFIFO_CTRL_TAFULLTHRESHOLD_Pos) /*!< 0x00020000 */ +#define I2S_TFIFO_CTRL_TAFULLTHRESHOLD_2 (0x4UL << I2S_TFIFO_CTRL_TAFULLTHRESHOLD_Pos) /*!< 0x00040000 */ + +/****************** Bit definition for RFIFO_CTRL register *************************/ +#define I2S_RFIFO_CTRL_RAEMPTYTHRESHOLD_Pos 0 +#define I2S_RFIFO_CTRL_RAEMPTYTHRESHOLD_Msk (0x7UL << I2S_RFIFO_CTRL_RAEMPTYTHRESHOLD_Pos) /*!< 0x00000007 */ +#define I2S_RFIFO_CTRL_RAEMPTYTHRESHOLD I2S_RFIFO_CTRL_RAEMPTYTHRESHOLD_Msk /*!< Transmit fifo almost empty threshold level */ +#define I2S_RFIFO_CTRL_RAEMPTYTHRESHOLD_0 (0x1UL << I2S_RFIFO_CTRL_RAEMPTYTHRESHOLD_Pos) /*!< 0x00000001 */ +#define I2S_RFIFO_CTRL_RAEMPTYTHRESHOLD_1 (0x2UL << I2S_RFIFO_CTRL_RAEMPTYTHRESHOLD_Pos) /*!< 0x00000002 */ +#define I2S_RFIFO_CTRL_RAEMPTYTHRESHOLD_2 (0x4UL << I2S_RFIFO_CTRL_RAEMPTYTHRESHOLD_Pos) /*!< 0x00000004 */ + +#define I2S_RFIFO_CTRL_RAFULLTHRESHOLD_Pos 16 +#define I2S_RFIFO_CTRL_RAFULLTHRESHOLD_Msk (0x7UL << I2S_RFIFO_CTRL_RAFULLTHRESHOLD_Pos) /*!< 0x00070000 */ +#define I2S_RFIFO_CTRL_RAFULLTHRESHOLD I2S_RFIFO_CTRL_RAFULLTHRESHOLD_Msk /*!< Transmit fifo almost full threshold level */ +#define I2S_RFIFO_CTRL_RAFULLTHRESHOLD_0 (0x1UL << I2S_RFIFO_CTRL_RAFULLTHRESHOLD_Pos) /*!< 0x00010000 */ +#define I2S_RFIFO_CTRL_RAFULLTHRESHOLD_1 (0x2UL << I2S_RFIFO_CTRL_RAFULLTHRESHOLD_Pos) /*!< 0x00020000 */ +#define I2S_RFIFO_CTRL_RAFULLTHRESHOLD_2 (0x4UL << I2S_RFIFO_CTRL_RAFULLTHRESHOLD_Pos) /*!< 0x00040000 */ + +/****************** Bit definition for DEV_CONF register ***************************/ +#define I2S_DEV_CONF_TRANSCKPOLAR_Pos 0 +#define I2S_DEV_CONF_TRANSCKPOLAR_Msk (0x1UL << I2S_DEV_CONF_TRANSCKPOLAR_Pos) /*!< 0x00000001 */ +#define I2S_DEV_CONF_TRANSCKPOLAR I2S_DEV_CONF_TRANSCKPOLAR_Msk /*!< Continuous serial clock active edge for transmission */ + +#define I2S_DEV_CONF_TRANWSPOLAR_Pos 1 +#define I2S_DEV_CONF_TRANWSPOLAR_Msk (0x1UL << I2S_DEV_CONF_TRANWSPOLAR_Pos) /*!< 0x00000002 */ +#define I2S_DEV_CONF_TRANWSPOLAR I2S_DEV_CONF_TRANWSPOLAR_Msk /*!< Word select signal polarity selection for transmission */ + +#define I2S_DEV_CONF_TRANAPBALIGNLR_Pos 2 +#define I2S_DEV_CONF_TRANAPBALIGNLR_Msk (0x1UL << I2S_DEV_CONF_TRANAPBALIGNLR_Pos) /*!< 0x00000004 */ +#define I2S_DEV_CONF_TRANAPBALIGNLR I2S_DEV_CONF_TRANAPBALIGNLR_Msk /*!< Alignment of the transmitted digital data sample at the APB bus */ + +#define I2S_DEV_CONF_TRANI2SALIGNLR_Pos 3 +#define I2S_DEV_CONF_TRANI2SALIGNLR_Msk (0x1UL << I2S_DEV_CONF_TRANI2SALIGNLR_Pos) /*!< 0x00000008 */ +#define I2S_DEV_CONF_TRANI2SALIGNLR I2S_DEV_CONF_TRANI2SALIGNLR_Msk /*!< Alignment of the transmitted digital data sample at the I2S serial data line */ + +#define I2S_DEV_CONF_TRANDATAWSDEL_Pos 4 +#define I2S_DEV_CONF_TRANDATAWSDEL_Msk (0x1UL << I2S_DEV_CONF_TRANDATAWSDEL_Pos) /*!< 0x00000010 */ +#define I2S_DEV_CONF_TRANDATAWSDEL I2S_DEV_CONF_TRANDATAWSDEL_Msk /*!< Transmitted valid data delay at the I2S SD output line afte the WS line edge */ + +#define I2S_DEV_CONF_TRANWSDSPMODE_Pos 5 +#define I2S_DEV_CONF_TRANWSDSPMODE_Msk (0x1UL << I2S_DEV_CONF_TRANWSDSPMODE_Pos) /*!< 0x00000020 */ +#define I2S_DEV_CONF_TRANWSDSPMODE I2S_DEV_CONF_TRANWSDSPMODE_Msk /*!< WS signal format according to DSP audio interface spec for transmitter */ + +#define I2S_DEV_CONF_RECSCKPOLAR_Pos 6 +#define I2S_DEV_CONF_RECSCKPOLAR_Msk (0x1UL << I2S_DEV_CONF_RECSCKPOLAR_Pos) /*!< 0x00000040 */ +#define I2S_DEV_CONF_RECSCKPOLAR I2S_DEV_CONF_RECSCKPOLAR_Msk /*!< Continuous serial clock active edge for reception */ + +#define I2S_DEV_CONF_RECWSPOLAR_Pos 7 +#define I2S_DEV_CONF_RECWSPOLAR_Msk (0x1UL << I2S_DEV_CONF_RECWSPOLAR_Pos) /*!< 0x00000080 */ +#define I2S_DEV_CONF_RECWSPOLAR I2S_DEV_CONF_RECWSPOLAR_Msk /*!< Word select signal polarity selection for reception */ + +#define I2S_DEV_CONF_RECAPBALIGNLR_Pos 8 +#define I2S_DEV_CONF_RECAPBALIGNLR_Msk (0x1UL << I2S_DEV_CONF_RECAPBALIGNLR_Pos) /*!< 0x00000100 */ +#define I2S_DEV_CONF_RECAPBALIGNLR I2S_DEV_CONF_RECAPBALIGNLR_Msk /*!< Alignment of the received digital data sample at the I2S serial data line */ + +#define I2S_DEV_CONF_RECI2SALIGNLR_Pos 9 +#define I2S_DEV_CONF_RECI2SALIGNLR_Msk (0x1UL << I2S_DEV_CONF_RECI2SALIGNLR_Pos) /*!< 0x00000200 */ +#define I2S_DEV_CONF_RECI2SALIGNLR I2S_DEV_CONF_RECI2SALIGNLR_Msk /*!< Alignment of the received digital data sample at the I2S serial data line */ + +#define I2S_DEV_CONF_RECDATAWSDEL_Pos 10 +#define I2S_DEV_CONF_RECDATAWSDEL_Msk (0x1UL << I2S_DEV_CONF_RECDATAWSDEL_Pos) /*!< 0x00000400 */ +#define I2S_DEV_CONF_RECDATAWSDEL I2S_DEV_CONF_RECDATAWSDEL_Msk /*!< Received valid data delay at the I2S SD input line afte the WS line edge */ + +#define I2S_DEV_CONF_RECWSDSPMODE_Pos 11 +#define I2S_DEV_CONF_RECWSDSPMODE_Msk (0x1UL << I2S_DEV_CONF_RECWSDSPMODE_Pos) /*!< 0x00000800 */ +#define I2S_DEV_CONF_RECWSDSPMODE I2S_DEV_CONF_RECWSDSPMODE_Msk /*!< WS signal format according to DSP audio interface spec for receiver */ + +/****************** Bit definition for POLL_STAT register **************************/ +#define I2S_POLL_STAT_TXEMPTY_Pos 0 +#define I2S_POLL_STAT_TXEMPTY_Msk (0x1UL << I2S_POLL_STAT_TXEMPTY_Pos) /*!< 0x00000001 */ +#define I2S_POLL_STAT_TXEMPTY I2S_POLL_STAT_TXEMPTY_Msk /*!< Transmit fifo empty flag*/ + +#define I2S_POLL_STAT_TXAEMPTY_Pos 1 +#define I2S_POLL_STAT_TXAEMPTY_Msk (0x1UL << I2S_POLL_STAT_TXAEMPTY_Pos) /*!< 0x00000002 */ +#define I2S_POLL_STAT_TXAEMPTY I2S_POLL_STAT_TXAEMPTY_Msk /*!< Transmit fifo almost flag*/ + +#define I2S_POLL_STAT_TXUNDERRUN_Pos 2 +#define I2S_POLL_STAT_TXUNDERRUN_Msk (0x1UL << I2S_POLL_STAT_TXUNDERRUN_Pos) /*!< 0x00000004 */ +#define I2S_POLL_STAT_TXUNDERRUN I2S_POLL_STAT_TXUNDERRUN_Msk /*!< Transmitter data underrun */ + +#define I2S_POLL_STAT_RXFULL_Pos 4 +#define I2S_POLL_STAT_RXFULL_Msk (0x1UL << I2S_POLL_STAT_RXFULL_Pos) /*!< 0x00000010 */ +#define I2S_POLL_STAT_RXFULL I2S_POLL_STAT_RXFULL_Msk /*!< Receive fifo full flag */ + +#define I2S_POLL_STAT_RXAFULL_Pos 5 +#define I2S_POLL_STAT_RXAFULL_Msk (0x1UL << I2S_POLL_STAT_RXAFULL_Pos) /*!< 0x00000020 */ +#define I2S_POLL_STAT_RXAFULL I2S_POLL_STAT_RXAFULL_Msk /*!< Receive fifo almost full flag */ + +#define I2S_POLL_STAT_RXOVERRUN_Pos 6 +#define I2S_POLL_STAT_RXOVERRUN_Msk (0x1UL << I2S_POLL_STAT_RXOVERRUN_Pos) /*!< 0x00000040 */ +#define I2S_POLL_STAT_RXOVERRUN I2S_POLL_STAT_RXOVERRUN_Msk /*!< Receiver data overrun */ + +/****************** Bit definition for FIFO register *******************************/ +#define I2S_FIFO_Pos 0 +#define I2S_FIFO_Msk (0xFFFFFFFFUL << I2S_FIFO_Pos) /*!< 0xFFFFFFFF */ +#define I2S_FIFO I2S_FIFO_Msk /*!< I2S data fifo */ +#define I2S_FIFO_0 (0x1UL << I2S_FIFO_Pos) /*!< 0x00000001 */ +#define I2S_FIFO_1 (0x2UL << I2S_FIFO_Pos) /*!< 0x00000002 */ +#define I2S_FIFO_2 (0x4UL << I2S_FIFO_Pos) /*!< 0x00000004 */ +#define I2S_FIFO_3 (0x8UL << I2S_FIFO_Pos) /*!< 0x00000008 */ +#define I2S_FIFO_4 (0x10UL << I2S_FIFO_Pos) /*!< 0x00000010 */ +#define I2S_FIFO_5 (0x20UL << I2S_FIFO_Pos) /*!< 0x00000020 */ +#define I2S_FIFO_6 (0x40UL << I2S_FIFO_Pos) /*!< 0x00000040 */ +#define I2S_FIFO_7 (0x80UL << I2S_FIFO_Pos) /*!< 0x00000080 */ +#define I2S_FIFO_8 (0x100UL << I2S_FIFO_Pos) /*!< 0x00000100 */ +#define I2S_FIFO_9 (0x200UL << I2S_FIFO_Pos) /*!< 0x00000200 */ +#define I2S_FIFO_10 (0x400UL << I2S_FIFO_Pos) /*!< 0x00000400 */ +#define I2S_FIFO_11 (0x800UL << I2S_FIFO_Pos) /*!< 0x00000800 */ +#define I2S_FIFO_12 (0x1000UL << I2S_FIFO_Pos) /*!< 0x00001000 */ +#define I2S_FIFO_13 (0x2000UL << I2S_FIFO_Pos) /*!< 0x00002000 */ +#define I2S_FIFO_14 (0x4000UL << I2S_FIFO_Pos) /*!< 0x00004000 */ +#define I2S_FIFO_15 (0x8000UL << I2S_FIFO_Pos) /*!< 0x00008000 */ +#define I2S_FIFO_16 (0x10000UL << I2S_FIFO_Pos) /*!< 0x00010000 */ +#define I2S_FIFO_17 (0x20000UL << I2S_FIFO_Pos) /*!< 0x00020000 */ +#define I2S_FIFO_18 (0x40000UL << I2S_FIFO_Pos) /*!< 0x00040000 */ +#define I2S_FIFO_19 (0x80000UL << I2S_FIFO_Pos) /*!< 0x00080000 */ +#define I2S_FIFO_20 (0x100000UL << I2S_FIFO_Pos) /*!< 0x00100000 */ +#define I2S_FIFO_21 (0x200000UL << I2S_FIFO_Pos) /*!< 0x00200000 */ +#define I2S_FIFO_22 (0x400000UL << I2S_FIFO_Pos) /*!< 0x00400000 */ +#define I2S_FIFO_23 (0x800000UL << I2S_FIFO_Pos) /*!< 0x00800000 */ +#define I2S_FIFO_24 (0x1000000UL << I2S_FIFO_Pos) /*!< 0x01000000 */ +#define I2S_FIFO_25 (0x2000000UL << I2S_FIFO_Pos) /*!< 0x02000000 */ +#define I2S_FIFO_26 (0x4000000UL << I2S_FIFO_Pos) /*!< 0x04000000 */ +#define I2S_FIFO_27 (0x8000000UL << I2S_FIFO_Pos) /*!< 0x08000000 */ +#define I2S_FIFO_28 (0x10000000UL << I2S_FIFO_Pos) /*!< 0x10000000 */ +#define I2S_FIFO_29 (0x20000000UL << I2S_FIFO_Pos) /*!< 0x10000000 */ +#define I2S_FIFO_30 (0x40000000UL << I2S_FIFO_Pos) /*!< 0x40000000 */ +#define I2S_FIFO_31 (0x80000000UL << I2S_FIFO_Pos) /*!< 0x80000000 */ + + + +/****************** USB_OTG_HS Exported Constants *******************************/ +#define USB_OTG_HS_HOST_MAX_CHANNEL_NBR 12U +#define USB_OTG_HS_MAX_IN_ENDPOINTS 6U /* Including EP0 */ +#define USB_OTG_HS_MAX_OUT_ENDPOINTS 6U /* Including EP0 */ +#define USB_OTG_HS_TOTAL_FIFO_SIZE 4096U /* in Bytes */ + +/************************* HCD Instances *************************************/ +#define IS_HCD_HS_ALL_INSTANCE(INSTANCE) ((INSTANCE) == USB_OTG_HS) +/************************* PCD Instances *************************************/ +#define IS_PCD_HS_ALL_INSTANCE(INSTANCE) ((INSTANCE) == USB_OTG_HS) + +/*@}*/ /* end of group __FT32F407XE_H Definitions */ + +#ifdef __cplusplus +} +#endif + +#endif /* __FT32F407XE_H */ diff --git a/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/ft32f4xx.h b/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/ft32f4xx.h new file mode 100644 index 00000000000..1407bd2e78d --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/ft32f4xx.h @@ -0,0 +1,117 @@ +/** + ****************************************************************************** + * @file ft32f4xx.h + * @author FMD AE + * @brief CMSIS FT32F4xx Device Peripheral Access Layer Header File. + * @version V1.0.0 + * @data 2025-03-04 + ****************************************************************************** + */ + +#ifndef __FT32F4xx_H +#define __FT32F4xx_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +#if !defined (FT32F4) +#define FT32F4 +#endif /* FT32F4 */ + + + +/** + * @brief CMSIS Device version number V2.3.3 + */ +#define __FT32F4_DEVICE_VERSION_MAIN (0x02) /*!< [31:24] main version */ +#define __FT32F4_DEVICE_VERSION_SUB1 (0x03) /*!< [23:16] sub1 version */ +#define __FT32F4_DEVICE_VERSION_SUB2 (0x03) /*!< [15:8] sub2 version */ +#define __FT32F4_DEVICE_VERSION_RC (0x00) /*!< [7:0] release candidate */ +#define __FT32F4_DEVICE_VERSION ((__FT32F4_DEVICE_VERSION_MAIN << 24)\ + |(__FT32F4_DEVICE_VERSION_SUB1 << 16)\ + |(__FT32F4_DEVICE_VERSION_SUB2 << 8 )\ + |(__FT32F4_DEVICE_VERSION_RC)) + + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT + +#define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ +//void assert_failed(uint8_t* file, uint32_t line); +void assert_failed(uint8_t *file, uint32_t line) +{ + printf("Wrong parameters value: file %s on line %d\r\n", file, line); +} +#else +#define assert_param(expr) ((void)0) +#endif /* USE_FULL_ASSERT */ + + +#if !defined(UNUSED) +#define UNUSED(x) ((void)(x)) +#endif + + +#if defined(FT32F407xE) +#include "ft32f407xe.h" +#else +#error "Please select first the target FT32F4xx device used in your application (in ft32f4xx.h file)" +#endif + +/** + * @} + */ + +#if defined(__CC_ARM) // AC5 ARMCC +#define WEAK __weak +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) // AC6 ARMclang +#define WEAK __attribute__((weak)) +#else +#define WEAK __attribute__((weak)) +#endif + + + +/** + * @} + */ + + +/** @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))) + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __FT32F4xx_H */ +/** + * @} + */ + +/** + * @} + */ + + + + +/*****************************END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/mpu_armv7.h b/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/mpu_armv7.h new file mode 100644 index 00000000000..be0d7048be2 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/mpu_armv7.h @@ -0,0 +1,277 @@ +/****************************************************************************** + * @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/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/mpu_armv8.h b/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/mpu_armv8.h new file mode 100644 index 00000000000..3de16efc86a --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/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/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/pac_armv81.h b/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/pac_armv81.h new file mode 100644 index 00000000000..854b60a204c --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/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/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/pmu_armv8.h b/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/pmu_armv8.h new file mode 100644 index 00000000000..f8f3d8935b8 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/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/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/system_ft32f4xx.h b/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/system_ft32f4xx.h new file mode 100644 index 00000000000..05158326e24 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/system_ft32f4xx.h @@ -0,0 +1,49 @@ +/** + ****************************************************************************** + * @file system_ft32f4xx.h + * @author FMD AE + * @brief CMSIS Cortex-M4 Device Peripheral Access Layer System Header File. + * @details + * @version V1.0.0 + * @date 2025-03-04 + ******************************************************************************* + */ + +/** + * @brief Define to prevent recursive inclusion + */ +#ifndef __SYSTEM_FT32F4xx_H +#define __SYSTEM_FT32F4xx_H +#include "ft32f4xx.h" +#ifdef __cplusplus +extern "C" { +#endif + +extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ + +extern void SystemInit(void); +extern void SystemCoreClockUpdate(void); + + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* */ + +/** + * @} + */ + +/** + * @} + */ +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/tz_context.h b/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/include/tz_context.h new file mode 100644 index 00000000000..0d09749f3a5 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/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/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/source/arm/FT32F407_OPT.s b/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/source/arm/FT32F407_OPT.s new file mode 100644 index 00000000000..bfa52deac21 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/source/arm/FT32F407_OPT.s @@ -0,0 +1,128 @@ +;/*******************************************************************************/ +;/* Copyright (c) 2014 Arm Limited (or its affiliates). All */ +;/* rights reserved. */ +;/* */ +;/* SPDX-License-Identifier: BSD-3-Clause */ +;/* */ +;/* 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 Arm 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 COPYRIGHT HOLDERS AND 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. */ +;/*******************************************************************************/ +;/* FT32F407_OPT.s: FT32F407 Flash Option Bytes */ +;/*******************************************************************************/ +;/* <<< Use Configuration Wizard in Context Menu >>> */ +;/*******************************************************************************/ + + +;// Flash Option Bytes +FLASH_OPT EQU 1 + +;// Flash Read Protection +;// Read protection is used to protect the software code stored in Flash memory +;// Read Protection Level +;// Level 0: No Protection +;// Level 1: Read Protection of Memories (debug features limited) +;// Level 2: Chip Protection (debug and boot in RAM features disabled) +;// <0xAA=> Level 0 (No Protection) +;// <0x00=> Level 1 (Read Protection of Memories) +;// <0xCC=> Level 2 (Chip Protection) +;// + +;// User Configuration +;// BOR_EN +;// BORF_LEV +;// <0=> BOR falling edge voltage 1: threshold value is approximately 2.0 V +;// <1=> BOR falling edge voltage 2: threshold value is approximately 2.2 V +;// <2=> BOR falling edge voltage 3: threshold value is approximately 2.5 V +;// <3=> BOR falling edge voltage 4: threshold value is approximately 2.8 V +;// BORR_LEV +;// <0=> BOR rising edge voltage 1: threshold value is approximately 2.1 V +;// <1=> BOR rising edge voltage 2: threshold value is approximately 2.3 V +;// <2=> BOR rising edge voltage 3: threshold value is approximately 2.6 V +;// <3=> BOR rising edge voltage 4: threshold value is approximately 2.9 V +;// WDG_SW +;// <0=> HW Watchdog +;// <1=> SW Watchdog +;// nRST_STOP +;// Generate Reset when entering STOP Mode +;// <0=> Enabled +;// <1=> Disabled +;// nRST_STDBY +;// Generate Reset when entering Standby Mode +;// <0=> Enabled +;// <1=> Disabled +;// + +;// Flash Write Protection +;// Flash write-protection setting, with 16KB as the unit, low effective +;// nWRP Page 0 to 1023 +;// Not write protect Page 0 to 1023 +;// Page 0 to 31 +;// Page 32 to 63 +;// Page 64 to 95 +;// Page 96 to 127 +;// Page 128 to 159 +;// Page 160 to 191 +;// Page 192 to 223 +;// Page 224 to 255 +;// Page 256 to 287 +;// Page 288 to 319 +;// Page 320 to 351 +;// Page 352 to 383 +;// Page 384 to 415 +;// Page 416 to 447 +;// Page 448 to 479 +;// Page 480 to 511 +;// Page 512 to 543 +;// Page 544 to 575 +;// Page 576 to 607 +;// Page 608 to 639 +;// Page 640 to 671 +;// Page 672 to 703 +;// Page 704 to 735 +;// Page 736 to 767 +;// Page 768 to 799 +;// Page 800 to 831 +;// Page 832 to 863 +;// Page 864 to 895 +;// Page 896 to 927 +;// Page 928 to 959 +;// Page 960 to 991 +;// Page 992 to 1023 +;// +;// + + +FLASH_OPBC EQU 0x001EAAE0 +FLASH_TEMP EQU ~FLASH_OPBC +FLASH_WRPR EQU 0xFFFFFFFF +;// + + + IF FLASH_OPT <> 0 + AREA |.ARM.__AT_0x1FFF0800|, CODE, READONLY + DCD FLASH_OPBC + DCD FLASH_TEMP + DCD FLASH_WRPR + ENDIF + + END diff --git a/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/source/arm/startup_ft32f407xe.s b/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/source/arm/startup_ft32f407xe.s new file mode 100644 index 00000000000..9336a63de75 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/source/arm/startup_ft32f407xe.s @@ -0,0 +1,491 @@ +;/**************************************************************************//** +; * @file startup_CMSDK_CM4.s +; * @brief CMSIS Cortex-M4 Core Device Startup File for +; * Device CMSDK_CM4 +; * @version V3.01 +; * @date 06. March 2012 +; * +; * @note +; * Copyright (C) 2012 ARM Limited. All rights reserved. +; * +; * @par +; * ARM Limited (ARM) is supplying this software for use with Cortex-M +; * processor based microcontrollers. This file can be freely distributed +; * within development tools that are supporting such ARM based processors. +; * +; * @par +; * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED +; * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF +; * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. +; * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR +; * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +; * +; ******************************************************************************/ + +;/*****************************************************************************/ +;/* Startup.s: Startup file for ARM Cortex-M4 Device Family */ +;/*****************************************************************************/ +;/* +;//-------- <<< Use Configuration Wizard in Context Menu >>> ------------------ +;*/ + + +; Stack Configuration +; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + +Stack_Size EQU 0x00000400 + + AREA STACK, NOINIT, READWRITE, ALIGN=3 +Stack_Mem SPACE Stack_Size +__initial_sp + + +; Heap Configuration +; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + +Heap_Size EQU 0x00000200 + + AREA HEAP, NOINIT, READWRITE, ALIGN=3 +__heap_base +Heap_Mem SPACE Heap_Size +__heap_limit + + + PRESERVE8 + THUMB + + +; Vector Table Mapped to Address 0 at Reset + + AREA RESET, DATA, READONLY + EXPORT __Vectors + EXPORT __Vectors_End + EXPORT __Vectors_Size + +__Vectors DCD __initial_sp ; Top of Stack + DCD Reset_Handler ; Reset Handler + DCD NMI_Handler ; NMI Handler + DCD HardFault_Handler ; Hard Fault Handler + DCD MemManage_Handler ; MPU Fault Handler + DCD BusFault_Handler ; Bus Fault Handler + DCD UsageFault_Handler ; Usage Fault Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; SVCall Handler + DCD DebugMon_Handler ; Debug Monitor Handler + DCD 0 ; Reserved + DCD PendSV_Handler ; PendSV Handler + DCD SysTick_Handler ; SysTick Handler + + ; External Interrupts + DCD WWDG_Handler ; 16+ 0: Window Watchdog + DCD PVD_Handler ; 16+ 1: PVD PROG VDDIO Handler + DCD TAMP_STAMP_Handler ; 16+ 2: TAMP and STAMP Handler + DCD RTC_Handler ; 16+ 3: RTC Handler + DCD FLASH_Handler ; 16+ 4: FLASH Handler + DCD RCC_Handler ; 16+ 5: RCC Handler + DCD EXTI0_Handler ; 16+ 6: EXTI 0 handler + DCD EXTI1_Handler ; 16+ 7: EXTI 1 Handler + DCD EXTI2_Handler ; 16+ 8: EXTI 2 Handler + DCD EXTI3_Handler ; 16+ 9: EXTI 3 Handler + DCD EXTI4_Handler ; 16+10: EXTI 4 Handler + DCD DMA1_CH0_Handler ; 16+11: DMA1 CH0 Handler + DCD DMA1_CH1_Handler ; 16+12: DMA1 CH1 Handler + DCD DMA1_CH2_Handler ; 16+13: DMA1 CH2 Handler + DCD DMA1_CH3_Handler ; 16+14: DMA1 CH3 Handler + DCD DMA1_CH4_Handler ; 16+15: DMA1 CH4 Handler + DCD DMA1_CH5_Handler ; 16+16: DMA1 CH5 Handler + DCD DMA1_CH6_Handler ; 16+17: DMA1 CH6 Handler + DCD ADC_Handler ; 16+18: ADC Handler + DCD CAN1_Handler ; 16+19: FDxCAN1 Handler + DCD CAN2_Handler ; 16+20: FDxCAN2 Handler + DCD CAN3_Handler ; 16+21: FDxCAN3 Handler + DCD CAN4_Handler ; 16+22: FDxCAN4 Handler + DCD EXTI9_5_Handler ; 16+23: EXTI[9:5] Handler + DCD TIM1_BRK_TIM9_Handler ; 16+24: TIM1 BRK and TIM9 Handler + DCD TIM1_UP_TIM1O_Handler ; 16+25: TIM1 UP and TIM10 Handler + DCD TIM1_TRG_COM_TIM11_Handler ; 16+26: TIM1 TRG/COM and TIM10 Hand + DCD TIM1_CC_Handler ; 16+27: TIM1 CC Handler + DCD TIM2_Handler ; 16+28: TIM2 Handler + DCD TIM3_Handler ; 16+29: TIM3 Handler + DCD TIM4_Handler ; 16+30: TIM4 Handler + DCD I2C1_Handler ; 16+31: I2C1 Handler + DCD I2C2_Handler ; 16+32: I2C2 Handler + DCD QSPI_Handler ; 16+33: QSPI Handler + DCD SPI1_Handler ; 16+34: SPI1 Handler + DCD SPI2_Handler ; 16+35: SPI2 Handler + DCD USART1_Handler ; 16+36: USART1 Handler + DCD USART2_Handler ; 16+37: USART2 Handler + DCD USART3_Handler ; 16+38: USART3 Handler + DCD EXTI15_10_Handler ; 16+39: EXTI[15:10] Handler + DCD RTCAlarm_Handler ; 16+40: RTC Alarm Handler + DCD OTG_FS_WKUP_Handler ; 16+41: Connect EXTI USB OTG WKUP H + DCD TIM8_BRK_TIM12_Handler ; 16+42: TIM8 BRK and TIM12 Handler + DCD TIM8_UP_TIM13_Handler ; 16+43: TIM8 UP and TIM13 Handler + DCD TIM8_TRG_COM_TIM14_Handler ; 16+44: TIM8 TRG/COM and TIM14 Hand + DCD TIM8_CC_Handler ; 16+45: TIM8 CC Handler + DCD DMA1_CH7_Handler ; 16+46: DMA1 CH7 Handler + DCD FMC_Handler ; 16+47: FMC Handler + DCD SDIO_Handler ; 16+48: SDIO Handler + DCD TIM5_Handler ; 16+49: TIM5 Handler + DCD SPI3_Handler ; 16+50: SPI3 Handler + DCD UART4_Handler ; 16+51: UART4 Handler + DCD UART5_Handler ; 16+52: UART5 Handler + DCD TIM6_DAC_Handler ; 16+53: TIM6 DAC Handler + DCD TIM7_Handler ; 16+54: TIM7 Handler + DCD DMA2_CH0_Handler ; 16+55: DMA2 CH0 Handler + DCD DMA2_CH1_Handler ; 16+56: DMA2 CH1 Handler + DCD DMA2_CH2_Handler ; 16+57: DMA2 CH2 Handler + DCD DMA2_CH3_Handler ; 16+58: DMA2 CH3 Handler + DCD DMA2_CH4_Handler ; 16+59: DMA2 CH4 Handler + DCD OTG_FS_Handler ; 16+60: OTG FS Handler + DCD DMA2_CH5_Handler ; 16+61: DMA2 CH5 Handler + DCD DMA2_CH6_Handler ; 16+62: DMA2 CH6 Handler + DCD DMA2_CH7_Handler ; 16+63: DMA2 CH7 Handler + DCD USART6_Handler ; 16+64: USART6 Handler + DCD I2C3_Handler ; 16+65: I2C3 Handler + DCD OTG_HS_EP1_OUT_Handler ; 16+66: OTG HS EP1OUT Handler + DCD OTG_HS_EP1_IN_Handler ; 16+67: OTG HS EP1IN Handler + DCD OTG_HS_WKUP_Handler ; 16+68: OTG HS WKUP Handler + DCD OTG_HS_Handler ; 16+69: OTG HS Handler + DCD RNG_Handler ; 16+70: RNG Handler + DCD FPU_Handler ; 16+71: FPU Handler + DCD CRS_Handler ; 16+72: CRS Handler + DCD SPDIF_Handler ; 16+73: SPDIF Handler + DCD SSI_AC97_Handler ; 16+74: SSI_AC97 Handler + DCD ETH_WKUP_Handler ; 16+75: ETH_WKUP Handler + DCD LPUART_Handler ; 16+76: LPUART Handler + DCD LPTIM_Handler ; 16+77: LPTIM Handler + DCD ETH_SBD_Handler ; 16+78: ETH_SBD Handler + DCD ETH_PERCHTX_Handler ; 16+79: ETH_PERCHTX Handler + DCD ETH_PERCHRX_Handler ; 16+80: ETH_PERCHRX Handler + DCD EPWM1_Handler ; 16+81: EPWM1 Handler + DCD EPWM1_TZ_Handler ; 16+82: EPWM1 TZ Handler + DCD EPWM2_Handler ; 16+83: EPWM2 Handler + DCD EPWM2_TZ_Handler ; 16+84: EPWM2 TZ Handler + DCD EPWM3_Handler ; 16+85: EPWM3 Handler + DCD EPWM3_TZ_Handler ; 16+86: EPWM3 TZ Handler + DCD EPWM4_Handler ; 16+87: EPWM4 Handler + DCD EPWM4_TZ_Handler ; 16+88: EPWM4 TZ Handler + DCD ECAP_Handler ; 16+89: ECAP Handler + DCD EQEP_Handler ; 16+90: EQEP Handler + DCD DLL_CAL_Handler ; 16+91: DLL CAL Handler + DCD COMP1_Handler ; 16+92: COMP1 Handler + DCD COMP2_Handler ; 16+93: COMP2 Handler + DCD COMP3_Handler ; 16+94: COMP3 Handler + DCD COMP4_Handler ; 16+95: COMP4 Handler + DCD COMP5_Handler ; 16+96: COMP5 Handler + DCD COMP6_Handler ; 16+97: COMP6 Handler + DCD ICACHE_Handler ; 16+98: ICACHE Handler + DCD DCACHE_Handler ; 16+99: DCACHE Handler + DCD UART7_Handler ; 16+100: UART7 Handler +__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 WWDG_Handler [WEAK] + EXPORT PVD_Handler [WEAK] + EXPORT TAMP_STAMP_Handler [WEAK] + EXPORT RTC_Handler [WEAK] + EXPORT FLASH_Handler [WEAK] + EXPORT RCC_Handler [WEAK] + EXPORT EXTI0_Handler [WEAK] + EXPORT EXTI1_Handler [WEAK] + EXPORT EXTI2_Handler [WEAK] + EXPORT EXTI3_Handler [WEAK] + EXPORT EXTI4_Handler [WEAK] + EXPORT DMA1_CH0_Handler [WEAK] + EXPORT DMA1_CH1_Handler [WEAK] + EXPORT DMA1_CH2_Handler [WEAK] + EXPORT DMA1_CH3_Handler [WEAK] + EXPORT DMA1_CH4_Handler [WEAK] + EXPORT DMA1_CH5_Handler [WEAK] + EXPORT DMA1_CH6_Handler [WEAK] + EXPORT ADC_Handler [WEAK] + EXPORT CAN1_Handler [WEAK] + EXPORT CAN2_Handler [WEAK] + EXPORT CAN3_Handler [WEAK] + EXPORT CAN4_Handler [WEAK] + EXPORT EXTI9_5_Handler [WEAK] + EXPORT TIM1_BRK_TIM9_Handler [WEAK] + EXPORT TIM1_UP_TIM1O_Handler [WEAK] + EXPORT TIM1_TRG_COM_TIM11_Handler [WEAK] + EXPORT TIM1_CC_Handler [WEAK] + EXPORT TIM2_Handler [WEAK] + EXPORT TIM3_Handler [WEAK] + EXPORT TIM4_Handler [WEAK] + EXPORT I2C1_Handler [WEAK] + EXPORT I2C2_Handler [WEAK] + EXPORT QSPI_Handler [WEAK] + EXPORT SPI1_Handler [WEAK] + EXPORT SPI2_Handler [WEAK] + EXPORT USART1_Handler [WEAK] + EXPORT USART2_Handler [WEAK] + EXPORT USART3_Handler [WEAK] + EXPORT EXTI15_10_Handler [WEAK] + EXPORT RTCAlarm_Handler [WEAK] + EXPORT OTG_FS_WKUP_Handler [WEAK] + EXPORT TIM8_BRK_TIM12_Handler [WEAK] + EXPORT TIM8_UP_TIM13_Handler [WEAK] + EXPORT TIM8_TRG_COM_TIM14_Handler [WEAK] + EXPORT TIM8_CC_Handler [WEAK] + EXPORT DMA1_CH7_Handler [WEAK] + EXPORT FMC_Handler [WEAK] + EXPORT SDIO_Handler [WEAK] + EXPORT TIM5_Handler [WEAK] + EXPORT SPI3_Handler [WEAK] + EXPORT UART4_Handler [WEAK] + EXPORT UART5_Handler [WEAK] + EXPORT TIM6_DAC_Handler [WEAK] + EXPORT TIM7_Handler [WEAK] + EXPORT DMA2_CH0_Handler [WEAK] + EXPORT DMA2_CH1_Handler [WEAK] + EXPORT DMA2_CH2_Handler [WEAK] + EXPORT DMA2_CH3_Handler [WEAK] + EXPORT DMA2_CH4_Handler [WEAK] + EXPORT OTG_FS_Handler [WEAK] + EXPORT DMA2_CH5_Handler [WEAK] + EXPORT DMA2_CH6_Handler [WEAK] + EXPORT DMA2_CH7_Handler [WEAK] + EXPORT USART6_Handler [WEAK] + EXPORT I2C3_Handler [WEAK] + EXPORT OTG_HS_EP1_OUT_Handler [WEAK] + EXPORT OTG_HS_EP1_IN_Handler [WEAK] + EXPORT OTG_HS_WKUP_Handler [WEAK] + EXPORT OTG_HS_Handler [WEAK] + EXPORT RNG_Handler [WEAK] + EXPORT FPU_Handler [WEAK] + EXPORT CRS_Handler [WEAK] + EXPORT SPDIF_Handler [WEAK] + EXPORT SSI_AC97_Handler [WEAK] + EXPORT ETH_WKUP_Handler [WEAK] + EXPORT LPUART_Handler [WEAK] + EXPORT LPTIM_Handler [WEAK] + EXPORT ETH_SBD_Handler [WEAK] + EXPORT ETH_PERCHTX_Handler [WEAK] + EXPORT ETH_PERCHRX_Handler [WEAK] + EXPORT EPWM1_Handler [WEAK] + EXPORT EPWM1_TZ_Handler [WEAK] + EXPORT EPWM2_Handler [WEAK] + EXPORT EPWM2_TZ_Handler [WEAK] + EXPORT EPWM3_Handler [WEAK] + EXPORT EPWM3_TZ_Handler [WEAK] + EXPORT EPWM4_Handler [WEAK] + EXPORT EPWM4_TZ_Handler [WEAK] + EXPORT ECAP_Handler [WEAK] + EXPORT EQEP_Handler [WEAK] + EXPORT DLL_CAL_Handler [WEAK] + EXPORT COMP1_Handler [WEAK] + EXPORT COMP2_Handler [WEAK] + EXPORT COMP3_Handler [WEAK] + EXPORT COMP4_Handler [WEAK] + EXPORT COMP5_Handler [WEAK] + EXPORT COMP6_Handler [WEAK] + EXPORT ICACHE_Handler [WEAK] + EXPORT DCACHE_Handler [WEAK] + EXPORT UART7_Handler [WEAK] + + +WWDG_Handler +PVD_Handler +TAMP_STAMP_Handler +RTC_Handler +FLASH_Handler +RCC_Handler +EXTI0_Handler +EXTI1_Handler +EXTI2_Handler +EXTI3_Handler +EXTI4_Handler +DMA1_CH0_Handler +DMA1_CH1_Handler +DMA1_CH2_Handler +DMA1_CH3_Handler +DMA1_CH4_Handler +DMA1_CH5_Handler +DMA1_CH6_Handler +ADC_Handler +CAN1_Handler +CAN2_Handler +CAN3_Handler +CAN4_Handler +EXTI9_5_Handler +TIM1_BRK_TIM9_Handler +TIM1_UP_TIM1O_Handler +TIM1_TRG_COM_TIM11_Handler +TIM1_CC_Handler +TIM2_Handler +TIM3_Handler +TIM4_Handler +I2C1_Handler +I2C2_Handler +QSPI_Handler +SPI1_Handler +SPI2_Handler +USART1_Handler +USART2_Handler +USART3_Handler +EXTI15_10_Handler +RTCAlarm_Handler +OTG_FS_WKUP_Handler +TIM8_BRK_TIM12_Handler +TIM8_UP_TIM13_Handler +TIM8_TRG_COM_TIM14_Handler +TIM8_CC_Handler +DMA1_CH7_Handler +FMC_Handler +SDIO_Handler +TIM5_Handler +SPI3_Handler +UART4_Handler +UART5_Handler +TIM6_DAC_Handler +TIM7_Handler +DMA2_CH0_Handler +DMA2_CH1_Handler +DMA2_CH2_Handler +DMA2_CH3_Handler +DMA2_CH4_Handler +OTG_FS_Handler +DMA2_CH5_Handler +DMA2_CH6_Handler +DMA2_CH7_Handler +USART6_Handler +I2C3_Handler +OTG_HS_EP1_OUT_Handler +OTG_HS_EP1_IN_Handler +OTG_HS_WKUP_Handler +OTG_HS_Handler +RNG_Handler +FPU_Handler +CRS_Handler +SPDIF_Handler +SSI_AC97_Handler +ETH_WKUP_Handler +LPUART_Handler +LPTIM_Handler +ETH_SBD_Handler +ETH_PERCHTX_Handler +ETH_PERCHRX_Handler +EPWM1_Handler +EPWM1_TZ_Handler +EPWM2_Handler +EPWM2_TZ_Handler +EPWM3_Handler +EPWM3_TZ_Handler +EPWM4_Handler +EPWM4_TZ_Handler +ECAP_Handler +EQEP_Handler +DLL_CAL_Handler +COMP1_Handler +COMP2_Handler +COMP3_Handler +COMP4_Handler +COMP5_Handler +COMP6_Handler +ICACHE_Handler +DCACHE_Handler +UART7_Handler + + B . + ENDP + + + ALIGN + + +; User Initial Stack & Heap + + IF :DEF:__MICROLIB + + EXPORT __initial_sp + EXPORT __heap_base + EXPORT __heap_limit + + ELSE + + IMPORT __use_two_region_memory + EXPORT __user_initial_stackheap + +__user_initial_stackheap PROC + LDR R0, = Heap_Mem + LDR R1, =(Stack_Mem + Stack_Size) + LDR R2, = (Heap_Mem + Heap_Size) + LDR R3, = Stack_Mem + BX LR + ENDP + + ALIGN + + ENDIF + + + END diff --git a/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/source/gcc/startup_ft32f407xe.s b/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/source/gcc/startup_ft32f407xe.s new file mode 100644 index 00000000000..83e14985f09 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/source/gcc/startup_ft32f407xe.s @@ -0,0 +1,583 @@ +/** + ****************************************************************************** + * @file startup_ft32f072xb.s + * @author MCD Application Team + * @brief FT32F407xE 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()). + * After Reset the Cortex-M0 processor is in Thread mode, + * priority is Privileged, and the Stack is set to Main. + ****************************************************************************** + * @attention + * + * Copyright (c) 2006-2025 Fremontmicro + * All rights reserved. + * + * This software component is licensed by FMD 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 + * + ****************************************************************************** + */ + + .syntax unified + .cpu cortex-m4 + .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 + + .section .text.Reset_Handler + .weak Reset_Handler + .type Reset_Handler, %function +Reset_Handler: + ldr r0, =_estack + mov sp, r0 /* set stack pointer */ + +/* 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 the clock system intitialization function.*/ + bl SystemInit +/* Call static constructors */ + bl __libc_init_array +/* Call the application's entry point.*/ + bl entry + +LoopForever: + b LoopForever + + +.size Reset_Handler, .-Reset_Handler + +/** + * @brief This is the code that gets called when the processor receives an + * unexpected interrupt. This simply enters an infinite loop, preserving + * the system state for examination by a debugger. + * + * @param None + * @retval : None +*/ + .section .text.Default_Handler,"ax",%progbits +Default_Handler: +Infinite_Loop: + b Infinite_Loop + .size Default_Handler, .-Default_Handler +/****************************************************************************** +* +* The minimal vector table for a Cortex M0. Note that the proper constructs +* must be placed on this to ensure that it ends up at physical address +* 0x0000.0000. +* +******************************************************************************/ + .section .isr_vector,"a",%progbits + .type g_pfnVectors, %object + .size g_pfnVectors, .-g_pfnVectors + + +g_pfnVectors: + .word _estack + .word Reset_Handler + .word NMI_Handler + .word HardFault_Handler + .word MemManage_Handler + .word BusFault_Handler + .word UsageFault_Handler + .word 0 + .word 0 + .word 0 + .word 0 + .word SVC_Handler + .word DebugMon_Handler + .word 0 + .word PendSV_Handler + .word SysTick_Handler + + .word WWDG_Handler + .word PVD_Handler + .word TAMP_STAMP_Handler + .word RTC_Handler + .word FLASH_Handler + .word RCC_Handler + .word EXTI0_Handler + .word EXTI1_Handler + .word EXTI2_Handler + .word EXTI3_Handler + .word EXTI4_Handler + .word DMA1_CH0_Handler + .word DMA1_CH1_Handler + .word DMA1_CH2_Handler + .word DMA1_CH3_Handler + .word DMA1_CH4_Handler + .word DMA1_CH5_Handler + .word DMA1_CH6_Handler + .word ADC_Handler + .word CAN1_Handler + .word CAN2_Handler + .word CAN3_Handler + .word CAN4_Handler + .word EXTI9_5_Handler + .word TIM1_BRK_TIM9_Handler + .word TIM1_UP_TIM1O_Handler + .word TIM1_TRG_COM_TIM11_Handler + .word TIM1_CC_Handler + .word TIM2_Handler + .word TIM3_Handler + .word TIM4_Handler + .word I2C1_Handler + .word I2C2_Handler + .word QSPI_Handler + .word SPI1_Handler + .word SPI2_Handler + .word USART1_Handler + .word USART2_Handler + .word USART3_Handler + .word EXTI15_10_Handler + .word RTCAlarm_Handler + .word OTG_FS_WKUP_Handler + .word TIM8_BRK_TIM12_Handler + .word TIM8_UP_TIM13_Handler + .word TIM8_TRG_COM_TIM14_Handler + .word TIM8_CC_Handler + .word DMA1_CH7_Handler + .word FMC_Handler + .word SDIO_Handler + .word TIM5_Handler + .word SPI3_Handler + .word UART4_Handler + .word UART5_Handler + .word TIM6_DAC_Handler + .word TIM7_Handler + .word DMA2_CH0_Handler + .word DMA2_CH1_Handler + .word DMA2_CH2_Handler + .word DMA2_CH3_Handler + .word DMA2_CH4_Handler + .word OTG_FS_Handler + .word DMA2_CH5_Handler + .word DMA2_CH6_Handler + .word DMA2_CH7_Handler + .word USART6_Handler + .word I2C3_Handler + .word OTG_HS_EP1_OUT_Handler + .word OTG_HS_EP1_IN_Handler + .word OTG_HS_WKUP_Handler + .word OTG_HS_Handler + .word RNG_Handler + .word FPU_Handler + .word CRS_Handler + .word SPDIF_Handler + .word SSI_AC97_Handler + .word ETH_WKUP_Handler + .word LPUART_Handler + .word LPTIM_Handler + .word ETH_SBD_Handler + .word ETH_PERCHTX_Handler + .word ETH_PERCHRX_Handler + .word EPWM1_Handler + .word EPWM1_TZ_Handler + .word EPWM2_Handler + .word EPWM2_TZ_Handler + .word EPWM3_Handler + .word EPWM3_TZ_Handler + .word EPWM4_Handler + .word EPWM4_TZ_Handler + .word ECAP_Handler + .word EQEP_Handler + .word DLL_CAL_Handler + .word COMP1_Handler + .word COMP2_Handler + .word COMP3_Handler + .word COMP4_Handler + .word COMP5_Handler + .word COMP6_Handler + .word ICACHE_Handler + .word DCACHE_Handler + .word UART7_Handler + +/******************************************************************************* +* +* Provide weak aliases for each Exception handler to the Default_Handler. +* As they are weak aliases, any function with the same name will override +* this definition. +* +*******************************************************************************/ + + .weak NMI_Handler + .thumb_set NMI_Handler,Default_Handler + + .weak HardFault_Handler + .thumb_set HardFault_Handler,Default_Handler + + .weak MemManage_Handler + .thumb_set MemManage_Handler,Default_Handler + + .weak BusFault_Handler + .thumb_set BusFault_Handler,Default_Handler + + .weak UsageFault_Handler + .thumb_set UsageFault_Handler,Default_Handler + + .weak SVC_Handler + .thumb_set SVC_Handler,Default_Handler + + .weak DebugMon_Handler + .thumb_set DebugMon_Handler,Default_Handler + + .weak PendSV_Handler + .thumb_set PendSV_Handler,Default_Handler + + .weak SysTick_Handler + .thumb_set SysTick_Handler,Default_Handler + + .weak WWDG_Handler + .thumb_set WWDG_Handler,Default_Handler + + .weak PVD_Handler + .thumb_set PVD_Handler,Default_Handler + + .weak TAMP_STAMP_Handler + .thumb_set TAMP_STAMP_Handler,Default_Handler + + .weak RTC_Handler + .thumb_set RTC_Handler,Default_Handler + + .weak FLASH_Handler + .thumb_set FLASH_Handler,Default_Handler + + .weak RCC_Handler + .thumb_set RCC_Handler,Default_Handler + + .weak EXTI0_Handler + .thumb_set EXTI0_Handler,Default_Handler + + .weak EXTI1_Handler + .thumb_set EXTI1_Handler,Default_Handler + + .weak EXTI2_Handler + .thumb_set EXTI2_Handler,Default_Handler + + .weak EXTI3_Handler + .thumb_set EXTI3_Handler,Default_Handler + + .weak EXTI4_Handler + .thumb_set EXTI4_Handler,Default_Handler + + .weak DMA1_CH0_Handler + .thumb_set DMA1_CH0_Handler,Default_Handler + + .weak DMA1_CH1_Handler + .thumb_set DMA1_CH1_Handler,Default_Handler + + .weak DMA1_CH2_Handler + .thumb_set DMA1_CH2_Handler,Default_Handler + + .weak DMA1_CH3_Handler + .thumb_set DMA1_CH3_Handler,Default_Handler + + .weak DMA1_CH4_Handler + .thumb_set DMA1_CH4_Handler,Default_Handler + + .weak DMA1_CH5_Handler + .thumb_set DMA1_CH5_Handler,Default_Handler + + .weak DMA1_CH6_Handler + .thumb_set DMA1_CH6_Handler,Default_Handler + + .weak ADC_Handler + .thumb_set ADC_Handler,Default_Handler + + .weak CAN1_Handler + .thumb_set CAN1_Handler,Default_Handler + + .weak CAN2_Handler + .thumb_set CAN2_Handler,Default_Handler + + .weak CAN3_Handler + .thumb_set CAN3_Handler,Default_Handler + + .weak CAN4_Handler + .thumb_set CAN4_Handler,Default_Handler + + .weak EXTI9_5_Handler + .thumb_set EXTI9_5_Handler,Default_Handler + + .weak TIM1_BRK_TIM9_Handler + .thumb_set TIM1_BRK_TIM9_Handler,Default_Handler + + .weak TIM1_UP_TIM1O_Handler + .thumb_set TIM1_UP_TIM1O_Handler,Default_Handler + + .weak TIM1_TRG_COM_TIM11_Handler + .thumb_set TIM1_TRG_COM_TIM11_Handler,Default_Handler + + .weak TIM1_CC_Handler + .thumb_set TIM1_CC_Handler,Default_Handler + + .weak TIM2_Handler + .thumb_set TIM2_Handler,Default_Handler + + .weak TIM3_Handler + .thumb_set TIM3_Handler,Default_Handler + + .weak TIM4_Handler + .thumb_set TIM4_Handler,Default_Handler + + .weak I2C1_Handler + .thumb_set I2C1_Handler,Default_Handler + + .weak I2C2_Handler + .thumb_set I2C2_Handler,Default_Handler + + .weak QSPI_Handler + .thumb_set QSPI_Handler,Default_Handler + + .weak SPI1_Handler + .thumb_set SPI1_Handler,Default_Handler + + .weak SPI2_Handler + .thumb_set SPI2_Handler,Default_Handler + + .weak USART1_Handler + .thumb_set USART1_Handler,Default_Handler + + .weak USART2_Handler + .thumb_set USART2_Handler,Default_Handler + + .weak USART3_Handler + .thumb_set USART3_Handler,Default_Handler + + .weak EXTI15_10_Handler + .thumb_set EXTI15_10_Handler,Default_Handler + + .weak RTCAlarm_Handler + .thumb_set RTCAlarm_Handler,Default_Handler + + .weak OTG_FS_WKUP_Handler + .thumb_set OTG_FS_WKUP_Handler,Default_Handler + + .weak TIM8_BRK_TIM12_Handler + .thumb_set TIM8_BRK_TIM12_Handler,Default_Handler + + .weak TIM8_UP_TIM13_Handler + .thumb_set TIM8_UP_TIM13_Handler,Default_Handler + + .weak TIM8_TRG_COM_TIM14_Handler + .thumb_set TIM8_TRG_COM_TIM14_Handler,Default_Handler + + .weak TIM8_CC_Handler + .thumb_set TIM8_CC_Handler,Default_Handler + + .weak DMA1_CH7_Handler + .thumb_set DMA1_CH7_Handler,Default_Handler + + .weak FMC_Handler + .thumb_set FMC_Handler,Default_Handler + + .weak SDIO_Handler + .thumb_set SDIO_Handler,Default_Handler + + .weak TIM5_Handler + .thumb_set TIM5_Handler,Default_Handler + + .weak SPI3_Handler + .thumb_set SPI3_Handler,Default_Handler + + .weak UART4_Handler + .thumb_set UART4_Handler,Default_Handler + + .weak UART5_Handler + .thumb_set UART5_Handler,Default_Handler + + .weak TIM6_DAC_Handler + .thumb_set TIM6_DAC_Handler,Default_Handler + + .weak TIM7_Handler + .thumb_set TIM7_Handler,Default_Handler + + .weak DMA2_CH0_Handler + .thumb_set DMA2_CH0_Handler,Default_Handler + + .weak DMA2_CH1_Handler + .thumb_set DMA2_CH1_Handler,Default_Handler + + .weak DMA2_CH2_Handler + .thumb_set DMA2_CH2_Handler,Default_Handler + + .weak DMA2_CH3_Handler + .thumb_set DMA2_CH3_Handler,Default_Handler + + .weak DMA2_CH4_Handler + .thumb_set DMA2_CH4_Handler,Default_Handler + + .weak OTG_FS_Handler + .thumb_set OTG_FS_Handler,Default_Handler + + .weak DMA2_CH5_Handler + .thumb_set DMA2_CH5_Handler,Default_Handler + + .weak DMA2_CH6_Handler + .thumb_set DMA2_CH6_Handler,Default_Handler + + .weak DMA2_CH7_Handler + .thumb_set DMA2_CH7_Handler,Default_Handler + + .weak USART6_Handler + .thumb_set USART6_Handler,Default_Handler + + .weak I2C3_Handler + .thumb_set I2C3_Handler,Default_Handler + + .weak OTG_HS_EP1_OUT_Handler + .thumb_set OTG_HS_EP1_OUT_Handler,Default_Handler + + .weak OTG_HS_EP1_IN_Handler + .thumb_set OTG_HS_EP1_IN_Handler,Default_Handler + + .weak OTG_HS_WKUP_Handler + .thumb_set OTG_HS_WKUP_Handler,Default_Handler + + .weak OTG_HS_Handler + .thumb_set OTG_HS_Handler,Default_Handler + + .weak RNG_Handler + .thumb_set RNG_Handler,Default_Handler + + .weak FPU_Handler + .thumb_set FPU_Handler,Default_Handler + + .weak CRS_Handler + .thumb_set CRS_Handler,Default_Handler + + .weak SPDIF_Handler + .thumb_set SPDIF_Handler,Default_Handler + + .weak SSI_AC97_Handler + .thumb_set SSI_AC97_Handler,Default_Handler + + .weak ETH_WKUP_Handler + .thumb_set ETH_WKUP_Handler,Default_Handler + + .weak LPUART_Handler + .thumb_set LPUART_Handler,Default_Handler + + .weak LPTIM_Handler + .thumb_set LPTIM_Handler,Default_Handler + + .weak ETH_SBD_Handler + .thumb_set ETH_SBD_Handler,Default_Handler + + .weak ETH_PERCHTX_Handler + .thumb_set ETH_PERCHTX_Handler,Default_Handler + + .weak ETH_PERCHRX_Handler + .thumb_set ETH_PERCHRX_Handler,Default_Handler + + .weak EPWM1_Handler + .thumb_set EPWM1_Handler,Default_Handler + + .weak EPWM1_TZ_Handler + .thumb_set EPWM1_TZ_Handler,Default_Handler + + .weak EPWM2_Handler + .thumb_set EPWM2_Handler,Default_Handler + + .weak EPWM2_TZ_Handler + .thumb_set EPWM2_TZ_Handler,Default_Handler + + .weak EPWM3_Handler + .thumb_set EPWM3_Handler,Default_Handler + + .weak EPWM3_TZ_Handler + .thumb_set EPWM3_TZ_Handler,Default_Handler + + .weak EPWM4_Handler + .thumb_set EPWM4_Handler,Default_Handler + + .weak EPWM4_TZ_Handler + .thumb_set EPWM4_TZ_Handler,Default_Handler + + .weak ECAP_Handler + .thumb_set ECAP_Handler,Default_Handler + + .weak EQEP_Handler + .thumb_set EQEP_Handler,Default_Handler + + .weak DLL_CAL_Handler + .thumb_set DLL_CAL_Handler,Default_Handler + + .weak COMP1_Handler + .thumb_set COMP1_Handler,Default_Handler + + .weak COMP2_Handler + .thumb_set COMP2_Handler,Default_Handler + + .weak COMP3_Handler + .thumb_set COMP3_Handler,Default_Handler + + .weak COMP4_Handler + .thumb_set COMP4_Handler,Default_Handler + + .weak COMP5_Handler + .thumb_set COMP5_Handler,Default_Handler + + .weak COMP6_Handler + .thumb_set COMP6_Handler,Default_Handler + + .weak ICACHE_Handler + .thumb_set ICACHE_Handler,Default_Handler + + .weak DCACHE_Handler + .thumb_set DCACHE_Handler,Default_Handler + + .weak UART7_Handler + .thumb_set UART7_Handler,Default_Handler + +/************************ (C) COPYRIGHT Fremontmicro *****END OF FILE****/ + diff --git a/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/source/iar/linker/ft32f407xe_flash.icf b/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/source/iar/linker/ft32f407xe_flash.icf new file mode 100644 index 00000000000..ae5a7f57f86 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/source/iar/linker/ft32f407xe_flash.icf @@ -0,0 +1,34 @@ +/*###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__ = 0x0807FFFF; +define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; +define symbol __ICFEDIT_region_RAM_end__ = 0x2001FFFF; +define symbol __ICFEDIT_region_CCMRAM_start__ = 0x10000000; +define symbol __ICFEDIT_region_CCMRAM_end__ = 0x1000FFFF; +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 0x400; +define symbol __ICFEDIT_size_heap__ = 0x200; +/**** End of ICF editor section. ###ICF###*/ + + +define memory mem with size = 4G; +define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; +define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; +define region CCMRAM_region = mem:[from __ICFEDIT_region_CCMRAM_start__ to __ICFEDIT_region_CCMRAM_end__]; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + +initialize by copy { readwrite }; +do not initialize { section .noinit }; + +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; + +place in ROM_region { readonly }; +place in RAM_region { readwrite, + block CSTACK, block HEAP }; \ No newline at end of file diff --git a/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/source/iar/startup_ft32f407xe.s b/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/source/iar/startup_ft32f407xe.s new file mode 100644 index 00000000000..b768cca602e --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/source/iar/startup_ft32f407xe.s @@ -0,0 +1,742 @@ +;******************************************************************************* +;* File Name : startup_ft32f407xe.s +;* Author : MCD Application Team +;* Description : FT32F407xE devices vector table for EWARM toolchain. +;* 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-M4 processor is in Thread mode, +;* priority is Privileged, and the Stack is set to Main. +;******************************************************************************* +;* @attention +;* +;* Copyright (c) 2006-2025 Fremontmicro. +;* All rights reserved. +;* +;* This software component is licensed by FMD 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 +;* +;******************************************************************************* +; +; +; 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 + + 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 ; MemManage_Handler + DCD BusFault_Handler ; BusFault_Handler + DCD UsageFault_Handler ; UsageFault_Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; SVCall Handler + DCD DebugMon_Handler ; DebugMon_Handler + DCD 0 ; Reserved + DCD PendSV_Handler ; PendSV Handler + DCD SysTick_Handler ; SysTick Handler + + ; External Interrupts + DCD WWDG_Handler ; 16+ 0: Window Watchdog + DCD PVD_Handler ; 16+ 1: PVD PROG VDDIO Handler + DCD TAMP_STAMP_Handler ; 16+ 2: TAMP and STAMP Handler + DCD RTC_Handler ; 16+ 3: RTC Handler + DCD FLASH_Handler ; 16+ 4: FLASH Handler + DCD RCC_Handler ; 16+ 5: RCC Handler + DCD EXTI0_Handler ; 16+ 6: EXTI 0 handler + DCD EXTI1_Handler ; 16+ 7: EXTI 1 Handler + DCD EXTI2_Handler ; 16+ 8: EXTI 2 Handler + DCD EXTI3_Handler ; 16+ 9: EXTI 3 Handler + DCD EXTI4_Handler ; 16+10: EXTI 4 Handler + DCD DMA1_CH0_Handler ; 16+11: DMA1 CH0 Handler + DCD DMA1_CH1_Handler ; 16+12: DMA1 CH1 Handler + DCD DMA1_CH2_Handler ; 16+13: DMA1 CH2 Handler + DCD DMA1_CH3_Handler ; 16+14: DMA1 CH3 Handler + DCD DMA1_CH4_Handler ; 16+15: DMA1 CH4 Handler + DCD DMA1_CH5_Handler ; 16+16: DMA1 CH5 Handler + DCD DMA1_CH6_Handler ; 16+17: DMA1 CH6 Handler + DCD ADC_Handler ; 16+18: ADC Handler + DCD CAN1_Handler ; 16+19: FDxCAN1 Handler + DCD CAN2_Handler ; 16+20: FDxCAN2 Handler + DCD CAN3_Handler ; 16+21: FDxCAN3 Handler + DCD CAN4_Handler ; 16+22: FDxCAN4 Handler + DCD EXTI9_5_Handler ; 16+23: EXTI[9:5] Handler + DCD TIM1_BRK_TIM9_Handler ; 16+24: TIM1 BRK and TIM9 Handler + DCD TIM1_UP_TIM1O_Handler ; 16+25: TIM1 UP and TIM10 Handler + DCD TIM1_TRG_COM_TIM11_Handler ; 16+26: TIM1 TRG/COM and TIM10 Hand + DCD TIM1_CC_Handler ; 16+27: TIM1 CC Handler + DCD TIM2_Handler ; 16+28: TIM2 Handler + DCD TIM3_Handler ; 16+29: TIM3 Handler + DCD TIM4_Handler ; 16+30: TIM4 Handler + DCD I2C1_Handler ; 16+31: I2C1 Handler + DCD I2C2_Handler ; 16+32: I2C2 Handler + DCD QSPI_Handler ; 16+33: QSPI Handler + DCD SPI1_Handler ; 16+34: SPI1 Handler + DCD SPI2_Handler ; 16+35: SPI2 Handler + DCD USART1_Handler ; 16+36: USART1 Handler + DCD USART2_Handler ; 16+37: USART2 Handler + DCD USART3_Handler ; 16+38: USART3 Handler + DCD EXTI15_10_Handler ; 16+39: EXTI[15:10] Handler + DCD RTCAlarm_Handler ; 16+40: RTC Alarm Handler + DCD OTG_FS_WKUP_Handler ; 16+41: Connect EXTI USB OTG WKUP H + DCD TIM8_BRK_TIM12_Handler ; 16+42: TIM8 BRK and TIM12 Handler + DCD TIM8_UP_TIM13_Handler ; 16+43: TIM8 UP and TIM13 Handler + DCD TIM8_TRG_COM_TIM14_Handler ; 16+44: TIM8 TRG/COM and TIM14 Hand + DCD TIM8_CC_Handler ; 16+45: TIM8 CC Handler + DCD DMA1_CH7_Handler ; 16+46: DMA1 CH7 Handler + DCD FMC_Handler ; 16+47: FMC Handler + DCD SDIO_Handler ; 16+48: SDIO Handler + DCD TIM5_Handler ; 16+49: TIM5 Handler + DCD SPI3_Handler ; 16+50: SPI3 Handler + DCD UART4_Handler ; 16+51: UART4 Handler + DCD UART5_Handler ; 16+52: UART5 Handler + DCD TIM6_DAC_Handler ; 16+53: TIM6 DAC Handler + DCD TIM7_Handler ; 16+54: TIM7 Handler + DCD DMA2_CH0_Handler ; 16+55: DMA2 CH0 Handler + DCD DMA2_CH1_Handler ; 16+56: DMA2 CH1 Handler + DCD DMA2_CH2_Handler ; 16+57: DMA2 CH2 Handler + DCD DMA2_CH3_Handler ; 16+58: DMA2 CH3 Handler + DCD DMA2_CH4_Handler ; 16+59: DMA2 CH4 Handler + DCD OTG_FS_Handler ; 16+60: OTG FS Handler + DCD DMA2_CH5_Handler ; 16+61: DMA2 CH5 Handler + DCD DMA2_CH6_Handler ; 16+62: DMA2 CH6 Handler + DCD DMA2_CH7_Handler ; 16+63: DMA2 CH7 Handler + DCD USART6_Handler ; 16+64: USART6 Handler + DCD I2C3_Handler ; 16+65: I2C3 Handler + DCD OTG_HS_EP1_OUT_Handler ; 16+66: OTG HS EP1OUT Handler + DCD OTG_HS_EP1_IN_Handler ; 16+67: OTG HS EP1IN Handler + DCD OTG_HS_WKUP_Handler ; 16+68: OTG HS WKUP Handler + DCD OTG_HS_Handler ; 16+69: OTG HS Handler + DCD RNG_Handler ; 16+70: RNG Handler + DCD FPU_Handler ; 16+71: FPU Handler + DCD CRS_Handler ; 16+72: CRS Handler + DCD SPDIF_Handler ; 16+73: SPDIF Handler + DCD SSI_AC97_Handler ; 16+74: SSI_AC97 Handler + DCD ETH_WKUP_Handler ; 16+75: ETH_WKUP Handler + DCD LPUART_Handler ; 16+76: LPUART Handler + DCD LPTIM_Handler ; 16+77: LPTIM Handler + DCD ETH_SBD_Handler ; 16+78: ETH_SBD Handler + DCD ETH_PERCHTX_Handler ; 16+79: ETH_PERCHTX Handler + DCD ETH_PERCHRX_Handler ; 16+80: ETH_PERCHRX Handler + DCD EPWM1_Handler ; 16+81: EPWM1 Handler + DCD EPWM1_TZ_Handler ; 16+82: EPWM1 TZ Handler + DCD EPWM2_Handler ; 16+83: EPWM2 Handler + DCD EPWM2_TZ_Handler ; 16+84: EPWM2 TZ Handler + DCD EPWM3_Handler ; 16+85: EPWM3 Handler + DCD EPWM3_TZ_Handler ; 16+86: EPWM3 TZ Handler + DCD EPWM4_Handler ; 16+87: EPWM4 Handler + DCD EPWM4_TZ_Handler ; 16+88: EPWM4 TZ Handler + DCD ECAP_Handler ; 16+89: ECAP Handler + DCD EQEP_Handler ; 16+90: EQEP Handler + DCD DLL_CAL_Handler ; 16+91: DLL CAL Handler + DCD COMP1_Handler ; 16+92: COMP1 Handler + DCD COMP2_Handler ; 16+93: COMP2 Handler + DCD COMP3_Handler ; 16+94: COMP3 Handler + DCD COMP4_Handler ; 16+95: COMP4 Handler + DCD COMP5_Handler ; 16+96: COMP5 Handler + DCD COMP6_Handler ; 16+97: COMP6 Handler + DCD ICACHE_Handler ; 16+98: ICACHE Handler + DCD DCACHE_Handler ; 16+99: DCACHE Handler + DCD UART7_Handler ; 16+100: UART7 Handler + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; 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 WWDG_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +WWDG_Handler + B WWDG_Handler + + PUBWEAK PVD_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +PVD_Handler + B PVD_Handler + + PUBWEAK TAMP_STAMP_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +TAMP_STAMP_Handler + B TAMP_STAMP_Handler + + PUBWEAK RTC_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +RTC_Handler + B RTC_Handler + + PUBWEAK FLASH_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +FLASH_Handler + B FLASH_Handler + + PUBWEAK RCC_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +RCC_Handler + B RCC_Handler + + PUBWEAK EXTI0_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI0_Handler + B EXTI0_Handler + + PUBWEAK EXTI1_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI1_Handler + B EXTI1_Handler + + PUBWEAK EXTI2_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI2_Handler + B EXTI2_Handler + + PUBWEAK EXTI3_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI3_Handler + B EXTI3_Handler + + PUBWEAK EXTI4_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI4_Handler + B EXTI4_Handler + + PUBWEAK DMA1_CH0_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_CH0_Handler + B DMA1_CH0_Handler + + PUBWEAK DMA1_CH1_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_CH1_Handler + B DMA1_CH1_Handler + + PUBWEAK DMA1_CH2_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_CH2_Handler + B DMA1_CH2_Handler + + PUBWEAK DMA1_CH3_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_CH3_Handler + B DMA1_CH3_Handler + + PUBWEAK DMA1_CH4_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_CH4_Handler + B DMA1_CH4_Handler + + PUBWEAK DMA1_CH5_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_CH5_Handler + B DMA1_CH5_Handler + + PUBWEAK DMA1_CH6_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_CH6_Handler + B DMA1_CH6_Handler + + PUBWEAK ADC_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +ADC_Handler + B ADC_Handler + + PUBWEAK CAN1_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +CAN1_Handler + B CAN1_Handler + + PUBWEAK CAN2_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +CAN2_Handler + B CAN2_Handler + + PUBWEAK CAN3_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +CAN3_Handler + B CAN3_Handler + + PUBWEAK CAN4_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +CAN4_Handler + B CAN4_Handler + + PUBWEAK EXTI9_5_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI9_5_Handler + B EXTI9_5_Handler + + PUBWEAK TIM1_BRK_TIM9_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM1_BRK_TIM9_Handler + B TIM1_BRK_TIM9_Handler + + PUBWEAK TIM1_UP_TIM1O_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM1_UP_TIM1O_Handler + B TIM1_UP_TIM1O_Handler + + PUBWEAK TIM1_TRG_COM_TIM11_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM1_TRG_COM_TIM11_Handler + B TIM1_TRG_COM_TIM11_Handler + + PUBWEAK TIM1_CC_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM1_CC_Handler + B TIM1_CC_Handler + + PUBWEAK TIM2_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM2_Handler + B TIM2_Handler + + PUBWEAK TIM3_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM3_Handler + B TIM3_Handler + + PUBWEAK TIM4_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM4_Handler + B TIM4_Handler + + PUBWEAK I2C1_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C1_Handler + B I2C1_Handler + + PUBWEAK I2C2_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C2_Handler + B I2C2_Handler + + PUBWEAK QSPI_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +QSPI_Handler + B QSPI_Handler + + PUBWEAK SPI1_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI1_Handler + B SPI1_Handler + + PUBWEAK SPI2_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI2_Handler + B SPI2_Handler + + PUBWEAK USART1_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +USART1_Handler + B USART1_Handler + + PUBWEAK USART2_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +USART2_Handler + B USART2_Handler + + PUBWEAK USART3_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +USART3_Handler + B USART3_Handler + + PUBWEAK EXTI15_10_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI15_10_Handler + B EXTI15_10_Handler + + PUBWEAK RTCAlarm_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +RTCAlarm_Handler + B RTCAlarm_Handler + + PUBWEAK OTG_FS_WKUP_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +OTG_FS_WKUP_Handler + B OTG_FS_WKUP_Handler + + PUBWEAK TIM8_BRK_TIM12_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM8_BRK_TIM12_Handler + B TIM8_BRK_TIM12_Handler + + PUBWEAK TIM8_UP_TIM13_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM8_UP_TIM13_Handler + B TIM8_UP_TIM13_Handler + + PUBWEAK TIM8_TRG_COM_TIM14_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM8_TRG_COM_TIM14_Handler + B TIM8_TRG_COM_TIM14_Handler + + PUBWEAK TIM8_CC_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM8_CC_Handler + B TIM8_CC_Handler + + PUBWEAK DMA1_CH7_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_CH7_Handler + B DMA1_CH7_Handler + + PUBWEAK FMC_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +FMC_Handler + B FMC_Handler + + PUBWEAK SDIO_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +SDIO_Handler + B SDIO_Handler + + PUBWEAK TIM5_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM5_Handler + B TIM5_Handler + + PUBWEAK SPI3_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI3_Handler + B SPI3_Handler + + PUBWEAK UART4_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +UART4_Handler + B UART4_Handler + + PUBWEAK UART5_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +UART5_Handler + B UART5_Handler + + PUBWEAK TIM6_DAC_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM6_DAC_Handler + B TIM6_DAC_Handler + + PUBWEAK TIM7_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM7_Handler + B TIM7_Handler + + PUBWEAK DMA2_CH0_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA2_CH0_Handler + B DMA2_CH0_Handler + + PUBWEAK DMA2_CH1_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA2_CH1_Handler + B DMA2_CH1_Handler + + PUBWEAK DMA2_CH2_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA2_CH2_Handler + B DMA2_CH2_Handler + + PUBWEAK DMA2_CH3_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA2_CH3_Handler + B DMA2_CH3_Handler + + PUBWEAK DMA2_CH4_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA2_CH4_Handler + B DMA2_CH4_Handler + + PUBWEAK OTG_FS_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +OTG_FS_Handler + B OTG_FS_Handler + + PUBWEAK DMA2_CH5_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA2_CH5_Handler + B DMA2_CH5_Handler + + PUBWEAK DMA2_CH6_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA2_CH6_Handler + B DMA2_CH6_Handler + + PUBWEAK DMA2_CH7_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA2_CH7_Handler + B DMA2_CH7_Handler + + PUBWEAK USART6_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +USART6_Handler + B USART6_Handler + + PUBWEAK I2C3_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C3_Handler + B I2C3_Handler + + PUBWEAK OTG_HS_EP1_OUT_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +OTG_HS_EP1_OUT_Handler + B OTG_HS_EP1_OUT_Handler + + PUBWEAK OTG_HS_EP1_IN_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +OTG_HS_EP1_IN_Handler + B OTG_HS_EP1_IN_Handler + + PUBWEAK OTG_HS_WKUP_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +OTG_HS_WKUP_Handler + B OTG_HS_WKUP_Handler + + PUBWEAK OTG_HS_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +OTG_HS_Handler + B OTG_HS_Handler + + PUBWEAK RNG_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +RNG_Handler + B RNG_Handler + + PUBWEAK FPU_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +FPU_Handler + B FPU_Handler + + PUBWEAK CRS_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +CRS_Handler + B CRS_Handler + + PUBWEAK SPDIF_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +SPDIF_Handler + B SPDIF_Handler + + PUBWEAK SSI_AC97_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +SSI_AC97_Handler + B SSI_AC97_Handler + + PUBWEAK ETH_WKUP_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +ETH_WKUP_Handler + B ETH_WKUP_Handler + + PUBWEAK LPUART_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +LPUART_Handler + B LPUART_Handler + + PUBWEAK LPTIM_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +LPTIM_Handler + B LPTIM_Handler + + PUBWEAK ETH_SBD_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +ETH_SBD_Handler + B ETH_SBD_Handler + + PUBWEAK ETH_PERCHTX_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +ETH_PERCHTX_Handler + B ETH_PERCHTX_Handler + + PUBWEAK ETH_PERCHRX_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +ETH_PERCHRX_Handler + B ETH_PERCHRX_Handler + + PUBWEAK EPWM1_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +EPWM1_Handler + B EPWM1_Handler + + PUBWEAK EPWM1_TZ_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +EPWM1_TZ_Handler + B EPWM1_TZ_Handler + + PUBWEAK EPWM2_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +EPWM2_Handler + B EPWM2_Handler + + PUBWEAK EPWM2_TZ_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +EPWM2_TZ_Handler + B EPWM2_TZ_Handler + + PUBWEAK EPWM3_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +EPWM3_Handler + B EPWM3_Handler + + PUBWEAK EPWM3_TZ_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +EPWM3_TZ_Handler + B EPWM3_TZ_Handler + + PUBWEAK EPWM4_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +EPWM4_Handler + B EPWM4_Handler + + PUBWEAK EPWM4_TZ_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +EPWM4_TZ_Handler + B EPWM4_TZ_Handler + + PUBWEAK ECAP_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +ECAP_Handler + B ECAP_Handler + + PUBWEAK EQEP_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +EQEP_Handler + B EQEP_Handler + + PUBWEAK DLL_CAL_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +DLL_CAL_Handler + B DLL_CAL_Handler + + PUBWEAK COMP1_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +COMP1_Handler + B COMP1_Handler + + PUBWEAK COMP2_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +COMP2_Handler + B COMP2_Handler + + PUBWEAK COMP3_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +COMP3_Handler + B COMP3_Handler + + PUBWEAK COMP4_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +COMP4_Handler + B COMP4_Handler + + PUBWEAK COMP5_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +COMP5_Handler + B COMP5_Handler + + PUBWEAK COMP6_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +COMP6_Handler + B COMP6_Handler + + PUBWEAK ICACHE_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +ICACHE_Handler + B ICACHE_Handler + + PUBWEAK DCACHE_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +DCACHE_Handler + B DCACHE_Handler + + PUBWEAK UART7_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +UART7_Handler + B UART7_Handler + + END +;************************ (C) COPYRIGHT Fremontmicro *****END OF FILE***** diff --git a/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/source/system_ft32f4xx.c b/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/source/system_ft32f4xx.c new file mode 100644 index 00000000000..6d2bb8f55fb --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/CMSIS/FT32F4xx/source/system_ft32f4xx.c @@ -0,0 +1,561 @@ +/** + ****************************************************************************** + * @file system_ft32f4xx.h + * @author FMD AE + * @brief CMSIS FT32F4xx Device Peripheral Access Layer Header File. + * @version V1.0.0 + * @data 2025-03-03 + ****************************************************************************** + */ + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup FT32f4xx_system + * @{ + */ + +/** @addtogroup FT32f114xx_System_Private_Includes + * @{ + */ + +#include "ft32f4xx.h" + +/** + * @} + */ + +/** @addtogroup FT32f114xx_System_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +/** @addtogroup FT32F114xx_System_Private_Defines + * @{ + */ + +// #define SYSCLK_FREQ_HSE HSI_VALUE +// #define SYSCLK_FREQ_105MHz 105000000 /* Value of Internal clk in Hz */ +// #define SYSCLK_FREQ_180MHz 180000000 /* Value of Internal clk in Hz */ +#define SYSCLK_FREQ_210MHz 210000000 /* Value of Internal clk in Hz */ +/** + * @} + */ + +/** @addtogroup FT32f114xx_System_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @addtogroup FT32f114xx_System_Private_Variables + * @{ + */ +/******************************************************************************* +* Clock Definitions +*******************************************************************************/ +#ifdef SYSCLK_FREQ_HSE + uint32_t SystemCoreClock = SYSCLK_FREQ_HSE; /*!< System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_105MHz + uint32_t SystemCoreClock = SYSCLK_FREQ_105MHz; /*!< System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_180MHz + uint32_t SystemCoreClock = SYSCLK_FREQ_180MHz; /*!< System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_210MHz + uint32_t SystemCoreClock = SYSCLK_FREQ_210MHz; /*!< System Clock Frequency (Core Clock) */ +#else /*!< HSI Selected as System Clock source */ + uint32_t SystemCoreClock = HSI_VALUE; /*!< System Clock Frequency (Core Clock) */ +#endif +__I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; + +/** + * @} + */ + +/** @addtogroup FT32f114xx_System_Private_FunctionPrototypes + * @{ + */ + +static void SetSysClock(void); + +#ifdef SYSCLK_FREQ_HSE + static void SetSysClockToHSE(void); +#elif defined SYSCLK_FREQ_105MHz + static void SetSysClockTo105(void); +#elif defined SYSCLK_FREQ_180MHz + static void SetSysClockTo180(void); +#elif defined SYSCLK_FREQ_210MHz + static void SetSysClockTo210(void); +#endif +/** + * @} + */ + +/** @addtogroup FT32f114xx_System_Private_Functions + * @{ + */ + +/** + * @brief Setup the microcontroller system. + * Initialize the Embedded Flash Interface, the PLL and update the + * SystemCoreClock variable. + * @param None + * @retval None + */ +void SystemInit(void) +{ +#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + SCB->CPACR |= ((3UL << 10 * 2) | (3UL << 11 * 2)); /* set CP10 and CP11 Full Access */ +#endif + /* Set HSION bit */ + RCC->CR |= (uint32_t)0x00000001; + + /* Reset SW[1:0], HPRE[3:0], PPRE1[2:0], PREE2[2:0] and MCOSEL[2:0] bits */ + RCC->CFGR &= (uint32_t)0x80FFC00C; + + /* Reset HSEON, CSSON , PLLON and PLL2ON bits */ + RCC->CR &= (uint32_t)0xFAF6FFFF; + + /* Reset HSEBYP bit */ + RCC->CR &= (uint32_t)0xFFFBFFFF; + + /* Reset PLLR[2:0], PLLREN, PLLQ[3:0], PLLQEN, PLLP[2:0], + * PLLPEN, PLLSRC, PLLN[7:0], PLLM[4:0] bits */ + RCC->PLLCFGR &= (uint32_t)0xE0008020; + + /* Reset PLL2R[2:0], PLL2REN, PLL2Q[3:0], PLL2QEN, PLL2SRC, PLL2N[7:0] and PLL2M[4:0] bits */ + RCC->PLL2CFGR &= (uint32_t)0xE00F8020; + + /* Reset HSI48ON bit */ + RCC->CR2 &= (uint32_t)0xFFFEFFFF; + + /* Disable all interrupts */ + RCC->CIR = 0x00000000; + + /* Configure the System clock frequency, AHB/APBx prescalers and Flash settings */ + SetSysClock(); + + RCC->APB1ENR |= RCC_APB1ENR_CRSEN; + CRS->CR &= ~(0x3F << 8); + CRS->CR |= (((*(uint32_t*)0x1FFF0A28) & 0x3F) << 8); + RCC->APB1ENR &= ~RCC_APB1ENR_CRSEN; + + RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN | RCC_APB2ENR_ADCEN; + if ((VREFBUF->VREFBUF_CSR & 0x4) == 0x4) //2.5V + { + VREFBUF->VREFBUF_CCR = 0; + VREFBUF->VREFBUF_CCR = ((*(uint32_t*)0x1FFF0A20) & 0x3F00) >> 16; + ADC1->CALFACT = (*(uint32_t*)0x1FFF0A3C); + ADC2->CALFACT = (*(uint32_t*)0x1FFF0A40); + ADC3->CALFACT = (*(uint32_t*)0x1FFF0A44); + } + else // 2.048V + { + VREFBUF->VREFBUF_CCR = 0; + VREFBUF->VREFBUF_CCR = ((*(uint32_t*)0x1FFF0A20) & 0x3F); + ADC1->CALFACT = (*(uint32_t*)0x1FFF0A30); + ADC2->CALFACT = (*(uint32_t*)0x1FFF0A34); + ADC3->CALFACT = (*(uint32_t*)0x1FFF0A38); + } + RCC->APB2ENR &= ~(RCC_APB2ENR_SYSCFGEN | RCC_APB2ENR_ADCEN); +} + +/** + * @brief Update SystemCoreClock according to Clock Register Values + * The SystemCoreClock variable contains the core clock (HCLK), it can + * be used by the user application to setup the SysTick timer or configure + * other parameters. + * + * @note Each time the core clock (HCLK) changes, this function must be called + * to update SystemCoreClock variable value. Otherwise, any configuration + * based on this variable will be incorrect. + * + * @note - The system frequency computed by this function is not the real + * frequency in the chip. It is calculated based on the predefined + * constant and the selected clock source: + * + * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*) + * + * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**) + * + * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**) + * or HSI_VALUE(*) multiplied/divided by the PLL factors. + * + * (*) HSI_VALUE is a constant defined in FT32f4xx.h file (default value + * 8 MHz) but the real value may vary depending on the variations + * in voltage and temperature. + * + * (**) HSE_VALUE is a constant defined in FT32f4xx.h file (default value + * 8 MHz), user has to ensure that HSE_VALUE is same as the real + * frequency of the crystal used. Otherwise, this function may + * have wrong result. + * + * - The result of this function could be not correct when using fractional + * value for HSE crystal. + * @param None + * @retval None + */ +void SystemCoreClockUpdate(void) +{ + uint32_t tmp = 0, pllm = 0, plln = 0, pllp = 0, pllvco = 0, pllsource = 0; + + /* Get SYSCLK source -------------------------------------------------------*/ + tmp = RCC->CFGR & RCC_CFGR_SWS; + + switch (tmp) + { + case 0x00: /* HSI used as system clock */ + SystemCoreClock = HSI_VALUE; + break; + case 0x01: /* HSE used as system clock */ + SystemCoreClock = HSE_VALUE; + break; + case 0x02: /* PLL used as system clock */ + /* PLL_VCO = (HSI_VALUE / PLLM ) * PLLN ---------------------- + * SYSCLK = PLL_VCO / PLLP + * */ + pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM; + plln = (RCC->PLLCFGR & RCC_PLLCFGR_PLLN >> 6); + pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC >> 14); + + if (pllsource == 0) /* HSI uses as PLL clock source */ + { + + pllvco = (HSI_VALUE / pllm); + } + else /* HSE uses as PLL clock source */ + { + pllvco = (HSE_VALUE / pllm); + } + + if (RCC->PLLCFGR & RCC_PLLCFGR_PLLP >> 17) /* PLLP != 0 */ + { + pllp = (RCC->PLLCFGR & RCC_PLLCFGR_PLLP >> 17) + 1U; + } + else /* PLLP == 0 , prescaler is 2 */ + { + pllp = (RCC->PLLCFGR & RCC_PLLCFGR_PLLP >> 17) + 2U; + } + + pllvco = pllvco * plln ; + SystemCoreClock = pllvco / pllp; + break; + default: /* HSI used as system clock */ + SystemCoreClock = HSI_VALUE; + break; + } + /* Compute HCLK clock frequency ----------------*/ + /* Get HCLK prescaler */ + tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)]; + /* HCLK clock frequency */ + SystemCoreClock >>= tmp; +} + + + +/** + * @brief Configures the System clock frequency, HCLK, PCLK prescalers. + * @param None + * @retval None + */ +static void SetSysClock(void) +{ +#ifdef SYSCLK_FREQ_HSE + SetSysClockToHSE(); +#elif defined SYSCLK_FREQ_105MHz + SetSysClockTo105(); +#elif defined SYSCLK_FREQ_180MHz + SetSysClockTo180(); +#elif defined SYSCLK_FREQ_210MHz + SetSysClockTo210(); +#endif + + /* If none of the define above is enabled, the HSI is used as System clock + source (default after reset) */ +} + +#ifdef SYSCLK_FREQ_HSE +/** + * @brief Selects HSE as System clock source and configure HCLK, PCLK + * prescalers. + * @note This function should be used only after reset. + * @param None + * @retval None + */ +static void SetSysClockToHSE(void) +{ + __IO uint32_t StartUpCounter = 0, HSEStatus = 0; + + /* SYSCLK, HCLK, PCLK configuration ----------------------------------------*/ + /* Enable HSE */ + RCC->CR |= ((uint32_t)RCC_CR_HSEON); + + /* Wait till HSE is ready and if Time out is reached exit */ + do + { + HSEStatus = RCC->CR & RCC_CR_HSERDY; + StartUpCounter++; + } + while ((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); + + if ((RCC->CR & RCC_CR_HSERDY) != RESET) + { + HSEStatus = (uint32_t)0x01; + } + else + { + HSEStatus = (uint32_t)0x00; + } + + if (HSEStatus == (uint32_t)0x01) + { + /* Enable Prefetch Buffer and set Flash Latency */ + if (HSE_VALUE <= 30000000) /* clk <= 30MHz ,latancy=0 */ + { + FLASH->RDC = FLASH_ACR_PRFTBE | ((uint32_t)0x00000000); + } + else /* clk > 30MHz ,latancy=1 */ + { + FLASH->RDC = FLASH_ACR_PRFTBE | ((uint32_t)0x00000001); + } + + /* HCLK = SYSCLK */ + RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; + + /* PCLK1 = HCLK/2, PCLK2 = HCLK/2 */ + RCC->CFGR |= (uint32_t)(RCC_CFGR_PPRE1_DIV2 | RCC_CFGR_PPRE2_DIV2); + + /* Select HSE as system clock source */ + RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); + RCC->CFGR |= (uint32_t)RCC_CFGR_SW_HSE; + + /* Wait till HSE is used as system clock source */ + while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)RCC_CFGR_SWS_HSE) + { + } + } + else + { + /* If HSE fails to start-up, the application will have wrong clock + configuration. User can add here some code to deal with this error */ + } +} + +#elif defined SYSCLK_FREQ_105MHz +/** + * @brief Sets System clock frequency to 105MHz and configure HCLK, PCLK + * prescalers. + * @note This function should be used only after reset. + * @param None + * @retval None + */ +static void SetSysClockTo105(void) +{ + __IO uint32_t StartUpCounter = 0, HSIStatus = 0; + + /* SYSCLK, HCLK, PCLK configuration ----------------------------------------*/ + /* Enable HSI */ + RCC->CR |= ((uint32_t)RCC_CR_HSION); + + /* Wait till HSI is ready and if Time out is reached exit */ + do + { + HSIStatus = RCC->CR & RCC_CR_HSIRDY; + StartUpCounter++; + } + while ((HSIStatus == 0) && (StartUpCounter != HSI_STARTUP_TIMEOUT)); + + if ((RCC->CR & RCC_CR_HSIRDY) != RESET) + { + HSIStatus = (uint32_t)0x01; + } + else + { + HSIStatus = (uint32_t)0x00; + } + + if (HSIStatus == (uint32_t)0x01) + { + + RCC->PLLCFGR |= (uint32_t)((105 << 6) | // PLLN=105 + RCC_PLLCFGR_PLLSRC_HSI | // Source : HSI + RCC_PLLCFGR_PLLPEN | // Enable PLLP + (8 << 0)) ; // PLLM=8, PLLPCLK=VCO/8 + /* Enable PLL */ + RCC->CR |= RCC_CR_PLLON; + + /* Wait till PLL is ready */ + while (((RCC->CR) & (uint32_t)RCC_CR_PLLRDY) != (uint32_t)RCC_CR_PLLRDY) //wait PLLRDY + { + } + + /* Enable Prefetch Buffer(default is enable) and set Flash Latency */ + FLASH->RDC |= (uint32_t)(0x3 << 0); + + /* Select PLL as system clock source */ + RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; + + /* Wait till PLL is used as system clock source */ + while (((RCC->CFGR) & (uint32_t)RCC_CFGR_SWS_PLL) != (uint32_t)RCC_CFGR_SWS_PLL) + { + } + } + +} +else +{ + /* If HSE fails to start-up, the application will have wrong clock + configuration. User can add here some code to deal with this error */ +} +} +#elif defined SYSCLK_FREQ_180MHz +/** + * @brief Sets System clock frequency to 180MHz and configure HCLK, PCLK + * prescalers. + * @note This function should be used only after reset. + * @param None + * @retval None + */ +static void SetSysClockTo180(void) +{ + __IO uint32_t StartUpCounter = 0, HSIStatus = 0; + + /* SYSCLK, HCLK, PCLK configuration ----------------------------------------*/ + /* Enable HSI */ + RCC->CR |= ((uint32_t)RCC_CR_HSION); + + /* Wait till HSI is ready and if Time out is reached exit */ + do + { + HSIStatus = RCC->CR & RCC_CR_HSIRDY; + StartUpCounter++; + } + while ((HSIStatus == 0) && (StartUpCounter != HSI_STARTUP_TIMEOUT)); + + if ((RCC->CR & RCC_CR_HSIRDY) != RESET) + { + HSIStatus = (uint32_t)0x01; + } + else + { + HSIStatus = (uint32_t)0x00; + } + + if (HSIStatus == (uint32_t)0x01) + { + + RCC->PLLCFGR |= (uint32_t)((45 << 6) | // PLLN=45 + RCC_PLLCFGR_PLLSRC_HSI | // Source : HSI + RCC_PLLCFGR_PLLPEN | // Enable PLLP + (2 << 0)) ; // PLLM=2, PLLPCLK=VCO/2 + /* Enable PLL */ + RCC->CR |= RCC_CR_PLLON; + + /* Wait till PLL is ready */ + while (((RCC->CR) & (uint32_t)RCC_CR_PLLRDY) != (uint32_t)RCC_CR_PLLRDY) //wait PLLRDY + { + } + + /* Enable Prefetch Buffer(default is enable) and set Flash Latency */ + FLASH->RDC |= (uint32_t)(0x5 << 0); + + /* Select PLL as system clock source */ + RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; + + /* Wait till PLL is used as system clock source */ + while (((RCC->CFGR) & (uint32_t)RCC_CFGR_SWS_PLL) != (uint32_t)RCC_CFGR_SWS_PLL) + { + } + } + + else + { + /* If HSE fails to start-up, the application will have wrong clock + configuration. User can add here some code to deal with this error */ + } +} +#elif defined SYSCLK_FREQ_210MHz +/** + * @brief Sets System clock frequency to 210MHz and configure HCLK, PCLK + * prescalers. + * @note This function should be used only after reset. + * @param None + * @retval None + */ +static void SetSysClockTo210(void) +{ + __IO uint32_t StartUpCounter = 0, HSIStatus = 0; + + /* SYSCLK, HCLK, PCLK configuration ----------------------------------------*/ + /* Enable HSI */ + RCC->CR |= ((uint32_t)RCC_CR_HSION); + + /* Wait till HSI is ready and if Time out is reached exit */ + do + { + HSIStatus = RCC->CR & RCC_CR_HSIRDY; + StartUpCounter++; + } + while ((HSIStatus == 0) && (StartUpCounter != HSI_STARTUP_TIMEOUT)); + + if ((RCC->CR & RCC_CR_HSIRDY) != RESET) + { + HSIStatus = (uint32_t)0x01; + } + else + { + HSIStatus = (uint32_t)0x00; + } + + if (HSIStatus == (uint32_t)0x01) + { + + RCC->PLLCFGR |= (uint32_t)((105 << 6) | // PLLN=105 + RCC_PLLCFGR_PLLSRC_HSI | // Source : HSI + RCC_PLLCFGR_PLLPEN | // Enable PLLP + (4 << 0)) ; // PLLM=4, PLLPCLK=VCO/2 + /* Enable PLL */ + RCC->CR |= RCC_CR_PLLON; + + /* Wait till PLL is ready */ + while (((RCC->CR) & (uint32_t)RCC_CR_PLLRDY) != (uint32_t)RCC_CR_PLLRDY) //wait PLLRDY + { + } + + /* Enable Prefetch Buffer(default is enable) and set Flash Latency */ + FLASH->RDC |= (uint32_t)(0x6 << 0); + + /* Select PLL as system clock source */ + RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; + + /* Wait till PLL is used as system clock source */ + while (((RCC->CFGR) & (uint32_t)RCC_CFGR_SWS_PLL) != (uint32_t)RCC_CFGR_SWS_PLL) + { + } + } + else + { + /* If HSE fails to start-up, the application will have wrong clock + configuration. User can add here some code to deal with this error */ + } +} +#endif + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_adc.h b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_adc.h new file mode 100644 index 00000000000..e48a3c2fbbc --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_adc.h @@ -0,0 +1,1855 @@ +/** + ****************************************************************************** + * @file ft32f4xx_adc.h + * @author FMD AE + * @brief This file contains all the functions prototypes for the ADC firmware + * library + * @version V1.0.0 + * @data 2025-04-08 + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __FT32F4XX_ADC_H +#define __FT32F4XX_ADC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx.h" + +/** @addtogroup ADC + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** + * @brief ADC group regular oversampling structure definition + */ +typedef struct +{ + uint32_t Ratio; /*!< Configures the oversampling ratio. + This parameter can be a value of @ref ADC_OVS_RATIO */ + + uint32_t RightBitShift; /*!< Configures the division coefficient for the Oversampler. + This parameter can be a value of @ref ADC_OVS_SHIFT */ + + uint32_t TriggeredMode; /*!< Selects the regular triggered oversampling mode. + This parameter can be a value of @ref ADC_OVS_DISCONT_MODE */ + + uint32_t OversamplingStopReset; /*!< Selects the regular oversampling mode. + The oversampling is either temporary stopped or reset upon an injected + sequence interruption. + If oversampling is enabled on both regular and injected groups, this + parameter is discarded and forced to setting + "ADC_REGOVERSAMPLING_RESUMED_MODE" (the oversampling buffer is zeroed + during injection sequence). + This parameter can be a value of @ref ADC_OVS_SCOPE_REG */ +} ADC_OversamplingTypeDef; + + + +/** + * @brief ADC group injected oversampling structure definition + */ +typedef struct +{ + uint32_t Ratio; /*!< Configures the oversampling ratio. + This parameter can be a value of @ref ADC_OVS_RATIO */ + + uint32_t RightBitShift; /*!< Configures the division coefficient for the Oversampler. + This parameter can be a value of @ref ADC_OVS_SHIFT */ + +} ADC_InjOversamplingTypeDef; + + +/** + * @brief Structure definition of ADC instance. + * @note Parameters of this structure are shared within 3 scopes: + * - Scope entire ADC (affects ADC groups regular and injected): Resolution, DataAlign, + * GainCompensation, AutoDelayedConvMode. + * - Scope ADC group regular: ContinuousConvMode, NbrOfConversion, ExternalTrigConv, ExternalTrigConvEdge, + * DiscontinuousConvMode, NbrOfDiscConversion, DMAMode, Overrun, OversamplingMode, Oversampling, + * SamplingMode. + * - Scope ADC group injected: InjectedDiscontinuousConvMode, AutoInjectedConv, QueueInjectedContext, + * QueueMode. + */ +typedef struct +{ + uint32_t Resolution; /*!< Selects the resolution of the conversion. + This parameter can be a value of @ref ADC_Resolution */ + + FunctionalState ContinuousConvMode; /*!< Specifies whether the conversion is performed in + Continuous or Single mode. + This parameter can be set to ENABLE or DISABLE. */ + + uint32_t DataAlign; /*!< Specifies whether the ADC data alignment is left or right. + This parameter can be a value of @ref ADC_data_align */ + + uint32_t GainCompensation; /*!< Specify the ADC gain compensation coefficient to be applied to ADC raw conversion + data, based on following formula: + DATA = DATA(raw) * (gain compensation coef) / 4096 + "2.12" bit format, unsigned: 2 bits exponents / 12 bits mantissa + Gain step is 1/4096 = 0.000244 + Gain range is 0.0000 to 3.999756 + This parameter value can be + 0 Gain compensation will be disabled and coefficient set to 0 + 1 -> 0x3FFF Gain compensation will be enabled and coefficient set to specified + value + Note: Gain compensation when enabled is applied to all channels. */ + + uint32_t NbrOfConversion; /*!< Specify the number of ranks that will be converted within the regular group + sequencer. + This parameter must be a number between Min_Data = 1 and Max_Data = 16. + Note: This parameter must be modified when no conversion is on going on regular + group (ADC disabled, or ADC stop conversion). */ + + uint32_t ExternalTrigConvEdge; /*!< Selects the external trigger Edge and enables the + trigger of a regular group. This parameter can be a value + of @ref ADC_regular_external_trigger_edge */ + + uint32_t ExternalTrigConv; /*!< Defines the external trigger used to start the analog + to digital conversion of regular channels. This parameter + can be a value of @ref ADC12_external_trigger_sources + or ADC3_external_trigger_sources */ + + FunctionalState DiscontinuousConvMode; /*!< Specify whether the conversions sequence of ADC group regular is performed + in Complete-sequence/Discontinuous-sequence (main sequence subdivided in + successive parts). + Discontinuous mode is used only if sequencer is enabled. If sequencer + is disabled, this parameter is discarded. + Discontinuous mode can be enabled only if continuous mode is disabled. + If continuous mode is enabled, this parameter setting is discarded. + This parameter can be set to ENABLE or DISABLE. */ + + uint32_t NbrOfDiscConversion; /*!< Specifies the number of discontinuous conversions in which the main sequence + of ADC group regular (parameter NbrOfConversion) will be subdivided. + If parameter 'DiscontinuousConvMode' is disabled, this parameter is discarded. + This parameter must be a number between Min_Data = 1 and Max_Data = 8. */ + + uint32_t DMAMode; /*!< Specify whether the DMA requests are performed in one shot mode (DMA + transfer stops when number of conversions is reached) or in continuous + mode (DMA transfer unlimited, whatever number of conversions). + This parameter can be set to ADC_DMAMODE_ONESHOT or ADC_DMAMODE_CIRCULAR. + Note: In continuous mode, DMA must be configured in circular mode. + Otherwise an overrun will be triggered when DMA buffer maximum + pointer is reached. */ + + FunctionalState AutoDelayedConvMode; /*!< Enables or disables the Wait conversion mode. + When the CPU clock is not fast enough to manage the data rate, a + Hardware delay can be introduced between ADC conversions to reduce + this data rate. + The Hardware delay is inserted after each conversions and until the + previous data is read from the ADC data register + This is a way to automatically adapt the speed of the ADC to the speed + of the system which will read the data. + Any hardware triggers wich occur while a conversion is on going or + while the automatic Delay is applied are ignored + ADCx: where x can be 1/2/3 to select the ADCx peripheral. + NewState: new state of the ADCx Auto-Delay. + This parameter can be: ENABLE or DISABLE. */ + + uint32_t Overrun; /*!< Select the behavior in case of overrun: data overwritten or preserved (default). + This parameter applies to ADC group regular only. + This parameter can be set to ADC_OVR_MODE_PRESERVED or ADC_OVR_MODE_OVERWRITTEN. + Note: In case of overrun set to data preserved and usage with programming model + with interruption (HAL_Start_IT()): ADC IRQ handler has to clear end of + conversion flags, this induces the release of the preserved data. If + needed, this data can be saved in function HAL_ADC_ConvCpltCallback(), + placed in user program code (called before end of conversion flags clear) + Note: Error reporting with respect to the conversion mode: + - Usage with ADC conversion by polling for event or interruption: Error is + reported only if overrun is set to data preserved. If overrun is set to + data overwritten, user can willingly not read all the converted data, + this is not considered as an erroneous case. + - Usage with ADC conversion by DMA: Error is reported whatever overrun + setting (DMA is expected to process all data from data register). */ + + + FunctionalState InjectedDiscontinuousConvMode; /*!< Specifies whether the conversions sequence of ADC group injected + is performed in Complete-sequence/Discontinuous-sequence + (main sequence subdivided in successive parts). + Discontinuous mode can be enabled only if continuous mode is disabled. + This parameter can be set to ENABLE or DISABLE. + Note: This parameter must be modified when ADC is disabled (before ADC + start conversion or after ADC stop conversion). + Note: For injected group, discontinuous mode converts the sequence + channel by channel (discontinuous length fixed to 1 rank). */ + + FunctionalState AutoInjectedConvMode; /*!< Enables or disables the selected ADC group injected automatic conversion + after regular one + This parameter can be set to ENABLE or DISABLE. + Note: To use Automatic injected conversion, discontinuous mode must + be disabled ('DiscontinuousConvMode' and + 'InjectedDiscontinuousConvMode' set to DISABLE) + Note: To use Automatic injected conversion, injected group external + triggers must be disabled ('ExternalTrigInjecConv' set to + ADC_INJECTED_SOFTWARE_START) */ + + FunctionalState QueueInjectedContext; /*!< Specifies whether the context queue feature is enabled. + This parameter can be set to ENABLE or DISABLE. + If context queue is enabled, injected sequencer&channels configurations + are queued on up to 2 contexts. If a new injected context is set when + queue is full, error is triggered by interruption. + Note: This parameter must be modified when ADC is disabled (before ADC + start conversion or after ADC stop conversion). */ + + FunctionalState QueueMode; /*!< Specifies how an empty Queue is managed. + This parameter can be set to JSQR mode 0 or JSQR mode 1. + JSQR mode 0 : The Queue is never empty and maintains the last written + configuration into JSQR. + JSQR mode 1 : The Queue can be empty and when this occurs, the software + and hardware triggers of the injected sequence are both + internally disabled just after the completion of the last + valid injected sequence. + Note: The software is allowed to write this bit only when JADSTART=0 + (which ensures that no injected conversion is ongoing). + When dual mode is enabled (Dual bits in ADC_Common->CCR register + are not equal to zero), the bit JQM of the slave ADC is no more + writable and its content is equal to the bit JQM of the master + ADC. */ + + uint32_t SamplingMode; /*!< Select the sampling mode to be used for ADC group regular conversion. + This parameter can be a value of @ref ADC_regular_sampling_mode */ + + uint32_t SamplingPlusTime; /*!< Addition of one clock cycle to the sampling time value to be set + for the ADC_SMPRx registers. + This parameter can be a value of @ref ADC_sampling_plus_times + Unit: ADC clock cycles. + Minimum sampling clock period, can select 1.5, 2.5, 3.5 or 4.5 clock cycles. + Note: To make sure no conversion is ongoing, the software is allowed + to write this bit only when this bit only when ADSTART=0 and + JADSTART=0 */ + + FunctionalState OversamplingMode; /*!< Specifies whether the oversampling feature is enabled or disabled. + This parameter can be set to ENABLE or DISABLE. + Note: This parameter can be modified only if there is no + conversion is ongoing (both ADSTART and JADSTART cleared). */ + + ADC_OversamplingTypeDef Oversampling; /*!< Specify the Oversampling parameters. + Caution: this setting overwrites the previous oversampling configuration + if oversampling is already enabled. + Note: This parameter can be modified only if there is no + conversion is ongoing (both ADSTART and JADSTART cleared).*/ + +} ADC_InitTypeDef; + + +/** + * @brief ADC group regular Channel Init structure definition + */ +typedef struct +{ + uint32_t Channel; /*!< Specify the channel to configure into ADC regular group. + This parameter can be a value of @ref ADC_channels + Note: Depending on devices and ADC instances, some channels may not be available + on device package pins. Refer to device datasheet for channels + availability. */ + + uint32_t Rank; /*!< Specify the rank in the regular group sequencer. + This parameter can be a value of @ref ADC_reg_seq_ranks + Note: to disable a channel or change order of conversion sequencer, rank + containing a previous channel setting can be overwritten by the new channel + setting (or parameter number of conversions adjusted) */ + + uint32_t SamplingTime; /*!< Sampling time value to be set for the selected channel. + Unit: ADC clock cycles + Conversion time is the addition of sampling time and processing time + This parameter can be a value of @ref ADC_sampling_times + Caution: This parameter applies to a channel that can be used into regular + and/or injected group. It overwrites the last setting. + Note: In case of usage of internal measurement channels (VrefInt, Vbat, ...), + sampling time constraints must be respected (sampling time can be adjusted + in function of ADC clock frequency and sampling time setting). + Refer to device datasheet for timings values. */ + + uint32_t SingleDiff; /*!< Select single-ended or differential input. + In differential mode: Differential measurement is carried out between the + selected channel 'i' (positive input) and channel 'i+1' (negative input). + Only channel 'i' has to be configured, channel 'i+1' is configured automatically + This parameter must be a value of @ref ADC_channel_single_diff_ending + Caution: This parameter applies to a channel that can be used in a regular + and/or injected group. + It overwrites the last setting. + Note: Refer to Reference Manual to ensure the selected channel is available in + differential mode. + Note: When configuring a channel 'i' in differential mode, the channel 'i+1' is + not usable separately. + Note: This parameter must be modified when ADC is disabled (before ADC start + conversion or after ADC stop conversion). + If ADC is enabled, this parameter setting is bypassed without error + reporting (as it can be the expected behavior in case of another parameter + update on the fly) */ + + uint32_t OffsetNumber; /*!< Select the offset number + This parameter can be a value of @ref ADC_offset_number + Caution: Only one offset is allowed per channel. This parameter overwrites the + last setting. */ + + uint32_t Offset; /*!< Define the offset to be applied on the raw converted data. + Offset value must be a positive number. + Depending of ADC resolution selected (12, 10, 8 or 6 bits), this parameter + must be a number between Min_Data = 0x000 and Max_Data = 0xFFF, + 0x3FF, 0xFF or 0x3F respectively. + Note: This parameter must be modified when no conversion is on going on both + regular and injected groups (ADC disabled, or ADC enabled without + continuous mode or external trigger that could launch a conversion). */ + + uint32_t OffsetSign; /*!< Define if the offset should be subtracted (negative sign) or added (positive + sign) from or to the raw converted data. + This parameter can be a value of @ref ADC_OffsetSign. + Note: This parameter must be modified when no conversion is on going on both + regular and injected groups (ADC disabled, or ADC enabled without + continuous mode or external trigger that could launch a conversion).*/ + + FunctionalState OffsetSaturation;/*!< Define if the offset should be saturated upon under or over flow. + This parameter value can be ENABLE or DISABLE. + Note: This parameter must be modified when no conversion is on going on both + regular and injected groups (ADC disabled, or ADC enabled without + continuous mode or external trigger that could launch a conversion). */ + +} ADC_ChannelConfTypeDef; + + +/** + * @brief ADC group injected Init structure definition + */ +typedef struct +{ + + uint32_t InjectedNbrOfConversion; /*!< Specifies the number of ranks that will be converted within the ADC group + injected sequencer. + To use the injected group sequencer and convert several ranks, parameter + 'ScanConvMode' must be enabled. + This parameter must be a number between Min_Data = 1 and Max_Data = 4. */ + + uint32_t InjectedChannel; /*!< Specifies the channel to configure into ADC group injected. + This parameter can be a value of @ref ADC_channels + Note: Depending on devices and ADC instances, some channels may not be + available on device package pins. Refer to device datasheet for + channels availability. */ + + uint32_t InjectedRank; /*!< Specifies the rank in the ADC group injected sequencer. + This parameter must be a value of @ref ADC_injected_seq_ranks. + Note: to disable a channel or change order of conversion sequencer, + rank containing a previous channel setting can be overwritten by + the new channel setting (or parameter number of conversions + adjusted) */ + + uint32_t ExternalTrigInjecConvEdge; /*!< Selects the external trigger edge of injected group. + This parameter can be a value of @ref ADC_injected_external_trigger_edge. + If trigger source is set to ADC_INJECTED_SOFTWARE_START, this parameter + is discarded. */ + + uint32_t ExternalTrigInjecConv; /*!< Selects the external event used to trigger the conversion start of + injected group. + If set to ADC_INJECTED_SOFTWARE_START, external triggers are disabled + and software trigger is used instead. + This parameter can be a value of @ref ADC12_injected_external_trigger_sources or + ADC3_injected_external_trigger_sources. */ + + + + FunctionalState InjectedOversamplingMode; /*!< Specifies whether the oversampling feature is enabled or disabled. + This parameter can be set to ENABLE or DISABLE. + Note: This parameter can be modified only if there is no + conversion is ongoing (both ADSTART and JADSTART cleared). */ + + ADC_InjOversamplingTypeDef InjectedOversampling; /*!< Specifies the Oversampling parameters. + Caution: this setting overwrites the previous oversampling + configuration if oversampling already enabled. + Note: This parameter can be modified only if there is no + conversion is ongoing (both ADSTART and JADSTART cleared).*/ + + uint32_t InjectedSamplingTime; /*!< Sampling time value to be set for the selected channel. + Unit: ADC clock cycles. + Conversion time is the addition of sampling time and processing time + (12.5 ADC clock cycles at ADC resolution 12 bits, 10.5 cycles at 10 bits, + 8.5 cycles at 8 bits, 6.5 cycles at 6 bits). + This parameter can be a value of @ref ADC_sampling_times. + Caution: This parameter applies to a channel that can be used in a + regular and/or injected group. It overwrites the last setting. + Note: In case of usage of internal measurement channels (VrefInt, ...), + sampling time constraints must be respected (sampling time can be + adjusted in function of ADC clock frequency and sampling time + setting). Refer to device datasheet for timings values. */ + + uint32_t InjectedSingleDiff; /*!< Selection of single-ended or differential input. + In differential mode: Differential measurement is between the selected + channel 'i' (positive input) and channel 'i+1' (negative input). + Only channel 'i' has to be configured, channel 'i+1' is configured + automatically. + This parameter must be a value of + @ref ADC_channel_single_diff_ending. + Caution: This parameter applies to a channel that can be used in a + regular and/or injected group. It overwrites the last setting. + Note: Refer to Reference Manual to ensure the selected channel is + available in differential mode. + Note: When configuring a channel 'i' in differential mode, the channel + 'i+1' is not usable separately. + Note: This parameter must be modified when ADC is disabled (before ADC + start conversion or after ADC stop conversion). + If ADC is enabled, this parameter setting is bypassed without error + reporting (as it can be the expected behavior in case of another + parameter update on the fly) */ + + uint32_t InjectedOffsetNumber; /*!< Selects the offset number. + This parameter can be a value of @ref ADC_offset_number. + Caution: Only one offset is allowed per channel. This parameter + overwrites the last setting. */ + + uint32_t InjectedOffset; /*!< Defines the offset to be applied on the raw converted data. + Offset value must be a positive number. + Depending of ADC resolution selected (12, 10, 8 or 6 bits), this + parameter must be a number between Min_Data = 0x000 and Max_Data = 0xFFF, + 0x3FF, 0xFF or 0x3F respectively. + Note: This parameter must be modified when no conversion is on going + on both regular and injected groups (ADC disabled, or ADC enabled + without continuous mode or external trigger that could launch a + conversion). */ + + uint32_t InjectedOffsetSign; /*!< Define if the offset should be subtracted (negative sign) or added + (positive sign) from or to the raw converted data. + This parameter can be a value of @ref ADCEx_OffsetSign. + Note: This parameter must be modified when no conversion is on going + on both regular and injected groups (ADC disabled, or ADC + enabled without continuous mode or external trigger that could + launch a conversion). */ + + FunctionalState InjectedOffsetSaturation; /*!< Define if the offset should be saturated upon under or over flow. + This parameter value can be ENABLE or DISABLE. + Note: This parameter must be modified when no conversion is on going + on both regular and injected groups (ADC disabled, or ADC enabled + without continuous mode or external trigger that could launch a + conversion). */ +} ADC_InjectedConfTypeDef; + + +/** + * @brief Structure definition of ADC analog watchdog + * @note The setting of these parameters by function ADC_AnalogWDGConfig() is conditioned to ADC state. + * ADC state can be either: + * - For all parameters except 'HighThreshold', 'LowThreshold': ADC disabled or ADC enabled without conversion + on going on ADC groups regular and injected. + * - For parameters 'HighThreshold', 'LowThreshold': ADC enabled with conversion on going on regular and + injected groups. + */ +typedef struct +{ + uint32_t WatchdogNumber; /*!< Select which ADC analog watchdog is monitoring the selected channel. + For Analog Watchdog 1: Only 1 channel can be monitored (or overall group of channels + by setting parameter 'WatchdogMode') + For Analog Watchdog 2 and 3: Several channels can be monitored (by successive calls + of 'ADC_AnalogWDGConfig()' for each channel) + This parameter can be a value of @ref ADCx_AnalogWatchdog_X_Selection. */ + + uint32_t WatchdogMode; /*!< Configure the ADC analog watchdog mode: single/all/none channels. + For Analog Watchdog 1: Configure the ADC analog watchdog mode: single channel or all + channels, ADC groups regular and-or injected. + For Analog Watchdog 2 and 3: No need to configure the ADC analog watchdog mode. + This parameter can be a value of @ref ADCx_AnalogWatchdog_1_Channel_Mode_Selection. */ + + uint32_t Channel; /*!< Select which ADC channel to monitor by analog watchdog. + For Analog Watchdog 1: this parameter has an effect only if parameter 'WatchdogMode' + is configured on single channel (only 1 channel can be + monitored). + This parameter can be a value of @ref ADC_channels for Analog Watchdog 1. + For Analog Watchdog 2 and 3: Several channels can be monitored. To use this feature, + call successively the function ADC_AnalogWDGConfig() + for each channel to be added (or removed with value + 'ADC_ANALOGWATCHDOG_NONE'). + This parameter can be a value of @ref ADCx_AnalogWatchdog_2_3_Channel_Selection + for Analog Watchdog 2 and 3. */ + + FunctionalState ITMode; /*!< Specify whether the analog watchdog is configured in interrupt or polling mode. + This parameter can be set to ENABLE or DISABLE */ + + uint32_t HighThreshold; /*!< Configure the ADC analog watchdog High threshold value. + Depending of ADC resolution selected (12, 10, 8 or 6 bits). For Analog watchdog 1, this parameter must be a + number between Min_Data = 0x000 and Max_Data = 0xFFF, 0x3FF, 0xFF or 0x3F + respectively. For Analog watchdog 2 and 3, this parameter must be a + number between Min_Data = 0x00 and Max_Data = 0xFF. + Note: Analog watchdog 2 and 3 are limited to a resolution of 8 bits: if ADC + resolution is 12 bits the 4 LSB are ignored, if ADC resolution is 10 bits the 2 + LSB are ignored. + Note: If ADC oversampling is enabled, ADC analog watchdog thresholds are + impacted: the comparison of analog watchdog thresholds is done on + oversampling final computation (after ratio and shift application): + ADC data register bitfield [11:4] (12 most significant bits). */ + + uint32_t LowThreshold; /*!< Configures the ADC analog watchdog Low threshold value. + Depending of ADC resolution selected (12, 10, 8 or 6 bits). For Analog watchdog 1, this parameter must be a + number between Min_Data = 0x000 and Max_Data = 0xFFF, 0x3FF, 0xFF or 0x3F + respectively. For Analog watchdog 2 and 3, this parameter must be a + number between Min_Data = 0x00 and Max_Data = 0xFF. + Note: Analog watchdog 2 and 3 are limited to a resolution of 8 bits: if ADC + resolution is 12 bits the 4 LSB are ignored, if ADC resolution is 10 bits the 2 + LSB are ignored. + Note: If ADC oversampling is enabled, ADC analog watchdog thresholds are + impacted: the comparison of analog watchdog thresholds is done on + oversampling final computation (after ratio and shift application): + ADC data register bitfield [11:4] (12 most significant bits).*/ + + uint32_t FilteringConfig; /*!< Specify whether filtering should be use and the number of samples to consider. + Before setting flag or raising interrupt, analog watchdog can wait to have several + consecutive out-of-window samples. This parameter allows to configure this number. + This parameter only applies to Analog watchdog 1. For others, use value + ADC_AWD_FILTERING_NONE. + This parameter can be a value of @ref ADC_analog_watchdog_filtering_config. */ +} ADC_AnalogWDGConfTypeDef; + + + +/** + * @brief Structure definition of ADC multimode + * @note The setting of these parameters by function ADCx_MultiModeConfigChannel() is conditioned by ADCs state + * (both Master and Slave ADCs). + * Both Master and Slave ADCs must be disabled. + */ +typedef struct +{ + uint32_t Mode; /*!< Configures the ADC to operate in independent or multimode. + This parameter can be a value of @ref ADC_MULTI_MODE. */ + + uint32_t DMAAccessMode; /*!< Configures the DMA mode for multimode ADC: + selection whether 2 DMA channels (each ADC uses its own DMA channel) or 1 DMA channel + (one DMA channel for both ADC, DMA of ADC master). + This parameter can be a value of @ref ADC_MULTI_DMA_TRANSFER_RESOLUTION. */ + + uint32_t DMAMode; /*!< Specify whether the DMA requests are performed in one shot mode (DMA + transfer stops when number of conversions is reached) or in continuous + mode (DMA transfer unlimited, whatever number of conversions). + This parameter can be a value of @ref ADC_MULTI_DMA_MODE. + Note: In continuous mode, DMA must be configured in circular mode. + Otherwise an overrun will be triggered when DMA buffer maximum + pointer is reached. */ + + uint32_t TwoSamplingDelay; /*!< Configures the Delay between 2 sampling phases. + This parameter can be a value of @ref ADC_MULTI_TWOSMP_DELAY. + Delay range from 1 to 16 clock cycles */ +} ADC_MultiModeTypeDef; + + + + + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup ADC_Exported_Constants + * @{ + */ +#define IS_ADC_ALL_PERIPH(PERIPH) (((PERIPH) == ADC1) || \ + ((PERIPH) == ADC2) || \ + ((PERIPH) == ADC3)) +/** + * @} + */ + +/** @defgroup ADC_ClockMode - ClockPreScaler + * @{ + */ +#define ADC_CLOCK_SYNC_HCLK_DIV1 (uint32_t)ADC_CCR_CKMODE_0 /*!< Synchronous clock mode no divided */ +#define ADC_CLOCK_SYNC_HCLK_DIV2 (uint32_t)ADC_CCR_CKMODE_1 /*!< Synchronous clock mode divided by 2 */ +#define ADC_CLOCK_SYNC_HCLK_DIV4 (uint32_t)ADC_CCR_CKMODE /*!< Synchronous clock mode divided by 4 */ + +#define ADC_CLOCK_ASYNC_DIV1 (uint32_t)0x00000000 /*!< ADC asynchronous clock without prescaler */ +#define ADC_CLOCK_ASYNC_DIV2 ((uint32_t)ADC_CCR_PRESC_0) /*!< ADC asynchronous clock with prescaler division by 2 */ +#define ADC_CLOCK_ASYNC_DIV4 ((uint32_t)ADC_CCR_PRESC_1) /*!< ADC asynchronous clock with prescaler division by 4 */ +#define ADC_CLOCK_ASYNC_DIV6 ((uint32_t)(ADC_CCR_PRESC_0|ADC_CCR_PRESC_1)) /*!< ADC asynchronous clock with prescaler division by 6 */ +#define ADC_CLOCK_ASYNC_DIV8 ((uint32_t)ADC_CCR_PRESC_2) /*!< ADC asynchronous clock with prescaler division by 8 */ +#define ADC_CLOCK_ASYNC_DIV10 ((uint32_t)(ADC_CCR_PRESC_0|ADC_CCR_PRESC_2)) /*!< ADC asynchronous clock with prescaler division by 10 */ +#define ADC_CLOCK_ASYNC_DIV12 ((uint32_t)(ADC_CCR_PRESC_1|ADC_CCR_PRESC_2)) /*!< ADC asynchronous clock with prescaler division by 12 */ +#define ADC_CLOCK_ASYNC_DIV16 ((uint32_t)(ADC_CCR_PRESC_0|ADC_CCR_PRESC_1|ADC_CCR_PRESC_2)) /*!< ADC asynchronous clock with prescaler division by 16 */ +#define ADC_CLOCK_ASYNC_DIV32 ((uint32_t)ADC_CCR_PRESC_3) /*!< ADC asynchronous clock with prescaler division by 32 */ +#define ADC_CLOCK_ASYNC_DIV64 ((uint32_t)(ADC_CCR_PRESC_0|ADC_CCR_PRESC_3)) /*!< ADC asynchronous clock with prescaler division by 64 */ +#define ADC_CLOCK_ASYNC_DIV128 ((uint32_t)(ADC_CCR_PRESC_1|ADC_CCR_PRESC_3)) /*!< ADC asynchronous clock with prescaler division by 128 */ +#define ADC_CLOCK_ASYNC_DIV256 ((uint32_t)(ADC_CCR_PRESC_0|ADC_CCR_PRESC_1|ADC_CCR_PRESC_3)) /*!< ADC asynchronous clock with prescaler division by 256 */ + +#define IS_ADC_CLOCKPRESCALER(ADC_CLOCK) (((ADC_CLOCK) == ADC_CLOCK_SYNC_HCLK_DIV1 ) ||\ + ((ADC_CLOCK) == ADC_CLOCK_SYNC_HCLK_DIV2 ) ||\ + ((ADC_CLOCK) == ADC_CLOCK_SYNC_HCLK_DIV4 ) ||\ + ((ADC_CLOCK) == ADC_CLOCK_ASYNC_DIV1 ) ||\ + ((ADC_CLOCK) == ADC_CLOCK_ASYNC_DIV2 ) ||\ + ((ADC_CLOCK) == ADC_CLOCK_ASYNC_DIV4 ) ||\ + ((ADC_CLOCK) == ADC_CLOCK_ASYNC_DIV6 ) ||\ + ((ADC_CLOCK) == ADC_CLOCK_ASYNC_DIV8 ) ||\ + ((ADC_CLOCK) == ADC_CLOCK_ASYNC_DIV10 ) ||\ + ((ADC_CLOCK) == ADC_CLOCK_ASYNC_DIV16 ) ||\ + ((ADC_CLOCK) == ADC_CLOCK_ASYNC_DIV32 ) ||\ + ((ADC_CLOCK) == ADC_CLOCK_ASYNC_DIV64 ) ||\ + ((ADC_CLOCK) == ADC_CLOCK_ASYNC_DIV128 ) ||\ + ((ADC_CLOCK) == ADC_CLOCK_ASYNC_DIV256 ) ) +/** + * @} + */ + +/** @defgroup ADC_Resolution + * @{ + */ +#define ADC_RESOLUTION_6B ((uint32_t)0x00000000) /*!< ADC resolution 6 bits */ +#define ADC_RESOLUTION_8B ADC_CFGR1_RES_0 /*!< ADC resolution 8 bits */ +#define ADC_RESOLUTION_10B ADC_CFGR1_RES_1 /*!< ADC resolution 10 bits */ +#define ADC_RESOLUTION_12B ADC_CFGR1_RES /*!< ADC resolution 12 bits */ + +#define IS_ADC_RESOLUTION(RESOLUTION) (((RESOLUTION) == ADC_RESOLUTION_12B) || \ + ((RESOLUTION) == ADC_RESOLUTION_10B) || \ + ((RESOLUTION) == ADC_RESOLUTION_8B) || \ + ((RESOLUTION) == ADC_RESOLUTION_6B)) +/** + * @} + */ + +/** @defgroup ADC_data_align ADC conversion data alignment + * @{ + */ +#define ADC_DATAALIGN_RIGHT (uint32_t)0x00000000 /*!< ADC conversion data alignment: right aligned + (alignment on data register LSB bit 0)*/ +#define ADC_DATAALIGN_LEFT ADC_CFGR1_ALIGN /*!< ADC conversion data alignment: left aligned + (alignment on data register MSB bit 15)*/ + +#define IS_ADC_DATA_ALIGN(ALIGN) (((ALIGN) == ADC_DATAALIGN_RIGHT) || \ + ((ALIGN) == ADC_DATAALIGN_LEFT)) +/** + * @} + */ + +/** @efgroup ADC_regular_external_trigger_edge ADC group regular trigger edge (when external trigger is selected) + * @{ + */ +#define ADC_SOFTWARE_START ((uint32_t)0x00000000) /*!< ADC group regular trigger + disabled (SW start)*/ +#define ADC_EXTERNALTRIGCONVEDGE_RISING ADC_CFGR1_EXTEN_0 /*!< ADC group regular conversion + trigger polarity set to rising edge */ +#define ADC_EXTERNALTRIGCONVEDGE_FALLING ADC_CFGR1_EXTEN_1 /*!< ADC group regular conversion + trigger polarity set to falling edge */ +#define ADC_EXTERNALTRIGCONVEDGE_RISINGFALLING ADC_CFGR1_EXTEN /*!< ADC group regular conversion + trigger polarity set to both rising and falling edges */ + +#define IS_ADC_EXT_TRIG_EDGE(EDGE) (((EDGE) == ADC_SOFTWARE_START ) || \ + ((EDGE) == ADC_EXTERNALTRIGCONVEDGE_RISING ) || \ + ((EDGE) == ADC_EXTERNALTRIGCONVEDGE_FALLING ) || \ + ((EDGE) == ADC_EXTERNALTRIGCONVEDGE_RISINGFALLING)) +/** + * @} + */ + +/** @defgroup ADC_injected_external_trigger_edge ADC group injected trigger edge (when external trigger is selected) + * @{ + */ +#define ADC_INJECTED_SOFTWARE_START ((uint32_t)0x00000000)/*!< Injected conversions trigger + disabled (SW start)*/ +#define ADC_EXTERNALTRIGINJECCONVEDGE_RISING (ADC_JSQR_JEXTEN_0) /*!< Injected conversions trigger + polarity set to rising edge */ +#define ADC_EXTERNALTRIGINJECCONVEDGE_FALLING (ADC_JSQR_JEXTEN_1) /*!< Injected conversions trigger + polarity set to falling edge */ +#define ADC_EXTERNALTRIGINJECCONVEDGE_RISINGFALLING (ADC_JSQR_JEXTEN) /*!< Injected conversions trigger + polarity set to both rising and falling edges */ + +#define IS_ADC_EXTTRIG_INJEC_EDGE(EDGE) (((EDGE) == ADC_INJECTED_SOFTWARE_START ) || \ + ((EDGE) == ADC_EXTERNALTRIGINJECCONVEDGE_RISING ) || \ + ((EDGE) == ADC_EXTERNALTRIGINJECCONVEDGE_FALLING) || \ + ((EDGE) == ADC_EXTERNALTRIGINJECCONVEDGE_RISINGFALLING)) +/** + * @} + */ + +/** @defgroup ADC12_external_trigger_sources for ADC1/2 regular channels conversion + * @{ + */ +#define ADC12_EXTERNALTRIG_TIM1_CC1 ((uint32_t)0x00000000) +#define ADC12_EXTERNALTRIG_TIM1_CC2 ((uint32_t)ADC_CFGR1_EXTSEL_0) +#define ADC12_EXTERNALTRIG_TIM1_CC3 ((uint32_t)ADC_CFGR1_EXTSEL_1) +#define ADC12_EXTERNALTRIG_TIM2_CC2 ((uint32_t)(ADC_CFGR1_EXTSEL_0|ADC_CFGR1_EXTSEL_1)) +#define ADC12_EXTERNALTRIG_TIM3_TRGO ((uint32_t)ADC_CFGR1_EXTSEL_2) +#define ADC12_EXTERNALTRIG_TIM4_CC4 ((uint32_t)(ADC_CFGR1_EXTSEL_0|ADC_CFGR1_EXTSEL_2)) +#define ADC12_EXTERNALTRIG_TIM8_TRGO ((uint32_t)(ADC_CFGR1_EXTSEL_1|ADC_CFGR1_EXTSEL_2)) +#define ADC12_EXTERNALTRIG_TIM8_TRGO2 ((uint32_t)(ADC_CFGR1_EXTSEL_0|ADC_CFGR1_EXTSEL_1|ADC_CFGR1_EXTSEL_2)) +#define ADC12_EXTERNALTRIG_TIM1_TRGO ((uint32_t)ADC_CFGR1_EXTSEL_3) +#define ADC12_EXTERNALTRIG_TIM1_TRGO2 ((uint32_t)(ADC_CFGR1_EXTSEL_0|ADC_CFGR1_EXTSEL_3)) +#define ADC12_EXTERNALTRIG_TIM2_TRGO ((uint32_t)(ADC_CFGR1_EXTSEL_1|ADC_CFGR1_EXTSEL_3)) +#define ADC12_EXTERNALTRIG_TIM4_TRGO ((uint32_t)(ADC_CFGR1_EXTSEL_0|ADC_CFGR1_EXTSEL_1|ADC_CFGR1_EXTSEL_3)) +#define ADC12_EXTERNALTRIG_TIM6_TRGO ((uint32_t)(ADC_CFGR1_EXTSEL_2|ADC_CFGR1_EXTSEL_3)) +#define ADC12_EXTERNALTRIG_TIM3_CC4 ((uint32_t)(ADC_CFGR1_EXTSEL_0|ADC_CFGR1_EXTSEL_2|ADC_CFGR1_EXTSEL_3)) +#define ADC12_EXTERNALTRIG_EPWM1_SOCA ((uint32_t)(ADC_CFGR1_EXTSEL_1|ADC_CFGR1_EXTSEL_2|ADC_CFGR1_EXTSEL_3)) +#define ADC12_EXTERNALTRIG_EPWM2_SOCA ((uint32_t)(ADC_CFGR1_EXTSEL_0|ADC_CFGR1_EXTSEL_1|ADC_CFGR1_EXTSEL_2|ADC_CFGR1_EXTSEL_3)) +#define ADC12_EXTERNALTRIG_EPWM3_SOCA ((uint32_t)ADC_CFGR1_EXTSEL_4) +#define ADC12_EXTERNALTRIG_EPWM3_SOCB ((uint32_t)(ADC_CFGR1_EXTSEL_0|ADC_CFGR1_EXTSEL_4)) +#define ADC12_EXTERNALTRIG_EPWM4_SOCA ((uint32_t)(ADC_CFGR1_EXTSEL_1|ADC_CFGR1_EXTSEL_4)) +#define ADC12_EXTERNALTRIG_EPWM4_SOCB ((uint32_t)(ADC_CFGR1_EXTSEL_0|ADC_CFGR1_EXTSEL_1|ADC_CFGR1_EXTSEL_4)) +#define ADC12_EXTERNALTRIG_LPTIM_OUT ((uint32_t)(ADC_CFGR1_EXTSEL_2|ADC_CFGR1_EXTSEL_4)) +#define ADC12_EXTERNALTRIG_TIM7_TRGO ((uint32_t)(ADC_CFGR1_EXTSEL_0|ADC_CFGR1_EXTSEL_2|ADC_CFGR1_EXTSEL_4)) +#define ADC12_EXTERNALTRIG_EXTI11 ((uint32_t)(ADC_CFGR1_EXTSEL_1|ADC_CFGR1_EXTSEL_2|ADC_CFGR1_EXTSEL_4)) + +#define IS_ADC12_REGULAR_EXTTRIG_SOURCE(SOURCE) (((SOURCE) == ADC12_EXTERNALTRIG_TIM1_CC1 ) ||\ + ((SOURCE) == ADC12_EXTERNALTRIG_TIM1_CC2 ) ||\ + ((SOURCE) == ADC12_EXTERNALTRIG_TIM1_CC3 ) ||\ + ((SOURCE) == ADC12_EXTERNALTRIG_TIM2_CC2 ) ||\ + ((SOURCE) == ADC12_EXTERNALTRIG_TIM3_TRGO ) ||\ + ((SOURCE) == ADC12_EXTERNALTRIG_TIM4_CC4 ) ||\ + ((SOURCE) == ADC12_EXTERNALTRIG_TIM8_TRGO ) ||\ + ((SOURCE) == ADC12_EXTERNALTRIG_TIM8_TRGO2 ) ||\ + ((SOURCE) == ADC12_EXTERNALTRIG_TIM1_TRGO ) ||\ + ((SOURCE) == ADC12_EXTERNALTRIG_TIM1_TRGO2 ) ||\ + ((SOURCE) == ADC12_EXTERNALTRIG_TIM2_TRGO ) ||\ + ((SOURCE) == ADC12_EXTERNALTRIG_TIM4_TRGO ) ||\ + ((SOURCE) == ADC12_EXTERNALTRIG_TIM6_TRGO ) ||\ + ((SOURCE) == ADC12_EXTERNALTRIG_TIM3_CC4 ) ||\ + ((SOURCE) == ADC12_EXTERNALTRIG_EPWM1_SOCA ) ||\ + ((SOURCE) == ADC12_EXTERNALTRIG_EPWM2_SOCA ) ||\ + ((SOURCE) == ADC12_EXTERNALTRIG_EPWM3_SOCA ) ||\ + ((SOURCE) == ADC12_EXTERNALTRIG_EPWM3_SOCB ) ||\ + ((SOURCE) == ADC12_EXTERNALTRIG_EPWM4_SOCA ) ||\ + ((SOURCE) == ADC12_EXTERNALTRIG_EPWM4_SOCB ) ||\ + ((SOURCE) == ADC12_EXTERNALTRIG_LPTIM_OUT ) ||\ + ((SOURCE) == ADC12_EXTERNALTRIG_TIM7_TRGO ) ||\ + ((SOURCE) == ADC12_EXTERNALTRIG_EXTI11 ) ) +/** + * @} + */ + +/** @defgroup ADC3_external_trigger_sources for ADC3 regular channels conversion + * @{ + */ +#define ADC3_EXTERNALTRIG_TIM3_CC1 ((uint32_t)0x00000000) +#define ADC3_EXTERNALTRIG_TIM2_CC3 ((uint32_t)ADC_CFGR1_EXTSEL_0) +#define ADC3_EXTERNALTRIG_TIM1_CC3 ((uint32_t)ADC_CFGR1_EXTSEL_1) +#define ADC3_EXTERNALTRIG_TIM8_CC1 ((uint32_t)(ADC_CFGR1_EXTSEL_0|ADC_CFGR1_EXTSEL_1)) +#define ADC3_EXTERNALTRIG_TIM3_TRGO ((uint32_t)ADC_CFGR1_EXTSEL_2) +#define ADC3_EXTERNALTRIG_TIM4_CC1 ((uint32_t)(ADC_CFGR1_EXTSEL_0|ADC_CFGR1_EXTSEL_2)) +#define ADC3_EXTERNALTRIG_TIM8_TRGO ((uint32_t)(ADC_CFGR1_EXTSEL_1|ADC_CFGR1_EXTSEL_2)) +#define ADC3_EXTERNALTRIG_TIM8_TRGO2 ((uint32_t)(ADC_CFGR1_EXTSEL_0|ADC_CFGR1_EXTSEL_1|ADC_CFGR1_EXTSEL_2)) +#define ADC3_EXTERNALTRIG_TIM1_TRGO ((uint32_t)ADC_CFGR1_EXTSEL_3) +#define ADC3_EXTERNALTRIG_TIM1_TRGO2 ((uint32_t)(ADC_CFGR1_EXTSEL_0|ADC_CFGR1_EXTSEL_3)) +#define ADC3_EXTERNALTRIG_TIM2_TRGO ((uint32_t)(ADC_CFGR1_EXTSEL_1|ADC_CFGR1_EXTSEL_3)) +#define ADC3_EXTERNALTRIG_TIM4_TRGO ((uint32_t)(ADC_CFGR1_EXTSEL_0|ADC_CFGR1_EXTSEL_1|ADC_CFGR1_EXTSEL_3)) +#define ADC3_EXTERNALTRIG_TIM6_TRGO ((uint32_t)(ADC_CFGR1_EXTSEL_2|ADC_CFGR1_EXTSEL_3)) +#define ADC3_EXTERNALTRIG_TIM2_CC1 ((uint32_t)(ADC_CFGR1_EXTSEL_0|ADC_CFGR1_EXTSEL_2|ADC_CFGR1_EXTSEL_3)) +#define ADC3_EXTERNALTRIG_EPWM1_SOCB ((uint32_t)(ADC_CFGR1_EXTSEL_1|ADC_CFGR1_EXTSEL_2|ADC_CFGR1_EXTSEL_3)) +#define ADC3_EXTERNALTRIG_EPWM2_SOCB ((uint32_t)(ADC_CFGR1_EXTSEL_0|ADC_CFGR1_EXTSEL_1|ADC_CFGR1_EXTSEL_2|ADC_CFGR1_EXTSEL_3)) +#define ADC3_EXTERNALTRIG_EPWM1_SOCA ((uint32_t)ADC_CFGR1_EXTSEL_4) +#define ADC3_EXTERNALTRIG_EPWM2_SOCA ((uint32_t)(ADC_CFGR1_EXTSEL_0|ADC_CFGR1_EXTSEL_4)) +#define ADC3_EXTERNALTRIG_EPWM3_SOCA ((uint32_t)(ADC_CFGR1_EXTSEL_1|ADC_CFGR1_EXTSEL_4)) +#define ADC3_EXTERNALTRIG_EPWM3_SOCB ((uint32_t)(ADC_CFGR1_EXTSEL_0|ADC_CFGR1_EXTSEL_1|ADC_CFGR1_EXTSEL_4)) +#define ADC3_EXTERNALTRIG_EPWM4_SOCA ((uint32_t)(ADC_CFGR1_EXTSEL_2|ADC_CFGR1_EXTSEL_4)) +#define ADC3_EXTERNALTRIG_EPWM4_SOCB ((uint32_t)(ADC_CFGR1_EXTSEL_0|ADC_CFGR1_EXTSEL_2|ADC_CFGR1_EXTSEL_4)) +#define ADC3_EXTERNALTRIG_LPTIM_OUT ((uint32_t)(ADC_CFGR1_EXTSEL_1|ADC_CFGR1_EXTSEL_2|ADC_CFGR1_EXTSEL_4)) +#define ADC3_EXTERNALTRIG_TIM7_TRGO ((uint32_t)(ADC_CFGR1_EXTSEL_0|ADC_CFGR1_EXTSEL_1|ADC_CFGR1_EXTSEL_2|ADC_CFGR1_EXTSEL_4)) +#define ADC3_EXTERNALTRIG_EXTI2 ((uint32_t)(ADC_CFGR1_EXTSEL_3|ADC_CFGR1_EXTSEL_4)) + +#define IS_ADC3_REGULAR_EXTTRIG_SOURCE(SOURCE) (((SOURCE) == ADC3_EXTERNALTRIG_TIM3_CC1 ) ||\ + ((SOURCE) == ADC3_EXTERNALTRIG_TIM2_CC3 ) ||\ + ((SOURCE) == ADC3_EXTERNALTRIG_TIM1_CC3 ) ||\ + ((SOURCE) == ADC3_EXTERNALTRIG_TIM8_CC1 ) ||\ + ((SOURCE) == ADC3_EXTERNALTRIG_TIM3_TRGO ) ||\ + ((SOURCE) == ADC3_EXTERNALTRIG_TIM4_CC1 ) ||\ + ((SOURCE) == ADC3_EXTERNALTRIG_TIM8_TRGO ) ||\ + ((SOURCE) == ADC3_EXTERNALTRIG_TIM8_TRGO2 ) ||\ + ((SOURCE) == ADC3_EXTERNALTRIG_TIM1_TRGO ) ||\ + ((SOURCE) == ADC3_EXTERNALTRIG_TIM1_TRGO2 ) ||\ + ((SOURCE) == ADC3_EXTERNALTRIG_TIM2_TRGO ) ||\ + ((SOURCE) == ADC3_EXTERNALTRIG_TIM4_TRGO ) ||\ + ((SOURCE) == ADC3_EXTERNALTRIG_TIM6_TRGO ) ||\ + ((SOURCE) == ADC3_EXTERNALTRIG_TIM2_CC1 ) ||\ + ((SOURCE) == ADC3_EXTERNALTRIG_EPWM1_SOCB ) ||\ + ((SOURCE) == ADC3_EXTERNALTRIG_EPWM2_SOCB ) ||\ + ((SOURCE) == ADC3_EXTERNALTRIG_EPWM1_SOCA ) ||\ + ((SOURCE) == ADC3_EXTERNALTRIG_EPWM2_SOCA ) ||\ + ((SOURCE) == ADC3_EXTERNALTRIG_EPWM3_SOCA ) ||\ + ((SOURCE) == ADC3_EXTERNALTRIG_EPWM3_SOCB ) ||\ + ((SOURCE) == ADC3_EXTERNALTRIG_EPWM4_SOCA ) ||\ + ((SOURCE) == ADC3_EXTERNALTRIG_EPWM4_SOCB ) ||\ + ((SOURCE) == ADC3_EXTERNALTRIG_LPTIM_OUT ) ||\ + ((SOURCE) == ADC3_EXTERNALTRIG_TIM7_TRGO ) ||\ + ((SOURCE) == ADC3_EXTERNALTRIG_EXTI2 ) ) +/** + * @} + */ + + +#define IS_ADC_REGULAR_EXTTRIG_SOURCE(ADCx, SOURCE) ((((ADCx == ADC1) || (ADCx == ADC2)) && IS_ADC12_REGULAR_EXTTRIG_SOURCE(SOURCE)) || \ + ((ADCx == ADC3) && IS_ADC3_REGULAR_EXTTRIG_SOURCE(SOURCE))) + + + + +/** @defgroup ADC12_injected_external_trigger_sources for ADC1/2 injected channels conversion + * @{ + */ +#define ADC12_EXTERNALTRIG_INJ_TIM1_CC1 ((uint32_t)0x00000000) +#define ADC12_EXTERNALTRIG_INJ_TIM1_CC4 ((uint32_t)ADC_JSQR_JEXTSEL_0) +#define ADC12_EXTERNALTRIG_INJ_TIM2_TRGO ((uint32_t)ADC_JSQR_JEXTSEL_1) +#define ADC12_EXTERNALTRIG_INJ_TIM2_CC1 ((uint32_t)(ADC_JSQR_JEXTSEL_0|ADC_JSQR_JEXTSEL_1)) +#define ADC12_EXTERNALTRIG_INJ_TIM3_CC4 ((uint32_t)ADC_JSQR_JEXTSEL_2) +#define ADC12_EXTERNALTRIG_INJ_TIM4_TRGO ((uint32_t)(ADC_JSQR_JEXTSEL_0|ADC_JSQR_JEXTSEL_2)) +#define ADC12_EXTERNALTRIG_INJ_TIM8_CC4 ((uint32_t)(ADC_JSQR_JEXTSEL_1|ADC_JSQR_JEXTSEL_2)) +#define ADC12_EXTERNALTRIG_INJ_TIM1_TRGO2 ((uint32_t)(ADC_JSQR_JEXTSEL_0|ADC_JSQR_JEXTSEL_1|ADC_JSQR_JEXTSEL_2)) +#define ADC12_EXTERNALTRIG_INJ_TIM8_TRGO ((uint32_t)ADC_JSQR_JEXTSEL_3) +#define ADC12_EXTERNALTRIG_INJ_TIM8_TRGO2 ((uint32_t)(ADC_JSQR_JEXTSEL_0|ADC_JSQR_JEXTSEL_3)) +#define ADC12_EXTERNALTRIG_INJ_TIM3_CC3 ((uint32_t)(ADC_JSQR_JEXTSEL_1|ADC_JSQR_JEXTSEL_3)) +#define ADC12_EXTERNALTRIG_INJ_TIM3_TRGO ((uint32_t)(ADC_JSQR_JEXTSEL_0|ADC_JSQR_JEXTSEL_1|ADC_JSQR_JEXTSEL_3)) +#define ADC12_EXTERNALTRIG_INJ_TIM3_CC1 ((uint32_t)(ADC_JSQR_JEXTSEL_2|ADC_JSQR_JEXTSEL_3)) +#define ADC12_EXTERNALTRIG_INJ_TIM6_TRGO ((uint32_t)(ADC_JSQR_JEXTSEL_0|ADC_JSQR_JEXTSEL_2|ADC_JSQR_JEXTSEL_3)) +#define ADC12_EXTERNALTRIG_INJ_EPWM1_SOCB ((uint32_t)(ADC_JSQR_JEXTSEL_1|ADC_JSQR_JEXTSEL_2|ADC_JSQR_JEXTSEL_3)) +#define ADC12_EXTERNALTRIG_INJ_EPWM2_SOCB ((uint32_t)(ADC_JSQR_JEXTSEL_0|ADC_JSQR_JEXTSEL_1|ADC_JSQR_JEXTSEL_2|ADC_JSQR_JEXTSEL_3)) +#define ADC12_EXTERNALTRIG_INJ_EPWM3_SOCA ((uint32_t)ADC_JSQR_JEXTSEL_4) +#define ADC12_EXTERNALTRIG_INJ_EPWM3_SOCB ((uint32_t)(ADC_JSQR_JEXTSEL_0|ADC_JSQR_JEXTSEL_4)) +#define ADC12_EXTERNALTRIG_INJ_EPWM4_SOCA ((uint32_t)(ADC_JSQR_JEXTSEL_1|ADC_JSQR_JEXTSEL_4)) +#define ADC12_EXTERNALTRIG_INJ_EPWM4_SOCB ((uint32_t)(ADC_JSQR_JEXTSEL_0|ADC_JSQR_JEXTSEL_1|ADC_JSQR_JEXTSEL_4)) +#define ADC12_EXTERNALTRIG_INJ_LPTIM_OUT ((uint32_t)(ADC_JSQR_JEXTSEL_2|ADC_JSQR_JEXTSEL_4)) +#define ADC12_EXTERNALTRIG_INJ_TIM7_TRGO ((uint32_t)(ADC_JSQR_JEXTSEL_0|ADC_JSQR_JEXTSEL_2|ADC_JSQR_JEXTSEL_4)) +#define ADC12_EXTERNALTRIG_INJ_EXTI15 ((uint32_t)(ADC_JSQR_JEXTSEL_1|ADC_JSQR_JEXTSEL_2|ADC_JSQR_JEXTSEL_4)) + +#define IS_ADC12_INJECTED_EXTTRIG_SOURCE(SOURCE) (((SOURCE) == ADC12_EXTERNALTRIG_INJ_TIM1_CC1 ) ||\ + ((SOURCE) == ADC12_EXTERNALTRIG_INJ_TIM1_CC4 ) ||\ + ((SOURCE) == ADC12_EXTERNALTRIG_INJ_TIM2_TRGO ) ||\ + ((SOURCE) == ADC12_EXTERNALTRIG_INJ_TIM2_CC1 ) ||\ + ((SOURCE) == ADC12_EXTERNALTRIG_INJ_TIM3_CC4 ) ||\ + ((SOURCE) == ADC12_EXTERNALTRIG_INJ_TIM4_TRGO ) ||\ + ((SOURCE) == ADC12_EXTERNALTRIG_INJ_TIM8_CC4 ) ||\ + ((SOURCE) == ADC12_EXTERNALTRIG_INJ_TIM1_TRGO2 ) ||\ + ((SOURCE) == ADC12_EXTERNALTRIG_INJ_TIM8_TRGO ) ||\ + ((SOURCE) == ADC12_EXTERNALTRIG_INJ_TIM8_TRGO2 ) ||\ + ((SOURCE) == ADC12_EXTERNALTRIG_INJ_TIM3_CC3 ) ||\ + ((SOURCE) == ADC12_EXTERNALTRIG_INJ_TIM3_TRGO ) ||\ + ((SOURCE) == ADC12_EXTERNALTRIG_INJ_TIM3_CC1 ) ||\ + ((SOURCE) == ADC12_EXTERNALTRIG_INJ_TIM6_TRGO ) ||\ + ((SOURCE) == ADC12_EXTERNALTRIG_INJ_EPWM1_SOCB ) ||\ + ((SOURCE) == ADC12_EXTERNALTRIG_INJ_EPWM2_SOCB ) ||\ + ((SOURCE) == ADC12_EXTERNALTRIG_INJ_EPWM3_SOCA ) ||\ + ((SOURCE) == ADC12_EXTERNALTRIG_INJ_EPWM3_SOCB ) ||\ + ((SOURCE) == ADC12_EXTERNALTRIG_INJ_EPWM4_SOCA ) ||\ + ((SOURCE) == ADC12_EXTERNALTRIG_INJ_EPWM4_SOCB ) ||\ + ((SOURCE) == ADC12_EXTERNALTRIG_INJ_LPTIM_OUT ) ||\ + ((SOURCE) == ADC12_EXTERNALTRIG_INJ_TIM7_TRGO ) ||\ + ((SOURCE) == ADC12_EXTERNALTRIG_INJ_EXTI15 ) ) +/** + * @} + */ + +/** @defgroup ADC3_injected_external_trigger_sources for ADC3 injected channels conversion + * @{ + */ +#define ADC3_EXTERNALTRIG_INJ_TIM1_TRGO ((uint32_t)0x00000000) +#define ADC3_EXTERNALTRIG_INJ_TIM1_CC4 ((uint32_t)ADC_JSQR_JEXTSEL_0) +#define ADC3_EXTERNALTRIG_INJ_TIM2_TRGO ((uint32_t)ADC_JSQR_JEXTSEL_1) +#define ADC3_EXTERNALTRIG_INJ_TIM8_CC2 ((uint32_t)(ADC_JSQR_JEXTSEL_0|ADC_JSQR_JEXTSEL_1)) +#define ADC3_EXTERNALTRIG_INJ_TIM4_CC3 ((uint32_t)ADC_JSQR_JEXTSEL_2) +#define ADC3_EXTERNALTRIG_INJ_TIM4_TRGO ((uint32_t)(ADC_JSQR_JEXTSEL_0|ADC_JSQR_JEXTSEL_2)) +#define ADC3_EXTERNALTRIG_INJ_TIM4_CC4 ((uint32_t)(ADC_JSQR_JEXTSEL_1|ADC_JSQR_JEXTSEL_2)) +#define ADC3_EXTERNALTRIG_INJ_TIM8_CC4 ((uint32_t)(ADC_JSQR_JEXTSEL_0|ADC_JSQR_JEXTSEL_1|ADC_JSQR_JEXTSEL_2)) +#define ADC3_EXTERNALTRIG_INJ_TIM1_TRGO2 ((uint32_t)ADC_JSQR_JEXTSEL_3) +#define ADC3_EXTERNALTRIG_INJ_TIM8_TRGO ((uint32_t)(ADC_JSQR_JEXTSEL_0|ADC_JSQR_JEXTSEL_3)) +#define ADC3_EXTERNALTRIG_INJ_TIM8_TRGO2 ((uint32_t)(ADC_JSQR_JEXTSEL_1|ADC_JSQR_JEXTSEL_3)) +#define ADC3_EXTERNALTRIG_INJ_TIM1_CC3 ((uint32_t)(ADC_JSQR_JEXTSEL_0|ADC_JSQR_JEXTSEL_1|ADC_JSQR_JEXTSEL_3)) +#define ADC3_EXTERNALTRIG_INJ_TIM3_TRGO ((uint32_t)(ADC_JSQR_JEXTSEL_2|ADC_JSQR_JEXTSEL_3)) +#define ADC3_EXTERNALTRIG_INJ_TIM6_TRGO ((uint32_t)(ADC_JSQR_JEXTSEL_0|ADC_JSQR_JEXTSEL_2|ADC_JSQR_JEXTSEL_3)) +#define ADC3_EXTERNALTRIG_INJ_EPWM1_SOCB ((uint32_t)(ADC_JSQR_JEXTSEL_1|ADC_JSQR_JEXTSEL_2|ADC_JSQR_JEXTSEL_3)) +#define ADC3_EXTERNALTRIG_INJ_EPWM2_SOCB ((uint32_t)(ADC_JSQR_JEXTSEL_0|ADC_JSQR_JEXTSEL_1|ADC_JSQR_JEXTSEL_2|ADC_JSQR_JEXTSEL_3)) +#define ADC3_EXTERNALTRIG_INJ_EPWM3_SOCA ((uint32_t)ADC_JSQR_JEXTSEL_4) +#define ADC3_EXTERNALTRIG_INJ_EPWM3_SOCB ((uint32_t)(ADC_JSQR_JEXTSEL_0|ADC_JSQR_JEXTSEL_4)) +#define ADC3_EXTERNALTRIG_INJ_EPWM4_SOCA ((uint32_t)(ADC_JSQR_JEXTSEL_1|ADC_JSQR_JEXTSEL_4)) +#define ADC3_EXTERNALTRIG_INJ_EPWM4_SOCB ((uint32_t)(ADC_JSQR_JEXTSEL_0|ADC_JSQR_JEXTSEL_1|ADC_JSQR_JEXTSEL_4)) +#define ADC3_EXTERNALTRIG_INJ_EPWM1_SOCA ((uint32_t)(ADC_JSQR_JEXTSEL_2|ADC_JSQR_JEXTSEL_4)) +#define ADC3_EXTERNALTRIG_INJ_EPWM2_SOCA ((uint32_t)(ADC_JSQR_JEXTSEL_0|ADC_JSQR_JEXTSEL_2|ADC_JSQR_JEXTSEL_4)) +#define ADC3_EXTERNALTRIG_INJ_LPTIM_OUT ((uint32_t)(ADC_JSQR_JEXTSEL_1|ADC_JSQR_JEXTSEL_2|ADC_JSQR_JEXTSEL_4)) +#define ADC3_EXTERNALTRIG_INJ_TIM7_TRGO ((uint32_t)(ADC_JSQR_JEXTSEL_0|ADC_JSQR_JEXTSEL_1|ADC_JSQR_JEXTSEL_2|ADC_JSQR_JEXTSEL_4)) +#define ADC3_EXTERNALTRIG_INJ_EXTI3 ((uint32_t)(ADC_JSQR_JEXTSEL_3|ADC_JSQR_JEXTSEL_4)) + +#define IS_ADC3_INJECTED_EXTTRIG_SOURCE(SOURCE) (((SOURCE) == ADC3_EXTERNALTRIG_INJ_TIM1_TRGO ) ||\ + ((SOURCE) == ADC3_EXTERNALTRIG_INJ_TIM1_CC4 ) ||\ + ((SOURCE) == ADC3_EXTERNALTRIG_INJ_TIM2_TRGO ) ||\ + ((SOURCE) == ADC3_EXTERNALTRIG_INJ_TIM8_CC2 ) ||\ + ((SOURCE) == ADC3_EXTERNALTRIG_INJ_TIM4_CC3 ) ||\ + ((SOURCE) == ADC3_EXTERNALTRIG_INJ_TIM4_TRGO ) ||\ + ((SOURCE) == ADC3_EXTERNALTRIG_INJ_TIM4_CC4 ) ||\ + ((SOURCE) == ADC3_EXTERNALTRIG_INJ_TIM8_CC4 ) ||\ + ((SOURCE) == ADC3_EXTERNALTRIG_INJ_TIM1_TRGO2 ) ||\ + ((SOURCE) == ADC3_EXTERNALTRIG_INJ_TIM8_TRGO ) ||\ + ((SOURCE) == ADC3_EXTERNALTRIG_INJ_TIM8_TRGO2 ) ||\ + ((SOURCE) == ADC3_EXTERNALTRIG_INJ_TIM1_CC3 ) ||\ + ((SOURCE) == ADC3_EXTERNALTRIG_INJ_TIM3_TRGO ) ||\ + ((SOURCE) == ADC3_EXTERNALTRIG_INJ_TIM6_TRGO ) ||\ + ((SOURCE) == ADC3_EXTERNALTRIG_INJ_EPWM1_SOCB ) ||\ + ((SOURCE) == ADC3_EXTERNALTRIG_INJ_EPWM2_SOCB ) ||\ + ((SOURCE) == ADC3_EXTERNALTRIG_INJ_EPWM3_SOCA ) ||\ + ((SOURCE) == ADC3_EXTERNALTRIG_INJ_EPWM3_SOCB ) ||\ + ((SOURCE) == ADC3_EXTERNALTRIG_INJ_EPWM4_SOCA ) ||\ + ((SOURCE) == ADC3_EXTERNALTRIG_INJ_EPWM4_SOCB ) ||\ + ((SOURCE) == ADC3_EXTERNALTRIG_INJ_EPWM1_SOCA ) ||\ + ((SOURCE) == ADC3_EXTERNALTRIG_INJ_EPWM2_SOCA ) ||\ + ((SOURCE) == ADC3_EXTERNALTRIG_INJ_LPTIM_OUT ) ||\ + ((SOURCE) == ADC3_EXTERNALTRIG_INJ_TIM7_TRGO ) ||\ + ((SOURCE) == ADC3_EXTERNALTRIG_INJ_EXTI3 ) ) +/** + * @} + */ + +#define IS_ADC_INJECTED_EXTTRIG_SOURCE(ADCx, SOURCE) ((((ADCx == ADC1) || (ADCx == ADC2)) && IS_ADC12_INJECTED_EXTTRIG_SOURCE(SOURCE)) || \ + ((ADCx == ADC3) && IS_ADC3_INJECTED_EXTTRIG_SOURCE(SOURCE))) + + + + +/** @defgroup ADC_DMA_Mode + * @{ + */ + +#define ADC_DMAMODE_ONESHOT ((uint32_t)0x00000000) +#define ADC_DMAMODE_CIRCULAR ADC_CFGR1_DMACFG + +#define IS_ADC_DMA_MODE(MODE) (((MODE) == ADC_DMAMODE_ONESHOT) || \ + ((MODE) == ADC_DMAMODE_CIRCULAR)) +/** + * @} + */ + + +/** @defgroup ADCx_AnalogWatchdog_X_Selection + * @{ + */ +#define ADC_ANALOGWATCHDOG_1 ((uint32_t)0x00000001) +#define ADC_ANALOGWATCHDOG_2 ((uint32_t)0x00000002) +#define ADC_ANALOGWATCHDOG_3 ((uint32_t)0x00000004) + +#define IS_ADC_ANALOG_WATCHDOG_NUMBER(NUMBER) (((NUMBER) == ADC_ANALOGWATCHDOG_1) ||\ + ((NUMBER) == ADC_ANALOGWATCHDOG_2) ||\ + ((NUMBER) == ADC_ANALOGWATCHDOG_3)) + + +/** + * @} + */ + +/** @defgroup ADCx_AnalogWatchdog_1_Channel_Mode_Selection + * @{ + */ +#define ADC_ANALOGWATCHDOG_NONE ((uint32_t)0x00000000) +/*!< ADC AWD not selected */ + +#define ADC_ANALOGWATCHDOG_SINGLE_REG ((uint32_t)(ADC_CFGR1_AWD1SGL|ADC_CFGR1_AWD1EN)) +/*!< ADC AWD applied to a regular group single channel */ + +#define ADC_ANALOGWATCHDOG_SINGLE_INJEC ((uint32_t)(ADC_CFGR1_AWD1SGL|ADC_CFGR1_JAWD1EN)) +/*!< ADC AWD applied to an injected group single channel */ + +#define ADC_ANALOGWATCHDOG_SINGLE_REGINJEC ((uint32_t)(ADC_CFGR1_AWD1SGL|ADC_CFGR1_AWD1EN|ADC_CFGR1_JAWD1EN)) +/*!< ADC AWD applied to a regular and injected groups single channel */ + +#define ADC_ANALOGWATCHDOG_ALL_REG ((uint32_t)ADC_CFGR1_AWD1EN) +/*!< ADC AWD applied to regular group all channels */ + +#define ADC_ANALOGWATCHDOG_ALL_INJEC ((uint32_t)ADC_CFGR1_JAWD1EN) +/*!< ADC AWD applied to injected group all channels */ + +#define ADC_ANALOGWATCHDOG_ALL_REGINJEC ((uint32_t)(ADC_CFGR1_AWD1EN|ADC_CFGR1_JAWD1EN)) +/*!< ADC AWD applied to regular and injected groups all channels */ + + +#define IS_ADC_ANALOG_WATCHDOG_1_MODE(MODE) (((MODE) == ADC_ANALOGWATCHDOG_NONE) ||\ + ((MODE) == ADC_ANALOGWATCHDOG_SINGLE_REG) ||\ + ((MODE) == ADC_ANALOGWATCHDOG_SINGLE_INJEC) ||\ + ((MODE) == ADC_ANALOGWATCHDOG_SINGLE_REGINJEC) ||\ + ((MODE) == ADC_ANALOGWATCHDOG_ALL_REG) ||\ + ((MODE) == ADC_ANALOGWATCHDOG_ALL_INJEC) ||\ + ((MODE) == ADC_ANALOGWATCHDOG_ALL_REGINJEC)) +/** + * @} + */ + +/** @defgroup ADCx_AnalogWatchdog_2_3_Channel_Selection + * @{ + */ +#define ADC_ANALOGWATCHDOG23_CHANNEL_0 ADC_AWD2CR_AWD2CH_0 +#define ADC_ANALOGWATCHDOG23_CHANNEL_1 ADC_AWD2CR_AWD2CH_1 +#define ADC_ANALOGWATCHDOG23_CHANNEL_2 ADC_AWD2CR_AWD2CH_2 +#define ADC_ANALOGWATCHDOG23_CHANNEL_3 ADC_AWD2CR_AWD2CH_3 +#define ADC_ANALOGWATCHDOG23_CHANNEL_4 ADC_AWD2CR_AWD2CH_4 +#define ADC_ANALOGWATCHDOG23_CHANNEL_5 ADC_AWD2CR_AWD2CH_5 +#define ADC_ANALOGWATCHDOG23_CHANNEL_6 ADC_AWD2CR_AWD2CH_6 +#define ADC_ANALOGWATCHDOG23_CHANNEL_7 ADC_AWD2CR_AWD2CH_7 +#define ADC_ANALOGWATCHDOG23_CHANNEL_8 ADC_AWD2CR_AWD2CH_8 +#define ADC_ANALOGWATCHDOG23_CHANNEL_9 ADC_AWD2CR_AWD2CH_9 +#define ADC_ANALOGWATCHDOG23_CHANNEL_10 ADC_AWD2CR_AWD2CH_10 +#define ADC_ANALOGWATCHDOG23_CHANNEL_11 ADC_AWD2CR_AWD2CH_11 +#define ADC_ANALOGWATCHDOG23_CHANNEL_12 ADC_AWD2CR_AWD2CH_12 +#define ADC_ANALOGWATCHDOG23_CHANNEL_13 ADC_AWD2CR_AWD2CH_13 +#define ADC_ANALOGWATCHDOG23_CHANNEL_14 ADC_AWD2CR_AWD2CH_14 +#define ADC_ANALOGWATCHDOG23_CHANNEL_15 ADC_AWD2CR_AWD2CH_15 +#define ADC_ANALOGWATCHDOG23_CHANNEL_16 ADC_AWD2CR_AWD2CH_17 +#define ADC_ANALOGWATCHDOG23_CHANNEL_18 ADC_AWD2CR_AWD2CH_18 + + +#define IS_ADC_ANALOGWATCHDOG23_CHANNEL_SEL(CHANNEL) (((CHANNEL) == ADC_AnalogWatchdog23_Channel_0) || \ + ((CHANNEL) == ADC_AnalogWatchdog23_Channel_1) || \ + ((CHANNEL) == ADC_AnalogWatchdog23_Channel_2) || \ + ((CHANNEL) == ADC_AnalogWatchdog23_Channel_3) || \ + ((CHANNEL) == ADC_AnalogWatchdog23_Channel_4) || \ + ((CHANNEL) == ADC_AnalogWatchdog23_Channel_5) || \ + ((CHANNEL) == ADC_AnalogWatchdog23_Channel_6) || \ + ((CHANNEL) == ADC_AnalogWatchdog23_Channel_7) || \ + ((CHANNEL) == ADC_AnalogWatchdog23_Channel_8) || \ + ((CHANNEL) == ADC_AnalogWatchdog23_Channel_9) || \ + ((CHANNEL) == ADC_AnalogWatchdog23_Channel_10) || \ + ((CHANNEL) == ADC_AnalogWatchdog23_Channel_11) || \ + ((CHANNEL) == ADC_AnalogWatchdog23_Channel_12) || \ + ((CHANNEL) == ADC_AnalogWatchdog23_Channel_13) || \ + ((CHANNEL) == ADC_AnalogWatchdog23_Channel_14) || \ + ((CHANNEL) == ADC_AnalogWatchdog23_Channel_15) || \ + ((CHANNEL) == ADC_AnalogWatchdog23_Channel_16) || \ + ((CHANNEL) == ADC_AnalogWatchdog23_Channel_17) || \ + ((CHANNEL) == ADC_AnalogWatchdog23_Channel_18)) +/** + * @} + */ + +/** @defgroup ADC_analog_watchdog_filtering_config ADC analog watchdog (AWD) filtering configuration + * @{ + */ +#define ADC_AWD_FILTERING_NONE (0x00000000UL) /*!< ADC AWD no filtering, one + out-of-window sample to raise flag or interrupt */ +#define ADC_AWD_FILTERING_2SAMPLES ((ADC_TR1_AWDFILT_0)) /*!< ADC AWD 2 consecutives + out-of-window samples to raise flag or interrupt */ +#define ADC_AWD_FILTERING_3SAMPLES ((ADC_TR1_AWDFILT_1)) /*!< ADC AWD 3 consecutives + out-of-window samples to raise flag or interrupt */ +#define ADC_AWD_FILTERING_4SAMPLES ((ADC_TR1_AWDFILT_1 | ADC_TR1_AWDFILT_0)) /*!< ADC AWD 4 consecutives + out-of-window samples to raise flag or interrupt */ +#define ADC_AWD_FILTERING_5SAMPLES ((ADC_TR1_AWDFILT_2)) /*!< ADC AWD 5 consecutives + out-of-window samples to raise flag or interrupt */ +#define ADC_AWD_FILTERING_6SAMPLES ((ADC_TR1_AWDFILT_2 | ADC_TR1_AWDFILT_0)) /*!< ADC AWD 6 consecutives + out-of-window samples to raise flag or interrupt */ +#define ADC_AWD_FILTERING_7SAMPLES ((ADC_TR1_AWDFILT_2 | ADC_TR1_AWDFILT_1)) /*!< ADC AWD 7 consecutives + out-of-window samples to raise flag or interrupt */ +#define ADC_AWD_FILTERING_8SAMPLES ((ADC_TR1_AWDFILT_2 | ADC_TR1_AWDFILT_1 |\ + ADC_TR1_AWDFILT_0)) /*!< ADC AWD 8 consecutives + out-of-window samples to raise flag or interrupt */ + +#define IS_ADC_ANALOG_WATCHDOG_FILTERING_MODE(FILTERING) (((FILTERING) == ADC_AWD_FILTERING_NONE) ||\ + ((FILTERING) == ADC_AWD_FILTERING_2SAMPLES) ||\ + ((FILTERING) == ADC_AWD_FILTERING_3SAMPLES) ||\ + ((FILTERING) == ADC_AWD_FILTERING_4SAMPLES) ||\ + ((FILTERING) == ADC_AWD_FILTERING_5SAMPLES) ||\ + ((FILTERING) == ADC_AWD_FILTERING_6SAMPLES) ||\ + ((FILTERING) == ADC_AWD_FILTERING_7SAMPLES) ||\ + ((FILTERING) == ADC_AWD_FILTERING_8SAMPLES) ) +/** + * @} + */ + +/** @defgroup ADC_sampling_plus_times + * @{ + */ +#define ADC_SAMPLETIMEPLUS_1_5CYCLES ((uint32_t)0x00000000) +#define ADC_SAMPLETIMEPLUS_2_5CYCLES ((uint32_t)ADC_SMPR1_SMPLUS_0) +#define ADC_SAMPLETIMEPLUS_3_5CYCLES ((uint32_t)ADC_SMPR1_SMPLUS_1) +#define ADC_SAMPLETIMEPLUS_4_5CYCLES ((uint32_t)ADC_SMPR1_SMPLUS) + +#define IS_ADC_SAMPLE_PLUS_TIME(PLUS_TIME) (((PLUS_TIME) == ADC_SAMPLETIMEPLUS_1_5CYCLES) || \ + ((PLUS_TIME) == ADC_SAMPLETIMEPLUS_2_5CYCLES) || \ + ((PLUS_TIME) == ADC_SAMPLETIMEPLUS_3_5CYCLES) || \ + ((PLUS_TIME) == ADC_SAMPLETIMEPLUS_4_5CYCLES)) +/** + * @} + */ + +/** @defgroup ADC_sampling_times + * @{ + */ +#define ADC_SAMPLETIME_1_5CYCLES ((uint32_t)0x00000000) +#define ADC_SAMPLETIME_6_5CYCLES ((uint32_t)0x00000001) +#define ADC_SAMPLETIME_12_5CYCLES ((uint32_t)0x00000002) +#define ADC_SAMPLETIME_24_5CYCLES ((uint32_t)0x00000003) +#define ADC_SAMPLETIME_47_5CYCLES ((uint32_t)0x00000004) +#define ADC_SAMPLETIME_92_5CYCLES ((uint32_t)0x00000005) +#define ADC_SAMPLETIME_247_5CYCLES ((uint32_t)0x00000006) +#define ADC_SAMPLETIME_640_5CYCLES ((uint32_t)0x00000007) + +#define IS_ADC_SAMPLE_TIME(TIME) (((TIME) == ADC_SAMPLETIME_1_5CYCLES) || \ + ((TIME) == ADC_SAMPLETIME_6_5CYCLES) || \ + ((TIME) == ADC_SAMPLETIME_12_5CYCLES) || \ + ((TIME) == ADC_SAMPLETIME_24_5CYCLES) || \ + ((TIME) == ADC_SAMPLETIME_47_5CYCLES) || \ + ((TIME) == ADC_SAMPLETIME_92_5CYCLES) || \ + ((TIME) == ADC_SAMPLETIME_247_5CYCLES) || \ + ((TIME) == ADC_SAMPLETIME_640_5CYCLES) ) +/** + * @} + */ + +/** @defgroup ADC_thresholds + * @{ + */ +#define IS_ADC_THRESHOLD(THRESHOLD) ((THRESHOLD) <= 0xFFF) +/** + * @} + */ + +/** @defgroup ADC_reg_seq_ranks ADC group regular - Sequencer ranks + * @{ + */ +#define ADC_REGULAR_RANK_1 (uint32_t)0x00000000 /*!< ADC group regular sequencer rank 1 */ +#define ADC_REGULAR_RANK_2 (uint32_t)0x00000001 /*!< ADC group regular sequencer rank 2 */ +#define ADC_REGULAR_RANK_3 (uint32_t)0x00000002 /*!< ADC group regular sequencer rank 3 */ +#define ADC_REGULAR_RANK_4 (uint32_t)0x00000003 /*!< ADC group regular sequencer rank 4 */ +#define ADC_REGULAR_RANK_5 (uint32_t)0x00000004 /*!< ADC group regular sequencer rank 5 */ +#define ADC_REGULAR_RANK_6 (uint32_t)0x00000005 /*!< ADC group regular sequencer rank 6 */ +#define ADC_REGULAR_RANK_7 (uint32_t)0x00000006 /*!< ADC group regular sequencer rank 7 */ +#define ADC_REGULAR_RANK_8 (uint32_t)0x00000007 /*!< ADC group regular sequencer rank 8 */ +#define ADC_REGULAR_RANK_9 (uint32_t)0x00000008 /*!< ADC group regular sequencer rank 9 */ +#define ADC_REGULAR_RANK_10 (uint32_t)0x00000009 /*!< ADC group regular sequencer rank 10 */ +#define ADC_REGULAR_RANK_11 (uint32_t)0x0000000a /*!< ADC group regular sequencer rank 11 */ +#define ADC_REGULAR_RANK_12 (uint32_t)0x0000000b /*!< ADC group regular sequencer rank 12 */ +#define ADC_REGULAR_RANK_13 (uint32_t)0x0000000c /*!< ADC group regular sequencer rank 13 */ +#define ADC_REGULAR_RANK_14 (uint32_t)0x0000000d /*!< ADC group regular sequencer rank 14 */ +#define ADC_REGULAR_RANK_15 (uint32_t)0x0000000e /*!< ADC group regular sequencer rank 15 */ +#define ADC_REGULAR_RANK_16 (uint32_t)0x0000000f /*!< ADC group regular sequencer rank 16 */ + +#define IS_ADC_REGULAR_RANK(RANK) (((RANK) == ADC_REGULAR_RANK_1 ) ||\ + ((RANK) == ADC_REGULAR_RANK_2 ) ||\ + ((RANK) == ADC_REGULAR_RANK_3 ) ||\ + ((RANK) == ADC_REGULAR_RANK_4 ) ||\ + ((RANK) == ADC_REGULAR_RANK_5 ) ||\ + ((RANK) == ADC_REGULAR_RANK_6 ) ||\ + ((RANK) == ADC_REGULAR_RANK_7 ) ||\ + ((RANK) == ADC_REGULAR_RANK_8 ) ||\ + ((RANK) == ADC_REGULAR_RANK_9 ) ||\ + ((RANK) == ADC_REGULAR_RANK_10) ||\ + ((RANK) == ADC_REGULAR_RANK_11) ||\ + ((RANK) == ADC_REGULAR_RANK_12) ||\ + ((RANK) == ADC_REGULAR_RANK_13) ||\ + ((RANK) == ADC_REGULAR_RANK_14) ||\ + ((RANK) == ADC_REGULAR_RANK_15) ||\ + ((RANK) == ADC_REGULAR_RANK_16) ) + +/** + * @} + */ + +/** @defgroup ADC_channels + * @{ + */ +#define ADC_CHANNEL_RESET ((uint32_t)0x0000001f) +#define ADC_CHANNEL_0 ((uint32_t)0x00000000) +#define ADC_CHANNEL_1 ((uint32_t)0x00000001) +#define ADC_CHANNEL_2 ((uint32_t)0x00000002) +#define ADC_CHANNEL_3 ((uint32_t)0x00000003) +#define ADC_CHANNEL_4 ((uint32_t)0x00000004) +#define ADC_CHANNEL_5 ((uint32_t)0x00000005) +#define ADC_CHANNEL_6 ((uint32_t)0x00000006) +#define ADC_CHANNEL_7 ((uint32_t)0x00000007) +#define ADC_CHANNEL_8 ((uint32_t)0x00000008) +#define ADC_CHANNEL_9 ((uint32_t)0x00000009) +#define ADC_CHANNEL_10 ((uint32_t)0x0000000a) +#define ADC_CHANNEL_11 ((uint32_t)0x0000000b) +#define ADC_CHANNEL_12 ((uint32_t)0x0000000c) +#define ADC_CHANNEL_13 ((uint32_t)0x0000000d) +#define ADC_CHANNEL_14 ((uint32_t)0x0000000e) +#define ADC_CHANNEL_15 ((uint32_t)0x0000000f) +#define ADC_CHANNEL_16 ((uint32_t)0x00000010) +#define ADC_CHANNEL_17 ((uint32_t)0x00000011) +#define ADC_CHANNEL_18 ((uint32_t)0x00000012) +#define ADC_CHANNEL_19 ((uint32_t)0x00000013) +#define ADC_CHANNEL_20 ((uint32_t)0x00000014) +#define ADC_CHANNEL_21 ((uint32_t)0x00000015) + +#define ADC1_CHANNEL_VREFINT ((uint32_t)ADC_CHANNEL_0) +#define ADC13_CHANNEL_TENOSENSOR ((uint32_t)ADC_CHANNEL_17) +#define ADC13_CHANNEL_VBAT ((uint32_t)ADC_CHANNEL_18) + +#define ADC12_CHANNEL_OP1 ((uint32_t)ADC_CHANNEL_19) +#define ADC12_CHANNEL_OP2 ((uint32_t)ADC_CHANNEL_20) +#define ADC12_CHANNEL_OP3 ((uint32_t)ADC_CHANNEL_21) + +#define ADC12_CHANNEL_DAC1 ((uint32_t)ADC_CHANNEL_17) +#define ADC12_CHANNEL_DAC2 ((uint32_t)ADC_CHANNEL_18) + +#define ADC3_CHANNEL_DAC1 ((uint32_t)ADC_CHANNEL_14) +#define ADC3_CHANNEL_DAC2 ((uint32_t)ADC_CHANNEL_15) + +#define IS_ADC_CHANNEL(CHANNEL) (((CHANNEL) == ADC_CHANNEL_0) || \ + ((CHANNEL) == ADC_CHANNEL_1) || \ + ((CHANNEL) == ADC_CHANNEL_2) || \ + ((CHANNEL) == ADC_CHANNEL_3) || \ + ((CHANNEL) == ADC_CHANNEL_4) || \ + ((CHANNEL) == ADC_CHANNEL_5) || \ + ((CHANNEL) == ADC_CHANNEL_6) || \ + ((CHANNEL) == ADC_CHANNEL_7) || \ + ((CHANNEL) == ADC_CHANNEL_8) || \ + ((CHANNEL) == ADC_CHANNEL_9) || \ + ((CHANNEL) == ADC_CHANNEL_10) || \ + ((CHANNEL) == ADC_CHANNEL_11) || \ + ((CHANNEL) == ADC_CHANNEL_12) || \ + ((CHANNEL) == ADC_CHANNEL_13) || \ + ((CHANNEL) == ADC_CHANNEL_14) || \ + ((CHANNEL) == ADC_CHANNEL_15) || \ + ((CHANNEL) == ADC_CHANNEL_16) || \ + ((CHANNEL) == ADC_CHANNEL_17) || \ + ((CHANNEL) == ADC_CHANNEL_18) || \ + ((CHANNEL) == ADC_CHANNEL_19) || \ + ((CHANNEL) == ADC_CHANNEL_20) || \ + ((CHANNEL) == ADC_CHANNEL_21) || \ + ((CHANNEL) == ADC1_CHANNEL_VREFINT) || \ + ((CHANNEL) == ADC13_CHANNEL_TENOSENSOR) || \ + ((CHANNEL) == ADC13_CHANNEL_VBAT) || \ + ((CHANNEL) == ADC12_CHANNEL_OP1) || \ + ((CHANNEL) == ADC12_CHANNEL_OP2) || \ + ((CHANNEL) == ADC12_CHANNEL_OP3) || \ + ((CHANNEL) == ADC12_CHANNEL_DAC1) || \ + ((CHANNEL) == ADC12_CHANNEL_DAC2) || \ + ((CHANNEL) == ADC3_CHANNEL_DAC1) || \ + ((CHANNEL) == ADC3_CHANNEL_DAC2) ) +/** + * @} + */ + +/** @defgroup ADC_injected_seq_ranks ADC group injected - Sequencer ranks + * @{ + */ +#define ADC_INJECTED_RANK_1 (uint32_t)0x00000000 /*!< ADC group injected sequencer rank 1 */ +#define ADC_INJECTED_RANK_2 (uint32_t)0x00000001 /*!< ADC group injected sequencer rank 2 */ +#define ADC_INJECTED_RANK_3 (uint32_t)0x00000002 /*!< ADC group injected sequencer rank 3 */ +#define ADC_INJECTED_RANK_4 (uint32_t)0x00000003 /*!< ADC group injected sequencer rank 4 */ + +#define IS_ADC_INJECTED_RANK(CHANNEL) (((CHANNEL) == ADC_INJECTED_RANK_1) || \ + ((CHANNEL) == ADC_INJECTED_RANK_2) || \ + ((CHANNEL) == ADC_INJECTED_RANK_3) || \ + ((CHANNEL) == ADC_INJECTED_RANK_4) ) +/** + * @} + */ + +/** @defgroup ADC_REG_SEQ_DISCONT_MODE ADC group regular - Sequencer discontinuous mode + * @{ + */ +#define ADC_REG_SEQ_DISCONT_DISABLE (uint32_t)0x00000000 /*!< ADC group regular sequencer + discontinuous mode disable */ +#define ADC_REG_SEQ_DISCNUM_1_CHANNEL (ADC_CFGR1_DISCEN) /*!< ADC group regular sequencer + discontinuous mode enable with + sequence interruption every rank */ +#define ADC_REG_SEQ_DISCNUM_2_CHANNELS (ADC_CFGR1_DISCNUM_0 | ADC_CFGR1_DISCEN) /*!< ADC group regular sequencer + discontinuous mode enabled with + sequence interruption every 2 ranks */ +#define ADC_REG_SEQ_DISCNUM_3_CHANNELS (ADC_CFGR1_DISCNUM_1 | ADC_CFGR1_DISCEN) /*!< ADC group regular sequencer + discontinuous mode enable with + sequence interruption every 3 ranks */ +#define ADC_REG_SEQ_DISCNUM_4_CHANNELS (ADC_CFGR1_DISCNUM_1 | ADC_CFGR1_DISCNUM_0 \ + | ADC_CFGR1_DISCEN) /*!< ADC group regular sequencer + discontinuous mode enable with + sequence interruption every 4 ranks */ +#define ADC_REG_SEQ_DISCNUM_5_CHANNELS (ADC_CFGR1_DISCNUM_2 | ADC_CFGR1_DISCEN) /*!< ADC group regular sequencer + discontinuous mode enable with + sequence interruption every 5 ranks */ +#define ADC_REG_SEQ_DISCNUM_6_CHANNELS (ADC_CFGR1_DISCNUM_2 | ADC_CFGR1_DISCNUM_0 \ + | ADC_CFGR1_DISCEN) /*!< ADC group regular sequencer + discontinuous mode enable with + sequence interruption every 6 ranks */ +#define ADC_REG_SEQ_DISCNUM_7_CHANNELS (ADC_CFGR1_DISCNUM_2 | ADC_CFGR1_DISCNUM_1 \ + | ADC_CFGR1_DISCEN) /*!< ADC group regular sequencer + discontinuous mode enable with + sequence interruption every 7 ranks */ +#define ADC_REG_SEQ_DISCNUM_8_CHANNELS (ADC_CFGR1_DISCNUM_2 | ADC_CFGR1_DISCNUM_1 \ + | ADC_CFGR1_DISCNUM_0 \ + | ADC_CFGR1_DISCEN) /*!< ADC group regular sequencer + discontinuous mode enable with + sequence interruption every 8 ranks */ + +#define ADC_REG_SEQ_DISCNUM(DISCNUM) (((DISCNUM) == ADC_REG_SEQ_DISCONT_DISABLE) || \ + ((DISCNUM) == ADC_REG_SEQ_DISCNUM_1_CHANNEL) || \ + ((DISCNUM) == ADC_REG_SEQ_DISCNUM_2_CHANNELS) || \ + ((DISCNUM) == ADC_REG_SEQ_DISCNUM_3_CHANNELS) || \ + ((DISCNUM) == ADC_REG_SEQ_DISCNUM_4_CHANNELS) || \ + ((DISCNUM) == ADC_REG_SEQ_DISCNUM_5_CHANNELS) || \ + ((DISCNUM) == ADC_REG_SEQ_DISCNUM_6_CHANNELS) || \ + ((DISCNUM) == ADC_REG_SEQ_DISCNUM_7_CHANNELS) || \ + ((DISCNUM) == ADC_REG_SEQ_DISCNUM_8_CHANNELS) ) + +/** + * @} + */ + +/** @defgroup ADC_OVS_RATIO Oversampling - Ratio + * @note The oversampling ratio is the number of ADC conversions performed, sum of these conversions data is computed + * to result as the ADC oversampling conversion data (before potential shift) + */ +#define ADC_OVERSAMPLING_RATIO_2 ((uint32_t)0x00000000) /*!< ADC oversampling ratio 2 */ +#define ADC_OVERSAMPLING_RATIO_4 ((uint32_t)ADC_CFGR2_OVSR_0) /*!< ADC oversampling ratio 4 */ +#define ADC_OVERSAMPLING_RATIO_8 ((uint32_t)ADC_CFGR2_OVSR_1) /*!< ADC oversampling ratio 8 */ +#define ADC_OVERSAMPLING_RATIO_16 ((uint32_t)(ADC_CFGR2_OVSR_0|ADC_CFGR2_OVSR_1)) /*!< ADC oversampling ratio 16 */ +#define ADC_OVERSAMPLING_RATIO_32 ((uint32_t)ADC_CFGR2_OVSR_2) /*!< ADC oversampling ratio 32 */ +#define ADC_OVERSAMPLING_RATIO_64 ((uint32_t)(ADC_CFGR2_OVSR_0|ADC_CFGR2_OVSR_2)) /*!< ADC oversampling ratio 64 */ +#define ADC_OVERSAMPLING_RATIO_128 ((uint32_t)(ADC_CFGR2_OVSR_1|ADC_CFGR2_OVSR_2)) /*!< ADC oversampling ratio 128 */ +#define ADC_OVERSAMPLING_RATIO_256 ((uint32_t)(ADC_CFGR2_OVSR_0|ADC_CFGR2_OVSR_1|ADC_CFGR2_OVSR_2)) /*!< ADC oversampling ratio 256 */ + + +#define IS_ADC_OVERSAMPLING_RATIO(RATIO) (((RATIO) == ADC_OVERSAMPLING_RATIO_2) ||\ + ((RATIO) == ADC_OVERSAMPLING_RATIO_4) ||\ + ((RATIO) == ADC_OVERSAMPLING_RATIO_8) ||\ + ((RATIO) == ADC_OVERSAMPLING_RATIO_16) ||\ + ((RATIO) == ADC_OVERSAMPLING_RATIO_32) ||\ + ((RATIO) == ADC_OVERSAMPLING_RATIO_64) ||\ + ((RATIO) == ADC_OVERSAMPLING_RATIO_128) ||\ + ((RATIO) == ADC_OVERSAMPLING_RATIO_256)) +/** + * @} + */ + +/** @defgroup ADC_OVS_SHIFT Oversampling - Data shift + * @{ + */ +/** + * @note The sum of the ADC conversions data is divided by "Rightbitshift" number to result as the ADC oversampling + * conversion data) + */ +#define ADC_RIGHTBITSHIFT_NONE ((uint32_t)0x00000000) /*!< ADC oversampling no shift */ +#define ADC_RIGHTBITSHIFT_1 ((uint32_t)ADC_CFGR2_OVSS_0) /*!< ADC oversampling right shift of 1 ranks */ +#define ADC_RIGHTBITSHIFT_2 ((uint32_t)ADC_CFGR2_OVSS_1) /*!< ADC oversampling right shift of 2 ranks */ +#define ADC_RIGHTBITSHIFT_3 ((uint32_t)(ADC_CFGR2_OVSS_0|ADC_CFGR2_OVSS_1)) /*!< ADC oversampling right shift of 3 ranks */ +#define ADC_RIGHTBITSHIFT_4 ((uint32_t)ADC_CFGR2_OVSS_2) /*!< ADC oversampling right shift of 4 ranks */ +#define ADC_RIGHTBITSHIFT_5 ((uint32_t)(ADC_CFGR2_OVSS_0|ADC_CFGR2_OVSS_2)) /*!< ADC oversampling right shift of 5 ranks */ +#define ADC_RIGHTBITSHIFT_6 ((uint32_t)(ADC_CFGR2_OVSS_1|ADC_CFGR2_OVSS_2)) /*!< ADC oversampling right shift of 6 ranks */ +#define ADC_RIGHTBITSHIFT_7 ((uint32_t)(ADC_CFGR2_OVSS_0|ADC_CFGR2_OVSS_1|ADC_CFGR2_OVSS_2)) /*!< ADC oversampling right shift of 7 ranks */ +#define ADC_RIGHTBITSHIFT_8 ((uint32_t)ADC_CFGR2_OVSS_3) /*!< ADC oversampling right shift of 8 ranks */ + +#define IS_ADC_RIGHT_BIT_SHIFT(SHIFT) (((SHIFT) == ADC_RIGHTBITSHIFT_NONE) ||\ + ((SHIFT) == ADC_RIGHTBITSHIFT_1) ||\ + ((SHIFT) == ADC_RIGHTBITSHIFT_2) ||\ + ((SHIFT) == ADC_RIGHTBITSHIFT_3) ||\ + ((SHIFT) == ADC_RIGHTBITSHIFT_4) ||\ + ((SHIFT) == ADC_RIGHTBITSHIFT_5) ||\ + ((SHIFT) == ADC_RIGHTBITSHIFT_6) ||\ + ((SHIFT) == ADC_RIGHTBITSHIFT_7) ||\ + ((SHIFT) == ADC_RIGHTBITSHIFT_8) ) +/** + * @} + */ + +/** @defgroup ADC_OVS_DISCONT_MODE Oversampling - Discontinuous mode + * @{ + */ +#define ADC_TRIGGEREDMODE_SINGLE_TRIGGER (0x00000000UL) /*!< ADC oversampling discontinuous mode: + continuous mode (all conversions of OVS ratio are done from 1 trigger) */ +#define ADC_TRIGGEREDMODE_MULTI_TRIGGER (ADC_CFGR2_TROVS) /*!< ADC oversampling discontinuous mode: + discontinuous mode (each conversion of OVS ratio needs a trigger) */ + +#define IS_ADC_TRIGGERED_OVERSAMPLING_MODE(MODE) (((MODE) == ADC_TRIGGEREDMODE_SINGLE_TRIGGER) ||\ + ((MODE) == ADC_TRIGGEREDMODE_MULTI_TRIGGER)) +/** + * @} + */ + +/** @defgroup ADC_OVS_SCOPE_REG Oversampling - Oversampling scope for ADC group regular + * @{ + */ +#define ADC_REGOVERSAMPLING_CONTINUED_MODE (0x00000000UL) /*!< Oversampling buffer maintained + during injection sequence */ +#define ADC_REGOVERSAMPLING_RESUMED_MODE (ADC_CFGR2_ROVSM) /*!< Oversampling buffer zeroed during + injection sequence */ + +#define IS_ADC_REGOVERSAMPLING_MODE(MODE) (((MODE) == ADC_REGOVERSAMPLING_CONTINUED_MODE) ||\ + ((MODE) == ADC_REGOVERSAMPLING_RESUMED_MODE)) +/** + * @} + */ + + +/** @defgroup ADC_interrupts_definition + * @{ + */ + +#define ADC_IT_ADRDY ADC_IER_ADRDYIE /*!< ADC Ready interrupt source */ +#define ADC_IT_EOSMP ADC_IER_EOSMPIE /*!< ADC End of sampling interrupt source */ +#define ADC_IT_EOC ADC_IER_EOCIE /*!< ADC End of regular conversion interrupt source */ +#define ADC_IT_EOS ADC_IER_EOSIE /*!< ADC End of regular sequence of conversions interrupt source */ +#define ADC_IT_OVR ADC_IER_OVRIE /*!< ADC overrun interrupt source */ +#define ADC_IT_JEOC ADC_IER_JEOCIE /*!< ADC End of injected conversion interrupt source */ +#define ADC_IT_JEOS ADC_IER_JEOSIE /*!< ADC End of injected sequence of conversions interrupt source */ +#define ADC_IT_AWD1 ADC_IER_AWD1IE /*!< ADC Analog watchdog 1 interrupt source (main analog watchdog) */ +#define ADC_IT_AWD2 ADC_IER_AWD2IE /*!< ADC Analog watchdog 2 interrupt source (additional analog watchdog) */ +#define ADC_IT_AWD3 ADC_IER_AWD3IE /*!< ADC Analog watchdog 3 interrupt source (additional analog watchdog) */ +#define ADC_IT_JQOV ADC_IER_JQOVIE /*!< ADC Injected Context Queue Overflow interrupt source */ + +#define IS_ADC_CONFIG_IT(IT) (((IT) != (uint32_t)RESET) && (((IT) & 0xFFFFF800) == (uint32_t)RESET)) + +#define IS_ADC_GET_IT(IT) (((IT) == ADC_IT_ADRDY) || ((IT) == ADC_IT_EOSMP) || \ + ((IT) == ADC_IT_EOC) || ((IT) == ADC_IT_EOS) || \ + ((IT) == ADC_IT_OVR) || ((IT) == ADC_IT_JEOC) || \ + ((IT) == ADC_IT_JEOS) || ((IT) == ADC_IT_AWD1) || \ + ((IT) == ADC_IT_AWD2) || ((IT) == ADC_IT_AWD3) || \ + ((IT) == ADC_IT_JQOV)) + +#define IS_ADC_CLEAR_IT(IT) (((IT) != (uint32_t)RESET) && (((IT) & 0xFFFFF800) == (uint32_t)RESET)) + +/** + * @} + */ + +/** @defgroup ADC_flags_definition + * @{ + */ + +#define ADC_FLAG_ADRDY ADC_ISR_ADRDY +#define ADC_FLAG_EOSMP ADC_ISR_EOSMP +#define ADC_FLAG_EOC ADC_ISR_EOC +#define ADC_FLAG_EOS ADC_ISR_EOS +#define ADC_FLAG_OVR ADC_ISR_OVR +#define ADC_FLAG_JEOC ADC_ISR_JEOC +#define ADC_FLAG_JEOS ADC_ISR_JEOS +#define ADC_FLAG_AWD1 ADC_ISR_AWD1 +#define ADC_FLAG_AWD2 ADC_ISR_AWD2 +#define ADC_FLAG_AWD3 ADC_ISR_AWD3 +#define ADC_FLAG_JQOVF ADC_ISR_JQOVF + +#define ADC_FLAG_ADEN ((uint32_t)0x01000001) +#define ADC_FLAG_ADDIS ((uint32_t)0x01000002) +#define ADC_FLAG_ADSTART ((uint32_t)0x01000004) +#define ADC_FLAG_JADSTART ((uint32_t)0x01000008) +#define ADC_FLAG_ADSTP ((uint32_t)0x01000010) +#define ADC_FLAG_JADSTP ((uint32_t)0x01000020) +#define ADC_FLAG_ADCAL ((uint32_t)0x81000000) + +#define IS_ADC_CLEAR_FLAG(FLAG) (((FLAG) != (uint32_t)RESET) && (((FLAG) & 0xFFFFF800) == (uint32_t)RESET)) + +#define IS_ADC_GET_FLAG(FLAG) (((FLAG) == ADC_FLAG_ADRDY) || ((FLAG) == ADC_FLAG_EOSMP) || \ + ((FLAG) == ADC_FLAG_EOC) || ((FLAG) == ADC_FLAG_EOS) || \ + ((FLAG) == ADC_FLAG_OVR) || ((FLAG) == ADC_FLAG_JEOC) || \ + ((FLAG) == ADC_FLAG_JEOS) || ((FLAG) == ADC_FLAG_AWD1) || \ + ((FLAG) == ADC_FLAG_AWD2) || ((FLAG) == ADC_FLAG_AWD3) || \ + ((FLAG) == ADC_FLAG_JQOVF) || \ + ((FLAG) == ADC_FLAG_ADEN) || ((FLAG) == ADC_FLAG_ADDIS) || \ + ((FLAG) == ADC_FLAG_ADSTART) || ((FLAG) == ADC_FLAG_JADSTART) || \ + ((FLAG) == ADC_FLAG_ADSTP) || ((FLAG) == ADC_FLAG_JADSTP) || \ + ((FLAG) == ADC_FLAG_ADCAL)) +/** + * @} + */ + + +/** @defgroup ADC_REG_OVR_DATA_BEHAVIOR ADC group regular - Overrun behavior on conversion data + * @{ + */ +#define ADC_OVR_MODE_PRESERVED ((uint32_t)0x00000000) /*!< ADC group regular behavior in case + of overrun: data preserved */ +#define ADC_OVR_MODE_OVERWRITTEN (ADC_CFGR1_OVRMOD) /*!< ADC group regular behavior in case + of overrun: data overwritten */ + +#define IS_ADC_OVERRUN(OVR) (((OVR) == ADC_OVR_MODE_PRESERVED) ||\ + ((OVR) == ADC_OVR_MODE_OVERWRITTEN)) +/** + * @} + */ + +/** @defgroup ADC_regular_sampling_mode ADC group regular sampling mode + * @{ + */ +#define ADC_SAMPLING_MODE_NORMAL ((uint32_t)0x00000000) /*!< ADC conversions sampling phase duration is + defined using @ref ADC_HAL_EC_CHANNEL_SAMPLINGTIME */ +#define ADC_SAMPLING_MODE_BULB (ADC_CFGR2_BULB) /*!< ADC conversions sampling phase starts + immediately after end of conversion, and stops upon trigger event. + Note: First conversion is using minimal sampling time + (see @ref ADC_CHANNEL_SAMPLINGTIME) */ +#define ADC_SAMPLING_MODE_TRIGGER_CONTROLED (ADC_CFGR2_SMPTRIG) /*!< ADC conversions sampling phase is controlled + by trigger events: + Trigger rising edge = start sampling + Trigger falling edge = stop sampling and start conversion */ + +#define IS_ADC_SAMPLINGMODE(SAMPLINGMODE) (((SAMPLINGMODE) == ADC_SAMPLING_MODE_NORMAL) || \ + ((SAMPLINGMODE) == ADC_SAMPLING_MODE_BULB) || \ + ((SAMPLINGMODE) == ADC_SAMPLING_MODE_TRIGGER_CONTROLED)) + +/** + * @} + */ + +/** @defgroup ADC_channel_single_diff_ending Channel - Single or differential ending + * @{ + */ +#define ADC_SINGLE_ENDED ((uint32_t)0x00000000) /*!< ADC channel ending set to single ended */ +#define ADC_DIFFERENTIAL_ENDED ((uint32_t)0x00000001) /*!< ADC channel ending set to differential */ + +#define IS_ADC_SINGLE_DIFFERENTIAL(SING_DIFF) (((SING_DIFF) == ADC_SINGLE_ENDED) || \ + ((SING_DIFF) == ADC_DIFFERENTIAL_ENDED) ) +/** + * @} + */ + +/** @defgroup ADC_offset_number ADC instance - Offset number + * @{ + */ +#define ADC_OFFSET_NONE ((uint32_t)0x00000000) /*!< ADC offset disabled: no offset correction for the selected + ADC channel */ +#define ADC_OFFSET_1 ((uint32_t)0x00000001) /*!< ADC offset number 1: ADC channel and offset level to which + the offset programmed will be applied (independently of channel mapped + on ADC group regular or group injected) */ +#define ADC_OFFSET_2 ((uint32_t)0x00000002) /*!< ADC offset number 2: ADC channel and offset level to which + the offset programmed will be applied (independently of channel mapped + on ADC group regular or group injected) */ +#define ADC_OFFSET_3 ((uint32_t)0x00000004) /*!< ADC offset number 3: ADC channel and offset level to which + the offset programmed will be applied (independently of channel mapped + on ADC group regular or group injected) */ +#define ADC_OFFSET_4 ((uint32_t)0x00000008) /*!< ADC offset number 4: ADC channel and offset level to which + the offset programmed will be applied (independently of channel mapped + on ADC group regular or group injected) */ + +#define IS_ADC_OFFSET_NUMBER(NUMBER) (((NUMBER) == ADC_OFFSET_NONE) || \ + ((NUMBER) == ADC_OFFSET_1) || \ + ((NUMBER) == ADC_OFFSET_2) || \ + ((NUMBER) == ADC_OFFSET_3) || \ + ((NUMBER) == ADC_OFFSET_4) ) +/** + * @} + */ + + +/** @defgroup ADC_OffsetSign ADC Extended Offset Sign + * @{ + */ +#define ADC_OFFSET_SIGN_NEGATIVE ((uint32_t)0x00000000) /*!< Offset sign negative, offset is subtracted */ +#define ADC_OFFSET_SIGN_POSITIVE (ADC_OFR1_OFFSETPOS) /*!< Offset sign positive, offset is added */ + +#define IS_ADC_OFFSET_SIGN(SIGN) (((SIGN) == ADC_OFFSET_SIGN_NEGATIVE) ||\ + ((SIGN) == ADC_OFFSET_SIGN_POSITIVE)) +/** + * @} + */ + + +/** @defgroup ADC_CFGR_fields ADCx CFGR fields + * @{ + */ +#define ADC_CFGR_FIELDS (ADC_CFGR1_AWD1CH | ADC_CFGR1_JAUTO | ADC_CFGR1_JAWD1EN |\ + ADC_CFGR1_AWD1EN | ADC_CFGR1_AWD1SGL | ADC_CFGR1_JQM |\ + ADC_CFGR1_JDISCEN | ADC_CFGR1_DISCNUM | ADC_CFGR1_DISCEN |\ + ADC_CFGR1_AUTDLY | ADC_CFGR1_CONT | ADC_CFGR1_OVRMOD |\ + ADC_CFGR1_EXTEN | ADC_CFGR1_EXTSEL | ADC_CFGR1_ALIGN |\ + ADC_CFGR1_RES | ADC_CFGR1_DMACFG | ADC_CFGR1_DMAEN ) +/** + * @} + */ + + +/** + * @} + */ + +/** @defgroup ADC_MULTI_MODE Multimode - Mode + * @{ + */ +#define ADC_MODE_INDEPENDENT ((uint32_t)0x00000000) +/*!< ADC dual mode disabled (ADC independent + mode) */ + +#define ADC_DUAL_MODE_REGSIMULT (uint32_t)(ADC_CCR_MULTI_2|ADC_CCR_MULTI_1) +/*!< ADC dual mode enabled: group regular + simultaneous */ + +#define ADC_DUAL_MODE_INTERL (uint32_t)(ADC_CCR_MULTI_2|ADC_CCR_MULTI_1|ADC_CCR_MULTI_0) +/*!< ADC dual mode enabled: Combined + group regular interleaved */ + +#define ADC_DUAL_MODE_INJECSIMULT (uint32_t)(ADC_CCR_MULTI_2|ADC_CCR_MULTI_0) +/*!< ADC dual mode enabled: group + injected simultaneous */ + +#define ADC_DUAL_MODE_ALTERTRIG (uint32_t)(ADC_CCR_MULTI_3|ADC_CCR_MULTI_0) +/*!< ADC dual mode enabled: group injected + alternate trigger. Works only with external + triggers (not internal SW start) */ + +#define ADC_DUAL_MODE_REGSIMULT_INJECSIMULT (uint32_t)(ADC_CCR_MULTI_0) +/*!< ADC dual mode enabled: Combined + group regular simultaneous + group + injected simultaneous */ + +#define ADC_DUAL_MODE_REGSIMULT_ALTERTRIG (uint32_t)(ADC_CCR_MULTI_1) +/*!< ADC dual mode enabled: Combined + group regular simultaneous + group + injected alternate trigger */ + + +#define ADC_TRIPLE_MODE_REGSIMULT (uint32_t)(ADC_CCR_MULTI_4|ADC_CCR_MULTI_2|ADC_CCR_MULTI_1) +/*!< ADC triple mode enabled: group regular + simultaneous */ + + +#define ADC_TRIPLE_MODE_INTERL (uint32_t)(ADC_CCR_MULTI_4|ADC_CCR_MULTI_2|ADC_CCR_MULTI_1|ADC_CCR_MULTI_0) +/*!< ADC triple mode enabled: Combined + group regular interleaved */ + +#define ADC_TRIPLE_MODE_INJECSIMULT (uint32_t)(ADC_CCR_MULTI_4|ADC_CCR_MULTI_2|ADC_CCR_MULTI_0) +/*!< ADC triple mode enabled: group + injected simultaneous */ + + +#define ADC_TRIPLE_MODE_ALTERTRIG (uint32_t)(ADC_CCR_MULTI_4|ADC_CCR_MULTI_3|ADC_CCR_MULTI_0) +/*!< ADC triple mode enabled: group injected + alternate trigger. Works only with external + triggers (not internal SW start) */ + +#define ADC_TRIPLE_MODE_REGSIMULT_INJECSIMULT (uint32_t)(ADC_CCR_MULTI_4|ADC_CCR_MULTI_0) +/*!< ADC triple mode enabled: Combined + group regular simultaneous + group + injected simultaneous */ + + +#define ADC_TRIPLE_MODE_REGSIMULT_ALTERTRIG (uint32_t)(ADC_CCR_MULTI_4|ADC_CCR_MULTI_1) +/*!< ADC triple mode enabled: Combined + group regular simultaneous + group + injected alternate trigger */ + + +#define IS_ADC_MULTIMODE(MODE) (((MODE) == ADC_MODE_INDEPENDENT) || \ + ((MODE) == ADC_DUAL_MODE_REGSIMULT_INJECSIMULT) || \ + ((MODE) == ADC_DUAL_MODE_REGSIMULT_ALTERTRIG) || \ + ((MODE) == ADC_DUAL_MODE_INJECSIMULT) || \ + ((MODE) == ADC_DUAL_MODE_REGSIMULT) || \ + ((MODE) == ADC_DUAL_MODE_INTERL) || \ + ((MODE) == ADC_DUAL_MODE_ALTERTRIG) || \ + ((MODE) == ADC_TRIPLE_MODE_REGSIMULT_INJECSIMULT) || \ + ((MODE) == ADC_TRIPLE_MODE_REGSIMULT_ALTERTRIG) || \ + ((MODE) == ADC_TRIPLE_MODE_INJECSIMULT) || \ + ((MODE) == ADC_TRIPLE_MODE_REGSIMULT) || \ + ((MODE) == ADC_TRIPLE_MODE_INTERL) || \ + ((MODE) == ADC_TRIPLE_MODE_ALTERTRIG) ) +/** + * @} + */ + +/** @defgroup ADC_MULTI_DMA_TRANSFER_RESOLUTION Multimode - DMA transfer mode depending on ADC resolution + * @{ + */ +#define ADC_DMAACCESSMODE_DISABLED ((uint32_t)0x00000000) /*!< DMA multimode disabled: each ADC uses its own + DMA channel */ +#define ADC_DMAACCESSMODE_1 (ADC_CCR_MDMA_0) /*!< DMA multimode enabled (2/3 half-words one by one - 1 then 2 then 3) */ +#define ADC_DMAACCESSMODE_2 (ADC_CCR_MDMA_1) /*!< DMA multimode enabled (2/3 half-words by pairs - 2&1 then 1&3 then 3&2) */ +#define ADC_DMAACCESSMODE_3 (ADC_CCR_MDMA) /*!< DMA multimode enabled (2/3 bytes by pairs - 2&1 then 1&3 then 3&2) */ + +#define IS_ADC_DMA_ACCESS_MULTIMODE(MODE) (((MODE) == ADC_DMAACCESSMODE_DISABLED) || \ + ((MODE) == ADC_DMAACCESSMODE_1) || \ + ((MODE) == ADC_DMAACCESSMODE_2) || \ + ((MODE) == ADC_DMAACCESSMODE_3 )) +/** + * @} + */ + +/** @defgroup ADC_MULTI_DMA_MODE + * @{ + */ +#define ADC_MULTI_DMAMODE_ONESHOT ((uint32_t)0x00000000) +#define ADC_MULTI_DMAMODE_CIRCULAR ADC_CCR_DMACFG + +#define IS_ADC_MULTI_DMA_MODE(MODE) (((MODE) == ADC_MULTI_DMAMODE_ONESHOT) || \ + ((MODE) == ADC_MULTI_DMAMODE_CIRCULAR)) +/** + * @} + */ + + +/** @defgroup ADC_MULTI_TWOSMP_DELAY Multimode - Delay between two sampling phases + * @{ + */ +#define ADC_TWOSAMPLINGDELAY_1CYCLE ((uint32_t)0x00000000) +/*!< ADC multimode delay between two + sampling phases: 1 ADC clock cycle */ +#define ADC_TWOSAMPLINGDELAY_2CYCLES ((uint32_t)ADC_CCR_DELAY_0) +/*!< ADC multimode delay between two + sampling phases: 2 ADC clock cycles */ +#define ADC_TWOSAMPLINGDELAY_3CYCLES ((uint32_t)ADC_CCR_DELAY_1) +/*!< ADC multimode delay between two + sampling phases: 3 ADC clock cycles */ +#define ADC_TWOSAMPLINGDELAY_4CYCLES ((uint32_t)(ADC_CCR_DELAY_0|ADC_CCR_DELAY_1)) +/*!< ADC multimode delay between two + sampling phases: 4 ADC clock cycles */ +#define ADC_TWOSAMPLINGDELAY_5CYCLES (ADC_CCR_DELAY_2) +/*!< ADC multimode delay between two + sampling phases: 5 ADC clock cycles */ +#define ADC_TWOSAMPLINGDELAY_6CYCLES ((uint32_t)(ADC_CCR_DELAY_0|ADC_CCR_DELAY_2)) +/*!< ADC multimode delay between two + sampling phases: 6 ADC clock cycles */ +#define ADC_TWOSAMPLINGDELAY_7CYCLES ((uint32_t)(ADC_CCR_DELAY_1|ADC_CCR_DELAY_2)) +/*!< ADC multimode delay between two + sampling phases: 7 ADC clock cycles */ +#define ADC_TWOSAMPLINGDELAY_8CYCLES ((uint32_t)(ADC_CCR_DELAY_0|ADC_CCR_DELAY_1|ADC_CCR_DELAY_2)) +/*!< ADC multimode delay between two + sampling phases: 8 ADC clock cycles */ +#define ADC_TWOSAMPLINGDELAY_9CYCLES ((uint32_t)ADC_CCR_DELAY_3) +/*!< ADC multimode delay between two + sampling phases: 9 ADC clock cycles */ +#define ADC_TWOSAMPLINGDELAY_10CYCLES ((uint32_t)(ADC_CCR_DELAY_0|ADC_CCR_DELAY_3)) +/*!< ADC multimode delay between two + sampling phases: 10 ADC clock cycles */ +#define ADC_TWOSAMPLINGDELAY_11CYCLES ((uint32_t)(ADC_CCR_DELAY_1|ADC_CCR_DELAY_3)) +/*!< ADC multimode delay between two + sampling phases: 11 ADC clock cycles */ +#define ADC_TWOSAMPLINGDELAY_12CYCLES ((uint32_t)(ADC_CCR_DELAY_0|ADC_CCR_DELAY_1|ADC_CCR_DELAY_3)) +/*!< ADC multimode delay between two + sampling phases: 12 ADC clock cycles */ +#define ADC_TWOSAMPLINGDELAY_13CYCLES ((uint32_t)(ADC_CCR_DELAY_2|ADC_CCR_DELAY_3)) +/*!< ADC multimode delay between two + sampling phases: 13 ADC clock cycles */ +#define ADC_TWOSAMPLINGDELAY_14CYCLES ((uint32_t)(ADC_CCR_DELAY_0|ADC_CCR_DELAY_2|ADC_CCR_DELAY_3)) +/*!< ADC multimode delay between two + sampling phases: 14 ADC clock cycles */ +#define ADC_TWOSAMPLINGDELAY_15CYCLES ((uint32_t)(ADC_CCR_DELAY_1|ADC_CCR_DELAY_2|ADC_CCR_DELAY_3)) +/*!< ADC multimode delay between two + sampling phases: 15 ADC clock cycles */ +#define ADC_TWOSAMPLINGDELAY_16CYCLES ((uint32_t)(ADC_CCR_DELAY_0|ADC_CCR_DELAY_1|ADC_CCR_DELAY_2|ADC_CCR_DELAY_3)) +/*!< ADC multimode delay between two + sampling phases: 16 ADC clock cycles */ + + +#define IS_ADC_TWOSAMPLING_DELAY(DELAY) (((DELAY) == ADC_TWOSAMPLINGDELAY_1CYCLE) || \ + ((DELAY) == ADC_TWOSAMPLINGDELAY_2CYCLES) || \ + ((DELAY) == ADC_TWOSAMPLINGDELAY_3CYCLES) || \ + ((DELAY) == ADC_TWOSAMPLINGDELAY_4CYCLES) || \ + ((DELAY) == ADC_TWOSAMPLINGDELAY_5CYCLES) || \ + ((DELAY) == ADC_TWOSAMPLINGDELAY_6CYCLES) || \ + ((DELAY) == ADC_TWOSAMPLINGDELAY_7CYCLES) || \ + ((DELAY) == ADC_TWOSAMPLINGDELAY_8CYCLES) || \ + ((DELAY) == ADC_TWOSAMPLINGDELAY_9CYCLES) || \ + ((DELAY) == ADC_TWOSAMPLINGDELAY_10CYCLES) || \ + ((DELAY) == ADC_TWOSAMPLINGDELAY_11CYCLES) || \ + ((DELAY) == ADC_TWOSAMPLINGDELAY_12CYCLES) || \ + ((DELAY) == ADC_TWOSAMPLINGDELAY_13CYCLES) || \ + ((DELAY) == ADC_TWOSAMPLINGDELAY_14CYCLES) || \ + ((DELAY) == ADC_TWOSAMPLINGDELAY_15CYCLES) || \ + ((DELAY) == ADC_TWOSAMPLINGDELAY_16CYCLES) ) +/** + * @} + */ + +/** + * @brief Verify the length of the scheduled regular conversions group. + * @param LENGTH number of programmed conversions. + * @retval SET (LENGTH is within the maximum number of possible programmable regular conversions) + * or RESET (LENGTH is null or too large) + */ +#define IS_ADC_REGULAR_NUMBER(LENGTH) (((LENGTH) >= (uint32_t)(1)) && ((LENGTH) <= (uint32_t)(16))) +/** + * @} + */ + + +/** + * @brief Verify the length of the scheduled injected conversions group. + * @param LENGTH number of programmed conversions. + * @retval SET (LENGTH is within the maximum number of possible programmable regular conversions) + * or RESET (LENGTH is null or too large) + */ +#define IS_ADC_INJECTED_NUMBER(LENGTH) (((LENGTH) >= (uint32_t)(1)) && ((LENGTH) <= (uint32_t)(4))) +/** + * @} + */ + + +/** + * @brief Verify the number of scheduled regular conversions in discontinuous mode. + * @param NUMBER number of scheduled regular conversions in discontinuous mode. + * @retval SET (NUMBER is within the maximum number of regular conversions in discontinuous mode) + * or RESET (NUMBER is null or too large) + */ +#define IS_ADC_REGULAR_DISCONT_NUMBER(NUMBER) (((NUMBER) >= (uint32_t)(1)) && ((NUMBER) <= (uint32_t)(8))) +/** + * @} + */ + +/** + * @brief Verify the ADC gain compensation. + * @param GAIN_COMPENSATION programmed ADC gain compensation coefficient. + * @retval SET (GAIN_COMPENSATION is a valid value) or RESET (GAIN_COMPENSATION is invalid) + */ +#define IS_ADC_GAIN_COMPENSATION(GAIN_COMPENSATION) ((GAIN_COMPENSATION) <= ((uint32_t)16383)) +/** + * @} + */ + + + + + + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +/* Function used to set the ADC configuration to the default reset state *****/ +void ADC_DeInit(void); + +/* Initialization and Configuration functions *********************************/ +void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct); +void ADC_StructInit(ADC_InitTypeDef* ADC_InitStruct); +void ADC_InjectedStructInit(ADC_InjectedConfTypeDef* ADC_InjectedConf); +void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState); +void ADC_ClockModeConfig(uint32_t ClockMode); +void ADC_MultiModeConfig(ADC_MultiModeTypeDef* MultiMode); + +/* Power saving functions *****************************************************/ +void ADC_AutoPowerOffCmd(ADC_TypeDef* ADCx, FunctionalState NewState); +void ADC_ADC_AutDlyModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState); +void ADC_DeepPWDModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState); +void ADC_InternalRegulatorCmd(ADC_TypeDef* ADCx, FunctionalState NewState); + +/* Analog Watchdog configuration functions ************************************/ +void ADC_AnalogWDGConfig(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct, ADC_AnalogWDGConfTypeDef* AnalogWDGConfig); + +/* Temperature Sensor , Vrefint and Vbat management function ... ******************/ +void ADC_TempSensorCmd(FunctionalState NewState); +void ADC_VrefintCmd(FunctionalState NewState); +void ADC_VbatCmd(FunctionalState NewState); +void ADC_BatteryAutoChargingCmd(FunctionalState NewState); +void ADC_AWD2MonitorVbatCmd(FunctionalState NewState); +void ADC_AWD3MonitorVbatCmd(FunctionalState NewState); + +/* Channels Configuration functions *******************************************/ +void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, ADC_ChannelConfTypeDef* RegularConfig); +void ADC_InjectedChannelConfig(ADC_TypeDef* ADCx, ADC_InjectedConfTypeDef* InjectedConfig); +void ADC_ContinuousModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState); +void ADC_AutoDelayModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState); +void ADC_AutoInjectedModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState); +void ADC_REG_DiscModeCmd(ADC_TypeDef* ADCx, uint32_t DiscontNum); +void ADC_INJ_DiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState); +void ADC_OverrunModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState); +uint32_t ADC_StartSingleCalibration(ADC_TypeDef* ADCx); +uint32_t ADC_StartDiffCalibration(ADC_TypeDef* ADCx); +uint32_t ADC_GetSingleCalibrationFactor(ADC_TypeDef* ADCx); +uint32_t ADC_GetDiffCalibrationFactor(ADC_TypeDef* ADCx); +void ADC_SetSingleCalibrationFactor(ADC_TypeDef* ADCx, uint32_t Calfact_S); +void ADC_SetDiffCalibrationFactor(ADC_TypeDef* ADCx, uint32_t Calfact_D); +void ADC_REG_StartOfConversion(ADC_TypeDef* ADCx); +void ADC_REG_StopOfConversion(ADC_TypeDef* ADCx); +void ADC_INJ_StartOfConversion(ADC_TypeDef* ADCx); +void ADC_INJ_StopOfConversion(ADC_TypeDef* ADCx); +uint16_t ADC_REG_GetConversionValue(ADC_TypeDef* ADCx); +uint16_t ADC_INJ_GetConversionValue(ADC_TypeDef* ADCx, uint32_t INJ_RANK); +uint32_t ADC_ReadMultiConversionData32(void); +void ADC_StartSamplingPhase(ADC_TypeDef* ADCx); +void ADC_StoptSamplingPhase(ADC_TypeDef* ADCx); + +/* Regular Channels DMA Configuration functions *******************************/ +void ADC_DMACmd(ADC_TypeDef* ADCx, FunctionalState NewState); +void ADC_DMARequestModeConfig(ADC_TypeDef* ADCx, uint32_t ADC_DMARequestMode); + +/* Interrupts and flags management functions **********************************/ +void ADC_ITConfig(ADC_TypeDef* ADCx, uint32_t ADC_IT, FunctionalState NewState); +FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint32_t ADC_FLAG); +FlagStatus ADC_GetMultiFlagStatus(ADC_TypeDef* ADCx, uint32_t ADC_FLAG); +void ADC_ClearFlag(ADC_TypeDef* ADCx, uint32_t ADC_FLAG); +ITStatus ADC_GetITStatus(ADC_TypeDef* ADCx, uint32_t ADC_IT); +void ADC_ClearITPendingBit(ADC_TypeDef* ADCx, uint32_t ADC_IT); + + +#ifdef __cplusplus +} +#endif + +#endif /*__ft32f4XX_ADC_H */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_comp.h b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_comp.h new file mode 100644 index 00000000000..c8d2a35fac3 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_comp.h @@ -0,0 +1,441 @@ +/** + ****************************************************************************** + * @file ft32f4xx_comp.h + * @author FMD AE + * @brief This file contains all the functions prototypes for the comparator + * firmware library. + * @version V1.0.0 + * @date 2025-03-20 + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __FT32F4XX_COMP_H +#define __FT32F4XX_COMP_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx.h" +/* Exported types ------------------------------------------------------------*/ +/** @defgroup COMP_Exported_Types COMP Exported Types + * @{ + */ + +/** + * @brief COMP Init structure definition + */ +typedef struct +{ + + uint32_t COMP_VipSel; /*!< Select the positive input of the comparator. + This parameter can be a value of @ref COMP_VipSel */ + + uint32_t COMP_VinSel; /*!< Select the negative input of the comparator. + This parameter can be a value of @ref COMP_VinSel */ + + uint32_t COMP_Hysteresis_Sel; /*!< Set comparator COMP_hysteresis mode of the input minus. + This parameter can be a value of @ref COMP_Hysteresis */ + + uint32_t COMP_Blanking_Sel; /*!< Set comparator blanking source. + This parameter can be a value of @ref COMP_BlankingSrce */ + + uint32_t COMP_Pol; /*!< Select the output polarity of the comparator. + This parameter can be a value of @ref COMP_Pol */ +} COMP_InitTypeDef; + +/** + * @brief HAL COMP state machine: HAL COMP states definition + */ + + + + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup COMP_Exported_Constants + * @{ + */ + +/** @defgroup COMP_Selection + * @{ + */ +#define COMP_Selection_COMP1 ((uint32_t)0x00000001) /*!< COMP1 Selection */ +#define COMP_Selection_COMP2 ((uint32_t)0x00000002) /*!< COMP2 Selection */ +#define COMP_Selection_COMP3 ((uint32_t)0x00000003) /*!< COMP3 Selection */ +#define COMP_Selection_COMP4 ((uint32_t)0x00000004) /*!< COMP4 Selection */ +#define COMP_Selection_COMP5 ((uint32_t)0x00000005) /*!< COMP5 Selection */ +#define COMP_Selection_COMP6 ((uint32_t)0x00000006) /*!< COMP6 Selection */ + +#define IS_COMP_ALL_PERIPH(PERIPH) (((PERIPH) == COMP_Selection_COMP1) || \ + ((PERIPH) == COMP_Selection_COMP2) || \ + ((PERIPH) == COMP_Selection_COMP3) || \ + ((PERIPH) == COMP_Selection_COMP4) || \ + ((PERIPH) == COMP_Selection_COMP5) || \ + ((PERIPH) == COMP_Selection_COMP6)) + +/** @defgroup COMP_WIN_Selection + * @{comp3 comp4 comp5 comp6 + */ +#define COMP_WIN_Selection_COMP3 ((uint32_t)0x00000003) /*!< COMP3 Selection */ +#define COMP_WIN_Selection_COMP4 ((uint32_t)0x00000004) /*!< COMP4 Selection */ +#define COMP_WIN_Selection_COMP5 ((uint32_t)0x00000005) /*!< COMP5 Selection */ +#define COMP_WIN_Selection_COMP6 ((uint32_t)0x00000006) /*!< COMP6 Selection */ + +#define IS_COMP_WIN_PERIPH(PERIPH) (((PERIPH) == COMP_WIN_Selection_COMP3) || \ + ((PERIPH) == COMP_WIN_Selection_COMP4) || \ + ((PERIPH) == COMP_WIN_Selection_COMP5) || \ + ((PERIPH) == COMP_WIN_Selection_COMP6)) + + +/** @defgroup COMP_1_2_Selection + * @{comp1 comp2 + */ +#define COMP_1_2_Selection_COMP1 ((uint32_t)0x00000001) /*!< COMP3 Selection */ +#define COMP_1_2_Selection_COMP2 ((uint32_t)0x00000002) /*!< COMP4 Selection */ + +#define IS_COMP_1_2_PERIPH(PERIPH) (((PERIPH) == COMP_1_2_Selection_COMP1) || \ + ((PERIPH) == COMP_1_2_Selection_COMP2)) + + +/** @defgroup COMP_qualsel + * @{ x= 1/2 (comp1 comp2) + */ +#define COMPx_QUALSEL_NONE ((uint32_t)0x00000000) /*!< COMPx_QUALICIFATION */ +#define COMPx_QUALSEL_1C ((uint32_t)0x00000200) /*!< COMPx_QUALICIFATION */ +#define COMPx_QUALSEL_2C ((uint32_t)0x00000400) /*!< COMPx_QUALICIFATION */ +#define COMPx_QUALSEL_3C ((uint32_t)0x00000600) /*!< COMPx_QUALICIFATION */ +#define COMPx_QUALSEL_4C ((uint32_t)0x00000800) /*!< COMPx_QUALICIFATION */ +#define COMPx_QUALSEL_5C ((uint32_t)0x00000a00) /*!< COMPx_QUALICIFATION */ +#define COMPx_QUALSEL_6C ((uint32_t)0x00000c00) /*!< COMPx_QUALICIFATION */ +#define COMPx_QUALSEL_7C ((uint32_t)0x00000e00) /*!< COMPx_QUALICIFATION */ +#define COMPx_QUALSEL_8C ((uint32_t)0x00001000) /*!< COMPx_QUALICIFATION */ +#define COMPx_QUALSEL_9C ((uint32_t)0x00001200) /*!< COMPx_QUALICIFATION */ +#define COMPx_QUALSEL_10C ((uint32_t)0x00001400) /*!< COMPx_QUALICIFATION */ +#define COMPx_QUALSEL_11C ((uint32_t)0x00001600) /*!< COMPx_QUALICIFATION */ +#define COMPx_QUALSEL_12C ((uint32_t)0x00001800) /*!< COMPx_QUALICIFATION */ +#define COMPx_QUALSEL_13C ((uint32_t)0x00001a00) /*!< COMPx_QUALICIFATION */ +#define COMPx_QUALSEL_14C ((uint32_t)0x00001c00) /*!< COMPx_QUALICIFATION */ +#define COMPx_QUALSEL_15C ((uint32_t)0x00001e00) /*!< COMPx_QUALICIFATION */ +#define COMPx_QUALSEL_16C ((uint32_t)0x00002000) /*!< COMPx_QUALICIFATION */ +#define COMPx_QUALSEL_17C ((uint32_t)0x00002200) /*!< COMPx_QUALICIFATION */ +#define COMPx_QUALSEL_18C ((uint32_t)0x00002400) /*!< COMPx_QUALICIFATION */ +#define COMPx_QUALSEL_19C ((uint32_t)0x00002600) /*!< COMPx_QUALICIFATION */ +#define COMPx_QUALSEL_20C ((uint32_t)0x00002800) /*!< COMPx_QUALICIFATION */ +#define COMPx_QUALSEL_21C ((uint32_t)0x00002a00) /*!< COMPx_QUALICIFATION */ +#define COMPx_QUALSEL_22C ((uint32_t)0x00002c00) /*!< COMPx_QUALICIFATION */ +#define COMPx_QUALSEL_23C ((uint32_t)0x00002e00) /*!< COMPx_QUALICIFATION */ +#define COMPx_QUALSEL_24C ((uint32_t)0x00003000) /*!< COMPx_QUALICIFATION */ +#define COMPx_QUALSEL_25C ((uint32_t)0x00003200) /*!< COMPx_QUALICIFATION */ +#define COMPx_QUALSEL_26C ((uint32_t)0x00003400) /*!< COMPx_QUALICIFATION */ +#define COMPx_QUALSEL_27C ((uint32_t)0x00003600) /*!< COMPx_QUALICIFATION */ +#define COMPx_QUALSEL_28C ((uint32_t)0x00003800) /*!< COMPx_QUALICIFATION */ +#define COMPx_QUALSEL_29C ((uint32_t)0x00003a00) /*!< COMPx_QUALICIFATION */ +#define COMPx_QUALSEL_30C ((uint32_t)0x00003c00) /*!< COMPx_QUALICIFATION */ +#define COMPx_QUALSEL_31C ((uint32_t)0x00003e00) /*!< COMPx_QUALICIFATION */ + +#define IS_COMP_QUALSER_PERIPH(QUALSEL) (((QUALSEL) == COMPx_QUALSEL_NONE) || \ + ((QUALSEL) == COMPx_QUALSEL_1C ) || \ + ((QUALSEL) == COMPx_QUALSEL_2C ) || \ + ((QUALSEL) == COMPx_QUALSEL_3C ) || \ + ((QUALSEL) == COMPx_QUALSEL_4C ) || \ + ((QUALSEL) == COMPx_QUALSEL_5C ) || \ + ((QUALSEL) == COMPx_QUALSEL_6C ) || \ + ((QUALSEL) == COMPx_QUALSEL_7C ) || \ + ((QUALSEL) == COMPx_QUALSEL_8C ) || \ + ((QUALSEL) == COMPx_QUALSEL_9C ) || \ + ((QUALSEL) == COMPx_QUALSEL_10C ) || \ + ((QUALSEL) == COMPx_QUALSEL_11C ) || \ + ((QUALSEL) == COMPx_QUALSEL_12C ) || \ + ((QUALSEL) == COMPx_QUALSEL_13C ) || \ + ((QUALSEL) == COMPx_QUALSEL_14C ) || \ + ((QUALSEL) == COMPx_QUALSEL_15C ) || \ + ((QUALSEL) == COMPx_QUALSEL_16C ) || \ + ((QUALSEL) == COMPx_QUALSEL_17C ) || \ + ((QUALSEL) == COMPx_QUALSEL_18C ) || \ + ((QUALSEL) == COMPx_QUALSEL_19C ) || \ + ((QUALSEL) == COMPx_QUALSEL_20C ) || \ + ((QUALSEL) == COMPx_QUALSEL_21C ) || \ + ((QUALSEL) == COMPx_QUALSEL_22C ) || \ + ((QUALSEL) == COMPx_QUALSEL_23C ) || \ + ((QUALSEL) == COMPx_QUALSEL_24C ) || \ + ((QUALSEL) == COMPx_QUALSEL_25C ) || \ + ((QUALSEL) == COMPx_QUALSEL_26C ) || \ + ((QUALSEL) == COMPx_QUALSEL_27C ) || \ + ((QUALSEL) == COMPx_QUALSEL_28C ) || \ + ((QUALSEL) == COMPx_QUALSEL_29C ) || \ + ((QUALSEL) == COMPx_QUALSEL_30C ) || \ + ((QUALSEL) == COMPx_QUALSEL_31C ) ) + + +/** @defgroup COMP_VipSel + * @{ + */ +#define COMP1_VIP_SEL_PAD_PC5 ((uint32_t)0x00000000) +#define COMP1_VIP_SEL_PAD_PB2 ((uint32_t)0x00000100) + +#define COMP2_VIP_SEL_PAD_PB4 ((uint32_t)0x00000000) +#define COMP2_VIP_SEL_PAD_PB6 ((uint32_t)0x00000100) + +#define COMP3_VIP_SEL_PAD_PA0 ((uint32_t)0x00000000) +#define COMP3_VIP_SEL_PAD_PC1 ((uint32_t)0x00000100) +#define COMP3_VIP_SEL_PAD_PA2 ((uint32_t)0x00000200) +#define COMP3_VIP_SEL_PAD_PA5 ((uint32_t)0x00000300) + +#define COMP4_VIP_SEL_PAD_PA2 ((uint32_t)0x00000000) +#define COMP4_VIP_SEL_PAD_PA5 ((uint32_t)0x00000100) +#define COMP4_VIP_SEL_PAD_PA0 ((uint32_t)0x00000200) +#define COMP4_VIP_SEL_PAD_PC1 ((uint32_t)0x00000300) + +#define COMP5_VIP_SEL_PAD_PB11 ((uint32_t)0x00000000) +#define COMP5_VIP_SEL_PAD_PB14 ((uint32_t)0x00000100) +#define COMP5_VIP_SEL_PAD_PA15 ((uint32_t)0x00000200) +#define COMP5_VIP_SEL_PAD_PC11 ((uint32_t)0x00000300) + +#define COMP6_VIP_SEL_PAD_PA15 ((uint32_t)0x00000000) +#define COMP6_VIP_SEL_PAD_PC11 ((uint32_t)0x00000100) +#define COMP6_VIP_SEL_PAD_PB11 ((uint32_t)0x00000200) +#define COMP6_VIP_SEL_PAD_PB14 ((uint32_t)0x00000300) + + +#define IS_COMP1_VIP_SEL(INPUT) (((INPUT) ==COMP1_VIP_SEL_PAD_PC5 ) || \ + ((INPUT) ==COMP1_VIP_SEL_PAD_PB2 ) ) + +#define IS_COMP2_VIP_SEL(INPUT) (((INPUT) ==COMP2_VIP_SEL_PAD_PB4 ) || \ + ((INPUT) ==COMP2_VIP_SEL_PAD_PB6 ) ) + +#define IS_COMP3_VIP_SEL(INPUT) (((INPUT) ==COMP3_VIP_SEL_PAD_PA0 ) || \ + ((INPUT) ==COMP3_VIP_SEL_PAD_PC1 ) || \ + ((INPUT) ==COMP3_VIP_SEL_PAD_PA2 ) || \ + ((INPUT) ==COMP3_VIP_SEL_PAD_PA5 ) ) + +#define IS_COMP4_VIP_SEL(INPUT) (((INPUT) == COMP4_VIP_SEL_PAD_PA2) || \ + ((INPUT) ==COMP4_VIP_SEL_PAD_PA5 ) || \ + ((INPUT) ==COMP4_VIP_SEL_PAD_PA0 ) || \ + ((INPUT) ==COMP4_VIP_SEL_PAD_PC1 ) ) + +#define IS_COMP5_VIP_SEL(INPUT) (((INPUT) ==COMP5_VIP_SEL_PAD_PB11 ) || \ + ((INPUT) ==COMP5_VIP_SEL_PAD_PB14 ) || \ + ((INPUT) ==COMP5_VIP_SEL_PAD_PA15 ) || \ + ((INPUT) ==COMP5_VIP_SEL_PAD_PC11 ) ) + +#define IS_COMP6_VIP_SEL(INPUT) (((INPUT) == COMP6_VIP_SEL_PAD_PA15) || \ + ((INPUT) ==COMP6_VIP_SEL_PAD_PC11 ) || \ + ((INPUT) ==COMP6_VIP_SEL_PAD_PB11 ) || \ + ((INPUT) ==COMP6_VIP_SEL_PAD_PB14 ) ) + +/** @defgroup COMP_VinSel + * @{ + */ +#define COMP1_VIN_1_4VREFINT ((uint32_t)0x00000000 | VREFEN) +#define COMP1_VIN_1_2VREFINT ((uint32_t)0x00000010 | VREFEN) +#define COMP1_VIN_3_4VREFINT ((uint32_t)0x00000020 | VREFEN) +#define COMP1_VIN_VREFINT ((uint32_t)0x00000030 | VREFEN) +#define COMP1_VIN_DAC1_CH1 ((uint32_t)0x00000040) +#define COMP1_VIN_DAC2_CH1 ((uint32_t)0x00000050) +#define COMP1_VIN_SEL_PAD_PB1 ((uint32_t)0x00000060) +#define COMP1_VIN_SEL_PAD_PC4 ((uint32_t)0x00000070) + +#define COMP2_VIN_1_4VREFINT ((uint32_t)0x00000000 | VREFEN) +#define COMP2_VIN_1_2VREFINT ((uint32_t)0x00000010 | VREFEN) +#define COMP2_VIN_3_4VREFINT ((uint32_t)0x00000020 | VREFEN) +#define COMP2_VIN_VREFINT ((uint32_t)0x00000030 | VREFEN) +#define COMP2_VIN_DAC1_CH1 ((uint32_t)0x00000040) +#define COMP2_VIN_DAC2_CH1 ((uint32_t)0x00000050) +#define COMP2_VIN_SEL_PAD_PB3 ((uint32_t)0x00000060) +#define COMP2_VIN_SEL_PAD_PB7 ((uint32_t)0x00000070) + +#define COMP3_VIN_3_4VREFINT ((uint32_t)0x00000020 | VREFEN) +#define COMP3_VIN_VREFINT ((uint32_t)0x00000030 | VREFEN) +#define COMP3_VIN_DAC1_CH1 ((uint32_t)0x00000040) +#define COMP3_VIN_DAC2_CH1 ((uint32_t)0x00000050) +#define COMP3_VIN_SEL_PAD_PC3 ((uint32_t)0x00000060) +#define COMP3_VIN_SEL_PAD_PC0 ((uint32_t)0x00000070) + +#define COMP4_VIN_1_4VREFINT ((uint32_t)0x00000000 | VREFEN) +#define COMP4_VIN_1_2VREFINT ((uint32_t)0x00000010 | VREFEN) +#define COMP4_VIN_3_4VREFINT ((uint32_t)0x00000020 | VREFEN) +#define COMP4_VIN_VREFINT ((uint32_t)0x00000030 | VREFEN) +#define COMP4_VIN_DAC1_CH1 ((uint32_t)0x00000040) +#define COMP4_VIN_DAC2_CH1 ((uint32_t)0x00000050) +#define COMP4_VIN_SEL_PAD_PA1 ((uint32_t)0x00000060) +#define COMP4_VIN_SEL_PAD_PA4 ((uint32_t)0x00000070) + +#define COMP5_VIN_3_4VREFINT ((uint32_t)0x00000020 | VREFEN) +#define COMP5_VIN_VREFINT ((uint32_t)0x00000030 | VREFEN) +#define COMP5_VIN_DAC1_CH1 ((uint32_t)0x00000040) +#define COMP5_VIN_DAC2_CH1 ((uint32_t)0x00000050) +#define COMP5_VIN_SEL_PAD_PB10 ((uint32_t)0x00000060) +#define COMP5_VIN_SEL_PAD_PB15 ((uint32_t)0x00000070) + +#define COMP6_VIN_1_4VREFINT ((uint32_t)0x00000000 | VREFEN) +#define COMP6_VIN_1_2VREFINT ((uint32_t)0x00000010 | VREFEN) +#define COMP6_VIN_3_4VREFINT ((uint32_t)0x00000020 | VREFEN) +#define COMP6_VIN_VREFINT ((uint32_t)0x00000030 | VREFEN) +#define COMP6_VIN_DAC1_CH1 ((uint32_t)0x00000040) +#define COMP6_VIN_DAC2_CH1 ((uint32_t)0x00000050) +#define COMP6_VIN_SEL_PAD_PC10 ((uint32_t)0x00000060) +#define COMP6_VIN_SEL_PAD_PC12 ((uint32_t)0x00000070) + + +#define IS_COMP1_VIN_SEL(INPUT) (((INPUT) ==COMP1_VIN_1_4VREFINT ) || \ + ((INPUT) == COMP1_VIN_1_2VREFINT ) || \ + ((INPUT) == COMP1_VIN_3_4VREFINT ) || \ + ((INPUT) == COMP1_VIN_VREFINT ) || \ + ((INPUT) == COMP1_VIN_DAC1_CH1 ) || \ + ((INPUT) == COMP1_VIN_DAC2_CH1 ) || \ + ((INPUT) == COMP1_VIN_SEL_PAD_PB1) || \ + ((INPUT) == COMP1_VIN_SEL_PAD_PC4) ) + +#define IS_COMP2_VIN_SEL(INPUT) (((INPUT) == COMP2_VIN_1_4VREFINT ) || \ + ((INPUT) ==COMP2_VIN_1_2VREFINT ) || \ + ((INPUT) ==COMP2_VIN_3_4VREFINT ) || \ + ((INPUT) ==COMP2_VIN_VREFINT ) || \ + ((INPUT) ==COMP2_VIN_DAC1_CH1 ) || \ + ((INPUT) ==COMP2_VIN_DAC2_CH1 ) || \ + ((INPUT) ==COMP2_VIN_SEL_PAD_PB3 ) || \ + ((INPUT) ==COMP2_VIN_SEL_PAD_PB7 ) ) + +#define IS_COMP3_VIN_SEL(INPUT) (((INPUT) == COMP3_VIN_3_4VREFINT ) || \ + ((INPUT) ==COMP3_VIN_VREFINT ) || \ + ((INPUT) ==COMP3_VIN_DAC1_CH1 ) || \ + ((INPUT) ==COMP3_VIN_DAC2_CH1 ) || \ + ((INPUT) ==COMP3_VIN_SEL_PAD_PC3 ) || \ + ((INPUT) ==COMP3_VIN_SEL_PAD_PC0 ) ) + +#define IS_COMP4_VIN_SEL(INPUT) (((INPUT) ==COMP4_VIN_1_4VREFINT ) || \ + ((INPUT) ==COMP4_VIN_1_2VREFINT ) || \ + ((INPUT) ==COMP4_VIN_3_4VREFINT ) || \ + ((INPUT) ==COMP4_VIN_VREFINT ) || \ + ((INPUT) ==COMP4_VIN_DAC1_CH1 ) || \ + ((INPUT) ==COMP4_VIN_DAC2_CH1 ) || \ + ((INPUT) ==COMP4_VIN_SEL_PAD_PA1 ) || \ + ((INPUT) ==COMP4_VIN_SEL_PAD_PA4 ) ) + +#define IS_COMP5_VIN_SEL(INPUT) (((INPUT) ==COMP5_VIN_3_4VREFINT ) || \ + ((INPUT) ==COMP5_VIN_VREFINT ) || \ + ((INPUT) ==COMP5_VIN_DAC1_CH1 ) || \ + ((INPUT) ==COMP5_VIN_DAC2_CH1 ) || \ + ((INPUT) ==COMP5_VIN_SEL_PAD_PB10 ) || \ + ((INPUT) ==COMP5_VIN_SEL_PAD_PB15 ) ) + +#define IS_COMP6_VIN_SEL(INPUT) (((INPUT) ==COMP6_VIN_1_4VREFINT ) || \ + ((INPUT) ==COMP6_VIN_1_2VREFINT ) || \ + ((INPUT) ==COMP6_VIN_3_4VREFINT ) || \ + ((INPUT) ==COMP6_VIN_VREFINT ) || \ + ((INPUT) ==COMP6_VIN_DAC1_CH1 ) || \ + ((INPUT) ==COMP6_VIN_DAC2_CH1 ) || \ + ((INPUT) ==COMP6_VIN_SEL_PAD_PC10 ) || \ + ((INPUT) ==COMP6_VIN_SEL_PAD_PC12 )) + +/** @defgroup COMP_Blanking_Sel + * @{ COMPx = comp1 /comp2/ comp3/ comp4/ comp5 /comp6 + */ +#define COMPx_BLANKING_NONE ((uint32_t)0x00000000) +#define COMPx_BLANKING_TIM1 ((uint32_t)0x00100000) +#define COMPx_BLANKING_TIM2 ((uint32_t)0x00200000) +#define COMPx_BLANKING_TIM3 ((uint32_t)0x00300000) +#define COMPx_BLANKING_TIM4 ((uint32_t)0x00400000) +#define COMPx_BLANKING_TIM8 ((uint32_t)0x00700000) +#define IS_COMP_BLANKING(INPUT) (((INPUT) == COMPx_BLANKING_NONE ) || \ + ((INPUT) == COMPx_BLANKING_TIM1 ) || \ + ((INPUT) == COMPx_BLANKING_TIM2 ) || \ + ((INPUT) == COMPx_BLANKING_TIM3 ) || \ + ((INPUT) == COMPx_BLANKING_TIM4 ) || \ + ((INPUT) == COMPx_BLANKING_TIM8 )) + +/** @defgroup COMP_Hysteresis_Sel + * @{ COMPx = comp1 /comp2/ comp3/ comp4/ comp5 /comp6 + */ +#define COMPx_HYST_NONE ((uint32_t)0x00000000) +#define COMPx_HYST_18MV ((uint32_t)0x00020000) +#define COMPx_HYST_36MV ((uint32_t)0x00040000) +#define COMPx_HYST_54MV ((uint32_t)0x00060000) +#define IS_COMP_HYSTERESIS(INPUT) (((INPUT) == COMPx_HYST_NONE ) || \ + ((INPUT) == COMPx_HYST_18MV ) || \ + ((INPUT) == COMPx_HYST_36MV ) || \ + ((INPUT) == COMPx_HYST_54MV )) + +/** @defgroup COMP_Pol + * @{COMPx = comp1 /comp2/ comp3/ comp4/ comp5 /comp6 + */ +#define COMPx_POL_NOT_INVERT ((uint32_t)0x00000000) +#define COMPx_POL_INVERT ((uint32_t)0x00008000) + +#define IS_COMP_POL(POL) (((POL) == COMPx_POL_NOT_INVERT)|| \ + ( (POL) == COMPx_POL_INVERT) ) + +/** @defgroup COMP_RAMP_SEL + * @{COMPx = comp1 /comp2 + */ +#define COMPx_RAMPSRC_PWM1 ((uint32_t)0x00000000) +#define COMPx_RAMPSRC_PWM2 ((uint32_t)0x01000000) +#define COMPx_RAMPSRC_PWM3 ((uint32_t)0x02000000) +#define COMPx_RAMPSRC_PWM4 ((uint32_t)0x03000000) + +#define IS_COMP_RAMPSRC(EPWM) (((EPWM) == COMPx_RAMPSRC_PWM1)|| \ + ((EPWM) == COMPx_RAMPSRC_PWM2)|| \ + ((EPWM) == COMPx_RAMPSRC_PWM3)|| \ + ((EPWM) == COMPx_RAMPSRC_PWM4)) + + + +/** @defgroup COMP_OutputLevel + * @{ + */ +/* When output polarity is not inverted, comparator output is high when + the non-inverting input is at a higher voltage than the inverting input */ +#define COMP_OutputLevel_High ((uint32_t)0x40000000) +/* When output polarity is not inverted, comparator output is low when + the non-inverting input is at a lower voltage than the inverting input*/ +#define COMP_OutputLevel_Low ((uint32_t)0x00000000) + + +#define IS_COMP_OUTPUT_LEVEL(LEVEL) (((LEVEL) == COMP_CSR_COMP1OUT) || \ + ((LEVEL) == COMP_CSR_COMP2OUT)) + + + + + +/* Initialization and Configuration functions *********************************/ +void COMP_Init(uint32_t COMP_Selection, COMP_InitTypeDef* COMP_InitStruct); +void COMP_DeInit(uint32_t COMP_Selection); + +/* Function used to set the COMP configuration to the default reset state ****/ +void COMP_Cmd(uint32_t COMP_Selection, FunctionalState NewState); +void COMP_WindowCmd(FunctionalState NewState, uint32_t COMP_Selection); +void COMPx_RAMP_EPWM_SEL(uint32_t COMP_1_2_Selection, uint32_t COMP_RAMP_SEL); +void COMPx_RAMP_RMPRLDIS(FunctionalState NewState, uint32_t COMP_1_2_Selection); +void COMP_RAMPVAL_SHADOW_LOAD(uint32_t COMP_1_2_Selection, uint16_t COMPx_RAMPDECVAL_SHADOW, uint16_t COMPx_RAMPMAXREF_SHADOW); + +void COMPx_QUALIFICATION(FunctionalState NewState, uint32_t COMP_1_2_Selection, uint32_t COMP_qualsel); +void COMPx_Resistor(FunctionalState NewState, uint32_t COMP_1_2_Selection); +void COMP_LockConfig(uint32_t COMP_Selection); +uint32_t COMP_GetOutputLevel(uint32_t COMP_Selection); + +#ifdef __cplusplus +} +#endif + +#endif /* __FT32F0XX_COMP_H */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ + + + + + + + + diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_crc.h b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_crc.h new file mode 100644 index 00000000000..947da3cc98c --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_crc.h @@ -0,0 +1,97 @@ +/** + ****************************************************************************** + * @file ft32f4xx_crc.h + * @author FMD AE + * @brief This file contains all the functions prototypes for + * the CRC firmware library. + * @version V1.0.0 + * @date 2025-03-25 + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __FT32F4XX_CRC_H +#define __FT32F4XX_CRC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/*!< Includes ----------------------------------------------------------------*/ +#include "ft32f4xx.h" + + +/** @addtogroup CRC + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup CRC_Exported_Constants I2S Exported Constants + * @{ + */ + +/** @defgroup CRC_ReverseInputData + * @{ + */ +#define CRC_ReverseInputData_No ((uint32_t)0x00000000) /*!< No reverse operation of Input Data */ +#define CRC_ReverseInputData_8bits CRC_CR_REV_IN_0 /*!< Reverse operation of Input Data on 8 bits */ +#define CRC_ReverseInputData_16bits CRC_CR_REV_IN_1 /*!< Reverse operation of Input Data on 16 bits */ +#define CRC_ReverseInputData_32bits CRC_CR_REV_IN /*!< Reverse operation of Input Data on 32 bits */ + +#define IS_CRC_REVERSE_INPUT_DATA(DATA) (((DATA) == CRC_ReverseInputData_No) || \ + ((DATA) == CRC_ReverseInputData_8bits) || \ + ((DATA) == CRC_ReverseInputData_16bits) || \ + ((DATA) == CRC_ReverseInputData_32bits)) + +/** + * @} + */ + +/** + * @} + */ + +/* Exported functions ------------------------------------------------------- */ +/** @addtogroup CRC_Exported_Functions + * @{ + */ +/* Configuration of the CRC computation unit **********************************/ +void CRC_DeInit(void); +void CRC_ResetDR(void); +void CRC_ReverseInputDataSelect(uint32_t CRC_ReverseInputData); +void CRC_ReverseOutputDataCmd(FunctionalState NewState); +void CRC_SetINITRegister(uint32_t CRC_InitValue); +void CRC_SetCRegister(uint32_t CRC_CRValue); + +/* CRC computation ************************************************************/ +uint32_t CRC_CalcCRC(uint32_t CRC_Data); +uint32_t CRC_CalcCRC16bits(uint16_t CRC_Data); +uint32_t CRC_CalcCRC8bits(uint8_t CRC_Data); +uint32_t CRC_CalcBlockCRC(uint32_t pBuffer[], uint32_t BufferLength); +uint32_t CRC_GetCRC(void); + +/* Independent register (IDR) access (write/read) *****************************/ +void CRC_SetIDRegister(uint8_t CRC_IDValue); +uint8_t CRC_GetIDRegister(void); + +/* Control register (CR) access (read) *****************************/ +uint32_t CRC_GetCRegister(void); + +/* Initial value register (INIT) access (read) *****************************/ +uint32_t CRC_GetINITRegister(void); + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __FT32F4XX_CRC_H */ + +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_crs.h b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_crs.h new file mode 100644 index 00000000000..ccaab2dc75d --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_crs.h @@ -0,0 +1,141 @@ +/** + ****************************************************************************** + * @file ft32f4xx_crs.h + ****************************************************************************** +**/ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __FT32F4XX_CRS_H +#define __FT32F4XX_CRS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/*!< Includes ----------------------------------------------------------------*/ +#include "ft32f4xx.h" + + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup CRS_Interrupt_Sources + * @{ + */ +#define CRS_IT_SYNCOK CRS_ISR_SYNCOKF /*!< SYNC event OK */ +#define CRS_IT_SYNCWARN CRS_ISR_SYNCWARNF /*!< SYNC warning */ +#define CRS_IT_ERR CRS_ISR_ERRF /*!< error */ +#define CRS_IT_ESYNC CRS_ISR_ESYNCF /*!< Expected SYNC */ +#define CRS_IT_TRIMOVF CRS_ISR_TRIMOVF /*!< Trimming overflow or underflow */ +#define CRS_IT_SYNCERR CRS_ISR_SYNCERR /*!< SYNC error */ +#define CRS_IT_SYNCMISS CRS_ISR_SYNCMISS /*!< SYNC missed*/ + +#define IS_CRS_IT(IT) (((IT) == CRS_IT_SYNCOK) || ((IT) == CRS_IT_SYNCWARN) || \ + ((IT) == CRS_IT_ERR) || ((IT) == CRS_IT_ESYNC)) + +#define IS_CRS_GET_IT(IT) (((IT) == CRS_IT_SYNCOK) || ((IT) == CRS_IT_SYNCWARN) || \ + ((IT) == CRS_IT_ERR) || ((IT) == CRS_IT_ESYNC) || \ + ((IT) == CRS_IT_TRIMOVF) || ((IT) == CRS_IT_SYNCERR) || \ + ((IT) == CRS_IT_SYNCMISS)) + +#define IS_CRS_CLEAR_IT(IT) ((IT) != 0x00) + + +/** @defgroup CRS_Flags + * @{ + */ +#define CRS_FLAG_SYNCOK CRS_ISR_SYNCOKF /*!< SYNC event OK */ +#define CRS_FLAG_SYNCWARN CRS_ISR_SYNCWARNF /*!< SYNC warning */ +#define CRS_FLAG_ERR CRS_ISR_ERRF /*!< error */ +#define CRS_FLAG_ESYNC CRS_ISR_ESYNCF /*!< Expected SYNC */ +#define CRS_FLAG_TRIMOVF CRS_ISR_TRIMOVF /*!< Trimming overflow or underflow */ +#define CRS_FLAG_SYNCERR CRS_ISR_SYNCERR /*!< SYNC error */ +#define CRS_FLAG_SYNCMISS CRS_ISR_SYNCMISS /*!< SYNC missed*/ + +#define IS_CRS_FLAG(FLAG) (((FLAG) == CRS_FLAG_SYNCOK) || ((FLAG) == CRS_FLAG_SYNCWARN) || \ + ((FLAG) == CRS_FLAG_ERR) || ((FLAG) == CRS_FLAG_ESYNC) || \ + ((FLAG) == CRS_FLAG_TRIMOVF) || ((FLAG) == CRS_FLAG_SYNCERR) || \ + ((FLAG) == CRS_FLAG_SYNCMISS)) + + +/** @defgroup CRS_Synchro_Source + * @{ + */ +#define CRS_SYNCSource_GPIO ((uint32_t)0x00) /*!< Synchro Signal soucre GPIO */ +#define CRS_SYNCSource_LSE CRS_CFGR_SYNCSRC_0 /*!< Synchro Signal source LSE */ +#define CRS_SYNCSource_USB CRS_CFGR_SYNCSRC_1 /*!< Synchro Signal source USB SOF */ + +#define IS_CRS_SYNC_SOURCE(SOURCE) (((SOURCE) == CRS_SYNCSource_GPIO) || \ + ((SOURCE) == CRS_SYNCSource_LSE) ||\ + ((SOURCE) == CRS_SYNCSource_USB)) + + +/** @defgroup CRS_SynchroDivider + * @{ + */ +#define CRS_SYNC_Div1 ((uint32_t)0x00) /*!< Synchro Signal not divided */ +#define CRS_SYNC_Div2 CRS_CFGR_SYNCDIV_0 /*!< Synchro Signal divided by 2 */ +#define CRS_SYNC_Div4 CRS_CFGR_SYNCDIV_1 /*!< Synchro Signal divided by 4 */ +#define CRS_SYNC_Div8 (CRS_CFGR_SYNCDIV_1 | CRS_CFGR_SYNCDIV_0) /*!< Synchro Signal divided by 8 */ +#define CRS_SYNC_Div16 CRS_CFGR_SYNCDIV_2 /*!< Synchro Signal divided by 16 */ +#define CRS_SYNC_Div32 (CRS_CFGR_SYNCDIV_2 | CRS_CFGR_SYNCDIV_0) /*!< Synchro Signal divided by 32 */ +#define CRS_SYNC_Div64 (CRS_CFGR_SYNCDIV_2 | CRS_CFGR_SYNCDIV_1) /*!< Synchro Signal divided by 64 */ +#define CRS_SYNC_Div128 CRS_CFGR_SYNCDIV /*!< Synchro Signal divided by 128 */ + +#define IS_CRS_SYNC_DIV(DIV) (((DIV) == CRS_SYNC_Div1) || ((DIV) == CRS_SYNC_Div2) ||\ + ((DIV) == CRS_SYNC_Div4) || ((DIV) == CRS_SYNC_Div8) || \ + ((DIV) == CRS_SYNC_Div16) || ((DIV) == CRS_SYNC_Div32) || \ + ((DIV) == CRS_SYNC_Div64) || ((DIV) == CRS_SYNC_Div128)) + + +/** @defgroup CRS_SynchroPolarity + * @{ + */ +#define CRS_SYNCPolarity_Rising ((uint32_t)0x00) /*!< Synchro Active on rising edge */ +#define CRS_SYNCPolarity_Falling CRS_CFGR_SYNCPOL /*!< Synchro Active on falling edge */ + +#define IS_CRS_SYNC_POLARITY(POLARITY) (((POLARITY) == CRS_SYNCPolarity_Rising) || \ + ((POLARITY) == CRS_SYNCPolarity_Falling)) + + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ +/* Configuration of the CRS **********************************/ +void CRS_DeInit(void); +void CRS_AdjustHSI48CalibrationValue(uint8_t CRS_HSI48CalibrationValue); +void CRS_FrequencyErrorCounterCmd(FunctionalState NewState); +void CRS_AutomaticCalibrationCmd(FunctionalState NewState); +void CRS_SoftwareSynchronizationGenerate(void); +void CRS_FrequencyErrorCounterReload(uint32_t CRS_ReloadValue); +void CRS_FrequencyErrorLimitConfig(uint8_t CRS_ErrorLimitValue); +void CRS_SynchronizationPrescalerConfig(uint32_t CRS_Prescaler); +void CRS_SynchronizationSourceConfig(uint32_t CRS_Source); +void CRS_SynchronizationPolarityConfig(uint32_t CRS_Polarity); +uint32_t CRS_GetReloadValue(void); +uint32_t CRS_GetHSI48CalibrationValue(void); +uint32_t CRS_GetFrequencyErrorValue(void); +uint32_t CRS_GetFrequencyErrorDirection(void); + +/* Interrupts and flags management functions **********************************/ +void CRS_ITConfig(uint32_t CRS_IT, FunctionalState NewState); +FlagStatus CRS_GetFlagStatus(uint32_t CRS_FLAG); +void CRS_ClearFlag(uint32_t CRS_FLAG); +ITStatus CRS_GetITStatus(uint32_t CRS_IT); +void CRS_ClearITPendingBit(uint32_t CRS_IT); + +#ifdef __cplusplus +} +#endif + +#endif /* __FT32F4XX_CRS_H */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ + diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_dac.h b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_dac.h new file mode 100644 index 00000000000..54ff328a18e --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_dac.h @@ -0,0 +1,208 @@ +/** + ****************************************************************************** + * @file ft32f4xx_dac.h + * @author FMD xzhang + * @brief This file contains all the functions prototypes for the DAC + * firmware library. + * @version V1.0.0 + * @data 2025-03-26 + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __FT32F4XX_DAC_H +#define __FT32F4XX_DAC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx.h" +/* Exported types ------------------------------------------------------------*/ +/** @defgroup dac Exported_Types dac Exported Types + * @{ + */ +/** + * @brief DAC Init structure definition + */ +typedef struct +{ + + uint32_t DAC_Trigger; /*!< Select the DAC trigger source from Timer or Exti. + This parameter can be a value of @ref DAC_Trigger */ + uint32_t DAC_OutputBuffer; /*!< Specifies whether the DAC channel output buffer is enabled or disabled. + This parameter can be a value of @ref DAC_OutputBuffer */ + uint32_t DAC_Input_sel; /*!< Select the DAC input source. + This parameter can be a value of @ref DAC_Input_sel */ + + uint32_t DAC_Output_sel; /*!< Select the DAC output pins. + This parameter can be a value of @ref DAC_Output_sel*/ + +} DAC_InitTypeDef; + + + +/** @defgroup DAC_1_2_Selection + * @{DAC1 ,DAC2 ,DAC12( dac double) + */ +#define DAC_CHANNEL_1 ((uint32_t)0x00000000) /*!< DAC1 Selection */ +#define DAC_CHANNEL_2 ((uint32_t)0x00000010) /*!< DAC2 Selection */ +#define DAC_CHANNEL_D12 ((uint32_t)0x00000011) /*!< DAC double Selection */ + +#define IS_DAC_1_2_PERIPH(PERIPH) (((PERIPH) == DAC_CHANNEL_1) || \ + ((PERIPH) == DAC_CHANNEL_2) || \ + ((PERIPH) == DAC_CHANNEL_D12)) + + +/** @defgroup Alignment DAC_data_alignment + * @{ + */ +#define DAC_ALIGN_12B_R 0x00000000U +#define DAC_ALIGN_12B_L 0x00000004U +#define DAC_ALIGN_8B_R 0x00000008U + +#define IS_DAC_ALIGN(ALIGN) (((ALIGN) == DAC_ALIGN_12B_R) || \ + ((ALIGN) == DAC_ALIGN_12B_L) || \ + ((ALIGN) == DAC_ALIGN_8B_R)) + + +/** @defgroup DAC_Trigger DAC trigger selection + * @{ DAC1 and DAC2 + */ +#define DAC_TRIGGER_NONE 0x00000000UL /*!< Conversion is automatic once the DAC1_DHRxxxx register has been loaded, and not by external trigger */ +#define DAC_TRIGGER_T2_TRGO (TSEL1_2 | TEN1) /*!< TIM2 TRGO selected as external conversion trigger for DAC channel */ +#define DAC_TRIGGER_T4_TRGO (TSEL1_2 | TSEL1_0 | TEN1) /*!< TIM4 TRGO selected as external conversion trigger for DAC channel */ +#define DAC_TRIGGER_T5_TRGO ( TSEL1_1 | TSEL1_0 | TEN1) /*!< TIM3 TRGO selected as external conversion trigger for DAC channel */ +#define DAC_TRIGGER_T6_TRGO ( TEN1) /*!< Conversion started by software trigger for DAC channel */ +#define DAC_TRIGGER_T7_TRGO ( TSEL1_1 | TEN1) /*!< TIM7 TRGO selected as external conversion trigger for DAC channel */ +#define DAC_TRIGGER_T8_TRGO ( TSEL1_0 | TEN1) /*!< TIM8 TRGO selected as external conversion trigger for DAC channel */ +#define DAC_TRIGGER_EXT_IT9 (TSEL1_2 | TSEL1_1 | TEN1) /*!< EXTI Line9 event selected as external conversion trigger for DAC channel */ +#define DAC_TRIGGER_SOFTWARE (DAC_CR_TSEL1_Msk | TEN1) /*!< Conversion started by software trigger for DAC channel */ + +#define IS_DAC_TRIGGER(TRIGGER) (((TRIGGER) == DAC_TRIGGER_NONE) || \ + ((TRIGGER) == DAC_TRIGGER_T2_TRGO) || \ + ((TRIGGER) == DAC_TRIGGER_T8_TRGO) || \ + ((TRIGGER) == DAC_TRIGGER_T7_TRGO) || \ + ((TRIGGER) == DAC_TRIGGER_T5_TRGO) || \ + ((TRIGGER) == DAC_TRIGGER_T6_TRGO) || \ + ((TRIGGER) == DAC_TRIGGER_T4_TRGO) || \ + ((TRIGGER) == DAC_TRIGGER_EXT_IT9) || \ + ((TRIGGER) == DAC_TRIGGER_SOFTWARE)) + + +/** @defgroup amplitude :DACEx_triangle_amplitude DACEx lfsrunmask triangle amplitude + * @{ + */ +#define DAC_LFSRUNMASK_BIT0 0x00000000UL /*!< Unmask DAC channel LFSR bit0 for noise wave generation */ +#define DAC_LFSRUNMASK_BITS1_0 ( MAMP1_0) /*!< Unmask DAC channel LFSR bit[1:0] for noise wave generation */ +#define DAC_LFSRUNMASK_BITS2_0 ( MAMP1_1 ) /*!< Unmask DAC channel LFSR bit[2:0] for noise wave generation */ +#define DAC_LFSRUNMASK_BITS3_0 ( MAMP1_1 | MAMP1_0) /*!< Unmask DAC channel LFSR bit[3:0] for noise wave generation */ +#define DAC_LFSRUNMASK_BITS4_0 ( MAMP1_2 ) /*!< Unmask DAC channel LFSR bit[4:0] for noise wave generation */ +#define DAC_LFSRUNMASK_BITS5_0 ( MAMP1_2 | MAMP1_0) /*!< Unmask DAC channel LFSR bit[5:0] for noise wave generation */ +#define DAC_LFSRUNMASK_BITS6_0 ( MAMP1_2 | MAMP1_1 ) /*!< Unmask DAC channel LFSR bit[6:0] for noise wave generation */ +#define DAC_LFSRUNMASK_BITS7_0 ( MAMP1_2 | MAMP1_1 | MAMP1_0) /*!< Unmask DAC channel LFSR bit[7:0] for noise wave generation */ +#define DAC_LFSRUNMASK_BITS8_0 (MAMP1_3 ) /*!< Unmask DAC channel LFSR bit[8:0] for noise wave generation */ +#define DAC_LFSRUNMASK_BITS9_0 (MAMP1_3 | MAMP1_0) /*!< Unmask DAC channel LFSR bit[9:0] for noise wave generation */ +#define DAC_LFSRUNMASK_BITS10_0 (MAMP1_3 | MAMP1_1 ) /*!< Unmask DAC channel LFSR bit[10:0] for noise wave generation */ +#define DAC_LFSRUNMASK_BITS11_0 (MAMP1_3 | MAMP1_1 | MAMP1_0) /*!< Unmask DAC channel LFSR bit[11:0] for noise wave generation */ +#define DAC_TRIANGLEAMPLITUDE_1 0x00000000UL /*!< Select max triangle amplitude of 1 */ +#define DAC_TRIANGLEAMPLITUDE_3 ( MAMP1_0) /*!< Select max triangle amplitude of 3 */ +#define DAC_TRIANGLEAMPLITUDE_7 ( MAMP1_1 ) /*!< Select max triangle amplitude of 7 */ +#define DAC_TRIANGLEAMPLITUDE_15 ( MAMP1_1 | MAMP1_0) /*!< Select max triangle amplitude of 15 */ +#define DAC_TRIANGLEAMPLITUDE_31 ( MAMP1_2 ) /*!< Select max triangle amplitude of 31 */ +#define DAC_TRIANGLEAMPLITUDE_63 ( MAMP1_2 | MAMP1_0) /*!< Select max triangle amplitude of 63 */ +#define DAC_TRIANGLEAMPLITUDE_127 ( MAMP1_2 | MAMP1_1 ) /*!< Select max triangle amplitude of 127 */ +#define DAC_TRIANGLEAMPLITUDE_255 ( MAMP1_2 | MAMP1_1 | MAMP1_0) /*!< Select max triangle amplitude of 255 */ +#define DAC_TRIANGLEAMPLITUDE_511 (MAMP1_3 ) /*!< Select max triangle amplitude of 511 */ +#define DAC_TRIANGLEAMPLITUDE_1023 (MAMP1_3 | MAMP1_0) /*!< Select max triangle amplitude of 1023 */ +#define DAC_TRIANGLEAMPLITUDE_2047 (MAMP1_3 | MAMP1_1 ) /*!< Select max triangle amplitude of 2047 */ +#define DAC_TRIANGLEAMPLITUDE_4095 (MAMP1_3 | MAMP1_1 | MAMP1_0) /*!< Select max triangle amplitude of 4095 */ + + + +#define IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(VALUE) (((VALUE) == DAC_LFSRUNMASK_BIT0) || \ + ((VALUE) == DAC_LFSRUNMASK_BITS1_0) || \ + ((VALUE) == DAC_LFSRUNMASK_BITS2_0) || \ + ((VALUE) == DAC_LFSRUNMASK_BITS3_0) || \ + ((VALUE) == DAC_LFSRUNMASK_BITS4_0) || \ + ((VALUE) == DAC_LFSRUNMASK_BITS5_0) || \ + ((VALUE) == DAC_LFSRUNMASK_BITS6_0) || \ + ((VALUE) == DAC_LFSRUNMASK_BITS7_0) || \ + ((VALUE) == DAC_LFSRUNMASK_BITS8_0) || \ + ((VALUE) == DAC_LFSRUNMASK_BITS9_0) || \ + ((VALUE) == DAC_LFSRUNMASK_BITS10_0) || \ + ((VALUE) == DAC_LFSRUNMASK_BITS11_0) || \ + ((VALUE) == DAC_TRIANGLEAMPLITUDE_1) || \ + ((VALUE) == DAC_TRIANGLEAMPLITUDE_3) || \ + ((VALUE) == DAC_TRIANGLEAMPLITUDE_7) || \ + ((VALUE) == DAC_TRIANGLEAMPLITUDE_15) || \ + ((VALUE) == DAC_TRIANGLEAMPLITUDE_31) || \ + ((VALUE) == DAC_TRIANGLEAMPLITUDE_63) || \ + ((VALUE) == DAC_TRIANGLEAMPLITUDE_127) || \ + ((VALUE) == DAC_TRIANGLEAMPLITUDE_255) || \ + ((VALUE) == DAC_TRIANGLEAMPLITUDE_511) || \ + ((VALUE) == DAC_TRIANGLEAMPLITUDE_1023) || \ + ((VALUE) == DAC_TRIANGLEAMPLITUDE_2047) || \ + ((VALUE) == DAC_TRIANGLEAMPLITUDE_4095)) + +/** @defgroup DAC_OutputBuffer + * @{ + */ +#define DAC_OUTPUTBUFFER_ENABLE 0x00000002U +#define DAC_OUTPUTBUFFER_DISABLE 0x00000000U + +#define IS_DAC_BUFFER(BUFFER) (((BUFFER) == DAC_OUTPUTBUFFER_ENABLE)|| \ + ( (BUFFER) == DAC_OUTPUTBUFFER_DISABLE)) + + +/** @defgroup DAC_Input_sel + * @{ + */ +#define DAC_INPUT_SEL_DOR 0x00000000U +#define DAC_INPUT_SEL_RAMP 0x00004000U + + +#define IS_DAC_INPUT(input) (((INPUT) ==DAC_INPUT_SEL_DOR ) || \ + ((INPUT) == DAC_INPUT_SEL_RAMP)) + + +/** @defgroup DAC_Output_sel + * @{ + */ +#define DAC_OUTPUT_SEL_PAD 0x00000000U +#define DAC_OUTPUT_SEL_Analog 0x00008000U + +#define IS_DAC_OUTPUT(output) (((output) == DAC_OUTPUT_SEL_PAD) || \ + ((output) == DAC_OUTPUT_SEL_Analog)) + + +/* Initialization and Configuration functions *********************************/ +void DAC_Init(uint32_t DAC_1_2_Selection, DAC_InitTypeDef* DAC_InitStruct); +void DAC_DeInit(uint32_t DAC_1_2_Selection); +void DAC_Start(uint32_t DAC_1_2_Selection); +void DAC_STOP(uint32_t DAC_1_2_Selection); +/* Function used to set the DAC configuration to the default reset state ****/ +void DAC_SetValue(uint32_t DAC_1_2_Selection, uint32_t Alignment, uint32_t Data); +uint32_t DAC_GetValue(uint32_t DAC_1_2_Selection); +void DAC_Start_DMA(uint32_t DAC_1_2_Selection, FunctionalState NewState); +void DAC_Stop_DMA(uint32_t DAC_1_2_Selection); +void DAC_TriangleWaveGenerate(uint32_t DAC_1_2_Selection, uint32_t Amplitude); +void DAC_NoiseWaveGenerate(uint32_t DAC_1_2_Selection, uint32_t Amplitude); +void Delay_read (void) ; + +#ifdef __cplusplus +} +#endif + +#endif /*__ft32f4XX_DAC_H */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_debug.h b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_debug.h new file mode 100644 index 00000000000..b841aac399a --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_debug.h @@ -0,0 +1,107 @@ +/** + ****************************************************************************** + * @file ft32f4xx_debug.h + * @author FMD AE + * @brief This file contains all the functions prototypes for the DBGMCU firmware + * library. + * @version V1.0.0 + * @data 2025-04-08 + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __FT32F4XX_DBGMCU_H +#define __FT32F4XX_DBGMCU_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx.h" + + +/** @addtogroup DBGMCU + * @{ + */ +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + + +/** @defgroup DBGMCU_Exported_Constants + * @{ + */ + +#define DBGMCU_SLEEP DBGMCU_CR_DBG_SLEEP +#define DBGMCU_STOP DBGMCU_CR_DBG_STOP +#define DBGMCU_STANDBY DBGMCU_CR_DBG_STANDBY + +#define IS_DBGMCU_PERIPH(PERIPH) ((((PERIPH) & 0xFFFFFFF8) == 0x00) && ((PERIPH) != 0x00)) + +/* DEBUG MCU APB1 Freeze Register bits */ +#define DBGMCU_CAN4_STOP DBG_CAN4_STOP +#define DBGMCU_CAN3_STOP DBG_CAN3_STOP +#define DBGMCU_CAN2_STOP DBG_CAN2_STOP +#define DBGMCU_CAN1_STOP DBG_CAN1_STOP +#define DBGMCU_I2C3_SMBUS_TIMEOUT_STOP DBG_I2C3_SMBUS_STOP +#define DBGMCU_I2C2_SMBUS_TIMEOUT_STOP DBG_I2C2_SMBUS_STOP +#define DBGMCU_I2C1_SMBUS_TIMEOUT_STOP DBG_I2C1_SMBUS_STOP +#define DBGMCU_WWDG_STOP DBG_WWDG_STOP +#define DBGMCU_IWDG_STOP DBG_IWDG_STOP +#define DBGMCU_RTC_STOP DBG_RTC_STOP +#define DBGMCU_TIM14_STOP DBG_TIM14_STOP +#define DBGMCU_TIM13_STOP DBG_TIM13_STOP +#define DBGMCU_TIM12_STOP DBG_TIM12_STOP +#define DBGMCU_TIM7_STOP DBG_TIM7_STOP +#define DBGMCU_TIM6_STOP DBG_TIM6_STOP +#define DBGMCU_TIM5_STOP DBG_TIM5_STOP +#define DBGMCU_TIM4_STOP DBG_TIM4_STOP +#define DBGMCU_TIM3_STOP DBG_TIM3_STOP +#define DBGMCU_TIM2_STOP DBG_TIM2_STOP + +#define IS_DBGMCU_APB1PERIPH(PERIPH) ((((PERIPH) & 0xE11FE200) == 0x00) && ((PERIPH) != 0x00)) + +/* DEBUG MCU APB2 Freeze Register bits */ +#define DBGMCU_EPWM4_STOP DBG_EPWM4_STOP +#define DBGMCU_EPWM3_STOP DBG_EPWM3_STOP +#define DBGMCU_EPWM2_STOP DBG_EPWM2_STOP +#define DBGMCU_EPWM1_STOP DBG_EPWM1_STOP +#define DBGMCU_TIM10_STOP DBG_TIM10_STOP +#define DBGMCU_TIM9_STOP DBG_TIM9_STOP +#define DBGMCU_LPTIM_STOP DBG_LPTIM_STOP +#define DBGMCU_TIM8_STOP DBG_TIM8_STOP +#define DBGMCU_TIM1_STOP DBG_TIM1_STOP + +#define IS_DBGMCU_APB2PERIPH(PERIPH) ((((PERIPH) & 0x87F8FFF8) == 0x00) && ((PERIPH) != 0x00)) + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +/* Device and Revision ID management functions ********************************/ +uint32_t DBGMCU_GetREVID(void); +uint32_t DBGMCU_GetDEVID(void); + +/* Peripherals Configuration functions ****************************************/ +void DBGMCU_Config(uint32_t DBGMCU_Periph, FunctionalState NewState); +void DBGMCU_APB1PeriphConfig(uint32_t DBGMCU_Periph, FunctionalState NewState); +void DBGMCU_APB2PeriphConfig(uint32_t DBGMCU_Periph, FunctionalState NewState); + +#ifdef __cplusplus +} +#endif + +#endif /* __FT32F4XX_DBGMCU_H */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_dma.h b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_dma.h new file mode 100644 index 00000000000..bb670c0e255 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_dma.h @@ -0,0 +1,743 @@ +/** + ****************************************************************************** + * @file ft32f4xx_dma.h + * @author FMD AE + * @brief This file contains all the functions prototypes for the DMA firmware + * library. + * @version V1.0.0 + * @data 2025-04-15 + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __FT32F4XX_DMA_H +#define __FT32F4XX_DMA_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx.h" + + +/** @addtogroup DMA + * @{ + */ +/* Exported types ------------------------------------------------------------*/ + +/** + * @brief DMA Init structures definition + */ +typedef struct +{ + uint32_t SrcAddress; /*!< Specifies the source address for DMAy Channelx. */ + uint32_t DstAddress; /*!< Specifies the destination address for DMAy Channelx. */ + + uint32_t BlockTransSize; /*!< Specifies the block transfer size for DMAy Channelx. + This parameter must be a number between 1 and 65535 + @ref DMA_block_transfer_size */ + + uint32_t SrcDstMasterSel; /*!< Specifies the source/destination master select for DMAy Channelx. + This parameter can be a value of @ref DMA_src_dst_master_select */ + + uint32_t TransferTypeFlowCtl; /*!< Specifies the transfer type and flow control for DMAy Channelx. + This parameter can be a value of @ref DMA_trans_type_flow_control */ + + uint32_t SrcBurstTransferLength; /*!< Specifies the source burst transaction length for DMAy Channelx. + The number of data with a width of DMA_SrcTransWidth. + This parameter can be a value of @ref DMA_src_burst_trans_length */ + + uint32_t DstBurstTransferLength; /*!< Specifies the destination burst transaction length for DMAy Channelx. + The number of data with a width of DMA_DstTransWidth. + This parameter can be a value of @ref DMA_dst_burst_trans_length */ + + uint32_t SrcAddrMode; /*!< Specifies the source address increment for DMAy Channelx. + This parameter can be a value of @ref DMA_src_addr_increment_mode */ + + uint32_t DstAddrMode; /*!< Specifies the destination address increment for DMAy Channelx. + This parameter can be a value of @ref DMA_dst_addr_increment_mode */ + + uint32_t SrcTransferWidth; /*!< Specifies the srouce transfer width for DMAy Channelx. + This parameter can be a value of @ref DMA_src_trans_width */ + + uint32_t DstTransferWidth; /*!< Specifies the destination transfer width for DMAy Channelx. + This parameter can be a value of @ref DMA_dst_trans_width */ + + + uint32_t DstHardwareInterface; /*!< Specifies a hardware handshaking interface to the destination of DMAy Channelx + if the CFGx.HS_SEL_DST field is 0. + Each channel is equipped with 8 destination hardware handshaking interfaces, such as: + DMA_DST_HARDWARE_INTERFACE_0 + ... + DMA_DST_HARDWARE_INTERFACE_7 + By configuring the DstHsIfPeriphSel field, each destination hardware handshaking interface + can be selectively assigned to support up to 8 peripheral requests. For example, + DMA_DST_HARDWARE_INTERFACE_0 of DMA1 provieds configurable options inculding: + SPI3_RX + I2C1_RX + TIM4_CH1 + LPUART_RX + UART5_RX + TIM5_CH3 + TIM5_UP + This parameter can be a value of @ref DMA_dst_hardware_interface */ + + uint32_t SrcHardwareInterface; /*!< Specifies a hardware handshaking interface to the source of DMAy Channelx + if the CFGx.HS_SEL_SRC field is 0. + Each channel is equipped with 8 source hardware handshaking interfaces, such as: + DMA_SRC_HARDWARE_INTERFACE_0 + ... + DMA_SRC_HARDWARE_INTERFACE_7 + By configuring the SrcHsIfPeriphSel field, each source hardware handshaking interface + can be selectively assigned to support up to 8 peripheral requests. For example, + DMA_SRC_HARDWARE_INTERFACE_0 of DMA2 provieds configurable options inculding: + ADC1 + ADC3 + SPI1_RX + SPDIF_CB + TIM1_TRIG + This parameter can be a value of @ref DMA_src_hardware_interface */ + + FunctionalState FIFOMode; /*!< Specifies the FIFO mode select for DMAy Channelx. + This parameter can be set to ENABLE or DISABLE. */ + + FunctionalState FlowCtlMode; /*!< Specifies the flow control mode for DMAy Channelx. + This parameter can be set to ENABLE or DISABLE. */ + + FunctionalState ReloadDst; /*!< Specifies the automatic destination reload for DMAy Channelx. + This parameter can be set to ENABLE or DISABLE. */ + + FunctionalState ReloadSrc; /*!< Specifies the automatic source reload for DMAy Channelx. + This parameter can be set to ENABLE or DISABLE. */ + + uint32_t MaxBurstLength; /*!< Specifies the maximum AMBA burst length for DMAy Channelx. + A value of 0 indicates that software is not limiting the + maximum AMBA burst length for DMA transfers on this channel. + This parameter can be a number greater than the maximum values + of src_burst_size_bytes and dst_burst_size_bytes. + +src_burst_size_bytes=SRC_MSIZE*SRC_TR_WIDTH; + +dst_burst_size_bytes=DST_MSIZE*DST_TR_WIDTH. */ + + uint32_t SrcHsIfPol; /*!< Specifies the source handshaking interface polarity for DMAy Channelx. + This parameter can be a value of @ref DMA_src_hs_if_polarity */ + + uint32_t DstHsIfPol; /*!< Specifies the destination handshaking interface polarity for DMAy Channelx. + This parameter can be a value of @ref DMA_dst_hs_if_polarity */ + + uint32_t SrcHsSel; /*!< Specifies the source software or handware handshaking select for DMAy Channelx. + This parameter can be a value of @ref DMA_src_hs_select */ + + uint32_t DstHsSel; /*!< Specifies the destination software or handware handshaking select for DMAy Channelx. + This parameter can be a value of @ref DMA_dst_hs_select */ + + uint32_t Polarity; /*!< Specifies the channel polarity for DMAy Channelx. + This parameter can be a value of @ref DMA_channel_polarity */ + + uint32_t SrcHsIfPeriphSel; /*!< Specifies the peripheral request for the handshake interface. + This parameter can be a value of @ref DMA_src_handshake_interface_channel_select */ + + uint32_t DstHsIfPeriphSel; /*!< Specifies the peripheral request for the handshake interface. + This parameter can be a value of @ref DMA_dst_handshake_interface_channel_select */ + +} DMA_InitTypeDef; + + +/** + * @brief DMA base address and channel index definition + */ +typedef struct +{ + DMA_TypeDef *BaseAddress; + uint32_t ChannelIndex; +} DMA_BaseAddressAndChannelIndex; + + +/** + * @brief DMA Software Request definition + */ +typedef enum +{ + DMA_SW_REQUEST_SRC = 0x00U, // + DMA_SW_REQUEST_DST = 0x01U, + DMA_SW_REQUEST_SRC_SGL = 0x02U, + DMA_SW_REQUEST_DST_SGL = 0x03U, + DMA_SW_REQUEST_SRC_LST = 0x04U, + DMA_SW_REQUEST_DST_LST = 0x05U +} DMA_SoftwareRequestTypeDef; + +#define IS_DMA_SOFTWARE_REQUEST(TYPE) (((TYPE) == DMA_SW_REQUEST_SRC) || \ + ((TYPE) == DMA_SW_REQUEST_DST) || \ + ((TYPE) == DMA_SW_REQUEST_SRC_SGL) || \ + ((TYPE) == DMA_SW_REQUEST_DST_SGL) || \ + ((TYPE) == DMA_SW_REQUEST_SRC_LST) || \ + ((TYPE) == DMA_SW_REQUEST_DST_LST) ) + +/** + * @brief DMA_interrupts_definition DMA_IT + */ +#define DMA_IT_TFR 0x01U +#define DMA_IT_BLOCK 0x02U +#define DMA_IT_SRC 0x04U +#define DMA_IT_DST 0x08U +#define DMA_IT_ERR 0x10U + +#define IS_DMA_IT(TYPE) (((TYPE) == DMA_IT_TFR) || \ + ((TYPE) == DMA_IT_BLOCK) || \ + ((TYPE) == DMA_IT_SRC) || \ + ((TYPE) == DMA_IT_DST) || \ + ((TYPE) == DMA_IT_ERR)) + + +/** + * @brief DMA_interrupts_flag_definition DMA_FLAG + */ +#define DMA_FLAG_TFR 0x01U +#define DMA_FLAG_BLOCK 0x02U +#define DMA_FLAG_SRC 0x04U +#define DMA_FLAG_DST 0x08U +#define DMA_FLAG_ERR 0x10U + +#define IS_DMA_FLAG(FLAG) (((FLAG) == DMA_FLAG_TFR) || \ + ((FLAG) == DMA_FLAG_BLOCK) || \ + ((FLAG) == DMA_FLAG_SRC) || \ + ((FLAG) == DMA_FLAG_DST) || \ + ((FLAG) == DMA_FLAG_ERR)) + + +/** + * @brief Enable the specified DMA. + * @param DMAx DMA base address + * @retval None + */ +#define DMA_ENABLE(DMAx) ((DMAx)->DMACFG |= DMA_DMACFG_DMA_EN) + + +/** + * @brief Disable the specified DMA. + * @param DMAx DMA base address + * @retval None + */ +#define DMA_DISABLE(DMAx) ((DMAx)->DMACFG &= ~DMA_DMACFG_DMA_EN) + + +/** @defgroup DMA_block_transfer_size + * @{ + */ +#define IS_DMA_BLOCK_TRANSFER_SIZE(SIZE) (((SIZE) >= 0x1U) && ((SIZE) <= 0xFFFFU)) + +/** + * @} + */ + + +/** @defgroup DMA_src_dst_master_select + * @{ + */ +#define DMA_SRCMASTER1_DSTMASTER1 0U +#define DMA_SRCMASTER1_DSTMASTER2 DMA_CTL_DMS +#define DMA_SRCMASTER2_DSTMASTER1 DMA_CTL_SMS +#define DMA_SRCMASTER2_DSTMASTER2 (DMA_CTL_SMS | DMA_CTL_DMS) + +#define IS_DMA_SRC_DST_MASTER_SEL(MASTER) (((MASTER) == DMA_SRCMASTER1_DSTMASTER1) || \ + ((MASTER) == DMA_SRCMASTER1_DSTMASTER2) || \ + ((MASTER) == DMA_SRCMASTER2_DSTMASTER1) || \ + ((MASTER) == DMA_SRCMASTER2_DSTMASTER2)) +/** + * @} + */ + +/** @defgroup DMA_trans_type_flow_control + * @{ + */ +#define DMA_TRANSFERTYPE_FLOWCTL_M2M_DMA 0U +#define DMA_TRANSFERTYPE_FLOWCTL_M2P_DMA DMA_CTL_TT_FC_0 +#define DMA_TRANSFERTYPE_FLOWCTL_P2M_DMA DMA_CTL_TT_FC_1 +#define DMA_TRANSFERTYPE_FLOWCTL_P2P_DMA (DMA_CTL_TT_FC_0 | DMA_CTL_TT_FC_1) +#define DMA_TRANSFERTYPE_FLOWCTL_P2M_PRE DMA_CTL_TT_FC_2 +#define DMA_TRANSFERTYPE_FLOWCTL_P2P_SRCPRE (DMA_CTL_TT_FC_0 | DMA_CTL_TT_FC_2) +#define DMA_TRANSFERTYPE_FLOWCTL_M2P_PRE (DMA_CTL_TT_FC_1 | DMA_CTL_TT_FC_2) +#define DMA_TRANSFERTYPE_FLOWCTL_P2P_DSTPRE DMA_CTL_TT_FC + +#define IS_DMA_TRANS_TYPE_FLOW_CTL(TYPE) (((TYPE) == DMA_TRANSFERTYPE_FLOWCTL_M2M_DMA ) || \ + ((TYPE) == DMA_TRANSFERTYPE_FLOWCTL_M2P_DMA ) || \ + ((TYPE) == DMA_TRANSFERTYPE_FLOWCTL_P2M_DMA ) || \ + ((TYPE) == DMA_TRANSFERTYPE_FLOWCTL_P2P_DMA ) || \ + ((TYPE) == DMA_TRANSFERTYPE_FLOWCTL_P2M_PRE ) || \ + ((TYPE) == DMA_TRANSFERTYPE_FLOWCTL_P2P_SRCPRE) || \ + ((TYPE) == DMA_TRANSFERTYPE_FLOWCTL_M2P_PRE ) || \ + ((TYPE) == DMA_TRANSFERTYPE_FLOWCTL_P2P_DSTPRE)) +/** + * @} + */ + + +/** @defgroup DMA_src_burst_trans_length + * @{ + */ +#define DMA_SRC_BURSTTRANSFERLENGTH_1 0U +#define DMA_SRC_BURSTTRANSFERLENGTH_4 DMA_CTL_SRC_MSIZE_0 +#define DMA_SRC_BURSTTRANSFERLENGTH_8 DMA_CTL_SRC_MSIZE_1 +#define DMA_SRC_BURSTTRANSFERLENGTH_16 DMA_CTL_SRC_MSIZE + +#define IS_DMA_SRC_BURST_TRANS_LENGTH(LENGTH) (((LENGTH) == DMA_SRC_BURSTTRANSFERLENGTH_1 ) || \ + ((LENGTH) == DMA_SRC_BURSTTRANSFERLENGTH_4 ) || \ + ((LENGTH) == DMA_SRC_BURSTTRANSFERLENGTH_8 ) || \ + ((LENGTH) == DMA_SRC_BURSTTRANSFERLENGTH_16)) +/** + * @} + */ + + +/** @defgroup DMA_dst_burst_trans_length + * @{ + */ +#define DMA_DST_BURSTTRANSFERLENGTH_1 0U +#define DMA_DST_BURSTTRANSFERLENGTH_4 DMA_CTL_SRC_MSIZE_0 +#define DMA_DST_BURSTTRANSFERLENGTH_8 DMA_CTL_SRC_MSIZE_1 +#define DMA_DST_BURSTTRANSFERLENGTH_16 DMA_CTL_DEST_MSIZE + +#define IS_DMA_DST_BURST_TRANS_LENGTH(LENGTH) (((LENGTH) == DMA_DST_BURSTTRANSFERLENGTH_1 ) || \ + ((LENGTH) == DMA_DST_BURSTTRANSFERLENGTH_4 ) || \ + ((LENGTH) == DMA_DST_BURSTTRANSFERLENGTH_8 ) || \ + ((LENGTH) == DMA_DST_BURSTTRANSFERLENGTH_16)) +/** + * @} + */ + + +/** @defgroup DMA_src_addr_increment_mode + * @{ + */ +#define DMA_SRC_ADDRMODE_INC 0U +#define DMA_SRC_ADDRMODE_DEC DMA_CTL_SINC_0 +#define DMA_SRC_ADDRMODE_HOLD DMA_CTL_SINC_1 + +#define IS_DMA_SRC_ADDR_MODE(MODE) (((MODE) == DMA_SRC_ADDRMODE_INC ) || \ + ((MODE) == DMA_SRC_ADDRMODE_DEC ) || \ + ((MODE) == DMA_SRC_ADDRMODE_HOLD)) +/** + * @} + */ + + +/** @defgroup DMA_dst_addr_increment_mode + * @{ + */ +#define DMA_DST_ADDRMODE_INC 0U +#define DMA_DST_ADDRMODE_DEC DMA_CTL_DINC_0 +#define DMA_DST_ADDRMODE_HOLD DMA_CTL_DINC_1 + +#define IS_DMA_DST_ADDR_MODE(MODE) (((MODE) == DMA_DST_ADDRMODE_INC ) || \ + ((MODE) == DMA_DST_ADDRMODE_DEC ) || \ + ((MODE) == DMA_DST_ADDRMODE_HOLD)) +/** + * @} + */ + + +/** @defgroup DMA_src_trans_width + * @{ + */ +#define DMA_SRC_TRANSFERWIDTH_8BITS 0U +#define DMA_SRC_TRANSFERWIDTH_16BITS DMA_CTL_SRC_TR_WIDTH_0 +#define DMA_SRC_TRANSFERWIDTH_32BITS DMA_CTL_SRC_TR_WIDTH_1 + +#define IS_DMA_SRC_TRANS_WIDTH(WIDTH) (((WIDTH) == DMA_SRC_TRANSFERWIDTH_8BITS ) || \ + ((WIDTH) == DMA_SRC_TRANSFERWIDTH_16BITS) || \ + ((WIDTH) == DMA_SRC_TRANSFERWIDTH_32BITS)) +/** + * @} + */ + + +/** @defgroup DMA_dst_trans_width + * @{ + */ +#define DMA_DST_TRANSFERWIDTH_8BITS 0U +#define DMA_DST_TRANSFERWIDTH_16BITS DMA_CTL_DST_TR_WIDTH_0 +#define DMA_DST_TRANSFERWIDTH_32BITS DMA_CTL_DST_TR_WIDTH_1 + +#define IS_DMA_DST_TRANS_WIDTH(WIDTH) (((WIDTH) == DMA_DST_TRANSFERWIDTH_8BITS ) || \ + ((WIDTH) == DMA_DST_TRANSFERWIDTH_16BITS) || \ + ((WIDTH) == DMA_DST_TRANSFERWIDTH_32BITS)) +/** + * @} + */ + + +/** @defgroup DMA_dst_hardware_interface + * @{ + */ +#define DMA_DST_HARDWARE_INTERFACE_0 0U +#define DMA_DST_HARDWARE_INTERFACE_1 1U +#define DMA_DST_HARDWARE_INTERFACE_2 2U +#define DMA_DST_HARDWARE_INTERFACE_3 3U +#define DMA_DST_HARDWARE_INTERFACE_4 4U +#define DMA_DST_HARDWARE_INTERFACE_5 5U +#define DMA_DST_HARDWARE_INTERFACE_6 6U +#define DMA_DST_HARDWARE_INTERFACE_7 7U + +#define IS_DMA_DST_HW_IF(IF) (((IF) == DMA_DST_HARDWARE_INTERFACE_0) || \ + ((IF) == DMA_DST_HARDWARE_INTERFACE_1) || \ + ((IF) == DMA_DST_HARDWARE_INTERFACE_2) || \ + ((IF) == DMA_DST_HARDWARE_INTERFACE_3) || \ + ((IF) == DMA_DST_HARDWARE_INTERFACE_4) || \ + ((IF) == DMA_DST_HARDWARE_INTERFACE_5) || \ + ((IF) == DMA_DST_HARDWARE_INTERFACE_6) || \ + ((IF) == DMA_DST_HARDWARE_INTERFACE_7)) +/** + * @} + */ + + +/** @defgroup DMA_src_hardware_interface + * @{ + */ +#define DMA_SRC_HARDWARE_INTERFACE_0 0U +#define DMA_SRC_HARDWARE_INTERFACE_1 1U +#define DMA_SRC_HARDWARE_INTERFACE_2 2U +#define DMA_SRC_HARDWARE_INTERFACE_3 3U +#define DMA_SRC_HARDWARE_INTERFACE_4 4U +#define DMA_SRC_HARDWARE_INTERFACE_5 5U +#define DMA_SRC_HARDWARE_INTERFACE_6 6U +#define DMA_SRC_HARDWARE_INTERFACE_7 7U + +#define IS_DMA_SRC_HW_IF(IF) (((IF) == DMA_SRC_HARDWARE_INTERFACE_0) || \ + ((IF) == DMA_SRC_HARDWARE_INTERFACE_1) || \ + ((IF) == DMA_SRC_HARDWARE_INTERFACE_2) || \ + ((IF) == DMA_SRC_HARDWARE_INTERFACE_3) || \ + ((IF) == DMA_SRC_HARDWARE_INTERFACE_4) || \ + ((IF) == DMA_SRC_HARDWARE_INTERFACE_5) || \ + ((IF) == DMA_SRC_HARDWARE_INTERFACE_6) || \ + ((IF) == DMA_SRC_HARDWARE_INTERFACE_7)) +/** + * @} + */ + + +///** @defgroup DMA_fifo_mode_select +// * @{ +// */ +//#define DMA_FIFOMODE_DISABLE 0U +//#define DMA_FIFOMODE_ENABLE 1U +////#define DMA_FIFOMODE_ENABLE DMA_CFG_FIFO_MODE +// +//#define IS_DMA_FIFO_MODE_STATE(STATE) (((STATE) == DMA_FIFOMODE_DISABLE) || \ +// ((STATE) == DMA_FIFOMODE_ENABLE )) +///** +// * @} +// */ + + +///** @defgroup DMA_fc_mode +// * @{ +// */ +//#define DMA_FLOWCTLMODE_DISABLE 0U +//#define DMA_FLOWCTLMODE_ENABLE 1U +////#define DMA_FLOWCTLMODE_ENABLE DMA_CFG_FCMODE +// +//#define IS_DMA_FCMODE_STATE(STATE) (((STATE) == DMA_FLOWCTLMODE_DISABLE) || \ +// ((STATE) == DMA_FLOWCTLMODE_ENABLE )) +///** +// * @} +// */ + + +///** @defgroup DMA_reload_destination +// * @{ +// */ +//#define DMA_RELOADDST_DISABLE 0U +//#define DMA_RELOADDST_ENABLE 1U +// +//#define IS_DMA_RELOAD_DST_STATE(STATE) (((STATE) == DMA_RELOADDST_DISABLE) || \ +// ((STATE) == DMA_RELOADDST_ENABLE )) +///** +// * @} +// */ +// +// +///** @defgroup DMA_reload_source +// * @{ +// */ +//#define DMA_RELOADSRC_DISABLE 0U +//#define DMA_RELOADSRC_ENABLE 1U +// +//#define IS_DMA_RELOAD_SRC_STATE(STATE) (((STATE) == DMA_RELOADSRC_DISABLE) || \ +// ((STATE) == DMA_RELOADSRC_ENABLE )) +///** +// * @} +// */ + + +/** @defgroup DMA_src_hs_if_polarity + * @{ + */ +#define DMA_SRCHSIFPOL_HIGH 0U +#define DMA_SRCHSIFPOL_LOW 1U + +#define IS_DMA_SRC_HS_IF_POL(MODE) (((MODE) == DMA_SRCHSIFPOL_HIGH) || \ + ((MODE) == DMA_SRCHSIFPOL_LOW )) +/** + * @} + */ + + +/** @defgroup DMA_dst_hs_if_polarity + * @{ + */ +#define DMA_DSTHSIFPOL_HIGH 0U +#define DMA_DSTHSIFPOL_LOW 1U + +#define IS_DMA_DST_HS_IF_POL(MODE) (((MODE) == DMA_DSTHSIFPOL_HIGH) || \ + ((MODE) == DMA_DSTHSIFPOL_LOW )) +/** + * @} + */ + + +/** @defgroup DMA_src_hs_select + * @{ + */ +#define DMA_SRCHSSEL_HARDWARE 0U +#define DMA_SRCHSSEL_SOFTWARE 1U + +#define IS_DMA_SRC_HS_SEL(MODE) (((MODE) == DMA_SRCHSSEL_HARDWARE) || \ + ((MODE) == DMA_SRCHSSEL_SOFTWARE)) +/** + * @} + */ + + +/** @defgroup DMA_dst_hs_select + * @{ + */ +#define DMA_DSTHSSEL_HARDWARE 0U +#define DMA_DSTHSSEL_SOFTWARE 1U + +#define IS_DMA_DST_HS_SEL(MODE) (((MODE) == DMA_DSTHSSEL_HARDWARE) || \ + ((MODE) == DMA_DSTHSSEL_SOFTWARE)) +/** + * @} + */ + + +/** @defgroup DMA_channel_suspend + * @{ + */ +#define DMA_CHANNELSUSPEND_DISABLE 0U +#define DMA_CHANNELSUSPEND_ENABLE 1U + +#define IS_DMA_CHANNEL_SUSPEND_STATE(STATE) (((STATE) == DMA_CHANNELSUSPEND_DISABLE) || \ + ((STATE) == DMA_CHANNELSUSPEND_ENABLE )) +/** + * @} + */ + + +/** @defgroup DMA_channel_polarity + * @{ + */ +#define DMA_CH_POLARITY_0 0U +#define DMA_CH_POLARITY_1 1U +#define DMA_CH_POLARITY_2 2U +#define DMA_CH_POLARITY_3 3U +#define DMA_CH_POLARITY_4 4U +#define DMA_CH_POLARITY_5 5U +#define DMA_CH_POLARITY_6 6U +#define DMA_CH_POLARITY_7 7U + +#define IS_DMA_CHANNEL_POLARITY(POLARITY) (((POLARITY) == DMA_CH_POLARITY_0) || \ + ((POLARITY) == DMA_CH_POLARITY_1) || \ + ((POLARITY) == DMA_CH_POLARITY_2) || \ + ((POLARITY) == DMA_CH_POLARITY_3) || \ + ((POLARITY) == DMA_CH_POLARITY_4) || \ + ((POLARITY) == DMA_CH_POLARITY_5) || \ + ((POLARITY) == DMA_CH_POLARITY_6) || \ + ((POLARITY) == DMA_CH_POLARITY_7)) +/** + * @} + */ + + +/** @defgroup DMA_enable + * @{ + */ +#define DMA_Disable ((uint64_t)0x0000000000000000) +#define DMA_Enable ((uint64_t)0x0000000000000001) + +#define IS_DMA_ENABLE(STATUS) (((STATUS) == DMA_Disable) || ((STATUS) == DMA_Enable)) +/** + * @} + */ + + +/** @defgroup DMA_channel_enable_write + * @{ + */ +#define DMA_ChannelEnable_EN_0 ((uint64_t)0x0000000000000100) +#define DMA_ChannelEnable_EN_1 ((uint64_t)0x0000000000000200) +#define DMA_ChannelEnable_EN_2 ((uint64_t)0x0000000000000400) +#define DMA_ChannelEnable_EN_3 ((uint64_t)0x0000000000000800) +#define DMA_ChannelEnable_EN_4 ((uint64_t)0x0000000000001000) +#define DMA_ChannelEnable_EN_5 ((uint64_t)0x0000000000002000) +#define DMA_ChannelEnable_EN_6 ((uint64_t)0x0000000000004000) +#define DMA_ChannelEnable_EN_7 ((uint64_t)0x0000000000008000) + +#define IS_DMA_CHANNEL_ENABLE_EN(CHANNEL) (((CHANNEL) == DMA_ChannelEnable_EN_0) || \ + ((CHANNEL) == DMA_ChannelEnable_EN_1) || \ + ((CHANNEL) == DMA_ChannelEnable_EN_2) || \ + ((CHANNEL) == DMA_ChannelEnable_EN_3) || \ + ((CHANNEL) == DMA_ChannelEnable_EN_4) || \ + ((CHANNEL) == DMA_ChannelEnable_EN_5) || \ + ((CHANNEL) == DMA_ChannelEnable_EN_6) || \ + ((CHANNEL) == DMA_ChannelEnable_EN_7)) + +/** + * @} + */ + +/** @defgroup DMA_channel_enable + * @{ + */ +#define DMA_ChannelEnable_0 ((uint64_t)0x0000000000000001) +#define DMA_ChannelEnable_1 ((uint64_t)0x0000000000000002) +#define DMA_ChannelEnable_2 ((uint64_t)0x0000000000000004) +#define DMA_ChannelEnable_3 ((uint64_t)0x0000000000000008) +#define DMA_ChannelEnable_4 ((uint64_t)0x0000000000000010) +#define DMA_ChannelEnable_5 ((uint64_t)0x0000000000000020) +#define DMA_ChannelEnable_6 ((uint64_t)0x0000000000000040) +#define DMA_ChannelEnable_7 ((uint64_t)0x0000000000000080) + +#define IS_DMA_CHANNEL_ENABLE(CHANNEL) (((CHANNEL) == DMA_ChannelEnable_0) || \ + ((CHANNEL) == DMA_ChannelEnable_1) || \ + ((CHANNEL) == DMA_ChannelEnable_2) || \ + ((CHANNEL) == DMA_ChannelEnable_3) || \ + ((CHANNEL) == DMA_ChannelEnable_4) || \ + ((CHANNEL) == DMA_ChannelEnable_5) || \ + ((CHANNEL) == DMA_ChannelEnable_6) || \ + ((CHANNEL) == DMA_ChannelEnable_7)) + +/** + * @} + */ + +/** @defgroup DMA_src_handshake_interface_channel_select + * @{ + */ +#define DMA_SRC_HANDSHAKE_INTERFACE_SEL_0 0U +#define DMA_SRC_HANDSHAKE_INTERFACE_SEL_1 1U +#define DMA_SRC_HANDSHAKE_INTERFACE_SEL_2 2U +#define DMA_SRC_HANDSHAKE_INTERFACE_SEL_3 3U +#define DMA_SRC_HANDSHAKE_INTERFACE_SEL_4 4U +#define DMA_SRC_HANDSHAKE_INTERFACE_SEL_5 5U +#define DMA_SRC_HANDSHAKE_INTERFACE_SEL_6 6U +#define DMA_SRC_HANDSHAKE_INTERFACE_SEL_7 7U + +#define IS_DMA_SRC_HANDSHAKE_INTERFACE_SEL(CH) (((CH) == DMA_SRC_HANDSHAKE_INTERFACE_SEL_0) || \ + ((CH) == DMA_SRC_HANDSHAKE_INTERFACE_SEL_1) || \ + ((CH) == DMA_SRC_HANDSHAKE_INTERFACE_SEL_2) || \ + ((CH) == DMA_SRC_HANDSHAKE_INTERFACE_SEL_3) || \ + ((CH) == DMA_SRC_HANDSHAKE_INTERFACE_SEL_4) || \ + ((CH) == DMA_SRC_HANDSHAKE_INTERFACE_SEL_5) || \ + ((CH) == DMA_SRC_HANDSHAKE_INTERFACE_SEL_6) || \ + ((CH) == DMA_SRC_HANDSHAKE_INTERFACE_SEL_7) ) + +/** + * @} + */ + +/** @defgroup DMA_dst_handshake_interface_channel_select + * @{ + */ +#define DMA_DST_HANDSHAKE_INTERFACE_SEL_0 0U +#define DMA_DST_HANDSHAKE_INTERFACE_SEL_1 1U +#define DMA_DST_HANDSHAKE_INTERFACE_SEL_2 2U +#define DMA_DST_HANDSHAKE_INTERFACE_SEL_3 3U +#define DMA_DST_HANDSHAKE_INTERFACE_SEL_4 4U +#define DMA_DST_HANDSHAKE_INTERFACE_SEL_5 5U +#define DMA_DST_HANDSHAKE_INTERFACE_SEL_6 6U +#define DMA_DST_HANDSHAKE_INTERFACE_SEL_7 7U + +#define IS_DMA_DST_HANDSHAKE_INTERFACE_SEL(CH) (((CH) == DMA_DST_HANDSHAKE_INTERFACE_SEL_0) || \ + ((CH) == DMA_DST_HANDSHAKE_INTERFACE_SEL_1) || \ + ((CH) == DMA_DST_HANDSHAKE_INTERFACE_SEL_2) || \ + ((CH) == DMA_DST_HANDSHAKE_INTERFACE_SEL_3) || \ + ((CH) == DMA_DST_HANDSHAKE_INTERFACE_SEL_4) || \ + ((CH) == DMA_DST_HANDSHAKE_INTERFACE_SEL_5) || \ + ((CH) == DMA_DST_HANDSHAKE_INTERFACE_SEL_6) || \ + ((CH) == DMA_DST_HANDSHAKE_INTERFACE_SEL_7) ) + +/** + * @} + */ + + +/** @defgroup DMA_Instances_definition + * @{ + */ +#define IS_DMA_ALL_INSTANCE(INSTANCE) (((INSTANCE) == DMA1_Channel0) || \ + ((INSTANCE) == DMA1_Channel1) || \ + ((INSTANCE) == DMA1_Channel2) || \ + ((INSTANCE) == DMA1_Channel3) || \ + ((INSTANCE) == DMA1_Channel4) || \ + ((INSTANCE) == DMA1_Channel5) || \ + ((INSTANCE) == DMA1_Channel6) || \ + ((INSTANCE) == DMA1_Channel7) || \ + ((INSTANCE) == DMA2_Channel0) || \ + ((INSTANCE) == DMA2_Channel1) || \ + ((INSTANCE) == DMA2_Channel2) || \ + ((INSTANCE) == DMA2_Channel3) || \ + ((INSTANCE) == DMA2_Channel4) || \ + ((INSTANCE) == DMA2_Channel5) || \ + ((INSTANCE) == DMA2_Channel6) || \ + ((INSTANCE) == DMA2_Channel7)) +/** + * @} + */ + + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + + +/* Function used to set the DMA configuration to the default reset state ******/ +void DMA_DeInit(DMA_Channel_TypeDef* DMAy_Channelx); + +/* Initialization and Configuration functions *********************************/ +void DMA_Init(DMA_Channel_TypeDef* DMAy_Channelx, DMA_InitTypeDef* Init); +void DMA_StructInit(DMA_InitTypeDef* DMA_InitStruct); + +/* DMA and channel enable functions *********************************/ +void DMA_Channel_Cmd(DMA_Channel_TypeDef* DMAy_Channelx, FunctionalState NewState); +void DMA_Cmd(DMA_Channel_TypeDef* DMAy_Channelx, FunctionalState NewState); + +/* Data Counter function******************************************************/ +uint16_t DMA_GetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx); + +/* DMA software request function **********************************/ +void DMA_SoftWare_Request(DMA_Channel_TypeDef* DMAy_Channelx, DMA_SoftwareRequestTypeDef SoftwareRequest); + +/* DMA base address and channel index calculate function **********************************/ +DMA_BaseAddressAndChannelIndex CalBaseAddressAndChannelIndex(DMA_Channel_TypeDef* DMAy_Channelx); + +/* Interrupts and flags management functions **********************************/ +void DMA_ITConfig(DMA_Channel_TypeDef* DMAy_Channelx, uint8_t DMA_IT, FunctionalState NewState); +void DMA_ClearFlagStatus(DMA_Channel_TypeDef* DMAy_Channelx, uint8_t DMA_IT); +ITStatus DMA_GetITStatus(DMA_Channel_TypeDef* DMAy_Channelx, uint8_t DMA_IT); +FlagStatus DMA_GetFlagStatus(DMA_Channel_TypeDef* DMAy_Channelx, uint8_t DMA_FLAG); + + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif /*__FT32F4XX_DMA_H */ + + +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_ecap.h b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_ecap.h new file mode 100644 index 00000000000..7e70d1fcbaa --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_ecap.h @@ -0,0 +1,422 @@ +/** + ****************************************************************************** + * @file ft32f4xx_ecap.h + * @author FMD AE + * @brief This file contains all the functions prototypes for the eCAP firmware + * library. + * @version V1.0.0 + * @data 2025-04-17 + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __FT32F4XX_ECAP_H +#define __FT32F4XX_ECAP_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx.h" + + +/** @addtogroup ECAP + * @{ + */ +/* Exported types ------------------------------------------------------------*/ + +/** + * @brief ECAP Init structures definition + */ +typedef struct +{ + uint32_t ECAPMode; /*!< Specifies the mode of operation for ecap. + This parameter can be a value of @ref ECAP_mode */ + uint32_t EventPrescaler; /*!< Specifies the event filter prescale of capture mode. + This parameter can be a value of @ref ECAP_event_prescaler */ + FunctionalState CaptureLoad; /*!< Specifies the enable loading of CAP1-4 registers on a capture event. + This parameter can be set to ENABLE or DISABLE. */ + FunctionalState CaptureEvent4Reset; /*!< Specifies whether the counter should be reset at capture event 4. + This parameter can be set to ENABLE or DISABLE */ + FunctionalState CaptureEvent3Reset; /*!< Specifies whether the counter should be reset at capture event 3. + This parameter can be set to ENABLE or DISABLE */ + FunctionalState CaptureEvent2Reset; /*!< Specifies whether the counter should be reset at capture event 2. + This parameter can be set to ENABLE or DISABLE */ + FunctionalState CaptureEvent1Reset; /*!< Specifies whether the counter should be reset at capture event 1. + This parameter can be set to ENABLE or DISABLE */ + uint32_t CaptureEvent4Polarity; /*!< Specifies the polarity of capture event 4. + This parameter can be a value of @ref ECAP_event_polarity */ + uint32_t CaptureEvent3Polarity; /*!< Specifies the polarity of capture event 3. + This parameter can be a value of @ref ECAP_event_polarity */ + uint32_t CaptureEvent2Polarity; /*!< Specifies the polarity of capture event 2. + This parameter can be a value of @ref ECAP_event_polarity */ + uint32_t CaptureEvent1Polarity; /*!< Specifies the polarity of capture event 1. + This parameter can be a value of @ref ECAP_event_polarity */ + FunctionalState CounterSyncIn; /*!< Specifies the Counter Sync-In select mode. + This parameter can be set to ENABLE or DISABLE */ + uint32_t ModCounterStopWrap; /*!< Specifies the stop value for one-shot mode, and wrap value for continuous mode. + This parameter can be a value of @ref ECAP_mod_counter_stop_wrap */ + uint32_t ModCounterMode; /*!< Specifies the one-shot or continuous mode for Mod4 counter. + This parameter can be a value of @ref ECAP_mod_counter_mode */ + uint32_t APWMPolarity; /*!< Specifies the polarity of APWM output. + This parameter can be a value of @ref ECAP_apwm_output_polarity + Note: This parameter is only valid if the ECAPMode is selected as APWM mode.*/ + uint32_t CounterValue; /*!< Specifies the counter value for ecap. + This parameter can be a value of @ref ECAP_counter_value + Note: This parameter is only valid if the ECAPMode is selected as APWM mode.*/ + uint32_t CounterPhaseValue; /*!< Specifies the counter phase offset value for ecap. + This parameter can be a value of @ref ECAP_counter_phase_value + Note: This parameter is only valid if the ECAPMode is selected as APWM mode.*/ + uint32_t Capture1RegisterValue; /*!< Specifies the capture 1 register value for ecap. + This parameter can be a value of @ref ECAP_capture1_register_value + Note: This parameter is only valid if the ECAPMode is selected as APWM mode.*/ + uint32_t Capture2RegisterValue; /*!< Specifies the capture 2 register value for ecap. + This parameter can be a value of @ref ECAP_capture2_register_value + Note: This parameter is only valid if the ECAPMode is selected as APWM mode.*/ + +} ECAP_InitTypeDef; + + + + +/** + * @brief ECAP_data_registers_definition + */ +#define ECAP_DATA_REG_TSCTR ((uint8_t)0x00U) +#define ECAP_DATA_REG_CTRPHS ((uint8_t)0x01U) +#define ECAP_DATA_REG_CAP1 ((uint8_t)0x02U) +#define ECAP_DATA_REG_CAP2 ((uint8_t)0x03U) +#define ECAP_DATA_REG_CAP3 ((uint8_t)0x04U) +#define ECAP_DATA_REG_CAP4 ((uint8_t)0x05U) + +#define IS_ECAP_DATA_REG(TYPE) (((TYPE) == ECAP_DATA_REG_TSCTR ) || \ + ((TYPE) == ECAP_DATA_REG_CTRPHS) || \ + ((TYPE) == ECAP_DATA_REG_CAP1 ) || \ + ((TYPE) == ECAP_DATA_REG_CAP2 ) || \ + ((TYPE) == ECAP_DATA_REG_CAP3 ) || \ + ((TYPE) == ECAP_DATA_REG_CAP4 )) + + + + +/** @defgroup ECAP_interrupts_definition ECAP_IT + * @{ + */ +#define ECAP_IT_CEVT1 ECAP_ECEINT_CEVT1 +#define ECAP_IT_CEVT2 ECAP_ECEINT_CEVT2 +#define ECAP_IT_CEVT3 ECAP_ECEINT_CEVT3 +#define ECAP_IT_CEVT4 ECAP_ECEINT_CEVT4 +#define ECAP_IT_CTROVF ECAP_ECEINT_CTROVF +#define ECAP_IT_CTRPRD ECAP_ECEINT_CTR_EQ_PRD +#define ECAP_IT_CTRCMP ECAP_ECEINT_CTR_EQ_CMP + +#define IS_ECAP_IT(IT) (((IT) == ECAP_IT_CEVT1 ) || \ + ((IT) == ECAP_IT_CEVT2 ) || \ + ((IT) == ECAP_IT_CEVT3 ) || \ + ((IT) == ECAP_IT_CEVT4 ) || \ + ((IT) == ECAP_IT_CTROVF ) || \ + ((IT) == ECAP_IT_CTRPRD ) || \ + ((IT) == ECAP_IT_CTRCMP ) ) + +/** + * @} + */ + + + +/** @defgroup ECAP_flags_definition + * @{ + */ +#define ECAP_FLAG_INT ECAP_ECFLG_INT +#define ECAP_FLAG_CEVT1 ECAP_ECFLG_CEVT1 +#define ECAP_FLAG_CEVT2 ECAP_ECFLG_CEVT2 +#define ECAP_FLAG_CEVT3 ECAP_ECFLG_CEVT3 +#define ECAP_FLAG_CEVT4 ECAP_ECFLG_CEVT4 +#define ECAP_FLAG_CTROVF ECAP_ECFLG_CTROVF +#define ECAP_FLAG_CTRPRD ECAP_ECFLG_CTR_PRD +#define ECAP_FLAG_CTRCMP ECAP_ECFLG_CTR_CMP + +#define IS_ECAP_FLAG(FLAG) (((FLAG) == ECAP_FLAG_INT ) || \ + ((FLAG) == ECAP_FLAG_CEVT1 ) || \ + ((FLAG) == ECAP_FLAG_CEVT2 ) || \ + ((FLAG) == ECAP_FLAG_CEVT3 ) || \ + ((FLAG) == ECAP_FLAG_CEVT4 ) || \ + ((FLAG) == ECAP_FLAG_CTROVF) || \ + ((FLAG) == ECAP_FLAG_CTRPRD) || \ + ((FLAG) == ECAP_FLAG_CTRCMP) ) + +//#define ECAP_FLAG_MASK ((uint32_t)(ECAP_FLAG_INT | \ +// ECAP_FLAG_CEVT1 | \ +// ECAP_FLAG_CEVT2 | \ +// ECAP_FLAG_CEVT3 | \ +// ECAP_FLAG_CEVT4 | \ +// ECAP_FLAG_CTROVF | \ +// ECAP_FLAG_CTRPRD | \ +// ECAP_FLAG_CTRCMP )) +/** + * @} + */ + + +/** @defgroup ECAP_mode + * @{ + */ +#define ECAP_MODE_CAPTURE 0U +#define ECAP_MODE_APWM ECAP_ECCTL2_CAP_APWM + +#define IS_ECAP_MODE(MODE) (((MODE) == ECAP_MODE_CAPTURE) || ((MODE) == ECAP_MODE_APWM)) + +/** + * @} + */ + +/** @defgroup ECAP_event_prescaler + * @{ + */ +#define ECAP_EVENT_PRESCALER_1 0x00U +#define ECAP_EVENT_PRESCALER_2 0x01U +#define ECAP_EVENT_PRESCALER_4 0x02U +#define ECAP_EVENT_PRESCALER_6 0x03U +#define ECAP_EVENT_PRESCALER_8 0x04U +#define ECAP_EVENT_PRESCALER_10 0x05U +#define ECAP_EVENT_PRESCALER_12 0x06U +#define ECAP_EVENT_PRESCALER_14 0x07U +#define ECAP_EVENT_PRESCALER_16 0x08U +#define ECAP_EVENT_PRESCALER_18 0x09U +#define ECAP_EVENT_PRESCALER_20 0x0AU +#define ECAP_EVENT_PRESCALER_22 0x0BU +#define ECAP_EVENT_PRESCALER_24 0x0CU +#define ECAP_EVENT_PRESCALER_26 0x0DU +#define ECAP_EVENT_PRESCALER_28 0x0EU +#define ECAP_EVENT_PRESCALER_30 0x0FU +#define ECAP_EVENT_PRESCALER_32 0x10U +#define ECAP_EVENT_PRESCALER_34 0x11U +#define ECAP_EVENT_PRESCALER_36 0x12U +#define ECAP_EVENT_PRESCALER_38 0x13U +#define ECAP_EVENT_PRESCALER_40 0x14U +#define ECAP_EVENT_PRESCALER_42 0x15U +#define ECAP_EVENT_PRESCALER_44 0x16U +#define ECAP_EVENT_PRESCALER_46 0x17U +#define ECAP_EVENT_PRESCALER_48 0x18U +#define ECAP_EVENT_PRESCALER_50 0x19U +#define ECAP_EVENT_PRESCALER_52 0x1AU +#define ECAP_EVENT_PRESCALER_54 0x1BU +#define ECAP_EVENT_PRESCALER_56 0x1CU +#define ECAP_EVENT_PRESCALER_58 0x1DU +#define ECAP_EVENT_PRESCALER_60 0x1EU +#define ECAP_EVENT_PRESCALER_62 0x1FU + +#define IS_ECAP_EVENT_PRESCALER(PRESCALER) (((PRESCALER) == ECAP_EVENT_PRESCALER_1 ) || \ + ((PRESCALER) == ECAP_EVENT_PRESCALER_2 ) || \ + ((PRESCALER) == ECAP_EVENT_PRESCALER_4 ) || \ + ((PRESCALER) == ECAP_EVENT_PRESCALER_6 ) || \ + ((PRESCALER) == ECAP_EVENT_PRESCALER_8 ) || \ + ((PRESCALER) == ECAP_EVENT_PRESCALER_10) || \ + ((PRESCALER) == ECAP_EVENT_PRESCALER_12) || \ + ((PRESCALER) == ECAP_EVENT_PRESCALER_14) || \ + ((PRESCALER) == ECAP_EVENT_PRESCALER_16) || \ + ((PRESCALER) == ECAP_EVENT_PRESCALER_18) || \ + ((PRESCALER) == ECAP_EVENT_PRESCALER_20) || \ + ((PRESCALER) == ECAP_EVENT_PRESCALER_22) || \ + ((PRESCALER) == ECAP_EVENT_PRESCALER_24) || \ + ((PRESCALER) == ECAP_EVENT_PRESCALER_26) || \ + ((PRESCALER) == ECAP_EVENT_PRESCALER_28) || \ + ((PRESCALER) == ECAP_EVENT_PRESCALER_30) || \ + ((PRESCALER) == ECAP_EVENT_PRESCALER_32) || \ + ((PRESCALER) == ECAP_EVENT_PRESCALER_34) || \ + ((PRESCALER) == ECAP_EVENT_PRESCALER_36) || \ + ((PRESCALER) == ECAP_EVENT_PRESCALER_38) || \ + ((PRESCALER) == ECAP_EVENT_PRESCALER_40) || \ + ((PRESCALER) == ECAP_EVENT_PRESCALER_42) || \ + ((PRESCALER) == ECAP_EVENT_PRESCALER_44) || \ + ((PRESCALER) == ECAP_EVENT_PRESCALER_46) || \ + ((PRESCALER) == ECAP_EVENT_PRESCALER_48) || \ + ((PRESCALER) == ECAP_EVENT_PRESCALER_50) || \ + ((PRESCALER) == ECAP_EVENT_PRESCALER_52) || \ + ((PRESCALER) == ECAP_EVENT_PRESCALER_54) || \ + ((PRESCALER) == ECAP_EVENT_PRESCALER_56) || \ + ((PRESCALER) == ECAP_EVENT_PRESCALER_58) || \ + ((PRESCALER) == ECAP_EVENT_PRESCALER_60) || \ + ((PRESCALER) == ECAP_EVENT_PRESCALER_62) ) +/** + * @} + */ + + +///** @defgroup ECAP_capture_load +// * @{ +// */ +//#define ECAP_CAPTURE_LOAD_DISABLE 0U +//#define ECAP_CAPTURE_LOAD_ENABLE 1U +// +//#define IS_ECAP_CAPTURE_LOAD(TYPE) (((TYPE) == ECAP_CAPTURE_LOAD_DISABLE) || ((TYPE) == ECAP_CAPTURE_LOAD_ENABLE)) +// +///** +// * @} +// */ + + +///** @defgroup ECAP_counter_reset_event +// * @{ +// */ +//#define ECAP_COUNTER_RESET_DISABLE 0U +//#define ECAP_COUNTER_RESET_ENABLE 1U +// +//#define IS_ECAP_COUNTER_RESET(STATE) (((STATE) == ECAP_COUNTER_RESET_DISABLE) || \ +// ((STATE) == ECAP_COUNTER_RESET_ENABLE )) + +/** + * @} + */ + + +/** @defgroup ECAP_event_polarity + * @{ + */ +#define ECAP_EVENT_POLARITY_RE 0U //Capture event 4 triggered on a rising edge(RE) +#define ECAP_EVENT_POLARITY_FE 1U //Capture event 4 triggered on a falling edge(FE) + +#define IS_ECAP_EVENT_POLARITY(TYPE) (((TYPE) == ECAP_EVENT_POLARITY_RE) || ((TYPE) == ECAP_EVENT_POLARITY_FE)) + +/** + * @} + */ + + +/** @defgroup ECAP_apwm_output_polarity + * @{ + */ +#define ECAP_APWM_POLARITY_HIGH 0U +#define ECAP_APWM_POLARITY_LOW ECAP_ECCTL2_APWMPOL + +#define IS_ECAP_APWM_POLARITY(TYPE) (((TYPE) == ECAP_APWM_POLARITY_HIGH) || \ + ((TYPE) == ECAP_APWM_POLARITY_LOW )) + +/** + * @} + */ + + +///** @defgroup ECAP_counter_syncin_select +// * @{ +// */ +//#define ECAP_COUNTER_SYNCIN_DISABLE 0U +//#define ECAP_COUNTER_SYNCIN_ENABLE 1U +// +//#define IS_ECAP_COUNTER_SYNCIN(STATE) (((STATE) == ECAP_COUNTER_SYNCIN_DISABLE) || \ +// ((STATE) == ECAP_COUNTER_SYNCIN_ENABLE )) + +/** + * @} + */ + + +/** @defgroup ECAP_mod_counter_stop_wrap + * @{ + */ +#define ECAP_STOP_WRAP_EVENT1 0U +#define ECAP_STOP_WRAP_EVENT2 ECAP_ECCTL2_STOP_WRAP_0 +#define ECAP_STOP_WRAP_EVENT3 ECAP_ECCTL2_STOP_WRAP_1 +#define ECAP_STOP_WRAP_EVENT4 ECAP_ECCTL2_STOP_WRAP + +#define IS_ECAP_MOD_COUNTER_STOP_WRAP(SEL) (((SEL) == ECAP_STOP_WRAP_EVENT1) || \ + ((SEL) == ECAP_STOP_WRAP_EVENT2) || \ + ((SEL) == ECAP_STOP_WRAP_EVENT3) || \ + ((SEL) == ECAP_STOP_WRAP_EVENT4) ) + +/** + * @} + */ + +/** @defgroup ECAP_mod_counter_mode + * @{ + */ +#define ECAP_MOD_COUNTER_CONT 0U +#define ECAP_MOD_COUNTER_ONESHOT ECAP_ECCTL2_CONT_ONESHT + +#define IS_ECAP_MOD_COUNTER_MODE(MODE) (((MODE) == ECAP_MOD_COUNTER_CONT) || ((MODE) == ECAP_MOD_COUNTER_ONESHOT)) + + +/** + * @} + */ + +/** @defgroup ECAP_counter_value + * @{ + */ +#define IS_ECAP_COUNTER_VALUE(VALUE) (((VALUE) >= 0x0U) && ((VALUE) <= 0xFFFFFFFFU)) + +/** + * @} + */ + +/** @defgroup ECAP_counter_phase_value + * @{ + */ +#define IS_ECAP_COUNTER_PHASE_VALUE(VALUE) (((VALUE) >= 0x0U) && ((VALUE) <= 0xFFFFFFFFU)) + +/** + * @} + */ + +/** @defgroup ECAP_capture1_register_value + * @{ + */ +#define IS_ECAP_CAPTURE1_REGISTER_VALUE(VALUE) (((VALUE) >= 0x0U) && ((VALUE) <= 0xFFFFFFFFU)) + +/** + * @} + */ + +/** @defgroup ECAP_capture2_register_value + * @{ + */ +#define IS_ECAP_CAPTURE2_REGISTER_VALUE(VALUE) (((VALUE) >= 0x0U) && ((VALUE) <= 0xFFFFFFFFU)) + +/** + * @} + */ + + + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +/* Function used to set the ECAP configuration to the default reset state ******/ +void ECAP_DeInit(); + +/* Initialization and Configuration functions *********************************/ +void ECAP_Init(ECAP_InitTypeDef* ECAP_InitStruct); +void ECAP_StructInit(ECAP_InitTypeDef* ECAP_InitStruct); + +/* ECAP control functions *********************************/ +void ECAP_Cmd(FunctionalState NewState); +void ECAP_ReArm(); +void ECAP_SoftwareForceSync(); + +/* Data register access function***********************************************/ +uint32_t ECAP_GetDataRegister(uint8_t ECAP_DATA_REG); +void ECAP_WriteDataRegister(uint8_t ECAP_DATA_REG, uint32_t Value); + +/* Interrupts and flags management functions **********************************/ +void ECAP_ITConfig(uint8_t ECAP_IT, FunctionalState NewState); +void ECAP_ClearFlag(uint8_t ECAP_FLAG); +void ECAP_ITForce(uint8_t ECAP_IT); +ITStatus ECAP_GetITStatus(uint8_t ECAP_IT); +FlagStatus ECAP_GetFlagStatus(uint8_t ECAP_FLAG); + + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif /*__FT32F4XX_ECAP_H */ + + +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_epwm.h b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_epwm.h new file mode 100644 index 00000000000..c85bf471e94 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_epwm.h @@ -0,0 +1,779 @@ +/** + ****************************************************************************** + * @file ft32f4xx_epwm.h + * @author FMD AE + * @brief This file contains all the functions prototypes for the EPWM + * firmware library. + * @version V1.0.0 + * @data 2025-03-25 + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __FT32F4XX_EPWM_H +#define __FT32F4XX_EPWM_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx.h" + +/** @addtogroup EPWM + * @{ + */ + + + + +/* Exported types ------------------------------------------------------------*/ + +/** + * @brief Enumeration to define the pulse width modulation (PWM) action + */ +typedef enum +{ + EPWM_ActionQual_Disabled = 0, + EPWM_ActionQual_Clear, + EPWM_ActionQual_Set, + EPWM_ActionQual_Toggle +} EPWM_ActionQual_e; + +/** + * @brief Enumeration to define the pulse width modulation (PWM) high speed + */ +typedef enum +{ + EPWM_HspClkDiv_by_1 = (0 << 7), + EPWM_HspClkDiv_by_2 = (1 << 7), + EPWM_HspClkDiv_by_4 = (2 << 7), + EPWM_HspClkDiv_by_6 = (3 << 7), + EPWM_HspClkDiv_by_8 = (4 << 7), + EPWM_HspClkDiv_by_10 = (5 << 7), + EPWM_HspClkDiv_by_12 = (6 << 7), + EPWM_HspClkDiv_by_14 = (7 << 7) +} EPWM_HspClkDiv_e; + +/** + * @brief Enumeration to define the pulse width modulation (PWM) clock + */ +typedef enum +{ + EPWM_ClkDiv_by_1 = (0 << 10), + EPWM_ClkDiv_by_2 = (1 << 10), + EPWM_ClkDiv_by_4 = (2 << 10), + EPWM_ClkDiv_by_8 = (3 << 10), + EPWM_ClkDiv_by_16 = (4 << 10), + EPWM_ClkDiv_by_32 = (5 << 10), + EPWM_ClkDiv_by_64 = (6 << 10), + EPWM_ClkDiv_by_128 = (7 << 10) +} EPWM_ClkDiv_e; + +/** + * @brief Enumeration to define the pulse width modulation (PWM) chopping + */ +typedef enum +{ + EPWM_ChoppingClkFreq_SysClkOut_by_1 = (0 << 5), + EPWM_ChoppingClkFreq_SysClkOut_by_2 = (1 << 5), + EPWM_ChoppingClkFreq_SysClkOut_by_3 = (2 << 5), + EPWM_ChoppingClkFreq_SysClkOut_by_4 = (3 << 5), + EPWM_ChoppingClkFreq_SysClkOut_by_5 = (4 << 5), + EPWM_ChoppingClkFreq_SysClkOut_by_6 = (5 << 5), + EPWM_ChoppingClkFreq_SysClkOut_by_7 = (6 << 5), + EPWM_ChoppingClkFreq_SysClkOut_by_8 = (7 << 5) +} EPWM_ChoppingClkFreq_e; + +/** + * @brief Enumeration to define the pulse width modulation (PWM) chopping + */ +typedef enum +{ + EPWM_ChoppingDutyCycle_One_Eighth = (0 << 8), + EPWM_ChoppingDutyCycle_Two_Eighths = (1 << 8), + EPWM_ChoppingDutyCycle_Three_Eighths = (2 << 8), + EPWM_ChoppingDutyCycle_Four_Eighths = (3 << 8), + EPWM_ChoppingDutyCycle_Five_Eighths = (4 << 8), + EPWM_ChoppingDutyCycle_Six_Eighths = (5 << 8), + EPWM_ChoppingDutyCycle_Seven_Eighths = (6 << 8) +} EPWM_ChoppingDutyCycle_e; + +/** + * @brief Enumeration to define the pulse width modulation (PWM) chopping + */ +typedef enum +{ + EPWM_ChoppingPulseWidth_One_Eighth_SysClkOut = (0 << 1), + EPWM_ChoppingPulseWidth_Two_Eighths_SysClkOut = (1 << 1), + EPWM_ChoppingPulseWidth_Three_Eighths_SysClkOut = (2 << 1), + EPWM_ChoppingPulseWidth_Four_Eighths_SysClkOut = (3 << 1), + EPWM_ChoppingPulseWidth_Five_Eighths_SysClkOut = (4 << 1), + EPWM_ChoppingPulseWidth_Six_Eighths_SysClkOut = (5 << 1), + EPWM_ChoppingPulseWidth_Seven_Eighths_SysClkOut = (6 << 1), + EPWM_ChoppingPulseWidth_Eight_Eighths_SysClkOut = (7 << 1), + EPWM_ChoppingPulseWidth_Nine_Eighths_SysClkOut = (8 << 1), + EPWM_ChoppingPulseWidth_Ten_Eighths_SysClkOut = (9 << 1), + EPWM_ChoppingPulseWidth_Eleven_Eighths_SysClkOut = (10 << 1), + EPWM_ChoppingPulseWidth_Twelve_Eighths_SysClkOut = (11 << 1), + EPWM_ChoppingPulseWidth_Thirteen_Eighths_SysClkOut = (12 << 1), + EPWM_ChoppingPulseWidth_Fourteen_Eighths_SysClkOut = (13 << 1), + EPWM_ChoppingPulseWidth_Fifteen_Eighths_SysClkOut = (14 << 1), + EPWM_ChoppingPulseWidth_Sixteen_Eighths_SysClkOut = (15 << 1) +} EPWM_ChoppingPulseWidth_e; + +/** + * @brief Enumeration to define the pulse width modulation (PWM) counter modes + */ +typedef enum +{ + EPWM_CounterMode_Up = (0 << 0), + EPWM_CounterMode_Down = (1 << 0), + EPWM_CounterMode_UpDown = (2 << 0), + EPWM_CounterMode_Stop = (3 << 0) +} EPWM_CounterMode_e; + +/** + * @brief Enumeration to define the pulse width modulation (PWM) deadband + */ +typedef enum +{ + EPWM_DeadBandInputMode_EPWMxA_Rising_and_Falling = (0 << 4), + EPWM_DeadBandInputMode_EPWMxA_Falling_EPWMxB_Rising = (1 << 4), + EPWM_DeadBandInputMode_EPWMxA_Rising_EPWMxB_Falling = (2 << 4), + EPWM_DeadBandInputMode_EPWMxB_Rising_and_Falling = (3 << 4) +} EPWM_DeadBandInputMode_e; + + +/** + * @brief Enumeration to define the pulse width modulation (PWM) deadband + */ +typedef enum +{ + EPWM_DeadBandOutputMode_Bypass = (0 << 0), + EPWM_DeadBandOutputMode_EPWMxA_Disable_EPWMxB_Falling = (1 << 0), + EPWM_DeadBandOutputMode_EPWMxA_Rising_EPWMxB_Disable = (2 << 0), + EPWM_DeadBandOutputMode_EPWMxA_Rising_EPWMxB_Falling = (3 << 0) +} EPWM_DeadBandOutputMode_e; + +/** + * @brief Enumeration to define the pulse width modulation (PWM) deadband + */ +typedef enum +{ + EPWM_DeadBandPolarity_EPWMxA_EPWMxB = (0 << 2), + EPWM_DeadBandPolarity_EPWMxA_Inverted = (1 << 2), + EPWM_DeadBandPolarity_EPWMxB_Inverted = (2 << 2), + EPWM_DeadBandPolarity_EPWMxA_Inverted_EPWMxB_Inverted = (3 << 2) +} EPWM_DeadBandPolarity_e; + +/** + * @brief Enumeration to define the pulse width modulation (PWM) digital + */ +typedef enum +{ + EPWM_DigitalCompare_A_High = 0, + EPWM_DigitalCompare_A_Low = 4, + EPWM_DigitalCompare_B_High = 8, + EPWM_DigitalCompare_B_Low = 12 +} EPWM_DigitalCompare_Input_e; + +/** + * @brief Enumeration to define the pulse width modulation (PWM) digital + */ +typedef enum +{ + EPWM_DigitalCompare_InputSel_TZ1 = (0 << 0), + EPWM_DigitalCompare_InputSel_TZ2 = (1 << 0), + EPWM_DigitalCompare_InputSel_TZ3 = (2 << 0), + EPWM_DigitalCompare_InputSel_COMP1OUT = (8 << 0), + EPWM_DigitalCompare_InputSel_COMP2OUT = (9 << 0), + EPWM_DigitalCompare_InputSel_COMP3OUT = (10 << 0) +} EPWM_DigitalCompare_InputSel_e; + +/** + * @brief Enumeration to define the pulse width modulation (PWM) digital + */ +typedef enum +{ + EPWM_DigitalCompare_FilterSrc_DCAEVT1 = 0, + EPWM_DigitalCompare_FilterSrc_DCAEVT2, + EPWM_DigitalCompare_FilterSrc_DCBEVT1, + EPWM_DigitalCompare_FilterSrc_DCBEVT2 +} EPWM_DigitalCompare_FilterSrc_e; + +/** + * @brief Enumeration to define the pulse width modulation (PWM) digital + */ +typedef enum +{ + EPWM_DigitalCompare_PulseSel_CTRPRD = 0, + EPWM_DigitalCompare_PulseSel_CTR0 +} EPWM_DigitalCompare_PulseSel_e; + +/** + * @brief Enumeration to define the pulse width modulation (PWM) high + */ +typedef enum +{ + EPWM_HrControlMode_Duty = (0 << 2), + EPWM_HrControlMode_Phase = (1 << 2) +} EPWM_HrControlMode_e; + +/** + * @brief Enumeration to define the pulse width modulation (PWM) high + */ +typedef enum +{ + EPWM_HrEdgeMode_Disabled = (0 << 0), + EPWM_HrEdgeMode_Rising = (1 << 0), + EPWM_HrEdgeMode_Falling = (2 << 0), + EPWM_HrEdgeMode_Both = (3 << 0) +} EPWM_HrEdgeMode_e; + +/** + * @brief Enumeration to define the pulse width modulation (PWM) high + */ +typedef enum +{ + EPWM_HrShadowMode_CTR_EQ_0 = (0 << 3), + EPWM_HrShadowMode_CTR_EQ_PRD = (1 << 3), + EPWM_HrShadowMode_CTR_EQ_0_OR_PRD = (2 << 3) +} EPWM_HrShadowMode_e; + +/** + * @brief Enumeration to define the pulse width modulation (PWM) interrupt + */ +typedef enum +{ + EPWM_IntMode_CounterEqualZero = (1 << 0), + EPWM_IntMode_CounterEqualPeriod = (2 << 0), + EPWM_IntMode_CounterEqualZeroOrPeriod = (3 << 0), + EPWM_IntMode_CounterEqualCmpAIncr = (4 << 0), + EPWM_IntMode_CounterEqualCmpADecr = (5 << 0), + EPWM_IntMode_CounterEqualCmpBIncr = (6 << 0), + EPWM_IntMode_CounterEqualCmpBDecr = (7 << 0) +} EPWM_IntMode_e; + +/** + * @brief Enumeration to define the pulse width modulation (PWM) interrupt + */ +typedef enum +{ + EPWM_IntPeriod_Disable = (0 << 0), + EPWM_IntPeriod_FirstEvent = (1 << 0), + EPWM_IntPeriod_SecondEvent = (2 << 0), + EPWM_IntPeriod_ThirdEvent = (3 << 0) +} EPWM_IntPeriod_e; + +/** + * @brief Enumeration to define the pulse width modulation (PWM) load modes + */ +typedef enum +{ + EPWM_LoadMode_Zero = 0, + EPWM_LoadMode_Period, + EPWM_LoadMode_Either, + EPWM_LoadMode_Freeze +} EPWM_LoadMode_e; + +/** + * @brief Enumeration to define the pulse width modulation (PWM) numbers + */ +typedef enum +{ + EPWM_Number_1 = 0, + EPWM_Number_2, + EPWM_Number_3, + EPWM_Number_4, + EPWM_Number_5, + EPWM_Number_6, + EPWM_Number_7 +} EPWM_Number_e; + +/** + * @brief Enumeration to define the pulse width modulation (PWM) period load + */ +typedef enum +{ + EPWM_PeriodLoad_Shadow = (0 << 3), + EPWM_PeriodLoad_Immediate = (1 << 3) +} EPWM_PeriodLoad_e; + + +/** + * @brief Enumeration to define the pulse width modulation (PWM) phase + */ +typedef enum +{ + EPWM_PhaseDir_CountDown = (0 << 13), + EPWM_PhaseDir_CountUp = (1 << 13) +} EPWM_PhaseDir_e; + +/** + * @brief Enumeration to define the pulse width modulation (PWM) run modes + */ +//typedef enum +//{ +// EPWM_RunMode_SoftStopAfterIncr=(0 << 14), +// EPWM_RunMode_SoftStopAfterDecr=(0 << 14), +// EPWM_RunMode_SoftStopAfterCycle=(1 << 14), +// EPWM_RunMode_FreeRun=(2 << 14) +//} EPWM_RunMode_e; + +/** + * @brief Enumeration to define the pulse width modulation (PWM) shadow modes + */ +typedef enum +{ + EPWM_ShadowMode_Shadow = 0, + EPWM_ShadowMode_Immediate +} EPWM_ShadowMode_e; + +/** + * @brief Enumeration to define the pulse width modulation (PWM) shadow status + */ +typedef enum +{ + EPWM_ShadowStatus_NotFull = 0, + EPWM_ShadowStatus_Full +} EPWM_ShadowStatus_e; + +/** + * @brief Enumeration to define the pulse width modulation (PWM) start of + */ +typedef enum +{ + EPWM_SocPeriod_Disable = 0, + EPWM_SocPeriod_FirstEvent, + EPWM_SocPeriod_SecondEvent, + EPWM_SocPeriod_ThirdEvent +} EPWM_SocPeriod_e; + +/** + * @brief Enumeration to define the pulse width modulation (PWM) start of + */ +typedef enum +{ + EPWM_SocPulseSrc_DcEvt = 0, + EPWM_SocPulseSrc_CounterEqualZero, + EPWM_SocPulseSrc_CounterEqualPeriod, + EPWM_SocPulseSrc_CounterEqualZeroOrPeriod, + EPWM_SocPulseSrc_CounterEqualCmpAIncr, + EPWM_SocPulseSrc_CounterEqualCmpADecr, + EPWM_SocPulseSrc_CounterEqualCmpBIncr, + EPWM_SocPulseSrc_CounterEqualCmpBDecr +} EPWM_SocPulseSrc_e; + +/** + * @brief Enumeration to define the pulse width modulation (PWM) sync modes + */ +typedef enum +{ + EPWM_SyncMode_EPWMxSYNC = (0 << 4), + EPWM_SyncMode_CounterEqualZero = (1 << 4), + EPWM_SyncMode_CounterEqualCounterCompareZero = (2 << 4), + EPWM_SyncMode_Disable = (3 << 4) +} EPWM_SyncMode_e; + +/** + * @brief Enumeration to define the pulse width modulation (PWM) trip zone + */ +typedef enum +{ + EPWM_TripZoneSrc_CycleByCycle_TZ1_NOT = (1 << 0), + EPWM_TripZoneSrc_CycleByCycle_TZ2_NOT = (1 << 1), + EPWM_TripZoneSrc_CycleByCycle_TZ3_NOT = (1 << 2), + EPWM_TripZoneSrc_CycleByCycle_TZ4_NOT = (1 << 3), + EPWM_TripZoneSrc_CycleByCycle_TZ5_NOT = (1 << 4), + EPWM_TripZoneSrc_CycleByCycle_TZ6_NOT = (1 << 5), + EPWM_TripZoneSrc_CycleByCycle_CmpA = (1 << 6), + EPWM_TripZoneSrc_CycleByCycle_CmpB = (1 << 7), + EPWM_TripZoneSrc_OneShot_TZ1_NOT = (1 << 8), + EPWM_TripZoneSrc_OneShot_TZ2_NOT = (1 << 9), + EPWM_TripZoneSrc_OneShot_TZ3_NOT = (1 << 10), + EPWM_TripZoneSrc_OneShot_TZ4_NOT = (1 << 11), + EPWM_TripZoneSrc_OneShot_TZ5_NOT = (1 << 12), + EPWM_TripZoneSrc_OneShot_TZ6_NOT = (1 << 13), + EPWM_TripZoneSrc_OneShot_CmpA = (1 << 14), + EPWM_TripZoneSrc_OneShot_CmpB = (1 << 15) +} EPWM_TripZoneSrc_e; + +/** + * @brief Enumeration to define the pulse width modulation (PWM) trip zone + */ +typedef enum +{ + EPWM_TripZoneState_HighImp = 0, + EPWM_TripZoneState_EPWM_High, + EPWM_TripZoneState_EPWM_Low, + EPWM_TripZoneState_DoNothing +} EPWM_TripZoneState_e; + +/** + * @brief Enumeration to define the pulse width modulation (PWM) trip zone + */ +typedef enum +{ + EPWM_TripZoneFlag_Global = (1 << 0), //!< Global Trip Zone flag + EPWM_TripZoneFlag_CBC = (1 << 1), //!< Cycle by cycle Trip Zone flag + EPWM_TripZoneFlag_OST = (1 << 2), //!< One Shot Trip Zone flag + EPWM_TripZoneFlag_DCAEVT1 = (1 << 3), //!< Digital Compare A Event 1 Trip Zone flag + EPWM_TripZoneFlag_DCAEVT2 = (1 << 4), //!< Digital Compare A Event 2 Trip Zone flag + EPWM_TripZoneFlag_DCBEVT1 = (1 << 5), //!< Digital Compare B Event 1 Trip Zone flag + EPWM_TripZoneFlag_DCBEVT2 = (1 << 6) //!< Digital Compare B Event 2 Trip Zone flag +} EPWM_TripZoneFlag_e; + +/** + * @brief Enumeration to define the pulse width modulation (PWM) trip zone + */ +typedef enum +{ + EPWM_TripZoneDCEventSel_Disabled = (0 << 0), //!< Event Disabled + EPWM_TripZoneDCEventSel_DCxHL_DCxLX = (1 << 0), //!< Compare H = Low, Compare L = Don't Care + EPWM_TripZoneDCEventSel_DCxHH_DCxLX = (2 << 0), //!< Compare H = High, Compare L = Don't Care + EPWM_TripZoneDCEventSel_DCxHX_DCxLL = (3 << 0), //!< Compare H = Don't Care, Compare L = Low + EPWM_TripZoneDCEventSel_DCxHX_DCxLH = (4 << 0), //!< Compare H = Don't Care, Compare L = High + EPWM_TripZoneDCEventSel_DCxHL_DCxLH = (5 << 0) //!< Compare H = Low, Compare L = High +} EPWM_TripZoneDCEventSel_e; + + + + + + + +/* Exported constants --------------------------------------------------------*/ + +#define EPWM_AQCTL_ZRO_BITS (3 << 0) +#define EPWM_AQCTL_PRD_BITS (3 << 2) +#define EPWM_AQCTL_CAU_BITS (3 << 4) +#define EPWM_AQCTL_CAD_BITS (3 << 6) +#define EPWM_AQCTL_CBU_BITS (3 << 8) +#define EPWM_AQCTL_CBD_BITS (3 << 10) +#define EPWM_CMPCTL_LOADAMODE_BITS (3 << 0) +#define EPWM_CMPCTL_LOADBMODE_BITS (3 << 2) +#define EPWM_CMPCTL_SHDWAMODE_BITS (1 << 4) +#define EPWM_CMPCTL_SHDWBMODE_BITS (1 << 6) +#define EPWM_CMPCTL_SHDWAFULL_BITS (1 << 5) +#define EPWM_CMPCTL_SHDWBFULL_BITS (1 << 7) +#define EPWM_DBCTL_OUTMODE_BITS (3 << 0) +#define EPWM_DBCTL_POLSEL_BITS (3 << 2) +#define EPWM_DBCTL_INMODE_BITS (3 << 4) +#define EPWM_DBCTL_HALFCYCLE_BITS (1 << 15) +#define EPWM_ETCLR_INT_BITS (1 << 0) +#define EPWM_ETCLR_SOCA_BITS (1 << 2) +#define EPWM_ETCLR_SOCB_BITS (1 << 3) +#define EPWM_ETPS_INTPRD_BITS (3 << 0) +#define EPWM_ETPS_INTCNT_BITS (3 << 2) +#define EPWM_ETPS_SOCAPRD_BITS (3 << 8) +#define EPWM_ETPS_SOCACNT_BITS (3 << 10) +#define EPWM_ETPS_SOCBPRD_BITS (3 << 12) +#define EPWM_ETPS_SOCBCNT_BITS (3 << 14) +#define EPWM_ETSEL_INTSEL_BITS (7 << 0) +#define EPWM_ETSEL_INTEN_BITS (1 << 3) +#define EPWM_ETSEL_SOCASEL_BITS (7 << 8) +#define EPWM_ETSEL_SOCAEN_BITS (1 << 11) +#define EPWM_ETSEL_SOCBSEL_BITS (7 << 12) +#define EPWM_ETSEL_SOCBEN_BITS (1 << 15) +#define EPWM_PCCTL_CHPEN_BITS (1 << 0) +#define EPWM_PCCTL_OSHTWTH_BITS (15 << 1) +#define EPWM_PCCTL_CHPFREQ_BITS (7 << 5) +#define EPWM_PCCTL_CHPDUTY_BITS (7 << 8) +#define EPWM_HRCNFG_EDGMODE_BITS (3 << 0) +#define EPWM_HRCNFG_CTLMODE_BITS (1 << 2) +#define EPWM_HRCNFG_HRLOAD_BITS (3 << 3) +#define EPWM_HRCNFG_SELOUTB_BITS (1 << 5) +#define EPWM_HRCNFG_AUTOCONV_BITS (1 << 6) +#define EPWM_HRCNFG_SWAPAB_BITS (1 << 7) +#define EPWM_HRPPWR_MEPOFF_BITS (1 << 0) +#define EPWM_HRPPWR_MEPSFO_BITS (1 << 1) +#define EPWM_HRPCTL_HRPE_BITS (1 << 0) +#define EPWM_HRPCTL_EPWMSYNCSEL_BITS (1 << 1) +#define EPWM_HRPCTL_TBPHSHRLOADE_BITS (1 << 2) +#define EPWM_TBCTL_CTRMODE_BITS (3 << 0) +#define EPWM_TBCTL_PHSEN_BITS (1 << 2) +#define EPWM_TBCTL_PRDLD_BITS (1 << 3) +#define EPWM_TBCTL_SYNCOSEL_BITS (3 << 4) +#define EPWM_TBCTL_SWFSYNC_BITS (1 << 6) +#define EPWM_TBCTL_HSPCLKDIV_BITS (7 << 7) +#define EPWM_TBCTL_CLKDIV_BITS (7 << 10) +#define EPWM_TBCTL_PHSDIR_BITS (1 << 13) +#define EPWM_TBCTL_FREESOFT_BITS (3 << 14) +#define EPWM_TZCLR_INT_BITS (1 << 0) +#define EPWM_TZCLR_CBC_BITS (1 << 1) +#define EPWM_TZCLR_OST_BITS (1 << 2) +#define EPWM_TZCLR_DCAEVT1_BITS (1 << 3) +#define EPWM_TZCLR_DCAEVT2_BITS (1 << 4) +#define EPWM_TZCLR_DCBEVT1_BITS (1 << 5) +#define EPWM_TZCLR_DCBEVT2_BITS (1 << 6) +#define EPWM_TZCTL_TZA_BITS (3 << 0) +#define EPWM_TZCTL_TZB_BITS (3 << 2) +#define EPWM_TZCTL_DCAEVT1_BITS (3 << 4) +#define EPWM_TZCTL_DCAEVT2_BITS (3 << 6) +#define EPWM_TZCTL_DCBEVT1_BITS (3 << 8) +#define EPWM_TZCTL_DCBEVT2_BITS (3 << 10) +#define EPWM_TZFRC_CBC_BITS (1 << 1) +#define EPWM_TZFRC_OST_BITS (1 << 2) +#define EPWM_TZFRC_DCAEVT1_BITS (1 << 3) +#define EPWM_TZFRC_DCAEVT2_BITS (1 << 4) +#define EPWM_TZFRC_DCBEVT1_BITS (1 << 5) +#define EPWM_TZFRC_DCBEVT2_BITS (1 << 6) +#define EPWM_TZDCSEL_DCAEVT1_BITS (7 << 0) +#define EPWM_TZDCSEL_DCAEVT2_BITS (7 << 3) +#define EPWM_TZDCSEL_DCBEVT1_BITS (7 << 6) +#define EPWM_TZDCSEL_DCBEVT2_BITS (7 << 9) +#define EPWM_DCTRIPSEL_DCAHCOMPSEL_BITS (15 << 0) +#define EPWM_DCTRIPSEL_DCALCOMPSEL_BITS (15 << 4) +#define EPWM_DCTRIPSEL_DCBHCOMPSEL_BITS (15 << 8) +#define EPWM_DCTRIPSEL_DCBLCOMPSEL_BITS (15 << 12) +#define EPWM_DCFCTL_SRCSEL_BITS (3 << 0) +#define EPWM_DCFCTL_BLANKE_BITS (1 << 2) +#define EPWM_DCFCTL_BLANKINV_BITS (1 << 3) +#define EPWM_DCFCTL_PULSESEL_BITS (3 << 4) + + +#define EPWM_TBCTL_EALLOW_BITS TBCTL_EALLOW +#define EPWM_MEP_INT_BITS MEPINT_MEPCAL + +/** @defgroup EPWM_TZ_flags_definition + * @{ + */ + +#define EPWM_TZ_FLAG_INT TZFLG_INT +#define EPWM_TZ_FLAG_CBC TZFLG_CBC +#define EPWM_TZ_FLAG_OST TZFLG_OST +#define EPWM_TZ_FLAG_DCAEVT1 TZFLG_DCAEVT1 +#define EPWM_TZ_FLAG_DCAEVT2 TZFLG_DCAEVT2 +#define EPWM_TZ_FLAG_DCBEVT1 TZFLG_DCBEVT1 +#define EPWM_TZ_FLAG_DCBEVT2 TZFLG_DCBEVT2 + +#define IS_EPWM_TZ_GET_FLAG(FLAG) (((FLAG) == EPWM_TZ_FLAG_INT) || \ + ((FLAG) == EPWM_TZ_FLAG_CBC) || \ + ((FLAG) == EPWM_TZ_FLAG_OST) || \ + ((FLAG) == EPWM_TZ_FLAG_DCAEVT1) || \ + ((FLAG) == EPWM_TZ_FLAG_DCAEVT2) || \ + ((FLAG) == EPWM_TZ_FLAG_DCBEVT1) || \ + ((FLAG) == EPWM_TZ_FLAG_DCBEVT2)) +/** + * @} + */ + + + +/** @defgroup EPWM_ET_flags_definition + * @{ + */ +#define EPWM_ET_FLAG_INT ETFLG_INT +#define EPWM_ET_FLAG_SOCA ETFLG_SOCA +#define EPWM_ET_FLAG_SOCB ETFLG_SOCB + +#define IS_EPWM_ET_GET_FLAG(FLAG) (((FLAG) == EPWM_ET_FLAG_INT) || \ + ((FLAG) == EPWM_ET_FLAG_SOCA) || \ + ((FLAG) == EPWM_ET_FLAG_SOCB)) +/** + * @} + */ + + +/** @defgroup EPWM_MEP_flags_definition + * @{ + */ + +#define EPWM_MEP_FLAG_INT MEPFLG_MEPCAL + +#define IS_EPWM_MEP_GET_FLAG(FLAG) ((FLAG) == EPWM_MEP_FLAG_INT) +/** + * @} + */ + + + + +/** + * @brief Defines the pulse width modulation (PWM) handle + */ +typedef struct _EPWM_Obj_ *EPWM_Handle; + + +/* Exported functions ------------------------------------------------------- */ + +/* Time-Base Configuration functions *********************************/ +void EALLOW(EPWM_TypeDef* EPWMx); +void EDIS(EPWM_TypeDef* EPWMx); +void EPWM_setPhaseDir(EPWM_TypeDef* EPWMx, const EPWM_PhaseDir_e phaseDir); +void EPWM_setClkDiv(EPWM_TypeDef* EPWMx, const EPWM_ClkDiv_e clkDiv); +void EPWM_setHighSpeedClkDiv(EPWM_TypeDef* EPWMx, const EPWM_HspClkDiv_e clkDiv); +void EPWM_setSwSync(EPWM_TypeDef* EPWMx); +void EPWM_forceSync(EPWM_TypeDef* EPWMx); +void EPWM_setSyncMode(EPWM_TypeDef* EPWMx, const EPWM_SyncMode_e syncMode); +void EPWM_setPeriodLoad(EPWM_TypeDef* EPWMx, const EPWM_PeriodLoad_e periodLoad); +void EPWM_disableCounterLoad(EPWM_TypeDef* EPWMx); +void EPWM_enableCounterLoad(EPWM_TypeDef* EPWMx); +void EPWM_setCounterMode(EPWM_TypeDef* EPWMx, const EPWM_CounterMode_e counterMode); + +void EPWM_setCount(EPWM_TypeDef* EPWMx, const uint16_t count); +void EPWM_setPeriod(EPWM_TypeDef* EPWMx, const uint16_t period); +void EPWM_setPeriodHr(EPWM_TypeDef* EPWMx, const uint16_t period); +void EPWM_setPhase(EPWM_TypeDef* EPWMx, const uint16_t phase); +//void EPWM_setRunMode(EPWM_TypeDef* EPWMx, const EPWM_RunMode_e runMode); + +uint16_t EPWM_getPeriod(EPWM_TypeDef* EPWMx); + + +/* Counter-Compare Configuration functions *********************************/ +void EPWM_setCmpA(EPWM_TypeDef* EPWMx, const uint16_t pwmData); +void EPWM_setCmpB(EPWM_TypeDef* EPWMx, const uint16_t pwmData); +void EPWM_setCmpAHr(EPWM_TypeDef* EPWMx, const uint16_t pwmData); +void EPWM_write_CmpA(EPWM_TypeDef* EPWMx, const int16_t pwmData); +void EPWM_write_CmpB(EPWM_TypeDef* EPWMx, const int16_t pwmData); +void EPWM_setShadowMode_CmpA(EPWM_TypeDef* EPWMx, const EPWM_ShadowMode_e shadowMode); +void EPWM_setShadowMode_CmpB(EPWM_TypeDef* EPWMx, const EPWM_ShadowMode_e shadowMode); +void EPWM_setLoadMode_CmpA(EPWM_TypeDef* EPWMx, const EPWM_LoadMode_e loadMode); +void EPWM_setLoadMode_CmpB(EPWM_TypeDef* EPWMx, const EPWM_LoadMode_e loadMode); + +uint16_t EPWM_getCmpA(EPWM_TypeDef* EPWMx); +uint16_t EPWM_getCmpAHr(EPWM_TypeDef* EPWMx); +uint16_t EPWM_getCmpB(EPWM_TypeDef* EPWMx); + + +//EPWM_Handle EPWM_init(void *pMemory, const size_t numBytes); + + +/* Action-Qualifier Configuration functions *********************************/ +void EPWM_setActionQual_CntDown_CmpA_PwmA(EPWM_TypeDef* EPWMx, const EPWM_ActionQual_e actionQual); +void EPWM_setActionQual_CntDown_CmpA_PwmB(EPWM_TypeDef* EPWMx, const EPWM_ActionQual_e actionQual); +void EPWM_setActionQual_CntDown_CmpB_PwmA(EPWM_TypeDef* EPWMx, const EPWM_ActionQual_e actionQual); +void EPWM_setActionQual_CntDown_CmpB_PwmB(EPWM_TypeDef* EPWMx, const EPWM_ActionQual_e actionQual); +void EPWM_setActionQual_CntUp_CmpA_PwmA(EPWM_TypeDef* EPWMx, const EPWM_ActionQual_e actionQual); +void EPWM_setActionQual_CntUp_CmpA_PwmB(EPWM_TypeDef* EPWMx, const EPWM_ActionQual_e actionQual); +void EPWM_setActionQual_CntUp_CmpB_PwmA(EPWM_TypeDef* EPWMx, const EPWM_ActionQual_e actionQual); +void EPWM_setActionQual_CntUp_CmpB_PwmB(EPWM_TypeDef* EPWMx, const EPWM_ActionQual_e actionQual); +void EPWM_setActionQual_Period_PwmA(EPWM_TypeDef* EPWMx, const EPWM_ActionQual_e actionQual); +void EPWM_setActionQual_Period_PwmB(EPWM_TypeDef* EPWMx, const EPWM_ActionQual_e actionQual); +void EPWM_setActionQual_Zero_PwmA(EPWM_TypeDef* EPWMx, const EPWM_ActionQual_e actionQual); +void EPWM_setActionQual_Zero_PwmB(EPWM_TypeDef* EPWMx, const EPWM_ActionQual_e actionQual); + + +/* PWM-Chopper Configuration functions *********************************/ +void EPWM_enableChopping(EPWM_TypeDef* EPWMx); +void EPWM_disableChopping(EPWM_TypeDef* EPWMx); +void EPWM_setChoppingClkFreq(EPWM_TypeDef* EPWMx, const EPWM_ChoppingClkFreq_e clkFreq); +void EPWM_setChoppingDutyCycle(EPWM_TypeDef* EPWMx, const EPWM_ChoppingDutyCycle_e dutyCycle); +void EPWM_setChoppingPulseWidth(EPWM_TypeDef* EPWMx, const EPWM_ChoppingPulseWidth_e pulseWidth); + + +/* Dead-Band Configuration functions *********************************/ +void EPWM_decrementDeadBandFallingEdgeDelay(EPWM_TypeDef* EPWMx); +void EPWM_decrementDeadBandRisingEdgeDelay(EPWM_TypeDef* EPWMx); +void EPWM_setDeadBandFallingEdgeDelay(EPWM_TypeDef* EPWMx, const uint16_t delay); +void EPWM_setDeadBandInputMode(EPWM_TypeDef* EPWMx, const EPWM_DeadBandInputMode_e inputMode); +void EPWM_setDeadBandOutputMode(EPWM_TypeDef* EPWMx, const EPWM_DeadBandOutputMode_e outputMode); +void EPWM_setDeadBandPolarity(EPWM_TypeDef* EPWMx, const EPWM_DeadBandPolarity_e polarity); +void EPWM_setDeadBandRisingEdgeDelay(EPWM_TypeDef* EPWMx, const uint16_t delay); +void EPWM_disableDeadBand(EPWM_TypeDef* EPWMx); +void EPWM_disableDeadBandHalfCycle(EPWM_TypeDef* EPWMx); +void EPWM_enableDeadBandHalfCycle(EPWM_TypeDef* EPWMx); +void EPWM_incrementDeadBandFallingEdgeDelay(EPWM_TypeDef* EPWMx); +void EPWM_incrementDeadBandRisingEdgeDelay(EPWM_TypeDef* EPWMx); + +uint16_t EPWM_getDeadBandFallingEdgeDelay(EPWM_TypeDef* EPWMx); +uint16_t EPWM_getDeadBandRisingEdgeDelay(EPWM_TypeDef* EPWMx); + + +/* Trip-Zone Configuration functions *********************************/ +void EPWM_setTripZoneFilter(EPWM_TypeDef* EPWMx, uint8_t FILTER); +void EPWM_setTripZoneDCEventSelect_DCAEVT1(EPWM_TypeDef* EPWMx, const EPWM_TripZoneDCEventSel_e tripZoneEvent); +void EPWM_setTripZoneDCEventSelect_DCAEVT2(EPWM_TypeDef* EPWMx, const EPWM_TripZoneDCEventSel_e tripZoneEvent); +void EPWM_setTripZoneDCEventSelect_DCBEVT1(EPWM_TypeDef* EPWMx, const EPWM_TripZoneDCEventSel_e tripZoneEvent); +void EPWM_setTripZoneDCEventSelect_DCBEVT2(EPWM_TypeDef* EPWMx, const EPWM_TripZoneDCEventSel_e tripZoneEvent); +void EPWM_setTripZoneState_DCAEVT1(EPWM_TypeDef* EPWMx, const EPWM_TripZoneState_e tripZoneState); +void EPWM_setTripZoneState_DCAEVT2(EPWM_TypeDef* EPWMx, const EPWM_TripZoneState_e tripZoneState); +void EPWM_setTripZoneState_DCBEVT1(EPWM_TypeDef* EPWMx, const EPWM_TripZoneState_e tripZoneState); +void EPWM_setTripZoneState_DCBEVT2(EPWM_TypeDef* EPWMx, const EPWM_TripZoneState_e tripZoneState); +void EPWM_setTripZoneState_TZA(EPWM_TypeDef* EPWMx, const EPWM_TripZoneState_e tripZoneState); +void EPWM_setTripZoneState_TZB(EPWM_TypeDef* EPWMx, const EPWM_TripZoneState_e tripZoneState); +void EPWM_setOneShotTrip(EPWM_TypeDef* EPWMx); +void EPWM_clearOneShotTrip(EPWM_TypeDef* EPWMx); +void EPWM_clearTripZone(EPWM_TypeDef* EPWMx, const EPWM_TripZoneFlag_e tripZoneFlag); +void EPWM_disableTripZones(EPWM_TypeDef* EPWMx); +void EPWM_disableTripZoneInt(EPWM_TypeDef* EPWMx, const EPWM_TripZoneFlag_e interruptSource); +void EPWM_disableTripZoneSrc(EPWM_TypeDef* EPWMx, const EPWM_TripZoneSrc_e src); +void EPWM_enableTripZoneInt(EPWM_TypeDef* EPWMx, const EPWM_TripZoneFlag_e interruptSource); +void EPWM_enableTripZoneSrc(EPWM_TypeDef* EPWMx, const EPWM_TripZoneSrc_e src); + +FlagStatus EPWM_TripZone_GetFlagStatus(EPWM_TypeDef* EPWMx, uint16_t TZ_FLAG); + + +/* Event-Trigger Configuration functions *********************************/ +void EPWM_clearIntFlag(EPWM_TypeDef* EPWMx); +void EPWM_clearSocAFlag(EPWM_TypeDef* EPWMx); +void EPWM_clearSocBFlag(EPWM_TypeDef* EPWMx); +void EPWM_setSocAPeriod(EPWM_TypeDef* EPWMx, const EPWM_SocPeriod_e intPeriod); +void EPWM_setSocAPulseSrc(EPWM_TypeDef* EPWMx, const EPWM_SocPulseSrc_e pulseSrc); +void EPWM_setSocBPeriod(EPWM_TypeDef* EPWMx, const EPWM_SocPeriod_e intPeriod); +void EPWM_setSocBPulseSrc(EPWM_TypeDef* EPWMx, const EPWM_SocPulseSrc_e pulseSrc); +void EPWM_setIntMode(EPWM_TypeDef* EPWMx, const EPWM_IntMode_e intMode); +void EPWM_setIntPeriod(EPWM_TypeDef* EPWMx, const EPWM_IntPeriod_e intPeriod); +void EPWM_disableInt(EPWM_TypeDef* EPWMx); +void EPWM_disableSocAPulse(EPWM_TypeDef* EPWMx); +void EPWM_disableSocBPulse(EPWM_TypeDef* EPWMx); +void EPWM_enableInt(EPWM_TypeDef* EPWMx); +void EPWM_enableSocAPulse(EPWM_TypeDef* EPWMx); +void EPWM_enableSocBPulse(EPWM_TypeDef* EPWMx); + +uint16_t EPWM_getIntCount(EPWM_TypeDef* EPWMx); +uint16_t EPWM_getSocACount(EPWM_TypeDef* EPWMx); +uint16_t EPWM_getSocBCount(EPWM_TypeDef* EPWMx); + +FlagStatus EPWM_EventTrigger_GetFlagStatus(EPWM_TypeDef* EPWMx, uint16_t ET_FLAG); + + +/* Digital-Compare Configuration functions *********************************/ +void EPWM_setDigitalCompareFilterSource(EPWM_TypeDef* EPWMx, const EPWM_DigitalCompare_FilterSrc_e input); +void EPWM_setDigitalCompareBlankingPulse(EPWM_TypeDef* EPWMx, const EPWM_DigitalCompare_PulseSel_e pulseSelect); +void EPWM_setDigitalCompareFilterOffset(EPWM_TypeDef* EPWMx, const uint16_t offset); +void EPWM_setDigitalCompareFilterWindow(EPWM_TypeDef* EPWMx, const uint16_t window); +void EPWM_setDigitalCompareInput(EPWM_TypeDef* EPWMx, const EPWM_DigitalCompare_Input_e input, const EPWM_DigitalCompare_InputSel_e inputSel); +void EPWM_setDigitalCompareAEvent1(EPWM_TypeDef* EPWMx, const uint16_t selectFilter, const uint16_t disableSync, const uint16_t enableSoc, const uint16_t generateSync); +void EPWM_setDigitalCompareAEvent2(EPWM_TypeDef* EPWMx, const uint16_t selectFilter, const uint16_t disableSync); +void EPWM_setDigitalCompareBEvent1(EPWM_TypeDef* EPWMx, const uint16_t selectFilter, const uint16_t disableSync, const uint16_t enableSoc, const uint16_t generateSync); +void EPWM_setDigitalCompareBEvent2(EPWM_TypeDef* EPWMx, const uint16_t selectFilter, const uint16_t disableSync); +void EPWM_disableDigitalCompareBlankingWindow(EPWM_TypeDef* EPWMx); +void EPWM_disableDigitalCompareBlankingWindowInversion(EPWM_TypeDef* EPWMx); +void EPWM_enableDigitalCompareBlankingWindow(EPWM_TypeDef* EPWMx); +void EPWM_enableDigitalCompareBlankingWindowInversion(EPWM_TypeDef* EPWMx); + + +/* HR-PWM Configuration functions *********************************/ +void EPWM_disableAutoConvert(EPWM_TypeDef* EPWMx); +void EPWM_disableHrPeriod(EPWM_TypeDef* EPWMx); +void EPWM_disableHrPhaseSync(EPWM_TypeDef* EPWMx); +void EPWM_disableMEPCalibrationOff(EPWM_TypeDef* EPWMx); +void EPWM_enableAutoConvert(EPWM_TypeDef* EPWMx); +void EPWM_enableHrPeriod(EPWM_TypeDef* EPWMx); +void EPWM_enableHrPhaseSync(EPWM_TypeDef* EPWMx); +void EPWM_enableMEPCalibrationOff(EPWM_TypeDef* EPWMx); +void EPWM_setHrControlMode(EPWM_TypeDef* EPWMx, const EPWM_HrControlMode_e controlMode); +void EPWM_setHrEdgeMode(EPWM_TypeDef* EPWMx, const EPWM_HrEdgeMode_e edgeMode); +void EPWM_setHrShadowMode(EPWM_TypeDef* EPWMx, const EPWM_HrShadowMode_e shadowMode); + +void EPWM_clearMepFlag(EPWM_TypeDef* EPWMx); +FlagStatus EPWM_MepCalibration_GetFlagStatus(EPWM_TypeDef* EPWMx, uint16_t MEP_FLAG); +uint8_t EPWM_enableMEPSFO(EPWM_TypeDef* EPWMx); +void EPWM_disableMEPSFO(EPWM_TypeDef* EPWMx); + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif /*__FT32F4XX_EPWM_H */ + +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ + diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_eqep.h b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_eqep.h new file mode 100644 index 00000000000..90c55abcc75 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_eqep.h @@ -0,0 +1,895 @@ +/** + ****************************************************************************** + * @file ft32f4xx_eqep.h + * @author FMD AE + * @brief This file contains all the functions prototypes for the eQEP firmware + * library. + * @version V1.0.0 + * @date 2025-04-17 + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __FT32F4XX_EQEP_H +#define __FT32F4XX_EQEP_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx.h" + + +/** @addtogroup EQEP + * @{ + */ +/* Exported types ------------------------------------------------------------*/ + +/** + * @brief EQEP quadrature decoder unit structures definition + */ +typedef struct +{ + uint32_t PosCounterSource; /*!< Specifies position counter srource selection. + This parameter can be a value of @ref EQEP_position_counter_source_select */ + + FunctionalState SyncOutput; /*!< Specifies whether synchronous output is enabled. + This parameter can be a value of @ref EQEP_sync_output_select + This parameter can be set to ENABLE or DISABLE. */ + + uint32_t SyncOutputPin; /*!< Specifies which pin is used for synchronous output. + This parameter can be a value of @ref EQEP_sync_output_pin_select */ + + uint32_t ExternalClockRate; /*!< Specifies the external clock rate. + This parameter can be a value of @ref EQEP_external_clock_rate_select */ + + FunctionalState ClockDirSwap; /*!< Specifies whether the quadrature clock inputs are swapped. + This parameter can be a value of @ref EQEP_clock_dir_swap + This parameter can be set to ENABLE or DISABLE. */ + + FunctionalState IndexGate; /*!< Specifies the index pulse gating option. + This parameter can be a value of @ref EQEP_index_gate_option + This parameter can be set to ENABLE or DISABLE. */ + + uint32_t QEPAPolarity; /*!< Specifies the input polarity of QEPA. + This parameter can be a value of @ref EQEP_qepa_polarity */ + + uint32_t QEPBPolarity; /*!< Specifies the input polarity of QEPB. + This parameter can be a value of @ref EQEP_qepb_polarity */ + + uint32_t QEPIPolarity; /*!< Specifies the input polarity of QEPI. + This parameter can be a value of @ref EQEP_qepi_polarity */ + + uint32_t QEPSPolarity; /*!< Specifies the input polarity of QEPS. + This parameter can be a value of @ref EQEP_qeps_polarity */ + +} EQEP_QDUInitTypeDef; + + +/** + * @brief EQEP position counter control structures definition + */ +typedef struct +{ + uint32_t PosCounterResetSrc; /*!< Specifies the reset source for the position counter. + This parameter can be a value of @ref EQEP_postion_counter_reset_source */ + + uint32_t SEInitPosCounter; /*!< Specifies the strobe event initialization of position counter. + This parameter can be a value of @ref EQEP_strobe_event_init_position_counter */ + + uint32_t IEInitPosCounter; /*!< Specifies the index event initialization of position counter. + This parameter can be a value of @ref EQEP_index_event_init_position_counter */ + + //uint32_t SWInitPosCounter; /*!< Specifies the software initialization of position counter. + // This parameter can be a value of @ref EQEP_software_init_position_counter */ + + uint32_t SELatchPosCounter; /*!< Specifies the strobe event latch of position counter. + This parameter can be a value of @ref EQEP_strobe_event_latch_position_counter */ + + uint32_t IELatchPosCounter; /*!< Specifies the index event latch of position counter. + This parameter can be a value of @ref EQEP_index_event_latch_position_counter */ + + //uint32_t PosCounter; /*!< Specifies the position counter enable or software reset. + // This parameter can be a value of @ref EQEP_position_counter_enable */ + + uint32_t CaptureLatchMode; /*!< Specifies the QEP capture latch mode. + This parameter can be a value of @ref EQEP_capture_latch_mode */ + + //uint32_t UnitTimer; /*!< Specifies the QEP unit timer enable. + // This parameter can be a value of @ref EQEP_unit_timer_enable */ + + //uint32_t WatchDog; /*!< Specifies the QEP watchdog enable. + // This parameter can be a value of @ref EQEP_watchdog_enable */ + + uint32_t PosCounterValue; /*!< Specifies the value of the position counter. + This parameter can be a value of @ref EQEP_position_counter_value */ + + uint32_t PosCounterInitValue; /*!< Specifies the initialization value of the position counter. + The value is used to initialize the position counter based on external strobe or + index event. The position counter can be initialized through software(QEPCTL.SWI). + This parameter can be a value of @ref EQEP_position_counter_init_value */ + + uint32_t PosCounterMaxValue; /*!< Specifies the maximum value of the position counter. + This parameter can be a value of @ref EQEP_position_counter_max_value */ + + uint32_t PosCounterCmpValue; /*!< Specifies the compare value of the position counter. + The position compare value in this register is compared with the position + counter(QPOSCNT) to generate sync output and/or interrupt on compare match. + This parameter can be a value of @ref EQEP_position_counter_cmp_value */ + + uint32_t UnitTimerPeriodValue; /*!< Specifies the period value of the unit timer. + The period value for the unit timer to generate periodic unit time events. + This parameter can be a value of @ref EQEP_unit_timer_period_value */ + + uint32_t WdgTimerPeriodValue; /*!< Specifies the period value of the watch dog timer. + This parameter can be a value of @ref EQEP_wdg_timer_period_value */ + + +} EQEP_InitTypeDef; + + +/** + * @brief EQEP capture control structures definition + */ +typedef struct +{ + //uint32_t Capture; /*!< Specifies the QEP capture enable. + // This parameter can be a value of @ref EQEP_capture_enable */ + + uint32_t CaptureClockPrescaler; /*!< Specifies the QEP capture timer clock prescaler. + This parameter can be a value of @ref EQEP_capture_timer_clock_prescaler */ + + uint32_t UnitPosEventPrescaler; /*!< Specifies the unit position event prescaler. + This parameter can be a value of @ref EQEP_unit_position_event_prescaler */ + + uint32_t CapturePeriodValue; /*!< Specifies the period value of the capture timer. + This parameter can be a value of @ref EQEP_capture_period_value */ + +} EQEP_CAPInitTypeDef; + + +/** + * @brief EQEP position compare structures definition + */ +typedef struct +{ + FunctionalState PosCompareShadow; /*!< Specifies the position compare of shadow enable. + This parameter can be a value of @ref EQEP_position_compare_shadow_enable + This parameter can be set to ENABLE or DISABLE. */ + + uint32_t PosCompareShadowLoad; /*!< Specifies the position compare of shadow load. + This parameter can be a value of @ref EQEP_position_compare_shadow_load */ + + uint32_t SyncOutPolarity; /*!< Specifies the polarity of the position compare sync output. + This parameter can be a value of @ref EQEP_sync_out_polarity */ + + FunctionalState PosCompare; /*!< Specifies the position compare enable. + This parameter can be a value of @ref EQEP_position_compare_enable + This parameter can be set to ENABLE or DISABLE. */ + + uint32_t SyncOutPulseWidth; /*!< Specifies the pulse width of the position compare sync output. + This parameter can be a value of @ref EQEP_sync_out_pulse_width */ + +} EQEP_PosCmpInitTypeDef; + + + + + +/** @defgroup EQEP_position_counter_source_select + * @{ + */ +#define EQEP_POSCNTSRC_QUADRATURE_COUNT 0x00000000U +#define EQEP_POSCNTSRC_DIRECTION_COUNT EQEP_QDECCTL_QSRC_0 +#define EQEP_POSCNTSRC_UP_COUNT EQEP_QDECCTL_QSRC_1 +#define EQEP_POSCNTSRC_DOWN_COUNT EQEP_QDECCTL_QSRC + +#define IS_EQEP_POSCNTSRC_MODE(MODE) (((MODE) == EQEP_POSCNTSRC_QUADRATURE_COUNT) || \ + ((MODE) == EQEP_POSCNTSRC_DIRECTION_COUNT ) || \ + ((MODE) == EQEP_POSCNTSRC_UP_COUNT ) || \ + ((MODE) == EQEP_POSCNTSRC_DOWN_COUNT ) ) + +/** + * @} + */ + + +///** @defgroup EQEP_sync_output_select +// * @{ +// */ +//#define EQEP_SYNC_OUTPUT_DISABLE 0x00000000U +//#define EQEP_SYNC_OUTPUT_ENABLE EQEP_QDECCTL_SOEN +// +//#define IS_EQEP_SYNC_OUTPUT_STATE(STATE) (((STATE) == EQEP_SYNC_OUTPUT_DISABLE) || \ +// ((STATE) == EQEP_SYNC_OUTPUT_ENABLE ) ) +// +///** +// * @} +// */ + + +/** @defgroup EQEP_sync_output_pin_select + * @{ + */ +#define EQEP_PIN_INDEX 0x00000000U +#define EQEP_PIN_STROBE EQEP_QDECCTL_SPSEL + +#define IS_EQEP_SYNC_OUTPUT_PIN(PIN) (((PIN) == EQEP_PIN_INDEX ) || \ + ((PIN) == EQEP_PIN_STROBE) ) + +/** + * @} + */ + + +/** @defgroup EQEP_external_clock_rate_select + * @{ + */ +#define EQEP_EXTERNAL_CLOCK_RATE_2x 0x00000000U +#define EQEP_EXTERNAL_CLOCK_RATE_1x EQEP_QDECCTL_XCR + +#define IS_EQEP_EXTERNAL_CLOCK_RATE(RATE) (((RATE) == EQEP_EXTERNAL_CLOCK_RATE_2x) || \ + ((RATE) == EQEP_EXTERNAL_CLOCK_RATE_1x) ) + +/** + * @} + */ + + +///** @defgroup EQEP_clock_dir_swap +// * @{ +// */ +//#define EQEP_CLOCK_DIR_SWAP_DISABLE 0x00000000U +//#define EQEP_CLOCK_DIR_SWAP_ENABLE EQEP_QDECCTL_SWAP +// +//#define IS_EQEP_CLOCK_DIR_SWAP_STATE(STATE) (((STATE) == EQEP_CLOCK_DIR_SWAP_DISABLE) || \ +// ((STATE) == EQEP_CLOCK_DIR_SWAP_ENABLE ) ) +// +///** +// * @} +// */ + + +///** @defgroup EQEP_index_gate_option +// * @{ +// */ +//#define EQEP_INDEX_GATE_DISABLE 0x00000000U +//#define EQEP_INDEX_GATE_ENABLE EQEP_QDECCTL_IGATE +// +//#define IS_EQEP_INDEX_GATE_STATE(STATE) (((STATE) == EQEP_INDEX_GATE_DISABLE) || \ +// ((STATE) == EQEP_INDEX_GATE_ENABLE ) ) +// +///** +// * @} +// */ + + +/** @defgroup EQEP_qepa_polarity + * @{ + */ +#define EQEP_QEPA_INPUT_NO_EFFECT 0x00000000U +#define EQEP_QEPA_INPUT_NEGATE EQEP_QDECCTL_QAP + +#define IS_EQEP_QEPA_POLARITY(STATE) (((STATE) == EQEP_QEPA_INPUT_NO_EFFECT) || \ + ((STATE) == EQEP_QEPA_INPUT_NEGATE ) ) + +/** + * @} + */ + + +/** @defgroup EQEP_qepb_polarity + * @{ + */ +#define EQEP_QEPB_INPUT_NO_EFFECT 0x00000000U +#define EQEP_QEPB_INPUT_NEGATE EQEP_QDECCTL_QBP + +#define IS_EQEP_QEPB_POLARITY(STATE) (((STATE) == EQEP_QEPB_INPUT_NO_EFFECT) || \ + ((STATE) == EQEP_QEPB_INPUT_NEGATE ) ) + +/** + * @} + */ + + +/** @defgroup EQEP_qepi_polarity + * @{ + */ +#define EQEP_QEPI_INPUT_NO_EFFECT 0x00000000U +#define EQEP_QEPI_INPUT_NEGATE EQEP_QDECCTL_QIP + +#define IS_EQEP_QEPI_POLARITY(STATE) (((STATE) == EQEP_QEPI_INPUT_NO_EFFECT) || \ + ((STATE) == EQEP_QEPI_INPUT_NEGATE ) ) + +/** + * @} + */ + + +/** @defgroup EQEP_qeps_polarity + * @{ + */ +#define EQEP_QEPS_INPUT_NO_EFFECT 0x00000000U +#define EQEP_QEPS_INPUT_NEGATE EQEP_QDECCTL_QSP + +#define IS_EQEP_QEPS_POLARITY(STATE) (((STATE) == EQEP_QEPS_INPUT_NO_EFFECT) || \ + ((STATE) == EQEP_QEPS_INPUT_NEGATE ) ) + +/** + * @} + */ + + + + + + + + +/** @defgroup EQEP_postion_counter_reset_source + * @{ + */ +#define EQEP_RESET_SOURCE_INDEX 0x00000000U +#define EQEP_RESET_SOURCE_MAX EQEP_QEPCTL_PCRM_0 +#define EQEP_RESET_SOURCE_FIRST EQEP_QEPCTL_PCRM_1 +#define EQEP_RESET_SOURCE_UNIT EQEP_QEPCTL_PCRM + +#define IS_EQEP_RESET_SOURCE(SEL) (((SEL) == EQEP_RESET_SOURCE_INDEX) || \ + ((SEL) == EQEP_RESET_SOURCE_MAX ) || \ + ((SEL) == EQEP_RESET_SOURCE_FIRST) || \ + ((SEL) == EQEP_RESET_SOURCE_UNIT ) ) + +/** + * @} + */ + + +/** @defgroup EQEP_strobe_event_init_position_counter + * @{ + */ +#define EQEP_SE_INIT_DISABLE 0x00000000U +#define EQEP_SE_INIT_RISING_EDGE EQEP_QEPCTL_SEI_1 +#define EQEP_SE_INIT_DOUBLE_EDGE EQEP_QEPCTL_SEI + +#define IS_EQEP_SE_INIT(MODE) (((MODE) == EQEP_SE_INIT_DISABLE ) || \ + ((MODE) == EQEP_SE_INIT_RISING_EDGE) || \ + ((MODE) == EQEP_SE_INIT_DOUBLE_EDGE) ) + +/** + * @} + */ + + +/** @defgroup EQEP_index_event_init_position_counter + * @{ + */ +#define EQEP_IE_INIT_DISABLE 0x00000000U +#define EQEP_IE_INIT_RISING_EDGE EQEP_QEPCTL_IEI_1 +#define EQEP_IE_INIT_DOUBLE_EDGE EQEP_QEPCTL_IEI + +#define IS_EQEP_IE_INIT(MODE) (((MODE) == EQEP_IE_INIT_DISABLE ) || \ + ((MODE) == EQEP_IE_INIT_RISING_EDGE) || \ + ((MODE) == EQEP_IE_INIT_DOUBLE_EDGE) ) + +/** + * @} + */ + + +///** @defgroup EQEP_software_init_position_counter +// * @{ +// */ +//#define EQEP_SW_INIT_DISABLE 0x00000000U +//#define EQEP_SW_INIT_ENABLE EQEP_QEPCTL_SWI +// +//#define IS_EQEP_SW_INIT(MODE) (((MODE) == EQEP_SW_INIT_DISABLE) || \ +// ((MODE) == EQEP_SW_INIT_ENABLE ) ) +// +///** +// * @} +// */ + + +/** @defgroup EQEP_strobe_event_latch_position_counter + * @{ + */ +#define EQEP_SE_LATCH_RISING_EDGE 0x00000000U +#define EQEP_SE_LATCH_DOUBLE_EDGE EQEP_QEPCTL_SEL + +#define IS_EQEP_SE_LATCH(MODE) (((MODE) == EQEP_SE_LATCH_RISING_EDGE) || \ + ((MODE) == EQEP_SE_LATCH_DOUBLE_EDGE) ) + +/** + * @} + */ + + +/** @defgroup EQEP_index_event_latch_position_counter + * @{ + */ +#define EQEP_IE_LATCH_DISABLE 0x00000000U +#define EQEP_IE_LATCH_RISING_EDGE EQEP_QEPCTL_IEL_0 +#define EQEP_IE_LATCH_FALLING_EDGE EQEP_QEPCTL_IEL_1 +#define EQEP_IE_LATCH_SOFTWAREMARKER EQEP_QEPCTL_IEL + +#define IS_EQEP_IE_LATCH(MODE) (((MODE) == EQEP_IE_LATCH_DISABLE ) || \ + ((MODE) == EQEP_IE_LATCH_RISING_EDGE ) || \ + ((MODE) == EQEP_IE_LATCH_FALLING_EDGE ) || \ + ((MODE) == EQEP_IE_LATCH_SOFTWAREMARKER) ) + +/** + * @} + */ + + +///** @defgroup EQEP_position_counter_enable +// * @{ +// */ +//#define EQEP_POSCOUNTER_DISABLE 0x00000000U +//#define EQEP_POSCOUNTER_ENABLE EQEP_QEPCTL_QPEN +// +//#define IS_EQEP_POSCOUNTER(STATE) (((STATE) == EQEP_POSCOUNTER_DISABLE) || \ +// ((STATE) == EQEP_POSCOUNTER_ENABLE ) ) +// +///** +// * @} +// */ + + +/** @defgroup EQEP_capture_latch_mode + * @{ + */ +#define EQEP_CAPTURELATCH_CPU 0x00000000U +#define EQEP_CAPTURELATCH_TIMEOUT EQEP_QEPCTL_QCLM + +#define IS_EQEP_CAPTURELATCH_MODE(MODE) (((MODE) == EQEP_CAPTURELATCH_CPU ) || \ + ((MODE) == EQEP_CAPTURELATCH_TIMEOUT) ) + +/** + * @} + */ + + +/** @defgroup EQEP_position_counter_value + * @{ + */ +#define IS_EQEP_POS_COUNTER_VALUE(VALUE) (((VALUE) >= 0x0U) && ((VALUE) <= 0xFFFFFFFFU)) + +/** + * @} + */ + + +/** @defgroup EQEP_position_counter_init_value + * @{ + */ +#define IS_EQEP_POS_COUNTER_INIT_VALUE(VALUE) (((VALUE) >= 0x0U) && ((VALUE) <= 0xFFFFFFFFU)) + +/** + * @} + */ + + +/** @defgroup EQEP_position_counter_max_value + * @{ + */ +#define IS_EQEP_POS_COUNTER_MAX_VALUE(VALUE) (((VALUE) >= 0x0U) && ((VALUE) <= 0xFFFFFFFFU)) + +/** + * @} + */ + + +/** @defgroup EQEP_position_counter_cmp_value + * @{ + */ +#define IS_EQEP_POS_COUNTER_CMP_VALUE(VALUE) (((VALUE) >= 0x0U) && ((VALUE) <= 0xFFFFFFFFU)) + +/** + * @} + */ + + +/** @defgroup EQEP_unit_timer_period_value + * @{ + */ +#define IS_EQEP_UNIT_TIMER_PERIOD_VALUE(VALUE) (((VALUE) >= 0x0U) && ((VALUE) <= 0xFFFFFFFFU)) + +/** + * @} + */ + + +/** @defgroup EQEP_wdg_timer_period_value + * @{ + */ +#define IS_EQEP_WDG_TIMER_PERIOD_VALUE(VALUE) (((VALUE) >= 0x0U) && ((VALUE) <= 0xFFFFU)) + +/** + * @} + */ + + + + + +///** @defgroup EQEP_unit_timer_enable +// * @{ +// */ +//#define EQEP_UNITTIMER_DISABLE 0x00000000U +//#define EQEP_UNITTIMER_ENABLE EQEP_QEPCTL_UTE +// +//#define IS_EQEP_UNITTIMER(STATE) (((STATE) == EQEP_UNITTIMER_DISABLE) || \ +// ((STATE) == EQEP_UNITTIMER_ENABLE ) ) +// +///** +// * @} +// */ +// +// +///** @defgroup EQEP_watchdog_enable +// * @{ +// */ +//#define EQEP_WATCHDOG_DISABLE 0x00000000U +//#define EQEP_WATCHDOG_ENABLE EQEP_QEPCTL_WDE +// +//#define IS_EQEP_WATCHDOG(STATE) (((STATE) == EQEP_WATCHDOG_DISABLE) || \ +// ((STATE) == EQEP_WATCHDOG_ENABLE ) ) +// +///** +// * @} +// */ + + + + + + +///** @defgroup EQEP_capture_enable +// * @{ +// */ +//#define EQEP_CAPTURE_DISABLE 0x00000000U +//#define EQEP_CAPTURE_ENABLE EQEP_QCAPCTL_CEN +// +//#define IS_EQEP_CAPTURE(STATE) (((STATE) == EQEP_CAPTURE_DISABLE) || \ +// ((STATE) == EQEP_CAPTURE_ENABLE ) ) +// +///** +// * @} +// */ + + +/** @defgroup EQEP_capture_timer_clock_prescaler + * @{ + */ +#define EQEP_CLOCKPRESCALER_1 0x00000000U +#define EQEP_CLOCKPRESCALER_2 EQEP_QCAPCTL_CCPS_0 +#define EQEP_CLOCKPRESCALER_4 EQEP_QCAPCTL_CCPS_1 +#define EQEP_CLOCKPRESCALER_8 (EQEP_QCAPCTL_CCPS_0 | EQEP_QCAPCTL_CCPS_1) +#define EQEP_CLOCKPRESCALER_16 EQEP_QCAPCTL_CCPS_2 +#define EQEP_CLOCKPRESCALER_32 (EQEP_QCAPCTL_CCPS_0 | EQEP_QCAPCTL_CCPS_2) +#define EQEP_CLOCKPRESCALER_64 (EQEP_QCAPCTL_CCPS_1 | EQEP_QCAPCTL_CCPS_2) +#define EQEP_CLOCKPRESCALER_128 EQEP_QCAPCTL_CCPS + +#define IS_EQEP_CLOCKPRESCALER(PRE) (((PRE) == EQEP_CLOCKPRESCALER_1 ) || \ + ((PRE) == EQEP_CLOCKPRESCALER_2 ) || \ + ((PRE) == EQEP_CLOCKPRESCALER_4 ) || \ + ((PRE) == EQEP_CLOCKPRESCALER_8 ) || \ + ((PRE) == EQEP_CLOCKPRESCALER_16 ) || \ + ((PRE) == EQEP_CLOCKPRESCALER_32 ) || \ + ((PRE) == EQEP_CLOCKPRESCALER_64 ) || \ + ((PRE) == EQEP_CLOCKPRESCALER_128) ) + +/** + * @} + */ + + +/** @defgroup EQEP_unit_position_event_prescaler + * @{ + */ +#define EQEP_EVENTPRESCALER_1 0x00000000U +#define EQEP_EVENTPRESCALER_2 0x00000001U +#define EQEP_EVENTPRESCALER_4 0x00000002U +#define EQEP_EVENTPRESCALER_8 0x00000003U +#define EQEP_EVENTPRESCALER_16 0x00000004U +#define EQEP_EVENTPRESCALER_32 0x00000005U +#define EQEP_EVENTPRESCALER_64 0x00000006U +#define EQEP_EVENTPRESCALER_128 0x00000007U +#define EQEP_EVENTPRESCALER_256 0x00000008U +#define EQEP_EVENTPRESCALER_512 0x00000009U +#define EQEP_EVENTPRESCALER_1024 0x0000000AU +#define EQEP_EVENTPRESCALER_2048 0x0000000BU + +#define IS_EQEP_EVENTPRESCALER(PRE) (((PRE) == EQEP_EVENTPRESCALER_1 ) || \ + ((PRE) == EQEP_EVENTPRESCALER_2 ) || \ + ((PRE) == EQEP_EVENTPRESCALER_4 ) || \ + ((PRE) == EQEP_EVENTPRESCALER_8 ) || \ + ((PRE) == EQEP_EVENTPRESCALER_16 ) || \ + ((PRE) == EQEP_EVENTPRESCALER_32 ) || \ + ((PRE) == EQEP_EVENTPRESCALER_64 ) || \ + ((PRE) == EQEP_EVENTPRESCALER_128 ) || \ + ((PRE) == EQEP_EVENTPRESCALER_256 ) || \ + ((PRE) == EQEP_EVENTPRESCALER_512 ) || \ + ((PRE) == EQEP_EVENTPRESCALER_1024) || \ + ((PRE) == EQEP_EVENTPRESCALER_2048) ) + +/** + * @} + */ + + +/** @defgroup EQEP_capture_period_value + * @{ + */ +#define IS_EQEP_CAPTURE_PERIOD_VALUE(VALUE) (((VALUE) >= 0x0U) && ((VALUE) <= 0xFFFFU)) + +/** + * @} + */ + + + +///** @defgroup EQEP_position_compare_shadow_enable +// * @{ +// */ +//#define EQEP_POSCMP_SHADOW_DISABLE 0x00000000U +//#define EQEP_POSCMP_SHADOW_ENABLE EQEP_QPOSCTL_PCSHDW +// +//#define IS_EQEP_POSCMP_SHADOW(STATE) (((STATE) == EQEP_POSCMP_SHADOW_DISABLE) || \ +// ((STATE) == EQEP_POSCMP_SHADOW_ENABLE ) ) +// +///** +// * @} +// */ + + +/** @defgroup EQEP_position_compare_shadow_load + * @{ + */ +#define EQEP_POSCMP_LOAD_CNTZERO 0x00000000U +#define EQEP_POSCMP_LOAD_CNTCMP EQEP_QPOSCTL_PCLOAD + +#define IS_EQEP_POSCMP_LOAD(STATE) (((STATE) == EQEP_POSCMP_LOAD_CNTZERO) || \ + ((STATE) == EQEP_POSCMP_LOAD_CNTCMP ) ) + +/** + * @} + */ + + +/** @defgroup EQEP_sync_out_polarity + * @{ + */ +#define EQEP_SYNCOUT_POLARITY_HIGH 0x00000000U +#define EQEP_SYNCOUT_POLARITY_LOW EQEP_QPOSCTL_PCPOL + +#define IS_EQEP_SYNCOUT_POLARITY(POLARITY) (((POLARITY) == EQEP_SYNCOUT_POLARITY_HIGH) || \ + ((POLARITY) == EQEP_SYNCOUT_POLARITY_LOW ) ) + +/** + * @} + */ + + +///** @defgroup EQEP_position_compare_enable +// * @{ +// */ +//#define EQEP_POSCOMPARE_DISABLE 0x00000000U +//#define EQEP_POSCOMPARE_ENABLE EQEP_QPOSCTL_PCMPE +// +//#define IS_EQEP_POSCOMPARE(STATE) (((STATE) == EQEP_POSCOMPARE_DISABLE) || \ +// ((STATE) == EQEP_POSCOMPARE_ENABLE ) ) +// +///** +// * @} +// */ + + +/** @defgroup EQEP_sync_out_pulse_width + * @{ + */ +#define IS_EQEP_SYNCOUT_PULSE_WIDTH(WIDTH) (((WIDTH) >= 0x0U) && ((WIDTH) <= 0xFFFU)) + +/** + * @} + */ + + + +/** @defgroup EQEP_interrupt_definition EQEP_IT + * @{ + */ +#define EQEP_IT_PCE EQEP_QEINT_PCE +#define EQEP_IT_PHE EQEP_QEINT_PHE +#define EQEP_IT_QDC EQEP_QEINT_QDC +#define EQEP_IT_WTO EQEP_QEINT_WTO +#define EQEP_IT_PCU EQEP_QEINT_PCU +#define EQEP_IT_PCO EQEP_QEINT_PCO +#define EQEP_IT_PCR EQEP_QEINT_PCR +#define EQEP_IT_PCM EQEP_QEINT_PCM +#define EQEP_IT_SEL EQEP_QEINT_SEL +#define EQEP_IT_IEL EQEP_QEINT_IEL +#define EQEP_IT_UTO EQEP_QEINT_UTO + +#define IS_EQEP_IT(TYPE) (((TYPE) == EQEP_IT_PCE) || \ + ((TYPE) == EQEP_IT_PHE) || \ + ((TYPE) == EQEP_IT_QDC) || \ + ((TYPE) == EQEP_IT_WTO) || \ + ((TYPE) == EQEP_IT_PCU) || \ + ((TYPE) == EQEP_IT_PCO) || \ + ((TYPE) == EQEP_IT_PCR) || \ + ((TYPE) == EQEP_IT_PCM) || \ + ((TYPE) == EQEP_IT_SEL) || \ + ((TYPE) == EQEP_IT_IEL) || \ + ((TYPE) == EQEP_IT_UTO) ) +/** + * @} + */ + + + +/** @defgroup EQEP_flags_definition EQEP_FLAG + * @{ + */ +#define EQEP_FLAG_INT EQEP_QFLG_INT +#define EQEP_FLAG_PCE EQEP_QFLG_PCE +#define EQEP_FLAG_PHE EQEP_QFLG_PHE +#define EQEP_FLAG_QDC EQEP_QFLG_QDC +#define EQEP_FLAG_WTO EQEP_QFLG_WTO +#define EQEP_FLAG_PCU EQEP_QFLG_PCU +#define EQEP_FLAG_PCO EQEP_QFLG_PCO +#define EQEP_FLAG_PCR EQEP_QFLG_PCR +#define EQEP_FLAG_PCM EQEP_QFLG_PCM +#define EQEP_FLAG_SEL EQEP_QFLG_SEL +#define EQEP_FLAG_IEL EQEP_QFLG_IEL +#define EQEP_FLAG_UTO EQEP_QFLG_UTO + +#define IS_EQEP_FLAG(TYPE) (((TYPE) == EQEP_FLAG_INT ) || \ + ((TYPE) == EQEP_FLAG_PCE) || \ + ((TYPE) == EQEP_FLAG_PHE) || \ + ((TYPE) == EQEP_FLAG_QDC) || \ + ((TYPE) == EQEP_FLAG_WTO) || \ + ((TYPE) == EQEP_FLAG_PCU) || \ + ((TYPE) == EQEP_FLAG_PCO) || \ + ((TYPE) == EQEP_FLAG_PCR) || \ + ((TYPE) == EQEP_FLAG_PCM) || \ + ((TYPE) == EQEP_FLAG_SEL) || \ + ((TYPE) == EQEP_FLAG_IEL) || \ + ((TYPE) == EQEP_FLAG_UTO) ) + +#define EQEP_IT_MASK 0x00000FFFU +/** + * @} + */ + + +/** @defgroup EQEP_status_definition EQEP_STATUS + * @{ + */ +#define EQEP_STATUS_UPEVNT EQEP_QEPSTS_UPEVNT +#define EQEP_STATUS_FIDF EQEP_QEPSTS_FIDF +#define EQEP_STATUS_QDF EQEP_QEPSTS_QDF +#define EQEP_STATUS_QDLF EQEP_QEPSTS_QDLF +#define EQEP_STATUS_COEF EQEP_QEPSTS_COEF +#define EQEP_STATUS_CDEF EQEP_QEPSTS_CDEF +#define EQEP_STATUS_FIMF EQEP_QEPSTS_FIMF +#define EQEP_STATUS_PCEF EQEP_QEPSTS_PCEF + +#define IS_EQEP_STATUS(STATUS) (((STATUS) == EQEP_STATUS_UPEVNT) || \ + ((STATUS) == EQEP_STATUS_FIDF ) || \ + ((STATUS) == EQEP_STATUS_QDF ) || \ + ((STATUS) == EQEP_STATUS_QDLF ) || \ + ((STATUS) == EQEP_STATUS_COEF ) || \ + ((STATUS) == EQEP_STATUS_CDEF ) || \ + ((STATUS) == EQEP_STATUS_FIMF ) || \ + ((STATUS) == EQEP_STATUS_PCEF ) ) +/** + * @} + */ + + +/** + * @brief EQEP_register_type_definition EQEP_REG_TYPE + */ +#define EQEP_QPOSCNT ((uint16_t)0x0001U) +#define EQEP_QUTMR ((uint16_t)0x0002U) +#define EQEP_QWDTMR ((uint16_t)0x0004U) +#define EQEP_QCTMR ((uint16_t)0x0008U) +#define EQEP_QPOSINIT ((uint16_t)0x0010U) +#define EQEP_QPOSMAX ((uint16_t)0x0020U) +#define EQEP_QPOSCMP ((uint16_t)0x0040U) +#define EQEP_QPOSILAT ((uint16_t)0x0080U) +#define EQEP_QPOSSLAT ((uint16_t)0x0100U) +#define EQEP_QPOSLAT ((uint16_t)0x0200U) +#define EQEP_QUPRD ((uint16_t)0x0400U) +#define EQEP_QWDPRD ((uint16_t)0x0800U) +#define EQEP_QCPRD ((uint16_t)0x1000U) +#define EQEP_QCTMRLAT ((uint16_t)0x2000U) +#define EQEP_QCPRDLAT ((uint16_t)0x4000U) + +#define IS_EQEP_REG_TYPE(TYPE) (((TYPE) == EQEP_QPOSCNT ) || \ + ((TYPE) == EQEP_QUTMR ) || \ + ((TYPE) == EQEP_QWDTMR ) || \ + ((TYPE) == EQEP_QCTMR ) || \ + ((TYPE) == EQEP_QPOSINIT ) || \ + ((TYPE) == EQEP_QPOSMAX ) || \ + ((TYPE) == EQEP_QPOSCMP ) || \ + ((TYPE) == EQEP_QPOSILAT ) || \ + ((TYPE) == EQEP_QPOSSLAT ) || \ + ((TYPE) == EQEP_QPOSLAT ) || \ + ((TYPE) == EQEP_QUPRD ) || \ + ((TYPE) == EQEP_QWDPRD ) || \ + ((TYPE) == EQEP_QCPRD ) || \ + ((TYPE) == EQEP_QCTMRLAT ) || \ + ((TYPE) == EQEP_QCPRDLAT )) + + +/** + * @brief EQEP_submodule_definition EQEP_SUBMDU_TYPE + */ +#define EQEP_POS_CNT ((uint8_t)0x01U) +#define EQEP_UNIT_TMR ((uint8_t)0x02U) +#define EQEP_WTD_TMR ((uint8_t)0x04U) +#define EQEP_CAP_TMR ((uint8_t)0x08U) + +#define IS_EQEP_SUBMDU_TYPE(TYPE) (((TYPE) == EQEP_POS_CNT ) || \ + ((TYPE) == EQEP_UNIT_TMR) || \ + ((TYPE) == EQEP_WTD_TMR ) || \ + ((TYPE) == EQEP_CAP_TMR )) + + + + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +/* Function used to set the EQEP configuration to the default reset state ******/ +void EQEP_DeInit(); + +/* Initialization and Configuration functions *********************************/ +void EQEP_Init(EQEP_InitTypeDef* EQEP_InitStruct); +void EQEP_QDUInit(EQEP_QDUInitTypeDef* EQEP_QDUInitStruct); +void EQEP_CAPInit(EQEP_CAPInitTypeDef* EQEP_CAPInitStruct); +void EQEP_POSCMPInit(EQEP_PosCmpInitTypeDef* EQEP_PosCmpInitStruct); + +void EQEP_StructInit(EQEP_InitTypeDef* EQEP_InitStruct); +void EQEP_QDUStructInit(EQEP_QDUInitTypeDef* EQEP_QDUInitStruct); +void EQEP_CAPStructInit(EQEP_CAPInitTypeDef* EQEP_CAPInitStruct); +void EQEP_POSCMPStructInit(EQEP_PosCmpInitTypeDef* EQEP_PosCmpInitStruct); + +/* EQEP control functions *********************************/ +void EQEP_Cmd(uint16_t EQEP_REG_TYPE, FunctionalState NewState); //QEPCTL.QPEN +//void EQEP_UnitTimerCmd(FunctionalState NewState); //QEPCTL.UTE +//void EQEP_WdgTimerCmd(FunctionalState NewState); //QEPCTL.WDE +//void EQEP_CaptureCmd(FunctionalState NewState); //QCAPCTL.CEN +////void EQEP_PosCmpCmd(FunctionalState NewState); //QPOSCTL.PCMPE +void EQEP_SoftwareInitPositionCounter(FunctionalState NewState); //QEPCTL.SWI + +/* Data register access function***********************************************/ +void EQEP_WriteDataRegister(uint16_t EQEP_REG_TYPE, uint32_t Value); +uint32_t EQEP_GetDataRegister(uint16_t EQEP_REG_TYPE); + +/* Interrupts and flags management functions **********************************/ +void EQEP_ITConfig(uint16_t EQEP_IT, FunctionalState NewState); +void EQEP_ClearFlag(uint16_t EQEP_FLAG); +void EQEP_ITForce(uint16_t EQEP_IT); +ITStatus EQEP_GetITStatus(uint16_t EQEP_IT); +FlagStatus EQEP_GetFlagStatus(uint16_t EQEP_FLAG); +FlagStatus EQEP_GetStatus(uint8_t EQEP_STATUS); + + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif /*__FT32F4XX_EQEP_H */ + + +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_eth.h b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_eth.h new file mode 100644 index 00000000000..96c771d9d9d --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_eth.h @@ -0,0 +1,1809 @@ +/** + ****************************************************************************** + * @file ft32f4xx_eth.h + * @author xcao + * @brief Header file of heth module. + ****************************************************************************** + * @attention + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __FT32F4XX_ETH_H +#define __FT32F4XX_ETH_H + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx.h" +//#if defined(eth) +typedef enum +{ + HAL_OK = 0x0U, + HAL_ERROR = 0x1U, + HAL_BUSY = 0x2U, + HAL_TIMEOUT = 0x3U +} HAL_StatusTypeDef; +/** @addtogroup FT32F4xx_Driver + * @{ + */ + +/** @addtogroup heth + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +#ifndef ETH_TX_DESC_CNT +#define ETH_TX_DESC_CNT 4U +#endif /* ETH_TX_DESC_CNT */ + +#ifndef ETH_RX_DESC_CNT +#define ETH_RX_DESC_CNT 4U +#endif /* ETH_RX_DESC_CNT */ + +#ifndef ETH_SWRESET_TIMEOUT +#define ETH_SWRESET_TIMEOUT 500U +#endif /* ETH_SWRESET_TIMEOUT */ + +#ifndef ETH_MDIO_BUS_TIMEOUT +#define ETH_MDIO_BUS_TIMEOUT 1000U +#endif /* ETH_MDIO_BUS_TIMEOUT */ + +#ifndef ETH_MAC_US_TICK +#define ETH_MAC_US_TICK 1000000U +#endif /* ETH_MAC_US_TICK */ + +/*********************** Common state type defination **************************/ +/*TODO START*/ +/*Need to be defined at high level header file*/ +//typedef enum +//{ +// DISABLE = 0, +// ENABLE = !DISABLE +//}FunctionalState; + +/*********************** Descriptors struct def section ************************/ +/** @defgroup ETH_Exported_Types heth Exported Types + * @{ + */ + +/** + * @brief heth DMA Descriptor structure definition + */ +typedef struct +{ + __IO uint32_t DESC0; + __IO uint32_t DESC1; + __IO uint32_t DESC2; + __IO uint32_t DESC3; + uint32_t BackupAddr0; /* used to store rx buffer 1 address */ + uint32_t BackupAddr1; /* used to store rx buffer 2 address */ +} ETH_DMADescTypeDef; +/** + * + */ + +/** + * @brief heth Buffers List structure definition + */ +typedef struct __ETH_BufferTypeDef +{ + uint8_t *buffer; /*gState = ETH_STATE_RESET; \ + (__HANDLE__)->MspInitCallback = NULL; \ + (__HANDLE__)->MspDeInitCallback = NULL; \ + } while(0) +#else +#define __ETH_RESET_HANDLE_STATE(__HANDLE__) do{ \ + (__HANDLE__)->gState = ETH_STATE_RESET; \ + } while(0) +#endif /*USE_ETH_REGISTER_CALLBACKS */ + +/** + * @brief Enables the specified ETHERNET DMA interrupts. + * @param __HANDLE__ : heth Handle + * @param __INTERRUPT__: specifies the ETHERNET DMA interrupt sources to be + * enabled @ref ETH_DMA_Interrupts + * @retval None + */ +#define __ETH_DMA_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->ETH_DMA_INTRENA |= (__INTERRUPT__)) + +/** + * @brief Disables the specified ETHERNET DMA interrupts. + * @param __HANDLE__ : heth Handle + * @param __INTERRUPT__: specifies the ETHERNET DMA interrupt sources to be + * disabled. @ref ETH_DMA_Interrupts + * @retval None + */ +#define __ETH_DMA_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->ETH_DMA_INTRENA &= ~(__INTERRUPT__)) + +/** + * @brief Gets the ETHERNET DMA IT source enabled or disabled. + * @param __HANDLE__ : heth Handle + * @param __INTERRUPT__: specifies the interrupt source to get . @ref ETH_DMA_Interrupts + * @retval The heth DMA IT Source enabled or disabled + */ +#define __ETH_DMA_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) \ + (((__HANDLE__)->Instance->ETH_DMA_INTRENA & (__INTERRUPT__)) == (__INTERRUPT__)) + +/** + * @brief Gets the ETHERNET DMA IT pending bit. + * @param __HANDLE__ : heth Handle + * @param __INTERRUPT__: specifies the interrupt source to get . @ref ETH_DMA_Interrupts + * @retval The state of heth DMA IT (SET or RESET) + */ +#define __ETH_DMA_GET_IT(__HANDLE__, __INTERRUPT__) \ + (((__HANDLE__)->Instance->ETH_DMA_STU & (__INTERRUPT__)) == (__INTERRUPT__)) + +/** + * @brief Clears the ETHERNET DMA IT pending bit. + * @param __HANDLE__ : heth Handle + * @param __INTERRUPT__: specifies the interrupt pending bit to clear. @ref ETH_DMA_Interrupts + * @retval None + */ +#define __ETH_DMA_CLEAR_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->ETH_DMA_STU = (__INTERRUPT__)) + +/** + * @brief Checks wether the specified ETHERNET DMA flag is set or not. + * @param __HANDLE__: heth Handle + * @param __FLAG__: specifies the flag to check. @ref ETH_DMA_Status_Flags + * @retval The state of heth DMA FLAG (SET or RESET). + */ +#define __ETH_DMA_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->ETH_DMA_STU &( __FLAG__)) == ( __FLAG__)) + +/** + * @brief Clears the specified ETHERNET DMA flag. + * @param __HANDLE__: heth Handle + * @param __FLAG__: specifies the flag to check. @ref ETH_DMA_Status_Flags + * @retval The state of heth DMA FLAG (SET or RESET). + */ +#define __ETH_DMA_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->ETH_DMA_STU = ( __FLAG__)) + +/** + * @brief Enables the specified ETHERNET MAC interrupts. + * @param __HANDLE__ : heth Handle + * @param __INTERRUPT__: specifies the ETHERNET MAC interrupt sources to be + * enabled @ref ETH_MAC_Interrupts + * @retval None + */ + +#define __ETH_MAC_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->ETH_MAC_IREN |= (__INTERRUPT__)) + +/** + * @brief Disables the specified ETHERNET MAC interrupts. + * @param __HANDLE__ : heth Handle + * @param __INTERRUPT__: specifies the ETHERNET MAC interrupt sources to be + * enabled @ref ETH_MAC_Interrupts + * @retval None + */ +#define __ETH_MAC_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->ETH_MAC_IREN &= ~(__INTERRUPT__)) + +/** + * @brief Checks wether the specified ETHERNET MAC flag is set or not. + * @param __HANDLE__: heth Handle + * @param __INTERRUPT__: specifies the flag to check. @ref ETH_MAC_Interrupts + * @retval The state of heth MAC IT (SET or RESET). + */ +#define __ETH_MAC_GET_IT(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->ETH_MAC_IRSTU &\ + ( __INTERRUPT__)) == ( __INTERRUPT__)) + +/*!< External interrupt line 19 Connected to the heth wakeup EXTI Line */ +#define ETH_WAKEUP_EXTI_LINE 0x00080000U + +/** + * @brief Enable the heth WAKEUP Exti Line. + * @param __EXTI_LINE__: specifies the heth WAKEUP Exti sources to be enabled. + * @arg ETH_WAKEUP_EXTI_LINE + * @retval None. + */ +#define __ETH_WAKEUP_EXTI_ENABLE_IT(__EXTI_LINE__) (EXTI->IMR |= (__EXTI_LINE__)) + +/** + * @brief checks wether the specified heth WAKEUP Exti interrupt flag is set or not. + * @param __EXTI_LINE__: specifies the heth WAKEUP Exti sources to be cleared. + * @arg ETH_WAKEUP_EXTI_LINE + * @retval EXTI heth WAKEUP Line Status. + */ +#define __ETH_WAKEUP_EXTI_GET_FLAG(__EXTI_LINE__) (EXTI->PR & (__EXTI_LINE__)) + +/** + * @brief Clear the heth WAKEUP Exti flag. + * @param __EXTI_LINE__: specifies the heth WAKEUP Exti sources to be cleared. + * @arg ETH_WAKEUP_EXTI_LINE + * @retval None. + */ +#define __ETH_WAKEUP_EXTI_CLEAR_FLAG(__EXTI_LINE__) (EXTI->PR = (__EXTI_LINE__)) + + +/** + * @brief enable rising edge interrupt on selected EXTI line. + * @param __EXTI_LINE__: specifies the heth WAKEUP EXTI sources to be disabled. + * @arg ETH_WAKEUP_EXTI_LINE + * @retval None + */ +#define __ETH_WAKEUP_EXTI_ENABLE_RISING_EDGE(__EXTI_LINE__) (EXTI->FTSR &= ~(__EXTI_LINE__)); \ + (EXTI->RTSR |= (__EXTI_LINE__)) + +/** + * @brief enable falling edge interrupt on selected EXTI line. + * @param __EXTI_LINE__: specifies the heth WAKEUP EXTI sources to be disabled. + * @arg ETH_WAKEUP_EXTI_LINE + * @retval None + */ +#define __ETH_WAKEUP_EXTI_ENABLE_FALLING_EDGE(__EXTI_LINE__) (EXTI->RTSR &= ~(__EXTI_LINE__));\ + (EXTI->FTSR |= (__EXTI_LINE__)) + +/** + * @brief enable falling edge interrupt on selected EXTI line. + * @param __EXTI_LINE__: specifies the heth WAKEUP EXTI sources to be disabled. + * @arg ETH_WAKEUP_EXTI_LINE + * @retval None + */ +#define __ETH_WAKEUP_EXTI_ENABLE_RISING_FALLING_EDGE(__EXTI_LINE__) (EXTI->RTSR |= (__EXTI_LINE__));\ + (EXTI->FTSR |= (__EXTI_LINE__)) + +/** + * @brief Generates a Software interrupt on selected EXTI line. + * @param __EXTI_LINE__: specifies the heth WAKEUP EXTI sources to be disabled. + * @arg ETH_WAKEUP_EXTI_LINE + * @retval None + */ +#define __ETH_WAKEUP_EXTI_GENERATE_SWIT(__EXTI_LINE__) (EXTI->SWIER |= (__EXTI_LINE__)) + +#define __ETH_GET_PTP_CONTROL(__HANDLE__, __FLAG__) (((((__HANDLE__)->Instance->ETH_PTP_TSCTL) & \ + (__FLAG__)) == (__FLAG__)) ? SET : RESET) + +#define __ETH_SET_PTP_CONTROL(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->ETH_PTP_TSCTL |= (__FLAG__)) + +/** + * @} + */ + +/* Include heth Extension module */ +//#include "ft32_eth_ex.h" + +/* Exported functions --------------------------------------------------------*/ + +/** @addtogroup ETH_Exported_Functions + * @{ + */ + +/** @addtogroup ETH_Exported_Functions_Group1 + * @{ + */ +/* Initialization and de initialization functions **********************************/ +uint32_t ETH_Init(ETH_HandleTypeDef *heth); +uint32_t ETH_DeInit(ETH_HandleTypeDef *heth); +void ETH_MspInit(ETH_HandleTypeDef *heth); +void ETH_MspDeInit(ETH_HandleTypeDef *heth); + +/* Callbacks Register/UnRegister functions ***********************************/ +#if (USE_ETH_REGISTER_CALLBACKS == 1) +StatusTypeDef ETH_RegisterCallback(ETH_HandleTypeDef *heth, ETH_CallbackIDTypeDef CallbackID, pETH_CallbackTypeDef pCallback); +StatusTypeDef ETH_UnRegisterCallback(ETH_HandleTypeDef *heth, ETH_CallbackIDTypeDef CallbackID); +#endif /* USE_ETH_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @addtogroup ETH_Exported_Functions_Group2 + * @{ + */ +/* IO operation functions *******************************************************/ +uint32_t ETH_Start(ETH_HandleTypeDef *heth); +uint32_t ETH_Start_IT(ETH_HandleTypeDef *heth); +uint32_t ETH_Stop(ETH_HandleTypeDef *heth); +uint32_t ETH_Stop_IT(ETH_HandleTypeDef *heth); + +uint32_t ETH_ReadData(ETH_HandleTypeDef *heth, void **pAppBuff); +uint32_t ETH_RegisterRxAllocateCallback(ETH_HandleTypeDef *heth, pETH_rxAllocateCallbackTypeDef rxAllocateCallback); +void ETH_UnRegisterRxAllocateCallback(ETH_HandleTypeDef *heth); +uint32_t ETH_RegisterRxLinkCallback(ETH_HandleTypeDef *heth, pETH_rxLinkCallbackTypeDef rxLinkCallback); +void ETH_UnRegisterRxLinkCallback(ETH_HandleTypeDef *heth); +void ETH_GetRxDataErrorCode(const ETH_HandleTypeDef *heth, uint32_t *pErrorCode); +uint32_t ETH_RegisterTxFreeCallback(ETH_HandleTypeDef *heth, pETH_txFreeCallbackTypeDef txFreeCallback); +void ETH_UnRegisterTxFreeCallback(ETH_HandleTypeDef *heth); +void ETH_ReleaseTxPacket(ETH_HandleTypeDef *heth); + +#ifdef ETH_USE_PTP +uint32_t ETH_PTP_SetConfig(ETH_HandleTypeDef *heth, ETH_PTP_ConfigTypeDef *ptpconfig); +uint32_t ETH_PTP_GetConfig(ETH_HandleTypeDef *heth, ETH_PTP_ConfigTypeDef *ptpconfig); +uint32_t ETH_PTP_SetTime(ETH_HandleTypeDef *heth, ETH_TimeTypeDef *time); +uint32_t ETH_PTP_GetTime(ETH_HandleTypeDef *heth, ETH_TimeTypeDef *time); +uint32_t ETH_PTP_AddTimeOffset(ETH_HandleTypeDef *heth, ETH_PtpUpdateTypeDef ptpoffsettype, + ETH_TimeTypeDef *timeoffset); +uint32_t ETH_PTP_InsertTxTimestamp(ETH_HandleTypeDef *heth); +uint32_t ETH_PTP_GetTxTimestamp(ETH_HandleTypeDef *heth, ETH_TimeStampTypeDef *timestamp); +uint32_t ETH_PTP_GetRxTimestamp(ETH_HandleTypeDef *heth, ETH_TimeStampTypeDef *timestamp); +uint32_t ETH_RegisterTxPtpCallback(ETH_HandleTypeDef *heth, pETH_txPtpCallbackTypeDef txPtpCallback); +uint32_t ETH_UnRegisterTxPtpCallback(ETH_HandleTypeDef *heth); +#endif /* ETH_USE_PTP */ + +uint32_t ETH_Transmit(ETH_HandleTypeDef *heth, ETH_TxPacketConfigTypeDef *pTxConfig, uint32_t Timeout); +uint32_t ETH_Transmit_IT(ETH_HandleTypeDef *heth, ETH_TxPacketConfigTypeDef *pTxConfig); + +uint32_t ETH_WritePHYRegister(const ETH_HandleTypeDef *heth, uint32_t PHYAddr, uint32_t PHYReg, uint32_t RegValue); +uint32_t ETH_ReadPHYRegister(ETH_HandleTypeDef *heth, uint32_t PHYAddr, uint32_t PHYReg, uint32_t *pRegValue); + +void ETH_IRQHandler(ETH_HandleTypeDef *heth); +void ETH_TxCpltCallback(ETH_HandleTypeDef *heth); +void ETH_RxCpltCallback(ETH_HandleTypeDef *heth); +void ETH_ErrorCallback(ETH_HandleTypeDef *heth); +void ETH_PMTCallback(ETH_HandleTypeDef *heth); +void ETH_WakeUpCallback(ETH_HandleTypeDef *heth); +void ETH_RxAllocateCallback(uint8_t **buff); +void ETH_RxLinkCallback(void **pStart, void **pEnd, uint8_t *buff, uint16_t Length); +void ETH_TxFreeCallback(uint32_t *buff); +void ETH_TxPtpCallback(uint32_t *buff, ETH_TimeStampTypeDef *timestamp); +/** + * @} + */ + +/** @addtogroup ETH_Exported_Functions_Group3 + * @{ + */ +/* Peripheral Control functions **********************************************/ +/* MAC & DMA Configuration APIs **********************************************/ +static void HAL_ETH_SetMACConfig(ETH_HandleTypeDef *heth, const ETH_MACConfigTypeDef *macconf); +static void ETH_SetDMAConfig(ETH_HandleTypeDef *heth, const ETH_DMAConfigTypeDef *dmaconf); +static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth); +static void ETH_DMATxDescListInit(ETH_HandleTypeDef *heth); +static void ETH_DMARxDescListInit(ETH_HandleTypeDef *heth); +static uint32_t ETH_Prepare_Tx_Descriptors(ETH_HandleTypeDef *heth, const ETH_TxPacketConfigTypeDef *pTxConfig, + uint32_t ItMode); +static void ETH_UpdateDescriptor(ETH_HandleTypeDef *heth); +uint32_t ETH_SetMACConfig(ETH_HandleTypeDef *heth, ETH_MACConfigTypeDef *macconf); +uint32_t ETH_GetMACConfig(const ETH_HandleTypeDef *heth, ETH_MACConfigTypeDef *macconf); +uint32_t ETH_GetDMAConfig(const ETH_HandleTypeDef *heth, ETH_DMAConfigTypeDef *dmaconf); +void ETH_SetMDIOClockRange(ETH_HandleTypeDef *heth); + +/* MAC VLAN Processing APIs ************************************************/ +void ETH_SetRxVLANIdentifier(ETH_HandleTypeDef *heth, uint32_t ComparisonBits, uint32_t VLANIdentifier); + +/* MAC L2 Packet Filtering APIs **********************************************/ +uint32_t ETH_GetMACFilterConfig(const ETH_HandleTypeDef *heth, ETH_MACFilterConfigTypeDef *pFilterConfig); +uint32_t ETH_SetMACFilterConfig(ETH_HandleTypeDef *heth, const ETH_MACFilterConfigTypeDef *pFilterConfig); +uint32_t ETH_SetHashTable(ETH_HandleTypeDef *heth, uint32_t *pHashTable); +uint32_t ETH_SetSourceMACAddrMatch(const ETH_HandleTypeDef *heth, uint32_t AddrNbr, const uint8_t *pMACAddr); + +/* MAC Power Down APIs *****************************************************/ +void ETH_EnterPowerDownMode(ETH_HandleTypeDef *heth, const ETH_PowerDownConfigTypeDef *pPowerDownConfig); +void ETH_ExitPowerDownMode(ETH_HandleTypeDef *heth); +uint32_t ETH_SetWakeUpFilter(ETH_HandleTypeDef *heth, uint32_t *pFilter, uint32_t Count); + +/** + * @} + */ + +/** @addtogroup ETH_Exported_Functions_Group4 + * @{ + */ +/* Peripheral State functions **************************************************/ +uint32_t ETH_GetState(const ETH_HandleTypeDef *heth); +uint32_t ETH_GetError(const ETH_HandleTypeDef *heth); +uint32_t ETH_GetDMAError(const ETH_HandleTypeDef *heth); +uint32_t ETH_GetMACError(const ETH_HandleTypeDef *heth); +uint32_t ETH_GetMACWakeUpSource(const ETH_HandleTypeDef *heth); +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +//#endif /* heth */ + +#ifdef __cplusplus +} +#endif + +#endif /* FT32F4xx_ETH_H */ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_exti.h b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_exti.h new file mode 100644 index 00000000000..ce51ea43a88 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_exti.h @@ -0,0 +1,186 @@ +/** + ****************************************************************************** + * @file ft32f4xx_exti.h + ****************************************************************************** + */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __FT32F4XX_EXTI_H +#define __FT32F4XX_EXTI_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx.h" + + +/* Exported types ------------------------------------------------------------*/ + +/** + * @brief EXTI mode enumeration + */ + +typedef enum +{ + EXTI_Mode_Interrupt = 0x00, + EXTI_Mode_Event = 0x04 +} EXTIMode_TypeDef; + +#define IS_EXTI_MODE(MODE) (((MODE) == EXTI_Mode_Interrupt) || ((MODE) == EXTI_Mode_Event)) + + +/** + * @brief EXTI Trigger enumeration + */ + +typedef enum +{ + EXTI_Trigger_Rising = 0x08, + EXTI_Trigger_Falling = 0x0C, + EXTI_Trigger_Rising_Falling = 0x10 +} EXTITrigger_TypeDef; + +#define IS_EXTI_TRIGGER(TRIGGER) (((TRIGGER) == EXTI_Trigger_Rising) || \ + ((TRIGGER) == EXTI_Trigger_Falling) || \ + ((TRIGGER) == EXTI_Trigger_Rising_Falling)) + +/** + * @brief EXTI Init Structure definition + */ + +typedef struct +{ + uint32_t EXTI_Line; /*!< Specifies the EXTI lines to be enabled or disabled. + This parameter can be any combination of @ref EXTI_Lines */ + + EXTIMode_TypeDef EXTI_Mode; /*!< Specifies the mode for the EXTI lines. + This parameter can be a value of @ref EXTIMode_TypeDef */ + + EXTITrigger_TypeDef EXTI_Trigger; /*!< Specifies the trigger signal active edge for the EXTI lines. + This parameter can be a value of @ref EXTIMode_TypeDef */ + + FunctionalState EXTI_LineCmd; /*!< Specifies the new state of the selected EXTI lines. + This parameter can be set either to ENABLE or DISABLE */ +} EXTI_InitTypeDef; + + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup EXTI_Exported_Constants + * @{ + */ +/** @defgroup EXTI_Lines + * @{ + */ + +#define EXTI_Line0 ((uint32_t)0x00000001) /*!< External interrupt line 0 */ +#define EXTI_Line1 ((uint32_t)0x00000002) /*!< External interrupt line 1 */ +#define EXTI_Line2 ((uint32_t)0x00000004) /*!< External interrupt line 2 */ +#define EXTI_Line3 ((uint32_t)0x00000008) /*!< External interrupt line 3 */ +#define EXTI_Line4 ((uint32_t)0x00000010) /*!< External interrupt line 4 */ +#define EXTI_Line5 ((uint32_t)0x00000020) /*!< External interrupt line 5 */ +#define EXTI_Line6 ((uint32_t)0x00000040) /*!< External interrupt line 6 */ +#define EXTI_Line7 ((uint32_t)0x00000080) /*!< External interrupt line 7 */ +#define EXTI_Line8 ((uint32_t)0x00000100) /*!< External interrupt line 8 */ +#define EXTI_Line9 ((uint32_t)0x00000200) /*!< External interrupt line 9 */ +#define EXTI_Line10 ((uint32_t)0x00000400) /*!< External interrupt line 10 */ +#define EXTI_Line11 ((uint32_t)0x00000800) /*!< External interrupt line 11 */ +#define EXTI_Line12 ((uint32_t)0x00001000) /*!< External interrupt line 12 */ +#define EXTI_Line13 ((uint32_t)0x00002000) /*!< External interrupt line 13 */ +#define EXTI_Line14 ((uint32_t)0x00004000) /*!< External interrupt line 14 */ +#define EXTI_Line15 ((uint32_t)0x00008000) /*!< External interrupt line 15 */ +#define EXTI_Line16 ((uint32_t)0x00010000) /*!< Internal interrupt line 16 + connected to the PVD + event */ +#define EXTI_Line17 ((uint32_t)0x00020000) /*!< Internal interrupt line 17 + Connected to the RTC Alarm + event */ +#define EXTI_Line18 ((uint32_t)0x00040000) /*!< Internal interrupt line 18 + Connected to the USB OTG FS wakeup + event*/ +#define EXTI_Line19 ((uint32_t)0x00080000) /*!< Internal interrupt line 19 + Connected to the Ethernet wakeup + events */ +#define EXTI_Line20 ((uint32_t)0x00100000) /*!< Internal interrupt line 20 + Connected to the USB OTG HS wakeup + event */ +#define EXTI_Line21 ((uint32_t)0x00200000) /*!< Internal interrupt line 21 + Connected to the RTC Tamper and Time Stamp + event */ +#define EXTI_Line22 ((uint32_t)0x00400000) /*!< Internal interrupt line 22 + Connected to the RTC wakeup + event*/ +#define EXTI_Line23 ((uint32_t)0x00800000) /*!< Internal interrupt line 23 + Connected to the Comparator 1 + event*/ +#define EXTI_Line24 ((uint32_t)0x01000000) /*!< Internal interrupt line 23 + Connected to the Comparator 2 + event*/ +#define EXTI_Line25 ((uint32_t)0x02000000) /*!< Internal interrupt line 25 + Connected to the Comparator 3 + event */ +#define EXTI_Line26 ((uint32_t)0x04000000) /*!< Internal interrupt line 26 + Connected to the Comparator 4 + event*/ +#define EXTI_Line27 ((uint32_t)0x08000000) /*!< Internal interrupt line 27 + Connected to the Comparator 5 + event */ +#define EXTI_Line28 ((uint32_t)0x10000000) /*!< Internal interrupt line 31 + Connected to the Comparator 6 + event */ +#define EXTI_Line29 ((uint32_t)0x20000000) /*!< Internal interrupt line 31 + Connected to the LPTIM wakeup + event */ +#define EXTI_Line30 ((uint32_t)0x40000000) /*!< Internal interrupt line 31 + Connected to the LPUART wakeup + event */ + +#define IS_GET_EXTI_LINE(LINE) (((LINE) == EXTI_Line0) || ((LINE) == EXTI_Line1) || \ + ((LINE) == EXTI_Line2) || ((LINE) == EXTI_Line3) || \ + ((LINE) == EXTI_Line4) || ((LINE) == EXTI_Line5) || \ + ((LINE) == EXTI_Line6) || ((LINE) == EXTI_Line7) || \ + ((LINE) == EXTI_Line8) || ((LINE) == EXTI_Line9) || \ + ((LINE) == EXTI_Line10) || ((LINE) == EXTI_Line11) || \ + ((LINE) == EXTI_Line12) || ((LINE) == EXTI_Line13) || \ + ((LINE) == EXTI_Line14) || ((LINE) == EXTI_Line15) || \ + ((LINE) == EXTI_Line16) || ((LINE) == EXTI_Line17) || \ + ((LINE) == EXTI_Line18) || ((LINE) == EXTI_Line19) || \ + ((LINE) == EXTI_Line20) || ((LINE) == EXTI_Line21) || \ + ((LINE) == EXTI_Line22) || ((LINE) == EXTI_Line23) || \ + ((LINE) == EXTI_Line24) || ((LINE) == EXTI_Line25) || \ + ((LINE) == EXTI_Line26) || ((LINE) == EXTI_Line27) || \ + ((LINE) == EXTI_Line28) || ((LINE) == EXTI_Line29) || \ + ((LINE) == EXTI_Line30)) + + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ +/* Function used to set the EXTI configuration to the default reset state *****/ +void EXTI_DeInit(void); + +/* Initialization and Configuration functions *********************************/ +void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct); +void EXTI_StructInit(EXTI_InitTypeDef* EXTI_InitStruct); +void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line); + +/* Interrupts and flags management functions **********************************/ +FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line); +void EXTI_ClearFlag(uint32_t EXTI_Line); +ITStatus EXTI_GetITStatus(uint32_t EXTI_Line); +void EXTI_ClearITPendingBit(uint32_t EXTI_Line); + +#ifdef __cplusplus +} +#endif + +#endif /* __FT32F4XX_EXTI_H */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_fdcan.h b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_fdcan.h new file mode 100644 index 00000000000..62f6584cf18 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_fdcan.h @@ -0,0 +1,816 @@ +/** + ****************************************************************************** + * @file ft32f4xx_fdcan.h + * @author FMD AE + * @brief This file contains all the functions prototypes for the FDCAN firmware + * library. + * @version V1.0.0 + * @data 2025-03-06 + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __FT32F4XX_FDCAN_H +#define __FT32F4XX_FDCAN_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx.h" + + +/** @addtogroup FDCAN + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** + * @brief FDCAN Init structure definition + */ +typedef struct +{ + + uint32_t Mode; /*!< Specifies the FDCAN mode. + This parameter can be a value of @ref FDCAN_operating_mode */ + + uint32_t FrameFormat; /*!< Specifies the FDCAN frame format. + This parameter can be a value of @ref FDCAN_frame_format + Be used config CAN_F_SEG_UNIT_SET register */ + + FunctionalState AutoPrimaryRetransmission; /*!< Enable or disable the automatic retransmission mode for PTB. + This parameter can be set to ENABLE or DISABLE */ + + FunctionalState AutoSecondaryRetransmission; /*!< Enable or disable the automatic retransmission mode for STB. + This parameter can be set to ENABLE or DISABLE */ + + FunctionalState TTCANMode; /*!< Enable or disable the Time Trigger CAN. + This parameter can be set to ENABLE or DISABLE*/ + + uint32_t FDCANSACK; /*!< Specifies the Self-ACKnowledge in External LoopBack mode. + This parameter can be a value of @ref FDCAN_SACK */ + + uint32_t ReceiveBufferStoreAllFrames; /*!< Specifies the receive buffer stores all frames or normal frames. + This parameter can be a value of @FDCAN_ReceiveBufferStoreAllFrames */ + + uint32_t NominalPrescaler; /*!< Specifies the value by which the oscillator frequency is + divided for generating the nominal bit time quanta. + This parameter must be a number between 1 and 255 */ + + uint32_t NominalSyncJumpWidth; /*!< Specifies the maximum number of time quanta the FDCAN + hardware is allowed to lengthen or shorten a bit to perform + resynchronization. + This parameter must be a number between 2 and 127 */ + + uint32_t NominalTimeSeg1; /*!< Specifies the number of time quanta in Bit Segment 1. + This parameter must be a number between 3 and 255 */ + + uint32_t NominalTimeSeg2; /*!< Specifies the number of time quanta in Bit Segment 2. + This parameter must be a number between 2 and 127 */ + + uint32_t DataPrescaler; /*!< Specifies the value by which the oscillator frequency is + divided for generating the data bit time quanta. + This parameter must be a number between 1 and 255 */ + + uint32_t DataSyncJumpWidth; /*!< Specifies the maximum number of time quanta the FDCAN + hardware is allowed to lengthen or shorten a data bit to + perform resynchronization. + This parameter must be a number between 2 and 15 */ + + uint32_t DataTimeSeg1; /*!< Specifies the number of time quanta in Data Bit Segment 1. + This parameter must be a number between 3 and 31 */ + + uint32_t DataTimeSeg2; /*!< Specifies the number of time quanta in Data Bit Segment 2. + This parameter must be a number between 2 and 15 */ + + uint32_t TimeTriggerPrescaler; /*!< Specifies the value by which bit time is divided for + time trigger timer. + This parameter can be a value of @ref Time_Trigger_Prescaler */ + + uint32_t TriggerTime; /*!< Specifies the cycle time for a trigger. + This paramter must be a value between 0 and 255 */ + + uint32_t TransmitEnableWindow; /*!< Specifies the ticks of transmit enable window. + This paramter must be a value between 0 and 15 */ + + uint32_t TimeTriggerType; /*!< Specifies the kind of trigger in Time Trigger mode. + This paramter can be a value of @ref FDCAN_Trigger_Type */ + + uint32_t TransmitTriggerTbSolt; /*!< Specifies the TTPTR */ + + uint32_t WatchTriggerTime; /*!< Specifies the cycle time for a watch trigger. + This paramter must be a value between 0 and 255 */ + +} FDCAN_InitTypeDef; + + +/** + * @brief FDCAN filter structure definition + */ +typedef struct +{ + uint32_t FilterAddress; /*!< Specifies the filter which will be initialized. + This parameter must be a number between: + - 0 and 15 */ + + FunctionalState SelectAcceptanceMask; /*!< Enable or disable the filter mask. + This parameter can be set to ENABLE or DISABLE */ + + uint32_t FilterAcceptanceCODE; /*!< Specifies the filter identification. + This parameter must be a number between: + - 0 and 0x7FF for standard frames + - 0 and 0x1FFFFFFF for extended frames */ + + uint32_t FilterAcceptanceMASK; /*!< Specifies the filter acceptance mask. + 1 : acceptance check for these bis of receive ID disable + 0 : acceptance check for these bis of receive ID enable + This parameter must be a number between: + - 0 and 0x7FF for standard frames + - 0 and 0x1FFFFFFF for extended frames */ + + uint32_t FilterAcceptanceMaskIDECheck; /*!< Specifies the filter acceptance mask IDE bit check enable. + This parameter can be a value of @Acceptance_Mask_IDE_Check_Enable */ + + uint32_t FilterAcceptanceMaskIDE; /*!< Specifies the filter acceptance mask IDE bit value. + This parameter can be a value of @Acceptance_Mask_IDE_Type, + only valid if FilterAcceptanceMaskIDECheck is enable. */ + +} FDCAN_FilterTypeDef; + + + +/** + * @brief FDCAN Tx header structure definition + */ +typedef struct +{ + uint32_t Identifier; /*!< Specifies the identifier. + This parameter must be a number between: + - 0 and 0x7FF, if IdType is FDCAN_STANDARD_ID + - 0 and 0x1FFFFFFF, if IdType is FDCAN_EXTENDED_ID */ + + uint32_t IdType; /*!< Specifies the identifier type for the transmitted message. + This parameter can be a value of @ref FDCAN_id_type */ + + uint32_t TxFrameType; /*!< Specifies the frame type of the transmitted message. + This parameter can be a value of @ref FDCAN_frame_type */ + + uint32_t DataLength; /*!< Specifies the length of the transmitted frame. + This parameter can be a value of @ref FDCAN_data_length_code */ + + uint32_t BitRateSwitch; /*!< Specifies whether the Tx frame is transmitted with or without bit + rate switching. + This parameter can be a value of @ref FDCAN_bit_rate_switching */ + + uint32_t FDFormat; /*!< Specifies whether the Tx frame is transmitted in classic or FD + format. + This parameter can be a value of @ref FDCAN_format */ + + uint32_t TTSEN; /*!< Specifies the enable if transmit Time-Stamp in CiA 603. + This patameter can be a value of @ref Transmit_Time_Stamp_Enable */ + +} FDCAN_TxHeaderTypeDef; + +/** + * @brief FDCAN Rx header structure definition + */ +typedef struct +{ + uint32_t Identifier; /*!< Specifies the identifier. + This parameter must be a number between: + - 0 and 0x7FF, if IdType is FDCAN_STANDARD_ID + - 0 and 0x1FFFFFFF, if IdType is FDCAN_EXTENDED_ID */ + + uint32_t IdType; /*!< Specifies the identifier type of the received message. + This parameter can be a value of @ref FDCAN_id_type */ + + uint32_t RxFrameType; /*!< Specifies the the received message frame type. + This parameter can be a value of @ref FDCAN_frame_type */ + + uint32_t DataLength; /*!< Specifies the received frame length. + This parameter can be a value of @ref FDCAN_data_length_code */ + + uint32_t ErrorStateIndicator; /*!< Specifies the error state indicator. + This parameter can be a value of @ref FDCAN_error_state_indicator */ + + uint32_t BitRateSwitch; /*!< Specifies whether the Rx frame is received with or without bit + rate switching. + This parameter can be a value of @ref FDCAN_bit_rate_switching */ + + uint32_t FDFormat; /*!< Specifies whether the Rx frame is received in classic or FD + format. + This parameter can be a value of @ref FDCAN_format */ + + + uint32_t RxKOER; /*!< Specifies the kind of ERROR of receive frames. + This parameter can be a value of @ref FDCAN_Error_Kind */ + + uint32_t CycleTime; /*!< Specifies the time-stamp cycle time only in TTCAN mode. + This parameter must be a number between 0 and 0xFFFF */ + +} FDCAN_RxHeaderTypeDef; + +/** + * @brief FDCAN Error and Arbitration structure definition + */ +typedef struct +{ + uint32_t ArbitrationLostCapture; /*!< Specifies the bit position in the frame where the arbitration + has been lost. + This parameter must be a number between 0 and 31 */ + +} FDCAN_ArbitrationLostCaptureTypeDef; + +/** + * @brief FDCAN Error Counters structure definition + */ +typedef struct +{ + uint32_t TxErrorCnt; /*!< Specifies the Transmit Error Counter Value. + This parameter can be a number between 0 and 255 */ + + uint32_t RxErrorCnt; /*!< Specifies the Receive Error Counter Value. + This parameter can be a number between 0 and 255 */ + + uint32_t KOER; /*!< Specifies the kind of Error. + This parameter can be a value of @ref FDCAN_Error_Kind */ + +} FDCAN_ErrorCountersTypeDef; + +#define Empty ((uint32_t)0x00000000U) +#define Less_HalfFull ((uint32_t)0x00000001U) +#define More_HalfFull ((uint32_t)0x00000002U) +#define Full ((uint32_t)0x00000003U) + +#define CAN_INT_FLAG1_MASK ((uint32_t)0xFFEA00FFU) + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup FDCAN_operating_mode + * @{ + */ +#define FDCAN_MODE_NORMAL ((uint32_t)0x00000000U) /*!< Normal mode */ +#define FDCAN_MODE_LOM ((uint32_t)0x00004000U) /*!< Listen Only mode */ +#define FDCAN_MODE_INTERNAL_LOOPBACK ((uint32_t)0x00000020U) /*!< Internal LoopBack mode */ +#define FDCAN_MODE_EXTERNAL_LOOPBACK ((uint32_t)0x00000040U) /*!< External LoopBack mode */ +/** + * @} + */ + +/** @defgroup FDCAN_frame_format + * @{ + */ +#define FDCAN_FRAME_CLASSIC ((uint32_t)0x00000000U) /*!< Classic mode */ +#define FDCAN_FRAME_FD_NO_BRS ((uint32_t)0x00000001U) /*!< FD mode without BitRate Switching */ +#define FDCAN_FRAME_FD_BRS ((uint32_t)0x00000002U) /*!< FD mode with BitRate Switching */ +/** + * @} + */ + + +/** @defgroup TBUF_select + * @{ + */ +#define FDCAN_SELECT_PTB ((uint32_t)0x00000000U) /*!< Select PTB */ +#define FDCAN_SELECT_STB ((uint32_t)CAN_CMD_CTRL_TBSEL) /*!< Select STB */ +/** + * @} + */ + +/** @defgroup FDCAN_STBFifoPriority_Mode + * @{ + */ +#define FDCAN_STB_FIFO ((uint32_t)0x00000000U) /*!< FIFO mode for STB */ +#define FDCAN_STB_PRIORITY ((uint32_t)CAN_CMD_CTRL_TSMODE) /*!< Priority decision mode for STB */ +/** + * @} + */ + +/** @defgroup FDCAN_STBTransmitOneAll_Mode + * @{ + */ +#define FDCAN_STB_NO_TRANSMIT ((uint32_t)0x00000000U) /*!< No transmission for the STB */ +#define FDCAN_STB_NO_TRANSMIT_ONE ((uint32_t)CAN_CMD_CTRL_TSONE) /*!< Transmisson enable of one in the STB */ +#define FDCAN_STB_NO_TRANSMIT_ALL ((uint32_t)CAN_CMD_CTRL_TSALL) /*!< Transmisson enable of all messages in the STB */ +/** + * @} + */ + +/** @defgroup FDCAN_SACK + * @{ + */ +#define FDCAN_NO_SACK ((uint32_t)0x00000000U) /*!< No self-ACK */ +#define FDCAN_SACK ((uint32_t)CAN_CMD_CTRL_SACK) /*!< Self-ACK when LBME=1(External LoopBack mode) */ +/** + * @} + */ + +/** @defgroup FDCAN_ReceiveBufferOverflow_Mode + * @{ + */ +#define FDCAN_RECEIVE_OVERFLOW_OVERWRITTEN ((uint32_t)0x00000000U) /*!< The oldest message will be overwritten */ +#define FDCAN_RECEIVE_OVERFLOW_DISCARD ((uint32_t)CAN_CMD_CTRL_ROM) /*!< The new message will not be stored */ +#define IS_RECEIVE_BUFFER_OVERFLOW_MODE(ROM) (((ROM)==FDCAN_RECEIVE_OVERFLOW_OVERWRITTEN) || \ + ((ROM)==FDCAN_RECEIVE_OVERFLOW_DISCARD) ) + + +/** + * @} + */ + +/** @defgroup FDCAN_ReceiveBufferStoreAllFrames + * @{ + */ +#define FDCAN_RBUF_STORE_NORMAL_OPERATION ((uint32_t)0x00000000U) /*!< Receive buffer only store valid data frames */ +#define FDCAN_RBUF_STORE_ALL_DATA_FRAMES ((uint32_t)CAN_CMD_CTRL_RBALL) /*!< Receive buffer store correct data frames as well as data frame with error */ +/** + * @} + */ + + + +/** @defgroup Acceptance_Mask_IDE_Check_Enable + * @{ + */ +#define FDCAN_ACCEP_MASK_AIDE_DISABLE ((uint32_t)0x00000000U) /*!< Acceptance filter accepts frame both standard or extended */ +#define FDCAN_ACCEP_MASK_AIDE_ENABLE ((uint32_t)CAN_ACF_AIDEE) /*!< Acceptance filter accepts frame define by FilterAcceptanceMaskIDE */ +/** + * @} + */ + +/** @defgroup Acceptance_Mask_IDE_Type + * @{ + */ +#define FDCAN_ACCEP_MASK_IDE_STANDARD ((uint32_t)0x00000000U) /*!< Acceptance filter accepts only extended frames */ +#define FDCAN_ACCEP_MASK_IDE_EXTENDED ((uint32_t)CAN_ACF_AIDE) /*!< Acceptance filter accepts only standard frames */ +/** + * @} + */ + +/** @defgroup FDCAN_id_type + * @{ + */ +#define FDCAN_STANDARD_ID ((uint32_t)0x00000000U) /*!< Standard ID element */ +#define FDCAN_EXTENDED_ID ((uint32_t)0x00000080U) /*!< Extended ID element */ +#define IS_FDCAN_IDTYPE(TYPE) (((TYPE)==FDCAN_STANDARD_ID) | \ + ((TYPE)==FDCAN_EXTENDED_ID) ) + +/** + * @} + */ + +/** @defgroup FDCAN_frame_type + * @{ + */ +#define FDCAN_DATA_FRAME ((uint32_t)0x00000000U) /*!< Data frame */ +#define FDCAN_REMOTE_FRAME ((uint32_t)0x00000040U) /*!< Remote frame */ +#define IS_FDCAN_FRAME_TYPE(TYPE) (((TYPE)==FDCAN_DATA_FRAME) || \ + ((TYPE)==FDCAN_REMOTE_FRAME) ) +/** + * @} + */ + +/** @defgroup FDCAN_data_length_code + * @{ + */ +#define FDCAN_DLC_BYTES_0 ((uint32_t)0x00000000U) /*!< 0 bytes data field */ +#define FDCAN_DLC_BYTES_1 ((uint32_t)0x00000001U) /*!< 1 bytes data field */ +#define FDCAN_DLC_BYTES_2 ((uint32_t)0x00000002U) /*!< 2 bytes data field */ +#define FDCAN_DLC_BYTES_3 ((uint32_t)0x00000003U) /*!< 3 bytes data field */ +#define FDCAN_DLC_BYTES_4 ((uint32_t)0x00000004U) /*!< 4 bytes data field */ +#define FDCAN_DLC_BYTES_5 ((uint32_t)0x00000005U) /*!< 5 bytes data field */ +#define FDCAN_DLC_BYTES_6 ((uint32_t)0x00000006U) /*!< 6 bytes data field */ +#define FDCAN_DLC_BYTES_7 ((uint32_t)0x00000007U) /*!< 7 bytes data field */ +#define FDCAN_DLC_BYTES_8 ((uint32_t)0x00000008U) /*!< 8 bytes data field */ +#define FDCAN_DLC_BYTES_12 ((uint32_t)0x00000009U) /*!< 12 bytes data field */ +#define FDCAN_DLC_BYTES_16 ((uint32_t)0x0000000AU) /*!< 16 bytes data field */ +#define FDCAN_DLC_BYTES_20 ((uint32_t)0x0000000BU) /*!< 20 bytes data field */ +#define FDCAN_DLC_BYTES_24 ((uint32_t)0x0000000CU) /*!< 24 bytes data field */ +#define FDCAN_DLC_BYTES_32 ((uint32_t)0x0000000DU) /*!< 32 bytes data field */ +#define FDCAN_DLC_BYTES_48 ((uint32_t)0x0000000EU) /*!< 48 bytes data field */ +#define FDCAN_DLC_BYTES_64 ((uint32_t)0x0000000FU) /*!< 64 bytes data field */ +#define IS_FDCAN_DATA_LENGTH(LENGTH) ((LENGTH==FDCAN_DLC_BYTES_0) || (LENGTH == FDCAN_DLC_BYTES_1) || \ + (LENGTH==FDCAN_DLC_BYTES_2) || (LENGTH == FDCAN_DLC_BYTES_3) || \ + (LENGTH==FDCAN_DLC_BYTES_4) || (LENGTH == FDCAN_DLC_BYTES_5) || \ + (LENGTH==FDCAN_DLC_BYTES_6) || (LENGTH == FDCAN_DLC_BYTES_7) || \ + (LENGTH==FDCAN_DLC_BYTES_8) || (LENGTH == FDCAN_DLC_BYTES_12) || \ + (LENGTH==FDCAN_DLC_BYTES_16) || (LENGTH == FDCAN_DLC_BYTES_20) || \ + (LENGTH==FDCAN_DLC_BYTES_24) || (LENGTH == FDCAN_DLC_BYTES_32) || \ + (LENGTH==FDCAN_DLC_BYTES_48) || (LENGTH == FDCAN_DLC_BYTES_64)) +/** + * @} + */ + +/** @defgroup FDCAN_bit_rate_switching + * @{ + */ +#define FDCAN_BRS_OFF ((uint32_t)0x00000000U) /*!< FDCAN frames transmitted/received without bit rate switching */ +#define FDCAN_BRS_ON ((uint32_t)0x00000010U) /*!< FDCAN frames transmitted/received with bit rate switching */ +#define IS_FDCAN_BRS(BRS) ((BRS == FDCAN_BRS_OFF) || (BRS == FDCAN_BRS_ON)) +/** + * @} + */ + +/** @defgroup FDCAN_format + * @{ + */ +#define FDCAN_CLASSIC_CAN ((uint32_t)0x00000000U) /*!< Frame transmitted/received in Classic CAN format */ +#define FDCAN_FD_CAN ((uint32_t)0x00000020U) /*!< Frame transmitted/received in FDCAN format */ +#define IS_FDCAN_TYPE(TYPE) ((TYPE == FDCAN_CLASSIC_CAN) || (TYPE == FDCAN_FD_CAN)) +/** + * @} + */ + +/** @defgroup Transmit_Time_Stamp_Enable + * @{ + */ +#define FDCAN_TTS_DISABLE ((uint32_t)0x00000000U) /*!< No acquisition of a transmit time stamp for this frame */ +#define FDCAN_TTS_ENABLE ((uint32_t)0x80000000U) /*!< TTS update enabled */ +#define IS_FDCAN_TTS_STATE(STATE) ((STATE ==FDCAN_TTS_DISABLE) || (STATE ==FDCAN_TTS_ENABLE)) +/** + * @} + */ + +/** @defgroup FDCAN_error_state_indicator + * @{ + */ +#define FDCAN_ESI_ACTIVE ((uint32_t)0x00000000U) /*!< CAN node is error active */ +#define FDCAN_ESI_PASSIVE ((uint32_t)0x80000000U) /*!< CAN node is error passive */ +#define IS_FDCAN_ERROR_STATE_INDICATOR(STATE) ((STATE == FDCAN_ESI_ACTIVE) || (STATE == FDCAN_ESI_PASSIVE)) +/** + * @} + */ + +/** @defgroup FDCAN_Error_Kind + * @{ + */ +#define FDCAN_NO_ERROR ((uint32_t)0x00000000U) /*!< No error */ +#define FDCAN_BIT_ERROR ((uint32_t)0x00000001U) /*!< Bit error */ +#define FDCAN_FORM_ERROR ((uint32_t)0x00000002U) /*!< Form error */ +#define FDCAN_STUFF_ERROR ((uint32_t)0x00000003U) /*!< Stuff error */ +#define FDCAN_ACK_ERROR ((uint32_t)0x00000004U) /*!< Acknowledgement error */ +#define FDCAN_CRC_ERROR ((uint32_t)0x00000005U) /*!< CRC error */ +#define FDCAN_OTHER_ERROR ((uint32_t)0x00000006U) /*!< Other error */ +#define FDCAN_NOT_USED ((uint32_t)0x00000007U) /*!< Not used */ +/** + * @} + */ + +/** @defgroup Time_Trigger_Prescaler + * @{ + */ +#define FDCAN_TIME_TRIGGER_PRESCALER_1 ((uint32_t)0x00000000U) /*!< No prescaler */ +#define FDCAN_TIME_TRIGGER_PRESCALER_2 ((uint32_t)0x02000000U) /*!< Divide 2 */ +#define FDCAN_TIME_TRIGGER_PRESCALER_4 ((uint32_t)0x04000000U) /*!< Divide 4 */ +#define FDCAN_TIME_TRIGGER_PRESCALER_8 ((uint32_t)0x06000000U) /*!< Divide 8 */ +/** + * @} + */ + +/** @defgroup FDCAN_Trigger_Type + * @{ + */ +#define FDCAN_TTCAN_IMMEDIATE_TRIG ((uint32_t)0x00000000U) /*!< Immediate Trigger */ +#define FDCAN_TTCAN_TIME_TRIG ((uint32_t)0x00000100U) /*!< Time Trigger */ +#define FDCAN_TTCAN_SINGLE_SHOT_TRIG ((uint32_t)0x00000200U) /*!< Single Shot Transmit Trigger */ +#define FDCAN_TTCAN_TRANSMIT_START_TRIG ((uint32_t)0x00000300U) /*!< Transmit start Trigger */ +#define FDCAN_TTCAN_TRANSMIT_STOP_TRIG ((uint32_t)0x00000400U) /*!< Transmit stop Trigger */ +/** + * @} + */ + + + +/** @defgroup + * @{ + */ + +/** + * @} + */ + +/** @defgroup FDCAN_Interrupts + * @{ + */ +#define FDCAN_IT_RECEIVE CAN_INT_FLAG1_RIE /*!< Receive */ +#define FDCAN_IT_RBUF_OVERRUN CAN_INT_FLAG1_ROIE /*!< RBUF overrun */ +#define FDCAN_IT_RBUF_FULL CAN_INT_FLAG1_RFIE /*!< RBUF full */ +#define FDCAN_IT_RB_ALMOST_FULL CAN_INT_FLAG1_RAFIE /*!< RBUF almost full */ +#define FDCAN_IT_TRANSMISSION_PRIMARY CAN_INT_FLAG1_TPIE /*!< Transmission primary successfully */ +#define FDCAN_IT_TRANSMISSION_SECONDARY CAN_INT_FLAG1_TSIE /*!< Transmission secondary successfully */ +#define FDCAN_IT_ERROR CAN_INT_FLAG1_EIE /*!< Error */ +#define FDCAN_IT_ERROR_PASSIVE CAN_INT_FLAG1_EPIE /*!< Node is error passive */ +#define FDCAN_IT_ARBITRATION_LOST CAN_INT_FLAG1_ALIE /*!< Lost arbitration */ +#define FDCAN_IT_BUS_ERROR CAN_INT_FLAG1_BEIE /*!< Bus error */ +#define FDCAN_IT_TIME_TRIGGER CAN_INT_FLAG2_TTIE /*!< Time Trigger */ +#define FDCAN_IT_WATCH_TRIGGER CAN_INT_FLAG2_WTIE /*!< Watch Trigger */ + +/** @defgroup Interrupt_Masks Interrupt masks + * @{ + */ +#define FDCAN_IR_MASK ((uint32_t)0x902A00FEU) /*!< FDCAN interrupts mask */ + +#define FDCAN_TIMESTAMP_SOF ((uint32_t)0x00000000U) +#define FDCAN_TIMESTAMP_EOF ((uint32_t)0x00000200U) +#define IS_FDCAN_TIME_STAMP_LOCATION(LOC) (((LOC) == FDCAN_TIMESTAMP_SOF) || \ + ((LOC) == FDCAN_TIMESTAMP_EOF) ) +#define FDCAN_TIMESTAMP_DISABLE ((uint32_t)0x00000000U) +#define FDCAN_TIMESTAMP_ENABLE ((uint32_t)0x00000100U) + +#define FDCAN_TXDELAY_DISABLE ((uint32_t)0x00000000U) +#define FDCAN_TXDELAY_ENABLE ((uint32_t)0x00008000U) +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup FDCAN_Exported_Functions + * @{ + */ +/* Initialization and Configuration functions *********************************/ + +/** + * @} + */ + + + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup FDCAN_Private_Macros FDCAN Private Macros + * @{ + */ + +#define IS_FDCAN_ALL_INSTANCE(PERIPH) ((PERIPH == FDCAN1) || \ + (PERIPH == FDCAN2) || \ + (PERIPH == FDCAN3) || \ + (PERIPH == FDCAN4)) +#define IS_FDCAN_MODE(MODE) ((MODE == FDCAN_MODE_NORMAL ) || \ + (MODE == FDCAN_MODE_LOM ) || \ + (MODE == FDCAN_MODE_INTERNAL_LOOPBACK) || \ + (MODE == FDCAN_MODE_EXTERNAL_LOOPBACK)) +#define IS_FDCAN_FRAME_FORMAT(FRAME_FORMAT) ((FRAME_FORMAT == FDCAN_FRAME_CLASSIC ) || \ + (FRAME_FORMAT == FDCAN_FRAME_FD_NO_BRS) || \ + (FRAME_FORMAT == FDCAN_FRAME_FD_BRS )) +#define IS_FDCAN_BUF_SEL(TBUF_SEL) ((TBUF_SEL == FDCAN_SELECT_PTB)|| \ + (TBUF_SEL == FDCAN_SELECT_STB)) +#define IS_FDCAN_STB_FP_MODE(STB_FP_MODE) ((STB_FP_MODE == FDCAN_STB_FIFO ) || \ + (STB_FP_MODE == FDCAN_STB_PRIORITY)) +#define IS_FDCAN_STB_OA_MODE(STB_OA_MODE) ((STB_OA_MODE == FDCAN_STB_NO_TRANSMIT ) || \ + (STB_OA_MODE == FDCAN_STB_NO_TRANSMIT_ONE) || \ + (STB_OA_MODE == FDCAN_STB_NO_TRANSMIT_ALL)) +#define IS_FDCAN_TTCAN_TBUF_MODE(TTCAN_TBUF_MODE) ((TTCAN_TBUF_MODE == FDCAN_TTCAN_TRANSMIT_SEPARATE) || \ + (TTCAN_TBUF_MODE == FDCAN_TTCAN_TRANSMIT_FULL )) +#define IS_FDCAN_FDCANSACK(FDCANSACK) ((FDCANSACK == FDCAN_NO_SACK) || \ + (FDCANSACK == FDCAN_SACK )) +#define IS_FDCAN_RBUF_OVERFLOW_MODE(OVERFLOW_MODE) ((OVERFLOW_MODE == FDCAN_RECEIVE_OVERFLOW_OVERWRITTEN) || \ + (OVERFLOW_MODE == FDCAN_RECEIVE_OVERFLOW_DISCARD )) +#define IS_FDCAN_RBUF_STORE_ALL(STORE_ALL) ((STORE_ALL == FDCAN_RBUF_STORE_NORMAL_OPERATION) || \ + (STORE_ALL == FDCAN_RBUF_STORE_ALL_DATA_FRAMES )) +#define IS_FDCAN_RBUF_AF_LIMIT(AF_LIMIT) ((AF_LIMIT >= 0U) && (AF_LIMIT <= 6U)) +#define IS_FDCAN_PROG_ERROR_WARN_LIMIT(ERROR_WARN_LIMIT) ((ERROR_WARN_LIMIT >= 0U) && (ERROR_WARN_LIMIT <= 15U)) +#define IS_FDCAN_NOMINAL_PRESCALER(N_PRESCALER) ((N_PRESCALER >= 0U) && (N_PRESCALER <= 255U)) +#define IS_FDCAN_NOMINAL_SJW(N_SJW) ((N_SJW >= 0U) && (N_SJW <= 127U)) +#define IS_FDCAN_NOMANAL_SEG1(N_SEG1) ((N_SEG1 >= 0U) && (N_SEG1 <= 255U)) +#define IS_FDCAN_NOMANAL_SEG2(N_SEG2) ((N_SEG2 >= 0U) && (N_SEG2 <= 127U)) +#define IS_FDCAN_DATA_PRESCALER(D_PRESCALER) ((D_PRESCALER >= 0U) && (D_PRESCALER <= 255U)) +#define IS_FDCAN_DATA_SJW(D_SJW) ((D_SJW >= 0U) && (D_SJW <= 15U)) +#define IS_FDCAN_DATA_SEG1(D_SEG1) ((D_SEG1 >= 0U) && (D_SEG1 <= 31U)) +#define IS_FDCAN_DATA_SEG2(D_SEG2) ((D_SEG2 >= 0U) && (D_SEG2 <= 15U)) +#define IS_FDCAN_TTCAN_PRESCALER(TTCAN_PRESCALER) ((TTCAN_PRESCALER == FDCAN_TIME_TRIGGER_PRESCALER_1) || \ + (TTCAN_PRESCALER == FDCAN_TIME_TRIGGER_PRESCALER_2) || \ + (TTCAN_PRESCALER == FDCAN_TIME_TRIGGER_PRESCALER_4) || \ + (TTCAN_PRESCALER == FDCAN_TIME_TRIGGER_PRESCALER_8)) +#define IS_FDCAN_TTCAN_REF_IDE(REF_IDE) ((REF_IDE == FDCAN_STANDARD_ID) || \ + (REF_IDE == FDCAN_EXTENDED_ID)) +#define IS_FDCAN_ID(ID) ((ID >= 0x0U) && (ID <= 0x1FFFFFFFU)) +#define IS_FDCAN_TTCAN_REF_ID(REF_ID) ((REF_ID >= 0x0U) && (REF_ID <= 0x1FFFFFFFU)) +#define IS_FDCAN_TTCAN_TBUF_POINTER(TTCAN_TBUF_POINTER) ((TTCAN_TBUF_POINTER >= 0U) && (TTCAN_TBUF_POINTER <= 3U)) +#define IS_FDCAN_TTCAN_TYPE(TTCAN_TYPE) ((TTCAN_TYPE == FDCAN_TTCAN_IMMEDIATE_TRIG ) || \ + (TTCAN_TYPE == FDCAN_TTCAN_TIME_TRIG ) || \ + (TTCAN_TYPE == FDCAN_TTCAN_SINGLE_SHOT_TRIG ) || \ + (TTCAN_TYPE == FDCAN_TTCAN_TRANSMIT_START_TRIG) || \ + (TTCAN_TYPE == FDCAN_TTCAN_TRANSMIT_STOP_TRIG )) +#define IS_FDCAN_TTCAN_TR_EN_WIN(TTCAN_TR_EN_WIN) ((TTCAN_TR_EN_WIN >= 0U) && (TTCAN_TR_EN_WIN <= 15U)) +#define IS_FDCAN_TTCAN_TRIGGER_TIME(TTCAN_TRIGGER_TIME) ((TTCAN_TRIGGER_TIME >= 0U) && (TTCAN_TRIGGER_TIME <= 0XFFFFU)) +#define IS_FDCAN_TTCAN_WATCH_TIME(TTCAN_WATCH_TIME) ((TTCAN_WATCH_TIME >= 0U) && (TTCAN_WATCH_TIME <= 0XFFFFU)) + +#define IS_FDCAN_FILTER_ADDR(ADDR) ((ADDR >= 0U) && (ADDR <= 15U)) +#define IS_FDCAN_FILTER_ACODE(ACODE) ((ACODE >= 0U) && (ACODE <= 0x1FFFFFFFU)) +#define IS_FDCAN_FILTER_AMASK(AMASK) ((AMASK >= 0U) && (AMASK <= 0x1FFFFFFFU)) +#define IS_FDCAN_FILTER_AMASK_IDEE(AMASK_IDEE) ((AMASK_IDEE == FDCAN_ACCEP_MASK_AIDE_DISABLE) || \ + (AMASK_IDEE == FDCAN_ACCEP_MASK_AIDE_ENABLE )) +#define IS_FDCAN_FILTER_AMASK_IDE(AMASK_IDE) ((AMASK_IDE == FDCAN_ACCEP_MASK_IDE_STANDARD) || \ + (AMASK_IDE == FDCAN_ACCEP_MASK_IDE_EXTENDED)) + + +#define IS_FDCAN_IT(IT) (((IT) & ~(FDCAN_IR_MASK)) == 0U) + +#define IS_FDCAN_TXDELAY_VALUE(VALUE) ((VALUE >= 0U) && (VALUE <= 0x7FU)) + +#define IS_FDCAN_ARBLOSTCAP_VALUE(VALUE) ((VALUE >= 0U) && (VALUE <= 0x1FU)) + +#define FDCAN_FLAG_ROV FDCAN_ISR_ROV +#define FDCAN_FLAG_RACTIVE FDCAN_ISR_RACTIVE +#define FDCAN_FLAG_TACTIVE FDCAN_ISR_TACTIVE +#define FDCAN_FLAG_EPIF CAN_INT_FLAG1_EPIF +#define FDCAN_FLAG_ALIF CAN_INT_FLAG1_ALIF +#define FDCAN_FLAG_BEIF CAN_INT_FLAG1_BEIF +#define FDCAN_FLAG_RIF CAN_INT_FLAG1_RIF +#define FDCAN_FLAG_ROIF CAN_INT_FLAG1_ROIF +#define FDCAN_FLAG_RFIF CAN_INT_FLAG1_RFIF +#define FDCAN_FLAG_RAFIF CAN_INT_FLAG1_RAFIF +#define FDCAN_FLAG_TPIF CAN_INT_FLAG1_TPIF +#define FDCAN_FLAG_TSIF CAN_INT_FLAG1_TSIF +#define FDCAN_FLAG_EIF CAN_INT_FLAG1_EIF +#define FDCAN_FLAG_AIF CAN_INT_FLAG1_AIF +#define FDCAN_FLAG_WTIF CAN_INT_FLAG2_WTIF +#define FDCAN_FLAG_TEIF CAN_INT_FLAG2_TEIF +#define FDCAN_FLAG_TTIF CAN_INT_FLAG2_TTIF +#define FDCAN_FLAG_RTIF_ALL ((uint32_t)0x0000FF00U) +#define IS_FDCAN_FLAG(FLAG) (((FLAG) == FDCAN_FLAG_RACTIVE) || ((FLAG) == FDCAN_FLAG_TACTIVE) || \ + ((FLAG) == FDCAN_FLAG_ROV) || ((FLAG) == FDCAN_FLAG_EPIF) || \ + ((FLAG) == FDCAN_FLAG_ALIF) || ((FLAG) == FDCAN_FLAG_BEIF) || \ + ((FLAG) == FDCAN_FLAG_RIF) || ((FLAG) == FDCAN_FLAG_ROIF) || \ + ((FLAG) == FDCAN_FLAG_RFIF) || ((FLAG) == FDCAN_FLAG_RAFIF) || \ + ((FLAG) == FDCAN_FLAG_TPIF) || ((FLAG) == FDCAN_FLAG_TSIF) || \ + ((FLAG) == FDCAN_FLAG_EIF) || ((FLAG) == FDCAN_FLAG_AIF) || \ + ((FLAG) == FDCAN_FLAG_WTIF) || ((FLAG) == FDCAN_FLAG_TEIF) || \ + ((FLAG) == FDCAN_FLAG_TTIF) || ((FLAG) == FDCAN_FLAG_RTIF_ALL)) + +#define FDCAN_FLAG_REG_CMD ((uint32_t)0x00000000U) +#define FDCAN_FLAG_REG_FLAG1 ((uint32_t)0x00000001U) +#define FDCAN_FLAG_REG_FLAG2 ((uint32_t)0x00000002U) +#define IS_FDCAN_FLAG_REG(REG) (((REG) == FDCAN_FLAG_REG_CMD) || ((REG) == FDCAN_FLAG_REG_FLAG1) || \ + ((REG) == FDCAN_FLAG_REG_FLAG2)) + +#define FDCAN_INT_REG_FLAG1 ((uint32_t)0x00000001U) +#define FDCAN_INT_REG_FLAG2 ((uint32_t)0x00000002U) +#define IS_FDCAN_INT_REG(REG) (((REG) == FDCAN_INT_REG_FLAG1) || ((REG) == FDCAN_INT_REG_FLAG2)) + +#define FDCAN_TRANS_BUFFER_STAT ((uint32_t)0x00000000U) +#define FDCAN_RECEIVE_BUFFER_STAT ((uint32_t)0x00000001U) +#define FDCAN_TBUF_FULL FDCAN_ISR_TSSTAT +#define FDCAN_RBUF_FULL FDCAN_ISR_RSTAT + +#define FDCAN_CAN_FILTER0 CAN_FILTER_CTRL_AE_0 +#define FDCAN_CAN_FILTER1 CAN_FILTER_CTRL_AE_1 +#define FDCAN_CAN_FILTER2 CAN_FILTER_CTRL_AE_2 +#define FDCAN_CAN_FILTER3 CAN_FILTER_CTRL_AE_3 +#define FDCAN_CAN_FILTER4 CAN_FILTER_CTRL_AE_4 +#define FDCAN_CAN_FILTER5 CAN_FILTER_CTRL_AE_5 +#define FDCAN_CAN_FILTER6 CAN_FILTER_CTRL_AE_6 +#define FDCAN_CAN_FILTER7 CAN_FILTER_CTRL_AE_7 +#define FDCAN_CAN_FILTER8 CAN_FILTER_CTRL_AE_8 +#define FDCAN_CAN_FILTER9 CAN_FILTER_CTRL_AE_9 +#define FDCAN_CAN_FILTER10 CAN_FILTER_CTRL_AE_10 +#define FDCAN_CAN_FILTER11 CAN_FILTER_CTRL_AE_11 +#define FDCAN_CAN_FILTER12 CAN_FILTER_CTRL_AE_12 +#define FDCAN_CAN_FILTER13 CAN_FILTER_CTRL_AE_13 +#define FDCAN_CAN_FILTER14 CAN_FILTER_CTRL_AE_14 +#define FDCAN_CAN_FILTER15 CAN_FILTER_CTRL_AE_15 +#define FDCAN_CAN_FILTER_ALL ((uint32_t)0xFFFF0000U) +#define IS_FDCAN_FILTER_ACE(ACE) (((ACE) == FDCAN_CAN_FILTER0) || ((ACE) == FDCAN_CAN_FILTER1) || \ + ((ACE) == FDCAN_CAN_FILTER2) || ((ACE) == FDCAN_CAN_FILTER3) || \ + ((ACE) == FDCAN_CAN_FILTER4) || ((ACE) == FDCAN_CAN_FILTER5) || \ + ((ACE) == FDCAN_CAN_FILTER6) || ((ACE) == FDCAN_CAN_FILTER7) || \ + ((ACE) == FDCAN_CAN_FILTER8) || ((ACE) == FDCAN_CAN_FILTER9) || \ + ((ACE) == FDCAN_CAN_FILTER10) || ((ACE) == FDCAN_CAN_FILTER11) || \ + ((ACE) == FDCAN_CAN_FILTER12) || ((ACE) == FDCAN_CAN_FILTER13) || \ + ((ACE) == FDCAN_CAN_FILTER14) || ((ACE) == FDCAN_CAN_FILTER15) || \ + ((ACE) == FDCAN_CAN_FILTER_ALL)) + +/** @defgroup FDCAN_REF_MSG_id_type + * @{ + */ +#define FDCAN_REF_MSG_STD ((uint32_t)0x00000000U) /*!< Standard ID element */ +#define FDCAN_REF_MSG_EXT ((uint32_t)0x80000000U) /*!< Extended ID element */ +#define IS_FDCAN_REF_MSG_IDTYPE(TYPE) (((TYPE)==FDCAN_REF_MSG_STD) | \ + ((TYPE)==FDCAN_REF_MSG_EXT) ) + +#define IS_FDCAN_REF_MSG_ID_VALUE(VALUE) ((VALUE >= 0U) && (VALUE <= 0x1FFFFFFFU)) + +#define IS_FDCAN_TBPTR_VALUE(VALUE) ((VALUE >= 0U) && (VALUE <= 0x3FU)) +#define IS_FDCAN_TTPTR_VALUE(VALUE) ((VALUE >= 0U) && (VALUE <= 0x3FU)) + +#define FDCAN_TIMEPOS_SOF ((uint32_t)0x00000000U) /*!< TIME STAMP POSITION IN SOF */ +#define FDCAN_TIMEPOS_EOF ((uint32_t)0x00000200U) /*!< TIME STAMP POSITION IN EOF */ +#define IS_FDCAN_TIME_POS(POS) (((POS)==FDCAN_TIMEPOS_SOF) | \ + ((POS)==FDCAN_TIMEPOS_EOF) ) + + + + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------------- */ +/** @addtogroup FDCAN_Exported_Functions + * @{ + */ + +/** @addtogroup FDCAN_Exported_Functions_Group1 + * @{ + */ +/* Initialization and de-initialization functions *************************************/ +void FDCAN_Init(FDCAN_TypeDef* fdcan, FDCAN_InitTypeDef* fdcanInit);/*Function used initial fdcan*/ +void FDCAN_DeInit(FDCAN_TypeDef* fdcan);/*Function used de-initial fdcan*/ +void FDCAN_Reset(FDCAN_TypeDef* fdcan, FunctionalState NewState);/*Function used set fdcan in reset*/ +void FDCAN_ConfigMode(FDCAN_TypeDef* fdcan, uint32_t Mode);/*Function used config fdcan mode*/ +void FDCAN_SetRxBufAFWL(FDCAN_TypeDef* fdcan, uint32_t ReceiveBufferAlmostFullWarningLimit);/*Function used set fdcan AFWL*/ +void FDCAN_SetEWL(FDCAN_TypeDef* fdcan, uint32_t ProgrammableErrorWarningLimit);/*Function used set fdcan EWL*/ +void FDCAN_TransBufferSelect(FDCAN_TypeDef* fdcan, uint32_t TransBufferSelect);/*Function used select trans buffer*/ +void FDCAN_TTCANTransBufferMode(FDCAN_TypeDef* fdcan, FunctionalState NewState);/*Function used select TTCAN Trans buffer Mode*/ +void FDCAN_PTBTrans(FDCAN_TypeDef* fdcan, FunctionalState NewState);/*Function used start ptb trans*/ +void FDCAN_PTBAbort(FDCAN_TypeDef* fdcan, FunctionalState NewState);/*Function used abort ptb trans*/ +void FDCAN_TransSTBMode(FDCAN_TypeDef* fdcan, uint32_t STBFifoPriorityMode);/*Function used config tsmode*/ +void FDCAN_STBTrans(FDCAN_TypeDef* fdcan, uint32_t STBTransmitOneAllMode, FunctionalState NewState);/*Function used start stb trans*/ +void FDCAN_STBAbort(FDCAN_TypeDef* fdcan, FunctionalState NewState);/*Function used abort stb trans*/ +uint8_t FDCAN_GetArbLostPosition(FDCAN_TypeDef* fdcan);/* Function use get arbitration lost position */ +uint8_t FDCAN_GetKindOfError(FDCAN_TypeDef* fdcan);/* Function use get Kind Of Error */ +void FDCAN_RxBufRelease(FDCAN_TypeDef* fdcan, FunctionalState NewState);/*Function used Release RxBuffer*/ +void FDCAN_StandbyMode(FDCAN_TypeDef* fdcan, FunctionalState NewState);/*Function used enable can standby*/ +void FDCAN_RbufOverFlowMode(FDCAN_TypeDef* fdcan, uint32_t FDCAN_ReceiveBufferOverflow_Mode);/*Function used config ROM*/ + + + +/** + * @} + */ + +/** @addtogroup FDCAN_Exported_Functions_Group2 + * @{ + */ +/* Configuration functions *************************************/ +void FDCAN_ConfigFilter(FDCAN_TypeDef* fdcan, FDCAN_FilterTypeDef* sFilterConfig);/*Function used config filter*/ +void FDCAN_EnableFilter(FDCAN_TypeDef* fdcan, uint32_t FDCAN_ACE, FunctionalState NewState);/*Function used enable or disable filter*/ +void FDCAN_ConfigRxFifoOverwrite(FDCAN_TypeDef* fdcan, uint32_t FdcanRbOverMode);/*Function used config Receive Buffer write mode while full*/ +void FDCAN_ConfigTimestampLocation(FDCAN_TypeDef* fdcan, uint32_t FdcanTimeStampLocation);/*Function used config timestamp Location*/ +void FDCAN_EnableTimestampCounter(FDCAN_TypeDef* fdcan, FunctionalState NewState);/*Function used enable Fdcan timestamp*/ +void FDCAN_ConfigTxDelayCompensation(FDCAN_TypeDef* fdcan, uint32_t FdcanTxDelayValue);/*Function used config TxDelay value */ +void FDCAN_EnableTxDelayCompensation(FDCAN_TypeDef* fdcan, FunctionalState NewState);/*Function used enable Fdcan TxDelay */ +void FDCAN_EnableISOMode(FDCAN_TypeDef* fdcan);/* Function used select ISO_CAN mode */ +void FDCAN_DisableISOMode(FDCAN_TypeDef* fdcan);/* Function used select BoShi CAN_FD mode */ +/** + * @} + */ + +/** @addtogroup FDCAN_Exported_Functions_Group3 + * @{ + */ +/* Configuration TxBuffer And Get RxBuffer *************************************/ +void FDCAN_ConfigTxBuffer(FDCAN_TypeDef* fdcan, FDCAN_TxHeaderTypeDef* TxHeader, uint8_t message_data[16][4]);/* Function used config TxBuffer */ +void FDCAN_GetRxBuffer(FDCAN_TypeDef* fdcan, FDCAN_RxHeaderTypeDef* RxHeader, uint8_t message_data[16][4]);/* Function used get RxBuffer */ +void FDCAN_GetArbLostCap(FDCAN_TypeDef* fdcan, FDCAN_ArbitrationLostCaptureTypeDef* ArbLostCap);/* Function used get ALC */ +void FDCAN_GetErrorCnt(FDCAN_TypeDef* fdcan, FDCAN_ErrorCountersTypeDef* ErrorCnt);/* Function used get TECNT, RECNT and KOER */ +void FDCAN_ConfigTsnext(FDCAN_TypeDef* fdcan);/* Function used set tsnext=1 and wait auto clear by hardware */ +void FDCAN_ConfigInitialOffset(FDCAN_TypeDef* fdcan);/* Function used set initial offset value */ +/** + * @} + */ + +/** @addtogroup FDCAN_Exported_Functions_Group4 + * @{ + */ +/* Interrupts management *************************************/ +void FDCAN_ActivateNotification(FDCAN_TypeDef* fdcan, uint32_t FDCAN_INT_REG, uint32_t ActiveITs);/* Function used enable interrupt */ +void FDCAN_DeactivateNotification(FDCAN_TypeDef* fdcan, uint32_t FDCAN_INT_REG, uint32_t InactiveITs);/* Function used disable interrupt */ +FlagStatus FDCAN_GetFlagStatus(FDCAN_TypeDef* fdcan, uint32_t FDCAN_FLAG_REG, uint32_t FDCAN_FLAG);/* Function used get flag */ +void FDCAN_ClearInterruptFlag(FDCAN_TypeDef* fdcan, uint32_t FDCAN_FLAG_REG, uint32_t FDCAN_FLAG);/* Function used clear interrupt flag */ +int FDCAN_GetFifoStatus(FDCAN_TypeDef* fdcan, uint32_t FDCAN_BUF_TYPE);/* Function used get tbuf and rbuf status */ +/** + * @} + */ + +/** @addtogroup FDCAN_Exported_Functions_Group5 + * @{ + */ +/* TTCAN management *************************************/ +void FDCAN_RefMessageSet(FDCAN_TypeDef* fdcan, uint32_t FDCAN_REF_MSG_IDE, uint32_t FDCAN_REF_MSG_ID);/* Function used config reference message */ +void FDCAN_TbufSoltPoint(FDCAN_TypeDef* fdcan, uint32_t FDCAN_TBPTR);/* Function used config TBPTR */ +void FDCAN_TransmitSoltPoint(FDCAN_TypeDef* fdcan, uint32_t FDCAN_TTPTR);/* Function used config TTPTR */ +void FDCAN_SetTbufSoltEmpty(FDCAN_TypeDef* fdcan, FunctionalState NewState);/* Function used config TBPTR choose's solt empty*/ +void FDCAN_SetTbufSoltFull(FDCAN_TypeDef* fdcan, FunctionalState NewState);/* Function used config TBPTR choose's solt full*/ +void FDCAN_TimeTrigEnable(FDCAN_TypeDef* fdcan, FunctionalState NewState);/* Function used enbale tten*/ +void FDCAN_TimeStampPosition(FDCAN_TypeDef* fdcan, uint32_t FDCAN_TIMEPOS);/* Function used set timepos*/ +void FDCAN_TimeStampEnable(FDCAN_TypeDef* fdcan, FunctionalState NewState);/* Function used enbale timepos*/ +void FDCAN_GetCanTransmisionTs(FDCAN_TypeDef* fdcan, uint32_t can_transmission_ts[2]);/* Function used get transmision ts */ + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif /*__FT32F4XX_FDCAN_H */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ + diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_flash.h b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_flash.h new file mode 100644 index 00000000000..e9683459ada --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_flash.h @@ -0,0 +1,371 @@ +/** + ****************************************************************************** + * @file ft32f4xx_flash.h + * @author FMD AE + * @brief This file contains all the functions prototypes for the FLASH + * firmware library. + * @version V1.0.0 + * @data 2025-03-13 + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __FT32F4XX_FLASH_H +#define __FT32F4XX_FLASH_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx.h" + + +#define FLASH_KEY1 0x45670123 +#define FLASH_KEY2 0xCDEF89AB + +#define FLASH_OPTKEY1 0x08192A3B +#define FLASH_OPTKEY2 0x4C5D6E7F + +#define HW32_REG(ADDRESS) (*((volatile unsigned long *)(ADDRESS))) +#define HW16_REG(ADDRESS) (*((volatile unsigned short *)(ADDRESS))) +#define HW8_REG(ADDRESS) (*((volatile unsigned char *)(ADDRESS))) +/** @addtogroup FLASH + * @{ + */ +/* Exported types ------------------------------------------------------------*/ + +/** + * @brief FLASH Status + */ +typedef enum +{ + FLASH_BUSY = 1, + FLASH_ERROR_WRP, //write portect error + FLASH_ERROR_PROGRAM, //program error + FLASH_ERROR_PGSERR, //program sequence error + FLASH_COMPLETE, //FLASH idle status + FLASH_TIMEOUT +} FLASH_Status; + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup FLASH_Exported_Constants + * @{ + */ + +/** @defgroup FLASH_Latency + * @{ + */ +#define FLASH_Latency_0 ((uint32_t)0x00000000) /*!< FLASH Zero Latency cycle */ +#define FLASH_Latency_1 ((uint32_t)0x00000001) /*!< FLASH One Latency cycle */ +#define FLASH_Latency_2 ((uint32_t)0x00000002) +#define FLASH_Latency_3 ((uint32_t)0x00000003) +#define FLASH_Latency_4 ((uint32_t)0x00000004) +#define FLASH_Latency_5 ((uint32_t)0x00000005) +#define FLASH_Latency_6 ((uint32_t)0x00000006) +#define FLASH_Latency_7 ((uint32_t)0x00000007)//max latency value +/* Other latency value (8-15) not be used*/ +#define FLASH_Latency_8 ((uint32_t)0x00000008) +#define FLASH_Latency_9 ((uint32_t)0x00000009) +#define FLASH_Latency_10 ((uint32_t)0x0000000a) +#define FLASH_Latency_11 ((uint32_t)0x0000000b) +#define FLASH_Latency_12 ((uint32_t)0x0000000c) +#define FLASH_Latency_13 ((uint32_t)0x0000000d) +#define FLASH_Latency_14 ((uint32_t)0x0000000e) +#define FLASH_Latency_15 ((uint32_t)0x0000000f) + +#define IS_FLASH_LATENCY(LATENCY) ( \ + ((LATENCY) == FLASH_Latency_0) || \ + ((LATENCY) == FLASH_Latency_1) || \ + ((LATENCY) == FLASH_Latency_2 ) || \ + ((LATENCY) == FLASH_Latency_3 ) || \ + ((LATENCY) == FLASH_Latency_4 ) || \ + ((LATENCY) == FLASH_Latency_5 ) || \ + ((LATENCY) == FLASH_Latency_6 ) || \ + ((LATENCY) == FLASH_Latency_7 ) || \ + ((LATENCY) == FLASH_Latency_8 ) || \ + ((LATENCY) == FLASH_Latency_9 ) || \ + ((LATENCY) == FLASH_Latency_10) || \ + ((LATENCY) == FLASH_Latency_11) || \ + ((LATENCY) == FLASH_Latency_12) || \ + ((LATENCY) == FLASH_Latency_13) || \ + ((LATENCY) == FLASH_Latency_14) || \ + ((LATENCY) == FLASH_Latency_15)) +/** + * @} + */ + +/** @defgroup FLASH_Interrupts + * @{ + */ +#define FLASH_IT_EOP FLASH_WRC_EOPIE /*!< End of programming interrupt source */ +#define FLASH_IT_ERR FLASH_WRC_ERRIE /*!< Error interrupt source */ +//#define IS_FLASH_IT(IT) ((((IT) & (uint32_t)0xFFF3FFFF) == 0x00000000) && (((IT) != 0x00000000))) +#define IS_FLASH_IT(IT) (((IT) == FLASH_IT_EOP) ||\ + ((IT) == FLASH_IT_ERR)) + +/** @defgroup FLASH_FR clear bit + * @{ + */ +#define FLASH_FR_CLEAR ((uint32_t) 0x0000003F) + +/** @defgroup FLASH_Address + * @{ + */ +//#if defined(FT32F4xx) /*512K devices */ +#define IS_FLASH_PROGRAM_ADDRESS(ADDRESS) (((ADDRESS) >= 0x08000000) && ((ADDRESS) <= 0x0807FFFF)) + +/** @defgroup FLASH_PAGE_number + * @{ + */ +//#if defined(FT32F4xx) /*1023 page */ +#define IS_FLASH_ERASE_PAGE_NUM(PAGE_NUM) (((PAGE_NUM) >= 0x00000000) && ((PAGE_NUM) <= 0x000003FF)) + +/** @defgroup FLASH_Option_Bytes_Write_Protection + * @{ + */ +#define ERASE_SIZE_0 FLASH_WRC_ESIZE//((uint32_t)0x00000000) /* Erase size:512B */ +#define ERASE_SIZE_1 FLASH_WRC_ESIZE_0//((uint32_t)0x00000010) /* Erase size:2KB */ +#define ERASE_SIZE_2 FLASH_WRC_ESIZE_1//((uint32_t)0x00000020) /* Erase size:16KB */ +#define IS_ERASE_SIZE(SIZE) (((SIZE) == ERASE_SIZE_0 ) ||\ + ((SIZE) == ERASE_SIZE_1 ) || \ + ((SIZE) == ERASE_SIZE_2 )) + + +/** @defgroup FLASH_Option_Bytes_Write_Protection + * @{ + */ +#define WRP_PAGE0_31 ((uint32_t)0xfffffffe) /* Write protection of page 0_31 */ +#define WRP_PAGE32_63 ((uint32_t)0xfffffffd) /* Write protection of page 32_63 */ +#define WRP_PAGE64_95 ((uint32_t)0xfffffffb) /* Write protection of page 64_95 */ +#define WRP_PAGE96_127 ((uint32_t)0xfffffff7) /* Write protection of page 96_127 */ +#define WRP_PAGE128_159 ((uint32_t)0xffffffef) /* Write protection of page 128_159 */ +#define WRP_PAGE160_191 ((uint32_t)0xffffffdf) /* Write protection of page 160_191 */ +#define WRP_PAGE192_223 ((uint32_t)0xffffffbf) /* Write protection of page 192_223 */ +#define WRP_PAGE224_255 ((uint32_t)0xffffff7f) /* Write protection of page 224_255 */ +#define WRP_PAGE256_287 ((uint32_t)0xfffffeff) /* Write protection of page 256_287 */ +#define WRP_PAGE288_319 ((uint32_t)0xfffffdff) /* Write protection of page 288_319 */ +#define WRP_PAGE320_351 ((uint32_t)0xfffffbff) /* Write protection of page 320_351 */ +#define WRP_PAGE352_383 ((uint32_t)0xfffff7ff) /* Write protection of page 352_383 */ +#define WRP_PAGE384_415 ((uint32_t)0xffffefff) /* Write protection of page 384_415 */ +#define WRP_PAGE416_447 ((uint32_t)0xffffdfff) /* Write protection of page 416_447 */ +#define WRP_PAGE448_479 ((uint32_t)0xffffbfff) /* Write protection of page 448_479 */ +#define WRP_PAGE480_511 ((uint32_t)0xffff7fff) /* Write protection of page 480_511 */ +#define WRP_PAGE512_543 ((uint32_t)0xfffeffff) /* Write protection of page 512_543 */ +#define WRP_PAGE544_575 ((uint32_t)0xfffdffff) /* Write protection of page 544_575 */ +#define WRP_PAGE576_607 ((uint32_t)0xfffbffff) /* Write protection of page 576_607 */ +#define WRP_PAGE608_639 ((uint32_t)0xfff7ffff) /* Write protection of page 608_639 */ +#define WRP_PAGE640_671 ((uint32_t)0xffefffff) /* Write protection of page 640_671 */ +#define WRP_PAGE672_703 ((uint32_t)0xffdfffff) /* Write protection of page 672_703 */ +#define WRP_PAGE704_735 ((uint32_t)0xffbfffff) /* Write protection of page 704_735 */ +#define WRP_PAGE736_767 ((uint32_t)0xff7fffff) /* Write protection of page 736_767 */ +#define WRP_PAGE768_799 ((uint32_t)0xfeffffff) /* Write protection of page 768_799 */ +#define WRP_PAGE800_831 ((uint32_t)0xfdffffff) /* Write protection of page 800_831 */ +#define WRP_PAGE832_863 ((uint32_t)0xfbffffff) /* Write protection of page 832_863 */ +#define WRP_PAGE864_895 ((uint32_t)0xf7ffffff) /* Write protection of page 864_895 */ +#define WRP_PAGE896_927 ((uint32_t)0xefffffff) /* Write protection of page 896_927 */ +#define WRP_PAGE928_959 ((uint32_t)0xdfffffff) /* Write protection of page 928_959 */ +#define WRP_PAGE960_991 ((uint32_t)0xbfffffff) /* Write protection of page 960_991 */ +#define WRP_PAGE992_1023 ((uint32_t)0x7fffffff) /* Write protection of page 992_1023*/ + +#define WRP_ALLPAGES ((uint32_t)0x00000000) /* Write protection of page 0_1023*/ + +#define IS_WRPR_WRP(PAGE) (((PAGE) == WRP_PAGE0_31 ) ||\ + ((PAGE) ==WRP_PAGE32_63 ) || \ + ((PAGE) ==WRP_PAGE64_95 ) || \ + ((PAGE) ==WRP_PAGE96_127 ) || \ + ((PAGE) ==WRP_PAGE128_159 ) || \ + ((PAGE) ==WRP_PAGE160_191 ) || \ + ((PAGE) ==WRP_PAGE192_223 ) || \ + ((PAGE) ==WRP_PAGE224_255 ) || \ + ((PAGE) ==WRP_PAGE256_287 ) || \ + ((PAGE) ==WRP_PAGE288_319 ) || \ + ((PAGE) ==WRP_PAGE320_351 ) || \ + ((PAGE) ==WRP_PAGE352_383 ) || \ + ((PAGE) ==WRP_PAGE384_415 ) || \ + ((PAGE) ==WRP_PAGE416_447 ) || \ + ((PAGE) ==WRP_PAGE448_479 ) || \ + ((PAGE) ==WRP_PAGE480_511 ) || \ + ((PAGE) ==WRP_PAGE512_543 ) || \ + ((PAGE) ==WRP_PAGE544_575 ) || \ + ((PAGE) ==WRP_PAGE576_607 ) || \ + ((PAGE) ==WRP_PAGE608_639 ) || \ + ((PAGE) ==WRP_PAGE640_671 ) || \ + ((PAGE) ==WRP_PAGE672_703 ) || \ + ((PAGE) ==WRP_PAGE704_735 ) || \ + ((PAGE) ==WRP_PAGE736_767 ) || \ + ((PAGE) ==WRP_PAGE768_799 ) || \ + ((PAGE) ==WRP_PAGE800_831 ) || \ + ((PAGE) ==WRP_PAGE832_863 ) || \ + ((PAGE) ==WRP_PAGE864_895 ) || \ + ((PAGE) ==WRP_PAGE896_927 ) || \ + ((PAGE) ==WRP_PAGE928_959 ) || \ + ((PAGE) ==WRP_PAGE960_991 ) || \ + ((PAGE) ==WRP_PAGE992_1023 ) || \ + ((PAGE) ==WRP_ALLPAGES )) + +/** @defgroup FLASH_Option_Bytes_Read_Protection + * @{ + */ + +/** + * @brief FLASH_Read Protection Level + */ +#define OPBC_RDP_Level_0 ((uint8_t)0xaa) +#define OPBC_RDP_Level_1 ((uint8_t)0xbb) //except "AA" or "CC" +/*!!! Be CAREFUL to USE OPBC_RDP_Level_2!!!*/ +#define OPBC_RDP_Level_2 ((uint8_t)0xcc) //Warning: When enabling read protection level 2 +//it's no more possible to go back to level 1 or 0 +#define IS_OPBC_RDP(LEVEL) (((LEVEL) == OPBC_RDP_Level_0)|| \ + ((LEVEL) == OPBC_RDP_Level_1)|| \ + ((LEVEL) == OPBC_RDP_Level_2)) +/** + * @} + */ +/** @defgroup FLASH_Option_Bytes_IWatchdog + * @{ + */ +#define OPBC_IWDG_SW ((uint8_t)0x20) /*!< Software IWDG selected */ +#define OPBC_IWDG_HW ((uint8_t)0x00) /*!< Hardware IWDG selected */ +#define IS_OPBC_IWDG_SOURCE(SOURCE) (((SOURCE) == OPBC_IWDG_SW) || ((SOURCE) == OPBC_IWDG_HW)) + +/** + * @} + */ + +/** @defgroup FLASH_Option_Bytes_nRST_STOP + * @{ + */ + +#define OPBC_STOP_NoRST ((uint8_t)0x40) /*!< No Reset generated when entering in STOP */ +#define OPBC_STOP_RST ((uint8_t)0x00) /*!< Reset generated when entering in STOP Automaticly*/ +#define IS_OPBC_STOP_SOURCE(SOURCE) (((SOURCE) == OPBC_STOP_NoRST) || ((SOURCE) == OPBC_STOP_RST)) + +/** + * @} + */ + +/** @defgroup FLASH_Option_Bytes_nRST_STDBY + * @{ + */ + +#define OPBC_STDBY_NoRST ((uint8_t)0x80) /*!< No reset generated when entering in STANDBY */ +#define OPBC_STDBY_RST ((uint8_t)0x00) /*!< Reset generated when entering in STANDBY Automaticly*/ +#define IS_OPBC_STDBY_SOURCE(SOURCE) (((SOURCE) == OPBC_STDBY_NoRST) || ((SOURCE) == OPBC_STDBY_RST)) + + + +/** @defgroup FLASH_Flags + * @{ + */ +#define FLASH_FLAG_BSY FLASH_FR_BSY /*!< FLASH Busy flag */ +#define FLASH_FLAG_PGERR FLASH_FR_PGERR /*!< FLASH Programming error flag */ +#define FLASH_FLAG_PGSERR FLASH_FR_PGSERR /*!< FLASH Programming sequence error flag */ +#define FLASH_FLAG_WRPERR FLASH_FR_WRPRTERR /*!< FLASH Write protected error flag */ +#define FLASH_FLAG_EOP FLASH_FR_EOP /*!< FLASH End of Programming flag */ +#define FLASH_FLAG_OPBERR FLASH_FR_OPBERR /*!< user option and factory are not load correctly flag */ + +#define IS_FLASH_CLEAR_FLAG(FLAG) ((((FLAG) & (uint32_t)0xFFFFFFC1) == 0x00000000) && ((FLAG) != 0x00000000)) + +#define IS_FLASH_GET_FLAG(FLAG) (((FLAG) == FLASH_FLAG_BSY) || ((FLAG) == FLASH_FLAG_PGERR) || \ + ((FLAG) == FLASH_FLAG_PGSERR) || ((FLAG) == FLASH_FLAG_WRPERR) || \ + ((FLAG) == FLASH_FLAG_EOP ) || ((FLAG) == FLASH_FLAG_OPBERR)) + +/** @defgroup FLASH_Timeout_definition + * @{ + */ +#define FLASH_ER_PRG_TIMEOUT ((uint32_t)0x000B0000) //TIM value is user define + + +/** @defgroup BORR_Level + * @{ + */ +#define OPBC_BORR_LEVEL0 ((uint32_t)0x00000000) +#define OPBC_BORR_LEVEL1 ((uint32_t)0x00080000) +#define OPBC_BORR_LEVEL2 ((uint32_t)0x00100000) +#define OPBC_BORR_LEVEL3 ((uint32_t)0x00180000) + +#define IS_OPBC_BORR_LEVEL(Level) (((Level) ==OPBC_BORR_LEVEL0)||\ + ((Level) == OPBC_BORR_LEVEL1)||\ + ((Level) == OPBC_BORR_LEVEL2)||\ + ((Level) == OPBC_BORR_LEVEL3)) + +/** @defgroup BORF_Level + * @{ + */ +#define OPBC_BORF_LEVEL0 ((uint32_t)0x00000000) +#define OPBC_BORF_LEVEL1 ((uint32_t)0x00020000) +#define OPBC_BORF_LEVEL2 ((uint32_t)0x00040000) +#define OPBC_BORF_LEVEL3 ((uint32_t)0x00060000) + +#define IS_OPBC_BORF_LEVEL(Level) (((Level) ==OPBC_BORF_LEVEL0)||\ + ((Level) == OPBC_BORF_LEVEL1)||\ + ((Level) == OPBC_BORF_LEVEL2)||\ + ((Level) == OPBC_BORF_LEVEL3)) + + + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +/** + * @brief FLASH memory functions that can be executed from FLASH. + */ +/* FLASH Interface configuration functions ************************************/ +void FLASH_SetLatency(uint32_t FLASH_Latency); +void FLASH_PrefetchBufferCmd(FunctionalState NewState); +FlagStatus FLASH_GetPrefetchBufferStatus(void); + +/* FLASH Memory Programming functions *****************************************/ +void FLASH_Unlock(void); +void FLASH_Lock(void); +FLASH_Status FLASH_ErasePage(uint32_t Page_Address, uint32_t erase_size); +FLASH_Status FLASH_EraseAllPages(void); +FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data3, uint32_t Data2, uint32_t Data1, uint32_t Data0); +FLASH_Status FLASH_Program_oneWord(uint32_t Address, uint32_t Data0); +FLASH_Status FLASH_Program_HalfWord(uint32_t Address, uint16_t Data0); +FLASH_Status FLASH_Program_Byte(uint32_t Address, uint8_t Data0); + +/* FLASH Option Bytes Programming functions *****************************************/ +void FLASH_OPBC_Unlock(void); +void FLASH_OPBC_Lock(void); +FLASH_Status FLASH_WRPR_EnableWRP(uint32_t WRPR_WRP); +FLASH_Status FLASH_OPBC_RDPConfig(uint8_t OPBC_RDP); +FLASH_Status FLASH_OPBC_UserConfig(uint8_t OPBC_IWDG, uint8_t OPBC_STOP, uint8_t OPBC_STDBY); +FLASH_Status FLASH_OPBC_BOR_LevelConfig(uint32_t BORR_Level, uint32_t BORF_Level, FunctionalState NewState); +uint32_t FLASH_OPBC_GetWRP(void); +FlagStatus FLASH_OPBC_GetRDP(void); + +/* FLASH Interrupts and flags management functions **********************************/ +void FLASH_ITConfig(uint32_t FLASH_IT, FunctionalState NewState); +FlagStatus FLASH_GetFlagStatus(uint32_t FLASH_FLAG); +void FLASH_ClearFlag(uint32_t FLASH_FLAG); +FLASH_Status FLASH_GetStatus(void); +FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout); +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __FT32F0XX_FLASH_H */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ + + + + + + + diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_fmc.h b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_fmc.h new file mode 100644 index 00000000000..2b21b18c4ed --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_fmc.h @@ -0,0 +1,1132 @@ +/** + ****************************************************************************** + * @file ft32f4xx_fmc.h + * @author FMD AE + * @brief This file contains all the functions prototypes for the FMC + * firmware library + * @version V1.0.0 + * @date 2025-04-15 + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __FT32F4XX_FMC_H +#define __FT32F4XX_FMC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx.h" + +/** @addtogroup FMC + * @{ + */ + +/** @addtogroup FMC_Private_Macros + * @{ + */ +#if defined(FMC_Bank1) + +#define IS_FMC_NORSRAM_BANK(__BANK__) (((__BANK__) == FMC_NORSRAM_BANK1) || \ + ((__BANK__) == FMC_NORSRAM_BANK2) || \ + ((__BANK__) == FMC_NORSRAM_BANK3) || \ + ((__BANK__) == FMC_NORSRAM_BANK4)) +#define IS_FMC_MUX(__MUX__) (((__MUX__) == FMC_DATA_ADDRESS_MUX_DISABLE) || \ + ((__MUX__) == FMC_DATA_ADDRESS_MUX_ENABLE)) +#define IS_FMC_MEMORY(__MEMORY__) (((__MEMORY__) == FMC_MEMORY_TYPE_SRAM) || \ + ((__MEMORY__) == FMC_MEMORY_TYPE_PSRAM)|| \ + ((__MEMORY__) == FMC_MEMORY_TYPE_NOR)) +#define IS_FMC_NORSRAM_MEMORY_WIDTH(__WIDTH__) (((__WIDTH__) == FMC_NORSRAM_MEM_BUS_WIDTH_8) || \ + ((__WIDTH__) == FMC_NORSRAM_MEM_BUS_WIDTH_16)) +#define IS_FMC_PAGESIZE(__SIZE__) (((__SIZE__) == FMC_PAGE_SIZE_NONE) || \ + ((__SIZE__) == FMC_PAGE_SIZE_128) || \ + ((__SIZE__) == FMC_PAGE_SIZE_256) || \ + ((__SIZE__) == FMC_PAGE_SIZE_512) || \ + ((__SIZE__) == FMC_PAGE_SIZE_1024)) +#define IS_FMC_ACCESS_MODE(__MODE__) (((__MODE__) == FMC_ACCESS_MODE_A) || \ + ((__MODE__) == FMC_ACCESS_MODE_B) || \ + ((__MODE__) == FMC_ACCESS_MODE_C) || \ + ((__MODE__) == FMC_ACCESS_MODE_D)) +#define IS_FMC_BURSTMODE(__STATE__) (((__STATE__) == FMC_BURST_ACCESS_MODE_DISABLE) || \ + ((__STATE__) == FMC_BURST_ACCESS_MODE_ENABLE)) +#define IS_FMC_WAIT_POLARITY(__POLARITY__) (((__POLARITY__) == FMC_WAIT_SIGNAL_POLARITY_LOW) || \ + ((__POLARITY__) == FMC_WAIT_SIGNAL_POLARITY_HIGH)) +#define IS_FMC_WAIT_SIGNAL_ACTIVE(__ACTIVE__) (((__ACTIVE__) == FMC_WAIT_TIMING_BEFORE_WS) || \ + ((__ACTIVE__) == FMC_WAIT_TIMING_DURING_WS)) +#define IS_FMC_WRITE_OPERATION(__OPERATION__) (((__OPERATION__) == FMC_WRITE_OPERATION_DISABLE) || \ + ((__OPERATION__) == FMC_WRITE_OPERATION_ENABLE)) +#define IS_FMC_WAITE_SIGNAL(__SIGNAL__) (((__SIGNAL__) == FMC_WAIT_SIGNAL_DISABLE) || \ + ((__SIGNAL__) == FMC_WAIT_SIGNAL_ENABLE)) +#define IS_FMC_EXTENDED_MODE(__MODE__) (((__MODE__) == FMC_EXTENDED_MODE_DISABLE) || \ + ((__MODE__) == FMC_EXTENDED_MODE_ENABLE)) +#define IS_FMC_ASYNWAIT(__STATE__) (((__STATE__) == FMC_ASYNCHRONOUS_WAIT_DISABLE) || \ + ((__STATE__) == FMC_ASYNCHRONOUS_WAIT_ENABLE)) +#define IS_FMC_DATA_LATENCY(__LATENCY__) (((__LATENCY__) > 1U) && ((__LATENCY__) <= 17U)) +#define IS_FMC_WRITE_BURST(__BURST__) (((__BURST__) == FMC_WRITE_BURST_DISABLE) || \ + ((__BURST__) == FMC_WRITE_BURST_ENABLE)) +#define IS_FMC_CONTINOUS_CLOCK(__CCLOCK__) (((__CCLOCK__) == FMC_CONTINUOUS_CLOCK_SYNC_ONLY) || \ + ((__CCLOCK__) == FMC_CONTINUOUS_CLOCK_SYNC_ASYNC)) +#define IS_FMC_ADDRESS_SETUP_TIME(__TIME__) ((__TIME__) <= 15U) +#define IS_FMC_ADDRESS_HOLD_TIME(__TIME__) (((__TIME__) > 0U) && ((__TIME__) <= 15U)) +#define IS_FMC_DATASETUP_TIME(__TIME__) (((__TIME__) > 0U) && ((__TIME__) <= 255U)) +#define IS_FMC_DATAHOLD_DURATION(__DATAHOLD__) ((__DATAHOLD__) <= 3U) +#define IS_FMC_TURNAROUND_TIME(__TIME__)(((__TIME__) >= 1U) && ((__TIME__) <= 16U)) +#define IS_FMC_CLK_DIV(__DIV__) (((__DIV__) > 1U) && ((__DIV__) <= 16U)) +#define IS_FMC_NORSRAM_DEVICE(__INSTANCE__) ((__INSTANCE__) == FMC_NORSRAM_DEVICE) +#define IS_FMC_NORSRAM_EXTENDED_DEVICE(__INSTANCE__) ((__INSTANCE__) == FMC_NORSRAM_EXTENDED_DEVICE) + +#endif /* FMC_Bank1 */ + +#if defined(FMC_Bank2_3) + +#define IS_FMC_NAND_BANK(__BANK__) (((__BANK__) == FMC_NAND_BANK2) || \ + ((__BANK__) == FMC_NAND_BANK3)) +#define IS_FMC_WAIT_FEATURE(__FEATURE__) (((__FEATURE__) == FMC_NAND_WAIT_FEATURE_DISABLE) || \ + ((__FEATURE__) == FMC_NAND_WAIT_FEATURE_ENABLE)) +#define IS_FMC_NAND_MEMORY_WIDTH(__WIDTH__) (((__WIDTH__) == FMC_NAND_MEM_BUS_WIDTH_8) || \ + ((__WIDTH__) == FMC_NAND_MEM_BUS_WIDTH_16)) +#define IS_FMC_ECC_STATE(__STATE__) (((__STATE__) == FMC_NAND_ECC_DISABLE) || \ + ((__STATE__) == FMC_NAND_ECC_ENABLE)) + +#define IS_FMC_ECCPAGE_SIZE(__SIZE__) (((__SIZE__) == FMC_NAND_ECC_PAGE_SIZE_256BYTE) || \ + ((__SIZE__) == FMC_NAND_ECC_PAGE_SIZE_512BYTE) || \ + ((__SIZE__) == FMC_NAND_ECC_PAGE_SIZE_1024BYTE) || \ + ((__SIZE__) == FMC_NAND_ECC_PAGE_SIZE_2048BYTE) || \ + ((__SIZE__) == FMC_NAND_ECC_PAGE_SIZE_4096BYTE) || \ + ((__SIZE__) == FMC_NAND_ECC_PAGE_SIZE_8192BYTE)) +#define IS_FMC_TCLR_TIME(__TIME__) (((__TIME__) >= 1U) && ((__TIME__) <= 16U)) +#define IS_FMC_TAR_TIME(__TIME__) (((__TIME__) >= 1U) && ((__TIME__) <= 16U)) +#define IS_FMC_SETUP_TIME(__TIME__) ((__TIME__) <= 254U) +#define IS_FMC_WAIT_TIME(__TIME__) ((__TIME__) <= 254U) +#define IS_FMC_HOLD_TIME(__TIME__) ((__TIME__) <= 254U) +#define IS_FMC_HIZ_TIME(__TIME__) ((__TIME__) <= 254U) +#define IS_FMC_NAND_DEVICE(__INSTANCE__) ((__INSTANCE__) == FMC_NAND_DEVICE) + +#endif /* FMC_Bank2_3 */ + +#if defined(FMC_Bank5_6) + +#define IS_FMC_SDMEMORY_WIDTH(__WIDTH__) (((__WIDTH__) == FMC_SDRAM_MEM_BUS_WIDTH_8) || \ + ((__WIDTH__) == FMC_SDRAM_MEM_BUS_WIDTH_16)) +#define IS_FMC_WRITE_PROTECTION(__WRITE__) (((__WRITE__) == FMC_SDRAM_WRITE_PROTECTION_DISABLE) || \ + ((__WRITE__) == FMC_SDRAM_WRITE_PROTECTION_ENABLE)) +#define IS_FMC_SDCLOCK_PERIOD(__PERIOD__) (((__PERIOD__) == FMC_SDRAM_CLOCK_DISABLE) || \ + ((__PERIOD__) == FMC_SDRAM_CLOCK_PERIOD_2) || \ + ((__PERIOD__) == FMC_SDRAM_CLOCK_PERIOD_3)) +#define IS_FMC_READ_BURST(__RBURST__) (((__RBURST__) == FMC_SDRAM_RBURST_DISABLE) || \ + ((__RBURST__) == FMC_SDRAM_RBURST_ENABLE)) +#define IS_FMC_READPIPE_DELAY(__DELAY__) (((__DELAY__) == FMC_SDRAM_RPIPE_DELAY_0) || \ + ((__DELAY__) == FMC_SDRAM_RPIPE_DELAY_1) || \ + ((__DELAY__) == FMC_SDRAM_RPIPE_DELAY_2)) +#define IS_FMC_COMMAND_MODE(__COMMAND__) (((__COMMAND__) == FMC_SDRAM_CMD_NORMAL_MODE) || \ + ((__COMMAND__) == FMC_SDRAM_CMD_CLK_ENABLE) || \ + ((__COMMAND__) == FMC_SDRAM_CMD_PALL) || \ + ((__COMMAND__) == FMC_SDRAM_CMD_AUTOREFRESH_MODE) || \ + ((__COMMAND__) == FMC_SDRAM_CMD_LOAD_MODE) || \ + ((__COMMAND__) == FMC_SDRAM_CMD_SELFREFRESH_MODE) || \ + ((__COMMAND__) == FMC_SDRAM_CMD_POWERDOWN_MODE)) +#define IS_FMC_COMMAND_TARGET(__TARGET__) (((__TARGET__) == FMC_SDRAM_CMD_TARGET_BANK1) || \ + ((__TARGET__) == FMC_SDRAM_CMD_TARGET_BANK2) || \ + ((__TARGET__) == FMC_SDRAM_CMD_TARGET_BANK1_2)) +#define IS_FMC_LOADTOACTIVE_DELAY(__DELAY__) (((__DELAY__) > 0U) && ((__DELAY__) <= 16U)) +#define IS_FMC_EXITSELFREFRESH_DELAY(__DELAY__) (((__DELAY__) > 0U) && ((__DELAY__) <= 16U)) +#define IS_FMC_SELFREFRESH_TIME(__TIME__) (((__TIME__) > 0U) && ((__TIME__) <= 16U)) +#define IS_FMC_ROWCYCLE_DELAY(__DELAY__) (((__DELAY__) > 0U) && ((__DELAY__) <= 16U)) +#define IS_FMC_WRITE_RECOVERY_TIME(__TIME__) (((__TIME__) > 0U) && ((__TIME__) <= 16U)) +#define IS_FMC_RP_DELAY(__DELAY__) (((__DELAY__) > 0U) && ((__DELAY__) <= 16U)) +#define IS_FMC_RCD_DELAY(__DELAY__) (((__DELAY__) > 0U) && ((__DELAY__) <= 16U)) +#define IS_FMC_AUTOREFRESH_NUMBER(__NUMBER__) (((__NUMBER__) > 0U) && ((__NUMBER__) <= 15U)) +#define IS_FMC_MODE_REGISTER(__CONTENT__) ((__CONTENT__) <= 8191U) +#define IS_FMC_REFRESH_RATE(__RATE__) ((__RATE__) <= 8191U) +#define IS_FMC_SDRAM_DEVICE(__INSTANCE__) ((__INSTANCE__) == FMC_SDRAM_DEVICE) +#define IS_FMC_SDRAM_BANK(__BANK__) (((__BANK__) == FMC_SDRAM_BANK1) || \ + ((__BANK__) == FMC_SDRAM_BANK2)) +#define IS_FMC_COLUMNBITS_NUMBER(__COLUMN__) (((__COLUMN__) == FMC_SDRAM_COLUMN_BITS_NUM_8) || \ + ((__COLUMN__) == FMC_SDRAM_COLUMN_BITS_NUM_9) || \ + ((__COLUMN__) == FMC_SDRAM_COLUMN_BITS_NUM_10) || \ + ((__COLUMN__) == FMC_SDRAM_COLUMN_BITS_NUM_11)) +#define IS_FMC_ROWBITS_NUMBER(__ROW__) (((__ROW__) == FMC_SDRAM_ROW_BITS_NUM_11) || \ + ((__ROW__) == FMC_SDRAM_ROW_BITS_NUM_12) || \ + ((__ROW__) == FMC_SDRAM_ROW_BITS_NUM_13)) +#define IS_FMC_INTERNALBANK_NUMBER(__NUMBER__) (((__NUMBER__) == FMC_SDRAM_INTERN_BANKS_NUM_2) || \ + ((__NUMBER__) == FMC_SDRAM_INTERN_BANKS_NUM_4)) +#define IS_FMC_CAS_LATENCY(__LATENCY__) (((__LATENCY__) == FMC_SDRAM_CAS_LATENCY_1) || \ + ((__LATENCY__) == FMC_SDRAM_CAS_LATENCY_2) || \ + ((__LATENCY__) == FMC_SDRAM_CAS_LATENCY_3)) + +#endif /* FMC_Bank5_6 */ + +/** + * @} + */ + +/* Exported typedef ----------------------------------------------------------*/ + +/** @defgroup FMC_Exported_typedef FMC Low Layer Exported Types + * @{ + */ + +#if defined(FMC_Bank1) +#define FMC_NORSRAM_TypeDef FMC_Bank1_TypeDef +#define FMC_NORSRAM_EXTENDED_TypeDef FMC_Bank1E_TypeDef +#endif /* FMC_Bank1 */ + +#if defined(FMC_Bank2_3) +#define FMC_NAND_TypeDef FMC_Bank2_3_TypeDef +#endif /* FMC_Bank2_3 */ + +#if defined(FMC_Bank5_6) +#define FMC_SDRAM_TypeDef FMC_Bank5_6_TypeDef +#endif /* FMC_Bank5_6 */ + +#if defined(FMC_Bank1) +#define FMC_NORSRAM_DEVICE FMC_Bank1 +#define FMC_NORSRAM_EXTENDED_DEVICE FMC_Bank1E +#endif /* FMC_Bank1 */ + +#if defined(FMC_Bank2_3) +#define FMC_NAND_DEVICE FMC_Bank2_3 +#endif /* FMC_Bank2_3 */ + +#if defined(FMC_Bank5_6) +#define FMC_SDRAM_DEVICE FMC_Bank5_6 +#endif /* FMC_Bank5_6 */ + +#if defined(FMC_Bank1) +/** + * @brief FMC NORSRAM Configuration Structure definition + */ +typedef struct +{ + uint32_t NSBank; /*!< Specifies the NORSRAM memory device that will be used. + This parameter can be a value of @ref FMC_NORSRAM_Bank */ + + uint32_t DataAddressMux; /*!< Specifies whether the address and data values are + multiplexed on the data bus or not. + This parameter can be a value of @ref FMC_Data_Address_Bus_Multiplexing */ + + uint32_t MemoryType; /*!< Specifies the type of external memory attached to + the corresponding memory device. + This parameter can be a value of @ref FMC_Memory_Type */ + + uint32_t MemoryDataWidth; /*!< Specifies the external memory device width. + This parameter can be a value of @ref FMC_NORSRAM_Data_Width */ + + uint32_t BurstAccessMode; /*!< Enables or disables the burst access mode for Flash memory, + valid only with synchronous burst Flash memories. + This parameter can be a value of @ref FMC_Burst_Access_Mode */ + + uint32_t WaitSignalPolarity; /*!< Specifies the wait signal polarity, valid only when accessing + the Flash memory in burst mode. + This parameter can be a value of @ref FMC_Wait_Signal_Polarity */ + + uint32_t WaitSignalActive; /*!< Specifies if the wait signal is asserted by the memory one + clock cycle before the wait state or during the wait state, + valid only when accessing memories in burst mode. + This parameter can be a value of @ref FMC_Wait_Timing */ + + uint32_t WriteOperation; /*!< Enables or disables the write operation in the selected device by the FMC. + This parameter can be a value of @ref FMC_Write_Operation */ + + uint32_t WaitSignal; /*!< Enables or disables the wait state insertion via wait + signal, valid for Flash memory access in burst mode. + This parameter can be a value of @ref FMC_Wait_Signal */ + + uint32_t ExtendedMode; /*!< Enables or disables the extended mode. + This parameter can be a value of @ref FMC_Extended_Mode */ + + uint32_t AsynchronousWait; /*!< Enables or disables wait signal during asynchronous transfers, + valid only with asynchronous Flash memories. + This parameter can be a value of @ref FMC_AsynchronousWait */ + + uint32_t WriteBurst; /*!< Enables or disables the write burst operation. + This parameter can be a value of @ref FMC_Write_Burst */ + + uint32_t ContinuousClock; /*!< Enables or disables the FMC clock output to external memory devices. + This parameter is only enabled through the FMC_BCR1 register, + and don't care through FMC_BCR2..4 registers. + This parameter can be a value of @ref FMC_Continous_Clock */ + + uint32_t PageSize; /*!< Specifies the memory page size. + This parameter can be a value of @ref FMC_Page_Size */ +} FMC_NORSRAM_InitTypeDef; + +/** + * @brief FMC NORSRAM Timing parameters structure definition + */ +typedef struct +{ + uint32_t AddressSetupTime; /*!< Defines the number of HCLK cycles to configure + the duration of the address setup time. + This parameter can be a value between Min_Data = 0 and Max_Data = 15. + @note This parameter is not used with synchronous NOR Flash memories. */ + + uint32_t AddressHoldTime; /*!< Defines the number of HCLK cycles to configure + the duration of the address hold time. + This parameter can be a value between Min_Data = 1 and Max_Data = 15. + @note This parameter is not used with synchronous NOR Flash memories. */ + + uint32_t DataSetupTime; /*!< Defines the number of HCLK cycles to configure + the duration of the data setup time. + This parameter can be a value between Min_Data = 1 and Max_Data = 255. + @note This parameter is used for SRAMs, ROMs and asynchronous multiplexed + NOR Flash memories. */ + + uint32_t BusTurnAroundDuration; /*!< Defines the number of HCLK cycles to configure + the duration of the bus turnaround. + This parameter can be a value between Min_Data = 0 and Max_Data = 15. + @note This parameter is only used for multiplexed NOR Flash memories. */ + + uint32_t CLKDivision; /*!< Defines the period of CLK clock output signal, expressed in number of + HCLK cycles. This parameter can be a value between Min_Data = 2 and + Max_Data = 16. + @note This parameter is not used for asynchronous NOR Flash, SRAM or ROM + accesses. */ + + uint32_t DataLatency; /*!< Defines the number of memory clock cycles to issue + to the memory before getting the first data. + The parameter value depends on the memory type as shown below: + - It must be set to 0 in case of a CRAM + - It is don't care in asynchronous NOR, SRAM or ROM accesses + - It may assume a value between Min_Data = 2 and Max_Data = 17 + in NOR Flash memories with synchronous burst mode enable */ + + uint32_t AccessMode; /*!< Specifies the asynchronous access mode. + This parameter can be a value of @ref FMC_Access_Mode */ +} FMC_NORSRAM_TimingTypeDef; +#endif /* FMC_Bank1 */ + +#if defined(FMC_Bank2_3) +/** + * @brief FMC NAND Configuration Structure definition + */ +typedef struct +{ + uint32_t NandBank; /*!< Specifies the NAND memory device that will be used. + This parameter can be a value of @ref FMC_NAND_Bank */ + + uint32_t Waitfeature; /*!< Enables or disables the Wait feature for the NAND Memory device. + This parameter can be any value of @ref FMC_Wait_feature */ + + uint32_t MemoryDataWidth; /*!< Specifies the external memory device width. + This parameter can be any value of @ref FMC_NAND_Data_Width */ + + uint32_t EccComputation; /*!< Enables or disables the ECC computation. + This parameter can be any value of @ref FMC_ECC */ + + uint32_t ECCPageSize; /*!< Defines the page size for the extended ECC. + This parameter can be any value of @ref FMC_ECC_Page_Size */ + + uint32_t TCLRSetupTime; /*!< Defines the number of HCLK cycles to configure the + delay between CLE low and RE low. + This parameter can be a value between Min_Data = 0 and Max_Data = 255 */ + + uint32_t TARSetupTime; /*!< Defines the number of HCLK cycles to configure the + delay between ALE low and RE low. + This parameter can be a number between Min_Data = 0 and Max_Data = 255 */ +} FMC_NAND_InitTypeDef; +#endif /* FMC_Bank2_3 */ + +#if defined(FMC_Bank2_3) +/** + * @brief FMC NAND Timing parameters structure definition + */ +typedef struct +{ + uint32_t SetupTime; /*!< Defines the number of HCLK cycles to setup address before + the command assertion for NAND-Flash read or write access + to common/Attribute or I/O memory space (depending on + the memory space timing to be configured). + This parameter can be a value between Min_Data = 0 and Max_Data = 254 */ + + uint32_t WaitSetupTime; /*!< Defines the minimum number of HCLK cycles to assert the + command for NAND-Flash read or write access to + common/Attribute or I/O memory space (depending on the + memory space timing to be configured). + This parameter can be a number between Min_Data = 0 and Max_Data = 254 */ + + uint32_t HoldSetupTime; /*!< Defines the number of HCLK clock cycles to hold address + (and data for write access) after the command de-assertion + for NAND-Flash read or write access to common/Attribute + or I/O memory space (depending on the memory space timing + to be configured). + This parameter can be a number between Min_Data = 0 and Max_Data = 254 */ + + uint32_t HiZSetupTime; /*!< Defines the number of HCLK clock cycles during which the + data bus is kept in HiZ after the start of a NAND-Flash + write access to common/Attribute or I/O memory space (depending + on the memory space timing to be configured). + This parameter can be a number between Min_Data = 0 and Max_Data = 254 */ +} FMC_NAND_TimingTypeDef; +#endif /* FMC_Bank2_3 */ + +#if defined(FMC_Bank5_6) +/** + * @brief FMC SDRAM Configuration Structure definition + */ +typedef struct +{ + uint32_t SDBank; /*!< Specifies the SDRAM memory device that will be used. + This parameter can be a value of @ref FMC_SDRAM_Bank */ + + uint32_t ColumnBitsNumber; /*!< Defines the number of bits of column address. + This parameter can be a value of @ref FMC_SDRAM_Column_Bits_number. */ + + uint32_t RowBitsNumber; /*!< Defines the number of bits of column address. + This parameter can be a value of @ref FMC_SDRAM_Row_Bits_number. */ + + uint32_t MemoryDataWidth; /*!< Defines the memory device width. + This parameter can be a value of @ref FMC_SDRAM_Memory_Bus_Width. */ + + uint32_t InternalBankNumber; /*!< Defines the number of the device's internal banks. + This parameter can be of @ref FMC_SDRAM_Internal_Banks_Number. */ + + uint32_t CASLatency; /*!< Defines the SDRAM CAS latency in number of memory clock cycles. + This parameter can be a value of @ref FMC_SDRAM_CAS_Latency. */ + + uint32_t WriteProtection; /*!< Enables the SDRAM device to be accessed in write mode. + This parameter can be a value of @ref FMC_SDRAM_Write_Protection. */ + + uint32_t SDClockPeriod; /*!< Define the SDRAM Clock Period for both SDRAM devices and they allow + to disable the clock before changing frequency. + This parameter can be a value of @ref FMC_SDRAM_Clock_Period. */ + + uint32_t ReadBurst; /*!< This bit enable the SDRAM controller to anticipate the next read + commands during the CAS latency and stores data in the Read FIFO. + This parameter can be a value of @ref FMC_SDRAM_Read_Burst. */ + + uint32_t ReadPipeDelay; /*!< Define the delay in system clock cycles on read data path. + This parameter can be a value of @ref FMC_SDRAM_Read_Pipe_Delay. */ +} FMC_SDRAM_InitTypeDef; + +/** + * @brief FMC SDRAM Timing parameters structure definition + */ +typedef struct +{ + uint32_t LoadToActiveDelay; /*!< Defines the delay between a Load Mode Register command and + an active or Refresh command in number of memory clock cycles. + This parameter can be a value between Min_Data = 1 and Max_Data = 16 */ + + uint32_t ExitSelfRefreshDelay; /*!< Defines the delay from releasing the self refresh command to + issuing the Activate command in number of memory clock cycles. + This parameter can be a value between Min_Data = 1 and Max_Data = 16 */ + + uint32_t SelfRefreshTime; /*!< Defines the minimum Self Refresh period in number of memory clock + cycles. + This parameter can be a value between Min_Data = 1 and Max_Data = 16 */ + + uint32_t RowCycleDelay; /*!< Defines the delay between the Refresh command and the Activate command + and the delay between two consecutive Refresh commands in number of + memory clock cycles. + This parameter can be a value between Min_Data = 1 and Max_Data = 16 */ + + uint32_t WriteRecoveryTime; /*!< Defines the Write recovery Time in number of memory clock cycles. + This parameter can be a value between Min_Data = 1 and Max_Data = 16 */ + + uint32_t RPDelay; /*!< Defines the delay between a Precharge Command and an other command + in number of memory clock cycles. + This parameter can be a value between Min_Data = 1 and Max_Data = 16 */ + + uint32_t RCDDelay; /*!< Defines the delay between the Activate Command and a Read/Write + command in number of memory clock cycles. + This parameter can be a value between Min_Data = 1 and Max_Data = 16 */ +} FMC_SDRAM_TimingTypeDef; + +/** + * @brief SDRAM command parameters structure definition + */ +typedef struct +{ + uint32_t CommandMode; /*!< Defines the command issued to the SDRAM device. + This parameter can be a value of @ref FMC_SDRAM_Command_Mode. */ + + uint32_t CommandTarget; /*!< Defines which device (1 or 2) the command will be issued to. + This parameter can be a value of @ref FMC_SDRAM_Command_Target. */ + + uint32_t AutoRefreshNumber; /*!< Defines the number of consecutive auto refresh command issued + in auto refresh mode. + This parameter can be a value between Min_Data = 1 and Max_Data = 15 */ + + uint32_t ModeRegisterDefinition; /*!< Defines the SDRAM Mode register content */ +} FMC_SDRAM_CommandTypeDef; +#endif /* FMC_Bank5_6 */ +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @addtogroup FMC_Exported_Constants FMC Low Layer Exported Constants + * @{ + */ +#if defined(FMC_Bank1) + +/** @defgroup FMC_NOR_SRAM_Controller FMC NOR/SRAM Controller + * @{ + */ + +/** @defgroup FMC_NORSRAM_Bank FMC NOR/SRAM Bank + * @{ + */ +#define FMC_NORSRAM_BANK1 (0x00000000U) +#define FMC_NORSRAM_BANK2 (0x00000002U) +#define FMC_NORSRAM_BANK3 (0x00000004U) +#define FMC_NORSRAM_BANK4 (0x00000006U) +/** + * @} + */ + +/** @defgroup FMC_Data_Address_Bus_Multiplexing FMC Data Address Bus Multiplexing + * @{ + */ +#define FMC_DATA_ADDRESS_MUX_DISABLE (0x00000000U) +#define FMC_DATA_ADDRESS_MUX_ENABLE (0x00000002U) +/** + * @} + */ + +/** @defgroup FMC_Memory_Type FMC Memory Type + * @{ + */ +#define FMC_MEMORY_TYPE_SRAM (0x00000000U) +#define FMC_MEMORY_TYPE_PSRAM (0x00000004U) +#define FMC_MEMORY_TYPE_NOR (0x00000008U) +/** + * @} + */ + +/** @defgroup FMC_NORSRAM_Data_Width FMC NORSRAM Data Width + * @{ + */ +#define FMC_NORSRAM_MEM_BUS_WIDTH_8 (0x00000000U) +#define FMC_NORSRAM_MEM_BUS_WIDTH_16 (0x00000010U) +/** + * @} + */ + +/** @defgroup FMC_NORSRAM_Flash_Access FMC NOR/SRAM Flash Access + * @{ + */ +#define FMC_NORSRAM_FLASH_ACCESS_ENABLE (0x00000040U) +#define FMC_NORSRAM_FLASH_ACCESS_DISABLE (0x00000000U) +/** + * @} + */ + +/** @defgroup FMC_Burst_Access_Mode FMC Burst Access Mode + * @{ + */ +#define FMC_BURST_ACCESS_MODE_DISABLE (0x00000000U) +#define FMC_BURST_ACCESS_MODE_ENABLE (0x00000100U) +/** + * @} + */ + +/** @defgroup FMC_Wait_Signal_Polarity FMC Wait Signal Polarity + * @{ + */ +#define FMC_WAIT_SIGNAL_POLARITY_LOW (0x00000000U) +#define FMC_WAIT_SIGNAL_POLARITY_HIGH (0x00000200U) +/** + * @} + */ + +/** @defgroup FMC_Wait_Timing FMC Wait Timing + * @{ + */ +#define FMC_WAIT_TIMING_BEFORE_WS (0x00000000U) +#define FMC_WAIT_TIMING_DURING_WS (0x00000800U) +/** + * @} + */ + +/** @defgroup FMC_Write_Operation FMC Write Operation + * @{ + */ +#define FMC_WRITE_OPERATION_DISABLE (0x00000000U) +#define FMC_WRITE_OPERATION_ENABLE (0x00001000U) +/** + * @} + */ + +/** @defgroup FMC_Wait_Signal FMC Wait Signal + * @{ + */ +#define FMC_WAIT_SIGNAL_DISABLE (0x00000000U) +#define FMC_WAIT_SIGNAL_ENABLE (0x00002000U) +/** + * @} + */ + +/** @defgroup FMC_Extended_Mode FMC Extended Mode + * @{ + */ +#define FMC_EXTENDED_MODE_DISABLE (0x00000000U) +#define FMC_EXTENDED_MODE_ENABLE (0x00004000U) +/** + * @} + */ + +/** @defgroup FMC_AsynchronousWait FMC Asynchronous Wait + * @{ + */ +#define FMC_ASYNCHRONOUS_WAIT_DISABLE (0x00000000U) +#define FMC_ASYNCHRONOUS_WAIT_ENABLE (0x00008000U) +/** + * @} + */ + +/** @defgroup FMC_Page_Size FMC Page Size + * @{ + */ +#define FMC_PAGE_SIZE_NONE (0x00000000U) +#define FMC_PAGE_SIZE_128 FMC_BCR1_CPSIZE_0 +#define FMC_PAGE_SIZE_256 FMC_BCR1_CPSIZE_1 +#define FMC_PAGE_SIZE_512 (FMC_BCR1_CPSIZE_0\ + | FMC_BCR1_CPSIZE_1) +#define FMC_PAGE_SIZE_1024 FMC_BCR1_CPSIZE_2 +/** + * @} + */ + +/** @defgroup FMC_Write_Burst FMC Write Burst + * @{ + */ +#define FMC_WRITE_BURST_DISABLE (0x00000000U) +#define FMC_WRITE_BURST_ENABLE (0x00080000U) +/** + * @} + */ + +/** @defgroup FMC_Continous_Clock FMC Continuous Clock + * @{ + */ +#define FMC_CONTINUOUS_CLOCK_SYNC_ONLY (0x00000000U) +#define FMC_CONTINUOUS_CLOCK_SYNC_ASYNC (0x00100000U) +/** + * @} + */ + +#if defined(FMC_BCR1_WFDIS) +/** @defgroup FMC_Write_FIFO FMC Write FIFO + * @note These values are available only for the STM32F446/469/479xx devices. + * @{ + */ +#define FMC_WRITE_FIFO_DISABLE FMC_BCR1_WFDIS +#define FMC_WRITE_FIFO_ENABLE (0x00000000U) +#endif /* FMC_BCR1_WFDIS */ +/** + * @} + */ + +/** @defgroup FMC_Access_Mode FMC Access Mode + * @{ + */ +#define FMC_ACCESS_MODE_A (0x00000000U) +#define FMC_ACCESS_MODE_B (0x10000000U) +#define FMC_ACCESS_MODE_C (0x20000000U) +#define FMC_ACCESS_MODE_D (0x30000000U) +/** + * @} + */ + +/** + * @} + */ +#endif /* FMC_Bank1 */ + +#if defined(FMC_Bank2_3) + +/** @defgroup FMC_NAND_Controller FMC NAND Controller + * @{ + */ +/** @defgroup FMC_NAND_Bank FMC NAND Bank + * @{ + */ +#if defined(FMC_Bank2_3) +#define FMC_NAND_BANK2 (0x00000010U) +#endif +#define FMC_NAND_BANK3 (0x00000100U) +/** + * @} + */ + +/** @defgroup FMC_Wait_feature FMC Wait feature + * @{ + */ +#define FMC_NAND_WAIT_FEATURE_DISABLE (0x00000000U) +#define FMC_NAND_WAIT_FEATURE_ENABLE (0x00000002U) +/** + * @} + */ + +/** @defgroup FMC_PCR_Memory_Type FMC PCR Memory Type + * @{ + */ +#define FMC_PCR_MEMORY_TYPE_NAND (0x00000008U) +/** + * @} + */ + +/** @defgroup FMC_NAND_Data_Width FMC NAND Data Width + * @{ + */ +#define FMC_NAND_MEM_BUS_WIDTH_8 (0x00000000U) +#define FMC_NAND_MEM_BUS_WIDTH_16 (0x00000010U) +/** + * @} + */ + +/** @defgroup FMC_ECC FMC ECC + * @{ + */ +#define FMC_NAND_ECC_DISABLE (0x00000000U) +#define FMC_NAND_ECC_ENABLE (0x00000040U) +/** + * @} + */ + +/** @defgroup FMC_ECC_Page_Size FMC ECC Page Size + * @{ + */ +#define FMC_NAND_ECC_PAGE_SIZE_256BYTE (0x00000000U) +#define FMC_NAND_ECC_PAGE_SIZE_512BYTE (0x00020000U) +#define FMC_NAND_ECC_PAGE_SIZE_1024BYTE (0x00040000U) +#define FMC_NAND_ECC_PAGE_SIZE_2048BYTE (0x00060000U) +#define FMC_NAND_ECC_PAGE_SIZE_4096BYTE (0x00080000U) +#define FMC_NAND_ECC_PAGE_SIZE_8192BYTE (0x000A0000U) +/** + * @} + */ + +/** + * @} + */ +#endif /* FMC_Bank2_3 */ + +#if defined(FMC_Bank5_6) +/** @defgroup FMC_SDRAM_Controller FMC SDRAM Controller + * @{ + */ +/** @defgroup FMC_SDRAM_Bank FMC SDRAM Bank + * @{ + */ +#define FMC_SDRAM_BANK1 (0x00000000U) +#define FMC_SDRAM_BANK2 (0x00000001U) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_Column_Bits_number FMC SDRAM Column Bits number + * @{ + */ +#define FMC_SDRAM_COLUMN_BITS_NUM_8 (0x00000000U) +#define FMC_SDRAM_COLUMN_BITS_NUM_9 (0x00000001U) +#define FMC_SDRAM_COLUMN_BITS_NUM_10 (0x00000002U) +#define FMC_SDRAM_COLUMN_BITS_NUM_11 (0x00000003U) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_Row_Bits_number FMC SDRAM Row Bits number + * @{ + */ +#define FMC_SDRAM_ROW_BITS_NUM_11 (0x00000000U) +#define FMC_SDRAM_ROW_BITS_NUM_12 (0x00000004U) +#define FMC_SDRAM_ROW_BITS_NUM_13 (0x00000008U) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_Memory_Bus_Width FMC SDRAM Memory Bus Width + * @{ + */ +#define FMC_SDRAM_MEM_BUS_WIDTH_8 (0x00000000U) +#define FMC_SDRAM_MEM_BUS_WIDTH_16 (0x00000010U) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_Internal_Banks_Number FMC SDRAM Internal Banks Number + * @{ + */ +#define FMC_SDRAM_INTERN_BANKS_NUM_2 (0x00000000U) +#define FMC_SDRAM_INTERN_BANKS_NUM_4 (0x00000040U) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_CAS_Latency FMC SDRAM CAS Latency + * @{ + */ +#define FMC_SDRAM_CAS_LATENCY_1 (0x00000080U) +#define FMC_SDRAM_CAS_LATENCY_2 (0x00000100U) +#define FMC_SDRAM_CAS_LATENCY_3 (0x00000180U) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_Write_Protection FMC SDRAM Write Protection + * @{ + */ +#define FMC_SDRAM_WRITE_PROTECTION_DISABLE (0x00000000U) +#define FMC_SDRAM_WRITE_PROTECTION_ENABLE (0x00000200U) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_Clock_Period FMC SDRAM Clock Period + * @{ + */ +#define FMC_SDRAM_CLOCK_DISABLE (0x00000000U) +#define FMC_SDRAM_CLOCK_PERIOD_2 (0x00000800U) +#define FMC_SDRAM_CLOCK_PERIOD_3 (0x00000C00U) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_Read_Burst FMC SDRAM Read Burst + * @{ + */ +#define FMC_SDRAM_RBURST_DISABLE (0x00000000U) +#define FMC_SDRAM_RBURST_ENABLE (0x00001000U) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_Read_Pipe_Delay FMC SDRAM Read Pipe Delay + * @{ + */ +#define FMC_SDRAM_RPIPE_DELAY_0 (0x00000000U) +#define FMC_SDRAM_RPIPE_DELAY_1 (0x00002000U) +#define FMC_SDRAM_RPIPE_DELAY_2 (0x00004000U) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_Command_Mode FMC SDRAM Command Mode + * @{ + */ +#define FMC_SDRAM_CMD_NORMAL_MODE (0x00000000U) +#define FMC_SDRAM_CMD_CLK_ENABLE (0x00000001U) +#define FMC_SDRAM_CMD_PALL (0x00000002U) +#define FMC_SDRAM_CMD_AUTOREFRESH_MODE (0x00000003U) +#define FMC_SDRAM_CMD_LOAD_MODE (0x00000004U) +#define FMC_SDRAM_CMD_SELFREFRESH_MODE (0x00000005U) +#define FMC_SDRAM_CMD_POWERDOWN_MODE (0x00000006U) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_Command_Target FMC SDRAM Command Target + * @{ + */ +#define FMC_SDRAM_CMD_TARGET_BANK2 FMC_SDCMR_CTB2 +#define FMC_SDRAM_CMD_TARGET_BANK1 FMC_SDCMR_CTB1 +#define FMC_SDRAM_CMD_TARGET_BANK1_2 (0x00000018U) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_Mode_Status FMC SDRAM Mode Status + * @{ + */ +#define FMC_SDRAM_NORMAL_MODE (0x00000000U) +#define FMC_SDRAM_SELF_REFRESH_MODE FMC_SDSR_MODES1_0 +#define FMC_SDRAM_POWER_DOWN_MODE FMC_SDSR_MODES1_1 +/** + * @} + */ + +/** + * @} + */ + +#endif /* FMC_Bank5_6 */ + +/** @defgroup FMC_Interrupt_definition FMC Low Layer Interrupt definition + * @{ + */ +#if defined(FMC_Bank5_6) +#define FMC_IT_REFRESH_ERROR (0x00004000U) +#endif /* FMC_Bank5_6 */ +/** + * @} + */ + +/** @defgroup FMC_Flag_definition FMC Low Layer Flag definition + * @{ + */ +#if defined(FMC_Bank2_3) +#define FMC_FLAG_FEMPT (0x00000040U) +#endif /* FMC_Bank2_3 */ + +#if defined(FMC_Bank5_6) +#define FMC_SDRAM_FLAG_REFRESH_IT FMC_SDSR_RE +#define FMC_SDRAM_FLAG_BUSY FMC_SDSR_BUSY +#define FMC_SDRAM_FLAG_REFRESH_ERROR FMC_SDRTR_CRE +#endif /* FMC_Bank5_6 */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/* Private macro -------------------------------------------------------------*/ +/** @defgroup FMC_Private_Macros FMC Private Macros + * @{ + */ +#if defined(FMC_Bank1) +/** @defgroup FMC_NOR_Macros FMC NOR/SRAM Macros + * @brief macros to handle NOR device enable/disable and read/write operations + * @{ + */ + +/** + * @brief Enable the NORSRAM device access. + * @param __INSTANCE__ FMC_NORSRAM Instance + * @param __BANK__ FMC_NORSRAM Bank + * @retval None + */ +#define __FMC_NORSRAM_ENABLE(__INSTANCE__, __BANK__) ((__INSTANCE__)->BTCR[(__BANK__)]\ + |= FMC_BCR1_MBKEN) + +/** + * @brief Disable the NORSRAM device access. + * @param __INSTANCE__ FMC_NORSRAM Instance + * @param __BANK__ FMC_NORSRAM Bank + * @retval None + */ +#define __FMC_NORSRAM_DISABLE(__INSTANCE__, __BANK__) ((__INSTANCE__)->BTCR[(__BANK__)]\ + &= ~FMC_BCR1_MBKEN) + +/** + * @} + */ +#endif /* FMC_Bank1 */ + +#if defined(FMC_Bank2_3) +/** @defgroup FMC_NAND_Macros FMC NAND Macros + * @brief macros to handle NAND device enable/disable + * @{ + */ + +/** + * @brief Enable the NAND device access. + * @param __INSTANCE__ FMC_NAND Instance + * @param __BANK__ FMC_NAND Bank + * @retval None + */ +#if defined(FMC_Bank2_3) +#define __FMC_NAND_ENABLE(__INSTANCE__, __BANK__) (((__BANK__) == FMC_NAND_BANK2)? ((__INSTANCE__)->PCR2 |= FMC_PCR2_PBKEN): \ + ((__INSTANCE__)->PCR3 |= FMC_PCR3_PBKEN)) +#endif /* FMC_Bank2_3 */ + +/** + * @brief Disable the NAND device access. + * @param __INSTANCE__ FMC_NAND Instance + * @param __BANK__ FMC_NAND Bank + * @retval None + */ +#if defined(FMC_Bank2_3) +#define __FMC_NAND_DISABLE(__INSTANCE__, __BANK__) (((__BANK__) == FMC_NAND_BANK2)? ((__INSTANCE__)->PCR2 &= ~(FMC_PCR2_PBKEN)): \ + ((__INSTANCE__)->PCR3 &= ~(FMC_PCR3_PBKEN))) +#endif /* FMC_Bank2_3 */ + +/** + * @brief Get flag status of the NAND device. + * @param __INSTANCE__ FMC_NAND Instance + * @param __BANK__ FMC_NAND Bank + * @param __FLAG__ FMC_NAND flag + * This parameter can be any combination of the following values: + * @arg FMC_FLAG_FEMPT: FIFO empty flag. + * @retval The state of FLAG (SET or RESET). + */ +#if defined(FMC_Bank2_3) +#define __FMC_NAND_GET_FLAG(__INSTANCE__, __BANK__, __FLAG__) (((__BANK__) == FMC_NAND_BANK2)? (((__INSTANCE__)->SR2 &(__FLAG__)) == (__FLAG__)): \ + (((__INSTANCE__)->SR3 &(__FLAG__)) == (__FLAG__))) +#endif /* FMC_Bank2_3 */ + +/** + * @} + */ +#endif /* defined(FMC_Bank2_3 */ + +#if defined(FMC_Bank5_6) +/** @defgroup FMC_SDRAM_Interrupt FMC SDRAM Interrupt + * @brief macros to handle SDRAM interrupts + * @{ + */ + +/** + * @brief Enable the SDRAM device interrupt. + * @param __INSTANCE__ FMC_SDRAM instance + * @param __INTERRUPT__ FMC_SDRAM interrupt + * This parameter can be any combination of the following values: + * @arg FMC_IT_REFRESH_ERROR: Interrupt refresh error + * @retval None + */ +#define __FMC_SDRAM_ENABLE_IT(__INSTANCE__, __INTERRUPT__) ((__INSTANCE__)->SDRTR |= (__INTERRUPT__)) + +/** + * @brief Disable the SDRAM device interrupt. + * @param __INSTANCE__ FMC_SDRAM instance + * @param __INTERRUPT__ FMC_SDRAM interrupt + * This parameter can be any combination of the following values: + * @arg FMC_IT_REFRESH_ERROR: Interrupt refresh error + * @retval None + */ +#define __FMC_SDRAM_DISABLE_IT(__INSTANCE__, __INTERRUPT__) ((__INSTANCE__)->SDRTR &= ~(__INTERRUPT__)) + +/** + * @brief Get flag status of the SDRAM device. + * @param __INSTANCE__ FMC_SDRAM instance + * @param __FLAG__ FMC_SDRAM flag + * This parameter can be any combination of the following values: + * @arg FMC_SDRAM_FLAG_REFRESH_IT: Interrupt refresh error. + * @arg FMC_SDRAM_FLAG_BUSY: SDRAM busy flag. + * @retval The state of FLAG (SET or RESET). + */ +#define __FMC_SDRAM_GET_FLAG(__INSTANCE__, __FLAG__) (((__INSTANCE__)->SDSR &(__FLAG__)) == (__FLAG__)) + +/** + * @brief Clear flag status of the SDRAM device. + * @param __INSTANCE__ FMC_SDRAM instance + * @param __FLAG__ FMC_SDRAM flag + * This parameter can be any combination of the following values: + * @arg FMC_SDRAM_FLAG_REFRESH_ERROR + * @retval None + */ +#define __FMC_SDRAM_CLEAR_FLAG(__INSTANCE__, __FLAG__) ((__INSTANCE__)->SDRTR |= (__FLAG__)) + +/** + * @} + */ +#endif /* FMC_Bank5_6 */ +/** + * @} + */ + + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup FMC_Private_Functions FMC Private Functions + * @{ + */ + +#if defined(FMC_Bank1) +/** @defgroup FMC_NORSRAM NOR SRAM + * @{ + */ +/** @defgroup FMC_NORSRAM_Private_Functions_Group1 NOR SRAM Initialization/de-initialization functions + * @{ + */ +void FMC_NORSRAM_Init(FMC_NORSRAM_TypeDef * FSMC_Data_Address_Bus_MultiplexingDevice, + FMC_NORSRAM_InitTypeDef *Init); +void FMC_NORSRAM_Timing_Init(FMC_NORSRAM_TypeDef *Device, + FMC_NORSRAM_TimingTypeDef *Timing, uint32_t Bank); +void FMC_NORSRAM_Extended_Timing_Init(FMC_NORSRAM_EXTENDED_TypeDef *Device, + FMC_NORSRAM_TimingTypeDef *Timing, uint32_t Bank, + uint32_t ExtendedMode); +void FMC_NORSRAM_DeInit(FMC_NORSRAM_TypeDef *Device, + FMC_NORSRAM_EXTENDED_TypeDef *ExDevice, uint32_t Bank); +/** + * @} + */ + +/** @defgroup FMC_NORSRAM_Private_Functions_Group2 NOR SRAM Control functions + * @{ + */ +void FMC_NORSRAM_WriteOperation_Enable(FMC_NORSRAM_TypeDef *Device, uint32_t Bank); +void FMC_NORSRAM_WriteOperation_Disable(FMC_NORSRAM_TypeDef *Device, uint32_t Bank); +/** + * @} + */ +/** + * @} + */ +#endif /* FMC_Bank1 */ + +#if defined(FMC_Bank2_3) +/** @defgroup FMC_NAND NAND + * @{ + */ +/** @defgroup FMC_NAND_Private_Functions_Group1 NAND Initialization/de-initialization functions + * @{ + */ +void FMC_NAND_Init(FMC_NAND_TypeDef *Device, FMC_NAND_InitTypeDef *Init); +void FMC_NAND_CommonSpace_Timing_Init(FMC_NAND_TypeDef *Device, + FMC_NAND_TimingTypeDef *Timing, uint32_t Bank); +void FMC_NAND_AttributeSpace_Timing_Init(FMC_NAND_TypeDef *Device, + FMC_NAND_TimingTypeDef *Timing, uint32_t Bank); +void FMC_NAND_DeInit(FMC_NAND_TypeDef *Device, uint32_t Bank); +/** + * @} + */ + +/** @defgroup FMC_NAND_Private_Functions_Group2 NAND Control functions + * @{ + */ +void FMC_NAND_ECC_Enable(FMC_NAND_TypeDef *Device, uint32_t Bank); +void FMC_NAND_ECC_Disable(FMC_NAND_TypeDef *Device, uint32_t Bank); +void FMC_NAND_GetECC(FMC_NAND_TypeDef *Device, uint32_t *ECCval, uint32_t Bank); +/** + * @} + */ +/** + * @} + */ +#endif /* FMC_Bank2_3 */ + +#if defined(FMC_Bank5_6) +/** @defgroup FMC_SDRAM SDRAM + * @{ + */ +/** @defgroup FMC_SDRAM_Private_Functions_Group1 SDRAM Initialization/de-initialization functions + * @{ + */ +void FMC_SDRAM_Init(FMC_SDRAM_TypeDef *Device, FMC_SDRAM_InitTypeDef *Init); +void FMC_SDRAM_Timing_Init(FMC_SDRAM_TypeDef *Device, + FMC_SDRAM_TimingTypeDef *Timing, uint32_t Bank); +void FMC_SDRAM_DeInit(FMC_SDRAM_TypeDef *Device, uint32_t Bank); +/** + * @} + */ + +/** @defgroup FMC_SDRAM_Private_Functions_Group2 SDRAM Control functions + * @{ + */ +void FMC_SDRAM_WriteProtection_Enable(FMC_SDRAM_TypeDef *Device, uint32_t Bank); +void FMC_SDRAM_WriteProtection_Disable(FMC_SDRAM_TypeDef *Device, uint32_t Bank); +void FMC_SDRAM_SendCommand(FMC_SDRAM_TypeDef *Device, + FMC_SDRAM_CommandTypeDef *Command); +void FMC_SDRAM_ProgramRefreshRate(FMC_SDRAM_TypeDef *Device, uint32_t RefreshRate); +void FMC_SDRAM_SetAutoRefreshNumber(FMC_SDRAM_TypeDef *Device, + uint32_t AutoRefreshNumber); +uint32_t FMC_SDRAM_GetModeStatus(const FMC_SDRAM_TypeDef *Device, uint32_t Bank); +/** + * @} + */ +/** + * @} + */ +#endif /* FMC_Bank5_6 */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __FT32F4XX_FMC_H */ + +/************************ (C) COPYRIGHT FMD *****END OF FILE*******************/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_gpio.h b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_gpio.h new file mode 100644 index 00000000000..57462b6bbc7 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_gpio.h @@ -0,0 +1,340 @@ +/** + ****************************************************************************** + * @file ft32f4xx_gpio.h + * @author FMD AE + * @brief This file contains all the functions prototypes for the GPIO + * firmware library. + * @version V1.0.0 + * @date 2025-03-27 + ****************************************************************************** + */ + + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __FT32F4XX_GPIO_H +#define __FT32F4XX_GPIO_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx.h" + + +/** @addtogroup GPIO + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +#define IS_GPIO_ALL_PERIPH(PERIPH) (((PERIPH) == GPIOA) || \ + ((PERIPH) == GPIOB) || \ + ((PERIPH) == GPIOC) || \ + ((PERIPH) == GPIOD) || \ + ((PERIPH) == GPIOE) || \ + ((PERIPH) == GPIOH)) + +/** @defgroup Configuration_Mode_enumeration + * @{ + */ +typedef enum +{ + GPIO_Mode_IN = 0x00, /*!< GPIO Input Mode */ + GPIO_Mode_OUT = 0x01, /*!< GPIO Output Mode */ + GPIO_Mode_AF = 0x02, /*!< GPIO Alternate function Mode */ + GPIO_Mode_AN = 0x03 /*!< GPIO Analog In/Out Mode */ +} GPIOMode_TypeDef; + +#define IS_GPIO_MODE(MODE) (((MODE) == GPIO_Mode_IN) || \ + ((MODE) == GPIO_Mode_OUT) || \ + ((MODE) == GPIO_Mode_AF) || \ + ((MODE) == GPIO_Mode_AN)) +/** + * @} + */ + +/** @defgroup Output_type_enumeration + * @{ + */ +typedef enum +{ + GPIO_OType_PP = 0x00, + GPIO_OType_OD = 0x01 +} GPIOOType_TypeDef; + +#define IS_GPIO_OTYPE(OTYPE) (((OTYPE) == GPIO_OType_PP) || \ + ((OTYPE) == GPIO_OType_OD)) + +/** + * @} + */ + +/** @defgroup Output_Maximum_frequency_enumeration + * @{ + */ +typedef enum +{ + GPIO_Speed_Level_0 = 0x00, /*!< I/O output speed: Low 4 MHz */ + GPIO_Speed_Level_1 = 0x01, /*!< I/O output speed: Medium 25 MHz */ + GPIO_Speed_Level_2 = 0x02, /*!< I/O output speed: High 50 MHz */ + GPIO_Speed_Level_3 = 0x03 /*!< I/O output speed: Very high 100 MHz */ +} GPIOSpeed_TypeDef; + +#define IS_GPIO_SPEED(SPEED) (((SPEED) == GPIO_Speed_Level_0) || \ + ((SPEED) == GPIO_Speed_Level_1) || \ + ((SPEED) == GPIO_Speed_Level_2) || \ + ((SPEED) == GPIO_Speed_Level_3)) +/** + * @} + */ + +/** @defgroup Configuration_Pull-Up_Pull-Down_enumeration + * @{ + */ +typedef enum +{ + GPIO_PuPd_NOPULL = 0x00, + GPIO_PuPd_UP = 0x01, + GPIO_PuPd_DOWN = 0x02 +} GPIOPuPd_TypeDef; + +#define IS_GPIO_PUPD(PUPD) (((PUPD) == GPIO_PuPd_NOPULL) || \ + ((PUPD) == GPIO_PuPd_UP) || \ + ((PUPD) == GPIO_PuPd_DOWN)) +/** + * @} + */ + +/** @defgroup Bit_SET_and_Bit_RESET_enumeration + * @{ + */ +typedef enum +{ + Bit_RESET = 0, + Bit_SET +} BitAction; + +#define IS_GPIO_BIT_ACTION(ACTION) (((ACTION) == Bit_RESET) || \ + ((ACTION) == Bit_SET)) +/** + * @} + */ + +/** @brief GPIO Init structure definition + * @{ + */ +typedef struct +{ + uint32_t GPIO_Pin; /*!< Specifies the GPIO pins to be configured. + This parameter can be any value of @ref GPIO_pins_define */ + + GPIOMode_TypeDef GPIO_Mode; /*!< Specifies the operating mode for the selected pins. + This parameter can be a value of @ref GPIOMode_TypeDef */ + + GPIOSpeed_TypeDef GPIO_Speed; /*!< Specifies the speed for the selected pins. + This parameter can be a value of @ref GPIOSpeed_TypeDef */ + + GPIOOType_TypeDef GPIO_OType; /*!< Specifies the operating output type for the selected pins. + This parameter can be a value of @ref GPIOOType_TypeDef */ + + GPIOPuPd_TypeDef GPIO_PuPd; /*!< Specifies the operating Pull-up/Pull down for the selected pins. + This parameter can be a value of @ref GPIOPuPd_TypeDef */ +} GPIO_InitTypeDef; + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup GPIO_Exported_Constants + * @{ + */ + +/** @defgroup GPIO_pins_define + * @{ + */ +#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 IS_GPIO_PIN(PIN) ((PIN) != (uint16_t)0x00) + +#define IS_GET_GPIO_PIN(PIN) (((PIN) == GPIO_Pin_0) || \ + ((PIN) == GPIO_Pin_1) || \ + ((PIN) == GPIO_Pin_2) || \ + ((PIN) == GPIO_Pin_3) || \ + ((PIN) == GPIO_Pin_4) || \ + ((PIN) == GPIO_Pin_5) || \ + ((PIN) == GPIO_Pin_6) || \ + ((PIN) == GPIO_Pin_7) || \ + ((PIN) == GPIO_Pin_8) || \ + ((PIN) == GPIO_Pin_9) || \ + ((PIN) == GPIO_Pin_10) || \ + ((PIN) == GPIO_Pin_11) || \ + ((PIN) == GPIO_Pin_12) || \ + ((PIN) == GPIO_Pin_13) || \ + ((PIN) == GPIO_Pin_14) || \ + ((PIN) == GPIO_Pin_15)) + +/** + * @} + */ + +/** @defgroup GPIO_Pin_sources + * @{ + */ +#define GPIO_PinSource0 ((uint8_t)0x00) +#define GPIO_PinSource1 ((uint8_t)0x01) +#define GPIO_PinSource2 ((uint8_t)0x02) +#define GPIO_PinSource3 ((uint8_t)0x03) +#define GPIO_PinSource4 ((uint8_t)0x04) +#define GPIO_PinSource5 ((uint8_t)0x05) +#define GPIO_PinSource6 ((uint8_t)0x06) +#define GPIO_PinSource7 ((uint8_t)0x07) +#define GPIO_PinSource8 ((uint8_t)0x08) +#define GPIO_PinSource9 ((uint8_t)0x09) +#define GPIO_PinSource10 ((uint8_t)0x0A) +#define GPIO_PinSource11 ((uint8_t)0x0B) +#define GPIO_PinSource12 ((uint8_t)0x0C) +#define GPIO_PinSource13 ((uint8_t)0x0D) +#define GPIO_PinSource14 ((uint8_t)0x0E) +#define GPIO_PinSource15 ((uint8_t)0x0F) + +#define IS_GPIO_PIN_SOURCE(PINSOURCE) (((PINSOURCE) == GPIO_PinSource0) || \ + ((PINSOURCE) == GPIO_PinSource1) || \ + ((PINSOURCE) == GPIO_PinSource2) || \ + ((PINSOURCE) == GPIO_PinSource3) || \ + ((PINSOURCE) == GPIO_PinSource4) || \ + ((PINSOURCE) == GPIO_PinSource5) || \ + ((PINSOURCE) == GPIO_PinSource6) || \ + ((PINSOURCE) == GPIO_PinSource7) || \ + ((PINSOURCE) == GPIO_PinSource8) || \ + ((PINSOURCE) == GPIO_PinSource9) || \ + ((PINSOURCE) == GPIO_PinSource10) || \ + ((PINSOURCE) == GPIO_PinSource11) || \ + ((PINSOURCE) == GPIO_PinSource12) || \ + ((PINSOURCE) == GPIO_PinSource13) || \ + ((PINSOURCE) == GPIO_PinSource14) || \ + ((PINSOURCE) == GPIO_PinSource15)) +/** + * @} + */ + +/** @defgroup GPIO_Alternate_function_selection_define + * @brief AF 0~15 selection + * @{ + */ + +#define GPIO_AF_0 ((uint8_t)0x00) /* SYS */ + +#define GPIO_AF_1 ((uint8_t)0x01) /* TIM1/2, LPTIM */ + +#define GPIO_AF_2 ((uint8_t)0x02) /* TIM3/4/5 */ + +#define GPIO_AF_3 ((uint8_t)0x03) /* TIM8/9/10/11, CRS */ + +#define GPIO_AF_4 ((uint8_t)0x04) /* I2C1/2/3, SPI3, I2S3 */ + +#define GPIO_AF_5 ((uint8_t)0x05) /* SPI1/2, I2S2 */ + +#define GPIO_AF_6 ((uint8_t)0x06) /* SPI3, I2S2, SDIO */ + +#define GPIO_AF_7 ((uint8_t)0x07) /* USART1/2/3, UART7 */ + +#define GPIO_AF_8 ((uint8_t)0x08) /* UART4/5, LPUART, USART6, COMP1/2/3/4/5/6 */ + +#define GPIO_AF_9 ((uint8_t)0x09) /* CAN1/2/3/4, TIM12/13/14 */ + +#define GPIO_AF_10 ((uint8_t)0x0A) /* OTG_FS, QUADSPI */ + +#define GPIO_AF_11 ((uint8_t)0x0B) /* ETH */ + +#define GPIO_AF_12 ((uint8_t)0x0C) /* OTH_HS, FMC */ + +#define GPIO_AF_13 ((uint8_t)0x0D) /* SSI, SPDIF */ + +#define GPIO_AF_14 ((uint8_t)0x0E) /* EPWM, EQEP, ECAP*/ + +#define GPIO_AF_15 ((uint8_t)0x0F) /* EVENTOUT*/ + + +#define IS_GPIO_AF(AF) (((AF) == GPIO_AF_0) || ((AF) == GPIO_AF_1) || \ + ((AF) == GPIO_AF_2) || ((AF) == GPIO_AF_3) || \ + ((AF) == GPIO_AF_4) || ((AF) == GPIO_AF_5) || \ + ((AF) == GPIO_AF_6) || ((AF) == GPIO_AF_7) || \ + ((AF) == GPIO_AF_8) || ((AF) == GPIO_AF_9) || \ + ((AF) == GPIO_AF_10) || ((AF) == GPIO_AF_11) || \ + ((AF) == GPIO_AF_12) || ((AF) == GPIO_AF_13) || \ + ((AF) == GPIO_AF_14) || ((AF) == GPIO_AF_15)) + +/** + * @} + */ + +/** @defgroup GPIO_Speed_Legacy + * @{ + */ + +#define GPIO_Speed_4MHz GPIO_Speed_Level_0 /*!< I/O output speed: Low 4 MHz */ +#define GPIO_Speed_25MHz GPIO_Speed_Level_1 /*!< I/O output speed: Medium 25 MHz */ +#define GPIO_Speed_50MHz GPIO_Speed_Level_2 /*!< I/O output speed: High 50 MHz */ +#define GPIO_Speed_100MHz GPIO_Speed_Level_3 /*!< I/O output speed: Very high 100 MHz */ + +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ +/* Function used to set the GPIO configuration to the default reset state *****/ +void GPIO_DeInit(GPIO_TypeDef* GPIOx); + +/* Initialization and Configuration functions *********************************/ +void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct); +void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct); +void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); + +/* GPIO Read and Write functions **********************************************/ +uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); +uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx); +uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); +uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx); +void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); +void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); +void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal); +void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal); + +/* GPIO Alternate functions configuration functions ***************************/ +void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __FT32F4XX_GPIO_H */ + +/************************ (C) COPYRIGHT FMD *****END OF FILE*******************/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_hcd_fs.h b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_hcd_fs.h new file mode 100644 index 00000000000..7fcdd473741 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_hcd_fs.h @@ -0,0 +1,152 @@ +/** + ****************************************************************************** + * @file ft32f4xx_hcd_fs.h + * @author FMD XA + * @brief This file contains all the functions prototypes for the + * >>->-USB_OTG_FS firmware library. + * @version V1.0.0 + * @data 2025-05-28 + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __FT32F4XX_HCD_FS_H +#define __FT32F4XX_HCD_FS_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx_usb_fs.h" + +#if defined (USB_OTG_FS) + +/* Exported types ------------------------------------------------------------*/ + +typedef enum +{ + HCD_FS_STATE_RESET = 0x00, + HCD_FS_STATE_READY = 0x01, + HCD_FS_STATE_ERROR = 0x02, + HCD_FS_STATE_BUSY = 0x03, + HCD_FS_STATE_TIMEOUT = 0x04, +} HCD_FS_StateTypeDef; + + +typedef USB_OTG_FS_CfgTypeDef HCD_FS_InitTypeDef; +typedef USB_OTG_FS_HEPTypeDef HCD_FS_EPTypeDef; +typedef USB_OTG_FS_URBStateTypeDef HCD_FS_URBStateTypeDef; +typedef USB_OTG_FS_HEPStateTypeDef HCD_FS_EPStateTypeDef; +typedef USB_FS_LockTypeDef HCD_FS_LockTypeDef; + +/** + * @} + */ + +typedef struct +{ + HCD_FS_InitTypeDef Init; /*!< HCD required parameters */ + HCD_FS_EPTypeDef ep[16]; /*!< Host endpoint parameters */ + HCD_FS_LockTypeDef Lock; /*!< HCD peripheral status */ + __IO HCD_FS_StateTypeDef State; /*!< HCD communication state */ + __IO uint32_t ErrorCode; /*!< HCD Error code */ + __IO uint32_t cur_ep; /*!< host current used ep pipe*/ + void *pData; /*!< Pointer Stack Handler */ +} HCD_FS_HandleTypeDef; +/** + * @} + */ + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup HCD_Speed HCD Speed + * @{ + */ +#define HCD_SPEED_FULL USB_FS_SPEED +#define HCD_SPEED_LOW USB_LS_SPEED +/** + * @} + */ + +/** @defgroup HCD_Device_Speed HCD Device Speed + * @{ + */ +#define HCD_DEVICE_SPEED_FULL 0U +#define HCD_DEVICE_SPEED_LOW 1U +/** + * @} + */ + + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ + +USB_FS_StatusTypeDef HCD_FS_Init(HCD_FS_HandleTypeDef *hhcd); +USB_FS_StatusTypeDef HCD_FS_DeInit(HCD_FS_HandleTypeDef *hhcd); +USB_FS_StatusTypeDef HCD_FS_EP_Init(HCD_FS_HandleTypeDef *hhcd, uint8_t pipe, + uint8_t epnum, uint8_t dev_address, + uint8_t speed, uint8_t ep_type, + uint16_t mps); + +void HCD_FS_MspInit(HCD_FS_HandleTypeDef *hhcd); +void HCD_FS_MspDeInit(HCD_FS_HandleTypeDef *hhcd); + +/** + * @} + */ + +/* I/O operation functions ***************************************************/ +void HCD_FS_EP_SubmitRequest(HCD_FS_HandleTypeDef *hhcd, uint8_t ep_num, + uint8_t direction, uint8_t ep_type, + uint8_t token, uint8_t *pbuff, + uint16_t length, uint8_t ctl_state); + +/* Non-Blocking mode: Interrupt */ +void HCD_FS_IRQHandler(HCD_FS_HandleTypeDef *hhcd); +void HCD_FS_WKUP_IRQHandler(HCD_FS_HandleTypeDef *hhcd); +void HCD_FS_SOF_Callback(HCD_FS_HandleTypeDef *hhcd); +void HCD_FS_VBusErr_Callback(HCD_FS_HandleTypeDef *hhcd); +void HCD_FS_Session_Callback(HCD_FS_HandleTypeDef *hhcd); +void HCD_FS_Babble_Callback(HCD_FS_HandleTypeDef *hhcd); +void HCD_FS_Resume_Callback(HCD_FS_HandleTypeDef *hhcd); +void HCD_FS_Connect_Callback(HCD_FS_HandleTypeDef *hhcd); +void HCD_FS_Disconnect_Callback(HCD_FS_HandleTypeDef *hhcd); +void HCD_FS_EP_NotifyURBChange_Callback(HCD_FS_HandleTypeDef *hhcd, uint8_t epnum, + HCD_FS_URBStateTypeDef urb_state); + + + +/* Peripheral Control functions **********************************************/ +void HCD_FS_ResetPort(void); +USB_FS_StatusTypeDef HCD_FS_Start(HCD_FS_HandleTypeDef *hhcd); +USB_FS_StatusTypeDef HCD_FS_Stop(HCD_FS_HandleTypeDef *hhcd); + + +/* Peripheral State functions ************************************************/ +HCD_FS_StateTypeDef HCD_FS_GetState(HCD_FS_HandleTypeDef *hhcd); +HCD_FS_URBStateTypeDef HCD_FS_EP_GetURBState(HCD_FS_HandleTypeDef *hhcd, uint8_t ep_num); +HCD_FS_EPStateTypeDef HCD_FS_EP_GetState(HCD_FS_HandleTypeDef *hhcd, uint8_t ep_num); +uint32_t HCD_FS_EP_GetXferCount(HCD_FS_HandleTypeDef *hhcd, uint8_t ep_num); +uint32_t HCD_FS_GetCurrEp(HCD_FS_HandleTypeDef *hhcd); +uint32_t HCD_FS_GetCurrentFrame(void); +uint32_t HCD_FS_GetCurrentSpeed(void); + + +#endif /* defined (USB_OTG_FS) */ + +#ifdef __cplusplus +} +#endif + + +#endif /* FT32F4XX_HCD_FS_H */ + +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_hcd_hs.h b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_hcd_hs.h new file mode 100644 index 00000000000..d7cccfd7092 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_hcd_hs.h @@ -0,0 +1,234 @@ +/** + ****************************************************************************** + * @file ft32f4xx_hcd_hs.h + * @author FMD XA + * @brief This file contains all the functions prototypes for the + * >>->-USB_OTG_HS firmware library. + * @version V1.0.0 + * @data 2025-03-26 + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __FT32F4XX_HCD_HS_H +#define __FT32F4XX_HCD_HS_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx_usb_hs.h" + +#if defined (USB_OTG_HS) +/** @addtogroup ft32f4xx Drive + * @ + */ + +/** @addtogroup HCD_HS + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup HCD_HS_Exported_Types HCD Exported Types + * @{ + */ + +/** @defgroup HCD_HS_Exported_Types_Group1 HCD State Structure definition + * @{ + */ +typedef enum +{ + HCD_HS_STATE_RESET = 0x00, + HCD_HS_STATE_READY = 0x01, + HCD_HS_STATE_ERROR = 0x02, + HCD_HS_STATE_BUSY = 0x03, + HCD_HS_STATE_TIMEOUT = 0x04 +} HCD_HS_StateTypeDef; + +typedef USB_OTG_HS_GlobalTypeDef HCD_HS_TypeDef; +typedef USB_OTG_HS_CfgTypeDef HCD_HS_InitTypeDef; +typedef USB_OTG_HS_HCTypeDef HCD_HS_HCTypeDef; +typedef USB_OTG_HS_URBStateTypeDef HCD_HS_URBStateTypeDef; +typedef USB_OTG_HS_HCStateTypeDef HCD_HS_HCStateTypeDef; +typedef USB_HS_LockTypeDef HCD_HS_LockTypeDef; +/** + * @} + */ + +/** @defgroup HCD_HS_Exported_Types_Group2 HCD Handle Structure definition + * @{ + */ +typedef struct +{ + HCD_HS_InitTypeDef Init; /*!< HCD required parameters */ + HCD_HS_HCTypeDef hc[16]; /*!< Host channels parameters */ + HCD_HS_LockTypeDef Lock; /*!< HCD peripheral status */ + __IO HCD_HS_StateTypeDef State; /*!< HCD communication state */ + __IO uint32_t ErrorCode; /*!< HCD Error code */ + void *pData; /*!< Pointer Stack Handler */ +} HCD_HS_HandleTypeDef; +/** + * @} + */ + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup HCD_HS_Exported_Constants HCD Exported Constants + * @{ + */ + +/** @defgroup HCD_Speed HCD Speed + * @{ + */ +#define HCD_SPEED_HIGH USBH_HS_SPEED +#define HCD_SPEED_FULL USBH_FSLS_SPEED +#define HCD_SPEED_LOW USBH_FSLS_SPEED +/** + * @} + */ + +/** @defgroup HCD_Device_Speed HCD Device Speed + * @{ + */ +#define HCD_DEVICE_SPEED_HIGH 0U +#define HCD_DEVICE_SPEED_FULL 1U +#define HCD_DEVICE_SPEED_LOW 2U +/** + * @} + */ + + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup HCD_HS_Exported_Macros HCD Exported Macros + * @brief macros to handle interrupts and specific clock configurations + * @{ + */ +#define __HCD_HS_ENABLE() (void)USB_HS_EnableGlobalInt () +#define __HCD_HS_DISABLE() (void)USB_HS_DisableGlobalInt () + +#define __HCD_HS_GET_FLAG(__INTERRUPT__) ((USB_HS_ReadInterrupts()\ + & (__INTERRUPT__)) == (__INTERRUPT__)) +#define __HCD_HS_GET_CH_FLAG(__chnum__, __INTERRUPT__) \ + ((USB_HS_ReadChInterrupts(__chnum__)\ + & (__INTERRUPT__)) == (__INTERRUPT__)) +#define __HCD_HS_CLEAR_FLAG(__INTERRUPT__) ((USB_HS->GINTSTS) = (__INTERRUPT__)) +#define __HCD_HS_IS_INVALID_INTERRUPT() (USB_HS_ReadInterrupts() == 0U) + +#define __HCD_HS_CLEAR_HC_INT(chnum, __INTERRUPT__) (USB_HS_HC(chnum)->HCINT = (__INTERRUPT__)) +#define __HCD_HS_MASK_HALT_HC_INT(chnum) (USB_HS_HC(chnum)->HCINTMSK &= ~OTG_HS_HCINTMSK_CHHM) +#define __HCD_HS_UNMASK_HALT_HC_INT(chnum) (USB_HS_HC(chnum)->HCINTMSK |= OTG_HS_HCINTMSK_CHHM) +#define __HCD_HS_MASK_ACK_HC_INT(chnum) (USB_HS_HC(chnum)->HCINTMSK &= ~OTG_HS_HCINTMSK_ACKM) +#define __HCD_HS_UNMASK_ACK_HC_INT(chnum) (USB_HS_HC(chnum)->HCINTMSK |= OTG_HS_HCINTMSK_ACKM) +#define __HCD_HS_SET_HC_CSPLT(chnum) (USB_HS_HC(chnum)->HCSPLT |= OTG_HS_HCSPLT_COMPLSPLT) +#define __HCD_HS_CLEAR_HC_CSPLT(chnum) (USB_HS_HC(chnum)->HCSPLT &= ~OTG_HS_HCSPLT_COMPLSPLT) +#define __HCD_HS_CLEAR_HC_SSPLT(chnum) (USB_HS_HC(chnum)->HCSPLT &= ~OTG_HS_HCSPLT_SPLITEN) +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup HCD_HS_Exported_Functions HCD Exported Functions + * @{ + */ + +/** @defgroup HCD_HS_Exported_Functions_Group1 Initialization and de-initialization functions + * @{ + */ +USB_HS_StatusTypeDef HCD_HS_Init(HCD_HS_HandleTypeDef *hhcd); +USB_HS_StatusTypeDef HCD_HS_DeInit(HCD_HS_HandleTypeDef *hhcd); +USB_HS_StatusTypeDef HCD_HS_HC_Init(HCD_HS_HandleTypeDef *hhcd, uint8_t ch_num, + uint8_t epnum, uint8_t dev_address, + uint8_t speed, uint8_t ep_type, uint16_t mps); + +USB_HS_StatusTypeDef HCD_HS_HC_Halt(HCD_HS_HandleTypeDef *hhcd, uint8_t ch_num); +void HCD_HS_MspInit(HCD_HS_HandleTypeDef *hhcd); +void HCD_HS_MspDeInit(HCD_HS_HandleTypeDef *hhcd); + +/** + * @} + */ + +/* I/O operation functions ***************************************************/ +/** @addtogroup HCD_Exported_Functions_Group2 Input and Output operation functions + * @{ + */ +void HCD_HS_HC_SubmitRequest(HCD_HS_HandleTypeDef *hhcd, uint8_t ch_num, + uint8_t direction, uint8_t ep_type, + uint8_t token, uint8_t *pbuff, + uint16_t length, uint8_t do_ping); + +void HCD_HS_HC_SetHubInfo(HCD_HS_HandleTypeDef *hhcd, uint8_t ch_num, + uint8_t addr, uint8_t PortNbr); + + +void HCD_HS_HC_ClearHubInfo(HCD_HS_HandleTypeDef *hhcd, uint8_t ch_num); + +/* Non-Blocking mode: Interrupt */ +void HCD_HS_IRQHandler(HCD_HS_HandleTypeDef *hhcd); +void HCD_HS_WKUP_IRQHandler(HCD_HS_HandleTypeDef *hhcd); +void HCD_HS_SOF_Callback(HCD_HS_HandleTypeDef *hhcd); +void HCD_HS_Connect_Callback(HCD_HS_HandleTypeDef *hhcd); +void HCD_HS_Disconnect_Callback(HCD_HS_HandleTypeDef *hhcd); +void HCD_HS_PortEnabled_Callback(HCD_HS_HandleTypeDef *hhcd); +void HCD_HS_PortDisabled_Callback(HCD_HS_HandleTypeDef *hhcd); +void HCD_HS_HC_NotifyURBChange_Callback(HCD_HS_HandleTypeDef *hhcd, uint8_t chnum, + HCD_HS_URBStateTypeDef urb_state); +/** + * @} + */ + +/* Peripheral Control functions **********************************************/ +/** @addtogroup HCD_HS_Exported_Functions_Group3 Peripheral Control functions + * @{ + */ +void HCD_HS_ResetPort(void); +USB_HS_StatusTypeDef HCD_HS_Start(HCD_HS_HandleTypeDef *hhcd); +USB_HS_StatusTypeDef HCD_HS_Stop(HCD_HS_HandleTypeDef *hhcd); +/** + * @} + */ + +/* Peripheral State functions ************************************************/ +/** @addtogroup HCD_Exported_Functions_Group4 Peripheral State functions + * @{ + */ +HCD_HS_StateTypeDef HCD_HS_GetState(HCD_HS_HandleTypeDef *hhcd); +HCD_HS_URBStateTypeDef HCD_HS_HC_GetURBState(HCD_HS_HandleTypeDef *hhcd, uint8_t chnum); +HCD_HS_HCStateTypeDef HCD_HS_HC_GetState(HCD_HS_HandleTypeDef *hhcd, uint8_t chnum); +uint32_t HCD_HS_HC_GetXferCount(HCD_HS_HandleTypeDef *hhcd, uint8_t chnum); +uint32_t HCD_HS_GetCurrentFrame(void); +uint32_t HCD_HS_GetCurrentSpeed(void); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +#endif /* defined (USB_OTG_HS) */ + +#ifdef __cplusplus +} +#endif + + +#endif /* FT32F4XX_HCD_HS_H */ + +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_i2c.h b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_i2c.h new file mode 100644 index 00000000000..05cbf0e869a --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_i2c.h @@ -0,0 +1,475 @@ +/** + ****************************************************************************** + * @file ft32f4xx_i2c.h + * @author FMD AE + * @brief This file contains all the functions prototypes for + * the I2C firmware library + * @version V1.0.0 + * @date 2025-03-31 + ****************************************************************************** + */ + + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __FT32F4XX_I2C_H +#define __FT32F4XX_I2C_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx.h" + + +/** @addtogroup I2C + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/**@brief I2C Init structure definition + * @{ + */ + +typedef struct +{ + uint32_t I2C_Timing; /*!< Specifies the I2C_TIMINGR_register value */ + + uint32_t I2C_AnalogFilter; /*!< Enables or disables analog noise filter. + This parameter can be a value of @ref I2C_Analog_Filter */ + + uint32_t I2C_DigitalFilter; /*!< Configures the digital noise filter. + This parameter can be a number between 0x00 and 0x0F */ + + uint32_t I2C_NoStretchMode; /*!< Specifies if nostretch mode is selected. + This parameter can be a value of @ref I2C_NoStretch_Mode */ + + uint32_t I2C_Mode; /*!< Specifies the I2C mode. + This parameter can be a value of @ref I2C_mode */ + + uint32_t I2C_OwnAddress1; /*!< Specifies the device own address 1. + This parameter can be a 7-bit or 10-bit address */ + + uint32_t I2C_Ack; /*!< Enables or disables the acknowledgement. + This parameter can be a value of @ref I2C_acknowledgement */ + + uint32_t I2C_AcknowledgedAddress; /*!< Specifies if 7-bit or 10-bit address is acknowledged. + This parameter can be a value of @ref I2C_acknowledged_address */ +} I2C_InitTypeDef; + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ + + +/** @defgroup I2C_Exported_Constants + * @{ + */ + +#define IS_I2C_ALL_PERIPH(PERIPH) (((PERIPH) == I2C1) || \ + ((PERIPH) == I2C2) || \ + ((PERIPH) == I2C3)) + + +/** @defgroup I2C_Analog_Filter + * @{ + */ + +#define I2C_AnalogFilter_Enable ((uint32_t)0x00000000) +#define I2C_AnalogFilter_Disable I2C_CR1_ANFOFF + +#define IS_I2C_ANALOG_FILTER(FILTER) (((FILTER) == I2C_AnalogFilter_Enable) || \ + ((FILTER) == I2C_AnalogFilter_Disable)) +/** + * @} + */ + +/** @defgroup I2C_Digital_Filter + * @{ + */ + +#define IS_I2C_DIGITAL_FILTER(FILTER) ((FILTER) <= 0x0000000F) + +/** + * @} + */ + +/** @defgroup I2C_NoStretch_Mode + * @{ + */ +#define I2C_NoStretch_Disable (0x00000000U) +#define I2C_NoStretch_Enable I2C_CR1_NOSTRETCH + +#define IS_I2C_NoStretch(MODE) (((MODE) == I2C_NoStretch_Enable) || \ + ((MODE) == I2C_NoStretch_Disable)) + +/** + * @} + */ + +/** @defgroup I2C_mode + * @{ + */ + +#define I2C_Mode_I2C ((uint32_t)0x00000000) +#define I2C_Mode_SMBusDevice I2C_CR1_SMBDEN +#define I2C_Mode_SMBusHost I2C_CR1_SMBHEN + +#define IS_I2C_MODE(MODE) (((MODE) == I2C_Mode_I2C) || \ + ((MODE) == I2C_Mode_SMBusDevice) || \ + ((MODE) == I2C_Mode_SMBusHost)) +/** + * @} + */ + +/** @defgroup I2C_acknowledgement + * @{ + */ + +#define I2C_Ack_Enable ((uint32_t)0x00000000) +#define I2C_Ack_Disable I2C_CR2_NACK + +#define IS_I2C_ACK(ACK) (((ACK) == I2C_Ack_Enable) || \ + ((ACK) == I2C_Ack_Disable)) +/** + * @} + */ + +/** @defgroup I2C_acknowledged_address + * @{ + */ + +#define I2C_AcknowledgedAddress_7bit ((uint32_t)0x00000000) +#define I2C_AcknowledgedAddress_10bit I2C_OAR1_OA1MODE + +#define IS_I2C_ACKNOWLEDGE_ADDRESS(ADDRESS) (((ADDRESS) == I2C_AcknowledgedAddress_7bit) || \ + ((ADDRESS) == I2C_AcknowledgedAddress_10bit)) +/** + * @} + */ + +/** @defgroup I2C_own_address1 + * @{ + */ + +#define IS_I2C_OWN_ADDRESS1(ADDRESS1) ((ADDRESS1) <= (uint32_t)0x000003FF) +/** + * @} + */ + +/** @defgroup I2C_transfer_direction + * @{ + */ + +#define I2C_Direction_Transmitter ((uint16_t)0x0000) +#define I2C_Direction_Receiver ((uint16_t)0x0400) + +#define IS_I2C_DIRECTION(DIRECTION) (((DIRECTION) == I2C_Direction_Transmitter) || \ + ((DIRECTION) == I2C_Direction_Receiver)) +/** + * @} + */ + +/** @defgroup I2C_DMA_transfer_requests + * @{ + */ + +#define I2C_DMAReq_Tx I2C_CR1_TXDMAEN +#define I2C_DMAReq_Rx I2C_CR1_RXDMAEN + +#define IS_I2C_DMA_REQ(REQ) ((((REQ) & (uint32_t)0xFFFF3FFF) == 0x00) && ((REQ) != 0x00)) +/** + * @} + */ + +/** @defgroup I2C_slave_address + * @{ + */ + +#define IS_I2C_SLAVE_ADDRESS(ADDRESS) ((ADDRESS) <= (uint16_t)0x03FF) +/** + * @} + */ + + +/** @defgroup I2C_own_address2 + * @{ + */ + +#define IS_I2C_OWN_ADDRESS2(ADDRESS2) ((ADDRESS2) <= (uint16_t)0x00FF) + +/** + * @} + */ + +/** @defgroup I2C_own_address2_mask + * @{ + */ + +#define I2C_OA2_NoMask ((uint8_t)0x00) +#define I2C_OA2_Mask01 ((uint8_t)0x01) +#define I2C_OA2_Mask02 ((uint8_t)0x02) +#define I2C_OA2_Mask03 ((uint8_t)0x03) +#define I2C_OA2_Mask04 ((uint8_t)0x04) +#define I2C_OA2_Mask05 ((uint8_t)0x05) +#define I2C_OA2_Mask06 ((uint8_t)0x06) +#define I2C_OA2_Mask07 ((uint8_t)0x07) + +#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)) + +/** + * @} + */ + +/** @defgroup I2C_timeout + * @{ + */ + +#define IS_I2C_TIMEOUT(TIMEOUT) ((TIMEOUT) <= (uint16_t)0x0FFF) + +/** + * @} + */ + +/** @defgroup I2C_registers + * @{ + */ + +#define I2C_Register_CR1 ((uint8_t)0x00) +#define I2C_Register_CR2 ((uint8_t)0x04) +#define I2C_Register_OAR1 ((uint8_t)0x08) +#define I2C_Register_OAR2 ((uint8_t)0x0C) +#define I2C_Register_TIMINGR ((uint8_t)0x10) +#define I2C_Register_TIMEOUTR ((uint8_t)0x14) +#define I2C_Register_ISR ((uint8_t)0x18) +#define I2C_Register_ICR ((uint8_t)0x1C) +#define I2C_Register_PECR ((uint8_t)0x20) +#define I2C_Register_RXDR ((uint8_t)0x24) +#define I2C_Register_TXDR ((uint8_t)0x28) + +#define IS_I2C_REGISTER(REGISTER) (((REGISTER) == I2C_Register_CR1) || \ + ((REGISTER) == I2C_Register_CR2) || \ + ((REGISTER) == I2C_Register_OAR1) || \ + ((REGISTER) == I2C_Register_OAR2) || \ + ((REGISTER) == I2C_Register_TIMINGR) || \ + ((REGISTER) == I2C_Register_TIMEOUTR) || \ + ((REGISTER) == I2C_Register_ISR) || \ + ((REGISTER) == I2C_Register_ICR) || \ + ((REGISTER) == I2C_Register_PECR) || \ + ((REGISTER) == I2C_Register_RXDR) || \ + ((REGISTER) == I2C_Register_TXDR)) +/** + * @} + */ + +/** @defgroup I2C_interrupts_definition + * @{ + */ + +#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 + +#define IS_I2C_CONFIG_IT(IT) ((((IT) & (uint32_t)0xFFFFFF01) == 0x00) && ((IT) != 0x00)) + +/** + * @} + */ + +/** @defgroup I2C_flags_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_NACKF 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 IS_I2C_CLEAR_FLAG(FLAG) ((((FLAG) & (uint32_t)0xFFFF4000) == 0x00) && ((FLAG) != 0x00)) + +#define IS_I2C_GET_FLAG(FLAG) (((FLAG) == I2C_FLAG_TXE) || ((FLAG) == I2C_FLAG_TXIS) || \ + ((FLAG) == I2C_FLAG_RXNE) || ((FLAG) == I2C_FLAG_ADDR) || \ + ((FLAG) == I2C_FLAG_NACKF) || ((FLAG) == I2C_FLAG_STOPF) || \ + ((FLAG) == I2C_FLAG_TC) || ((FLAG) == I2C_FLAG_TCR) || \ + ((FLAG) == I2C_FLAG_BERR) || ((FLAG) == I2C_FLAG_ARLO) || \ + ((FLAG) == I2C_FLAG_OVR) || ((FLAG) == I2C_FLAG_PECERR) || \ + ((FLAG) == I2C_FLAG_TIMEOUT) || ((FLAG) == I2C_FLAG_ALERT) || \ + ((FLAG) == I2C_FLAG_BUSY)) + +/** + * @} + */ + + +/** @defgroup I2C_interrupts_definition + * @{ + */ + +#define I2C_IT_TXIS I2C_ISR_TXIS +#define I2C_IT_RXNE I2C_ISR_RXNE +#define I2C_IT_ADDR I2C_ISR_ADDR +#define I2C_IT_NACKF I2C_ISR_NACKF +#define I2C_IT_STOPF I2C_ISR_STOPF +#define I2C_IT_TC I2C_ISR_TC +#define I2C_IT_TCR I2C_ISR_TCR +#define I2C_IT_BERR I2C_ISR_BERR +#define I2C_IT_ARLO I2C_ISR_ARLO +#define I2C_IT_OVR I2C_ISR_OVR +#define I2C_IT_PECERR I2C_ISR_PECERR +#define I2C_IT_TIMEOUT I2C_ISR_TIMEOUT +#define I2C_IT_ALERT I2C_ISR_ALERT + +#define IS_I2C_CLEAR_IT(IT) ((((IT) & (uint32_t)0xFFFFC001) == 0x00) && ((IT) != 0x00)) + +#define IS_I2C_GET_IT(IT) (((IT) == I2C_IT_TXIS) || ((IT) == I2C_IT_RXNE) || \ + ((IT) == I2C_IT_ADDR) || ((IT) == I2C_IT_NACKF) || \ + ((IT) == I2C_IT_STOPF) || ((IT) == I2C_IT_TC) || \ + ((IT) == I2C_IT_TCR) || ((IT) == I2C_IT_BERR) || \ + ((IT) == I2C_IT_ARLO) || ((IT) == I2C_IT_OVR) || \ + ((IT) == I2C_IT_PECERR) || ((IT) == I2C_IT_TIMEOUT) || \ + ((IT) == I2C_IT_ALERT)) + + +/** + * @} + */ + +/** @defgroup I2C_ReloadEndMode_definition + * @{ + */ + +#define I2C_Reload_Mode I2C_CR2_RELOAD +#define I2C_AutoEnd_Mode I2C_CR2_AUTOEND +#define I2C_SoftEnd_Mode ((uint32_t)0x00000000) + + +#define IS_RELOAD_END_MODE(MODE) (((MODE) == I2C_Reload_Mode) || \ + ((MODE) == I2C_AutoEnd_Mode) || \ + ((MODE) == I2C_SoftEnd_Mode)) + + +/** + * @} + */ + +/** @defgroup I2C_StartStopMode_definition + * @{ + */ + +#define I2C_No_StartStop ((uint32_t)0x00000000) +#define I2C_Generate_Stop I2C_CR2_STOP +#define I2C_Generate_Start_Read (uint32_t)(I2C_CR2_START | I2C_CR2_RD_WRN) +#define I2C_Generate_Start_Write I2C_CR2_START + + +#define IS_START_STOP_MODE(MODE) (((MODE) == I2C_Generate_Stop) || \ + ((MODE) == I2C_Generate_Start_Read) || \ + ((MODE) == I2C_Generate_Start_Write) || \ + ((MODE) == I2C_No_StartStop)) + + +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + + +/* Initialization and Configuration functions *********************************/ +void I2C_DeInit(I2C_TypeDef* I2Cx); +void I2C_Init(I2C_TypeDef* I2Cx, I2C_InitTypeDef* I2C_InitStruct); +void I2C_StructInit(I2C_InitTypeDef* I2C_InitStruct); +void I2C_Cmd(I2C_TypeDef* I2Cx, FunctionalState NewState); +void I2C_SoftwareResetCmd(I2C_TypeDef* I2Cx); +void I2C_ITConfig(I2C_TypeDef* I2Cx, uint32_t I2C_IT, FunctionalState NewState); +void I2C_StretchClockCmd(I2C_TypeDef* I2Cx, FunctionalState NewState); +void I2C_DualAddressCmd(I2C_TypeDef* I2Cx, FunctionalState NewState); +void I2C_OwnAddress2Config(I2C_TypeDef* I2Cx, uint16_t Address, uint8_t Mask); +void I2C_GeneralCallCmd(I2C_TypeDef* I2Cx, FunctionalState NewState); +void I2C_SlaveByteControlCmd(I2C_TypeDef* I2Cx, FunctionalState NewState); +void I2C_SlaveAddressConfig(I2C_TypeDef* I2Cx, uint16_t Address); +void I2C_10BitAddressingModeCmd(I2C_TypeDef* I2Cx, FunctionalState NewState); + +/* Communications handling functions ******************************************/ +void I2C_AutoEndCmd(I2C_TypeDef* I2Cx, FunctionalState NewState); +void I2C_ReloadCmd(I2C_TypeDef* I2Cx, FunctionalState NewState); +void I2C_NumberOfBytesConfig(I2C_TypeDef* I2Cx, uint8_t Number_Bytes); +void I2C_MasterRequestConfig(I2C_TypeDef* I2Cx, uint16_t I2C_Direction); +void I2C_GenerateSTART(I2C_TypeDef* I2Cx, FunctionalState NewState); +void I2C_GenerateSTOP(I2C_TypeDef* I2Cx, FunctionalState NewState); +void I2C_10BitAddressHeaderCmd(I2C_TypeDef* I2Cx, FunctionalState NewState); +void I2C_AcknowledgeConfig(I2C_TypeDef* I2Cx, FunctionalState NewState); +uint8_t I2C_GetAddressMatched(I2C_TypeDef* I2Cx); +uint16_t I2C_GetTransferDirection(I2C_TypeDef* I2Cx); +void I2C_GenerateTXIS(I2C_TypeDef* I2Cx, FunctionalState NewState); +void I2C_GenerateTXE(I2C_TypeDef* I2Cx, FunctionalState NewState); +void I2C_TransferHandling(I2C_TypeDef* I2Cx, uint16_t Address, uint8_t Number_Bytes, uint32_t ReloadEndMode, uint32_t StartStopMode); + +/* SMBUS management functions ************************************************/ +void I2C_SMBusAlertCmd(I2C_TypeDef* I2Cx, FunctionalState NewState); +void I2C_ClockTimeoutCmd(I2C_TypeDef* I2Cx, FunctionalState NewState); +void I2C_ExtendedClockTimeoutCmd(I2C_TypeDef* I2Cx, FunctionalState NewState); +void I2C_IdleClockTimeoutCmd(I2C_TypeDef* I2Cx, FunctionalState NewState); +void I2C_TimeoutAConfig(I2C_TypeDef* I2Cx, uint16_t Timeout); +void I2C_TimeoutBConfig(I2C_TypeDef* I2Cx, uint16_t Timeout); +void I2C_CalculatePEC(I2C_TypeDef* I2Cx, FunctionalState NewState); +void I2C_PECRequestCmd(I2C_TypeDef* I2Cx, FunctionalState NewState); +uint8_t I2C_GetPEC(I2C_TypeDef* I2Cx); + +/* I2C registers management functions *****************************************/ +uint32_t I2C_ReadRegister(I2C_TypeDef* I2Cx, uint8_t I2C_Register); + +/* Data transfers management functions ****************************************/ +void I2C_SendData(I2C_TypeDef* I2Cx, uint8_t Data); +uint8_t I2C_ReceiveData(I2C_TypeDef* I2Cx); + +/* DMA transfers management functions *****************************************/ +void I2C_DMACmd(I2C_TypeDef* I2Cx, uint32_t I2C_DMAReq, FunctionalState NewState); + +/* Interrupts and flags management functions **********************************/ +FlagStatus I2C_GetFlagStatus(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG); +void I2C_ClearFlag(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG); +ITStatus I2C_GetITStatus(I2C_TypeDef* I2Cx, uint32_t I2C_IT); +void I2C_ClearITPendingBit(I2C_TypeDef* I2Cx, uint32_t I2C_IT); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /*__FT32F4XX_I2C_H */ + +/************************ (C) COPYRIGHT FMD *****END OF FILE*******************/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_i2s.h b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_i2s.h new file mode 100644 index 00000000000..605db5c6796 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_i2s.h @@ -0,0 +1,488 @@ +/** + ****************************************************************************** + * @file ft32f4xx_i2s.h + * @author FMD AE + * @brief This file contains all the functions prototypes for + * the I2S firmware library + * @version V1.0.0 + * @date 2025-04-01 + ****************************************************************************** + */ + + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __FT32F4XX_I2S_H +#define __FT32F4XX_I2S_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx.h" + + +/** @addtogroup I2S + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup I2S_Exported_Types I2S Exported Types + * @{ + */ + +/** + * @brief I2S Init structure definition + */ +typedef struct +{ + uint32_t I2S_Channel0; /*!< Specifies the I2S channel 0 operating mode. + This parameter can be a value of @ref I2S_Channel0_Configuration */ + + uint32_t I2S_Channel1; /*!< Specifies the I2S channel 1 operating mode. + This parameter can be a value of @ref I2S_Channel1_Configuration */ + + uint32_t I2S_TranMasterSlaveConfig; /*!< Specifies the I2S transmitter master or slave. + This parameter can be a value of @ref I2S_MASTER_SLAVE */ + + uint32_t I2S_RecMasterSlaveConfig; /*!< Specifies the I2S receiver master or slave. + This parameter can be a value of @ref I2S_MASTER_SLAVE */ + + uint32_t I2S_TranSampleRate; /*!< Specifies the I2S transmit sample rate. + This parameter can be a value of @ref I2S_RATE */ + + uint32_t I2S_TranSampleResolution; /*!< Specifies the I2S transmit sample resolution. + This parameter can be a value of @ref I2S_RESOLUTION */ + + uint32_t I2S_RecSampleRate; /*!< Specifies the I2S receive sample rate. + This parameter can be a value of @ref I2S_RATE */ + + uint32_t I2S_RecSampleResolution; /*!< Specifies the I2S transmit sample resolution. + This parameter can be a value of @ref I2S_RESOLUTION */ + + uint32_t I2S_TFIFOAEmptyThreshold; /*!< Specifies the I2S transmit FIFO almost empty threshold + This parameter can be a value of @ref I2S_FIFO_THRESHOLD */ + + uint32_t I2S_TFIFOAFullThreshold; /*!< Specifies the I2S transmit FIFO almost full threshold + This parameter can be a value of @ref I2S_FIFO_THRESHOLD */ + + uint32_t I2S_RFIFOAEmptyThreshold; /*!< Specifies the I2S receive FIFO almost empty threshold + This parameter can be a value of @ref I2S_FIFO_THRESHOLD */ + + uint32_t I2S_RFIFOAFullThreshold; /*!< Specifies the I2S receive FIFO almost full threshold + This parameter can be a value of @ref I2S_FIFO_THRESHOLD */ + + uint32_t I2S_Standard; /*!< Specifies the standard used for the I2S communication + This parameter can be a value of @ref I2S_STANDARD */ +} I2S_InitTypeDef; +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup I2S_Exported_Constants I2S Exported Constants + * @{ + */ +/** @defgroup I2S_Periph + * @{ + */ +#define IS_I2S_ALL_PERIPH(PERIPH) (((PERIPH) == I2S2) || \ + ((PERIPH) == I2S3)) +/** + * @} + */ + +/** @defgroup I2S_Channel0_Configuration + * @{ + */ +#define I2S_Ch0_Disable ((uint32_t)0x00000000) +#define I2S_Ch0_Transmitter ((uint32_t)0x00000001) +#define I2S_Ch0_Receiver ((uint32_t)0x00000010) + +#define IS_I2S_CH0_CONFIG(CONFIG) (((CONFIG) == I2S_Ch0_Disable) || \ + ((CONFIG) == I2S_Ch0_Transmitter) || \ + ((CONFIG) == I2S_Ch0_Receiver)) +/** + * @} + */ + +/** @defgroup I2S_Channel1_Configuration + * @{ + */ +#define I2S_Ch1_Disable ((uint32_t)0x00000000) +#define I2S_Ch1_Transmitter ((uint32_t)0x00000001) +#define I2S_Ch1_Receiver ((uint32_t)0x00000010) + +#define IS_I2S_CH1_CONFIG(CONFIG) (((CONFIG) == I2S_Ch1_Disable) || \ + ((CONFIG) == I2S_Ch1_Transmitter) || \ + ((CONFIG) == I2S_Ch1_Receiver)) +/** + * @} + */ + +/** @defgroup I2S_MASTER_SLAVE + * @{ + */ +#define I2S_MASTER 0x00000000 +#define I2S_SLAVE 0x00000001 + + +#define IS_I2S_MASTERSLAVE_STATE(STATE) (((STATE) == I2S_MASTER) || \ + ((STATE) == I2S_SLAVE)) +/** + * @} + */ + +/** @defgroup I2S_SAMPLE_RATE + * @{ + */ +#define IS_I2S_SAMPLE_RATE(SAMPLE_RATE) ((SAMPLE_RATE) <= (uint16_t)0x7FF) +/** + * @} + */ + +/** @defgroup I2S_RESOLUTION + * @{ + */ +#define IS_I2S_RESOLUTION(RESOLUTION) ((RESOLUTION) <= (uint8_t)0x1F) +/** + * @} + */ + +/** @defgroup I2S_FIFO_THRESHOLD + * @{ + */ +#define IS_I2S_FIFO_THRESHOLD(FIFO_THRESHOLD) ((FIFO_THRESHOLD) <= (uint8_t)0x07) +/** + * @} + */ + +/** @defgroup I2S_STANDARD + * @{ + */ +#define I2S_Philips ((uint32_t)0x00000249) +#define I2S_Right_Justified ((uint32_t)0x000004D3) +#define I2S_Left_Justified ((uint32_t)0x000006DB) +#define I2S_DSP ((uint32_t)0x00000A69) + +#define IS_I2S_STANDARD(STANDARD) (((STANDARD) == I2S_Philips) || \ + ((STANDARD) == I2S_Right_Justified) || \ + ((STANDARD) == I2S_Left_Justified) || \ + ((STANDARD) == I2S_DSP)) +/** + * @} + */ + +/** @defgroup I2S_CHANNEL_ENABLE + * @{ + */ +#define I2S_CH0 I2S_CTRL_I2SEN0 +#define I2S_CH1 I2S_CTRL_I2SEN1 + +#define IS_I2S_CHANNEL_SEL(CHy) (((CHy) == I2S_CH0) || \ + ((CHy) == I2S_CH1)) +/** + * @} + */ + +/** @defgroup I2S_CHANNEL_TRANSMITTER_OR_RECEIVER + * @{ + */ +#define I2S_CH0_TRANREC I2S_CTRL_TRCFG0 +#define I2S_CH1_TRANREC I2S_CTRL_TRCFG1 + +#define IS_I2S_CHANNEL_TRANREC(CHy_TRANREC) (((CHy_TRANREC) == I2S_CTRL_TRCFG0) || \ + ((CHy_TRANREC) == I2S_CTRL_TRCFG1)) +/** + * @} + */ +/** @defgroup I2S_TRANSMITTER_RECEIVER + * @{ + */ +#define I2S_TRANSMITTER 0x00000001 +#define I2S_RECEIVER 0x00000000 + +#define IS_I2S_TRANREC_STATE(STATE) (((STATE) == I2S_TRANSMITTER) || \ + ((STATE) == I2S_RECEIVER)) +/** + * @} + */ + +/** @defgroup I2S_CHANNEL_CLOCK_STROBE + * @{ + */ +#define I2S_CH0_CLOCK_STROBE I2S_CID_CTRL_I2SSTROBE0 +#define I2S_CH1_CLOCK_STROBE I2S_CID_CTRL_I2SSTROBE1 + +#define IS_I2S_CHANNEL_CLOCK_STROBE(CHy_CLOCK) (((CHy_CLOCK) == I2S_CID_CTRL_I2SSTROBE0) || \ + ((CHy_CLOCK) == I2S_CID_CTRL_I2SSTROBE1)) +/** + * @} + */ + +/** @defgroup I2S_SCK_POLAR + * @{ + */ +#define I2S_SCK_POLAR_RISE ((uint8_t)0x00) +#define I2S_SCK_POLAR_FALL ((uint8_t)0x01) + +#define IS_I2S_SCK_POLAR(SCK_POLAR) (((SCK_POLAR) == I2S_SCK_POLAR_FALL) || \ + ((SCK_POLAR) == I2S_SCK_POLAR_RISE)) +/** + * @} + */ + +/** @defgroup I2S_WS_POLAR + * @{ + */ +#define I2S_WS_POLAR_0 ((uint8_t)0x00) +#define I2S_WS_POLAR_1 ((uint8_t)0x01) + +#define IS_I2S_WS_POLAR(WS_POLAR) (((WS_POLAR) == I2S_WS_POLAR_0) || \ + ((WS_POLAR) == I2S_WS_POLAR_1)) +/** + * @} + */ + +/** @defgroup I2S_ALIGNMENT + * @{ + */ +#define I2S_ALIGN_LSB ((uint8_t)0x00) +#define I2S_ALIGN_MSB ((uint8_t)0x01) + +#define IS_I2S_ALIGNMENT(ALIGNMENT) (((ALIGNMENT) == I2S_ALIGN_LSB) || \ + ((ALIGNMENT) == I2S_ALIGN_MSB)) +/** + * @} + */ + +/** @defgroup I2S_TRAN_DATA_WS_DEL + * @{ + */ +#define I2S_TRAN_DATA_WS_DEL_0 ((uint8_t)0x00) +#define I2S_TRAN_DATA_WS_DEL_1 ((uint8_t)0x01) + +#define IS_I2S_TRAN_DATA_WS_DEL(DELAY) (((DELAY) == I2S_TRAN_DATA_WS_DEL_0) || \ + ((DELAY) == I2S_TRAN_DATA_WS_DEL_1)) +/** + * @} + */ + +/** @defgroup I2S_REC_DATA_WS_DEL + * @{ + */ +#define I2S_REC_DATA_WS_DEL_0 ((uint8_t)0x00) +#define I2S_REC_DATA_WS_DEL_1 ((uint8_t)0x01) + +#define IS_I2S_REC_DATA_WS_DEL(DELAY) (((DELAY) == I2S_REC_DATA_WS_DEL_0) || \ + ((DELAY) == I2S_REC_DATA_WS_DEL_1)) +/** + * @} + */ + +/** @defgroup I2S_WS_FORMAT + * @{ + */ +#define I2S_WS_PHILIPS ((uint8_t)0x00) +#define I2S_WS_DSP ((uint8_t)0x01) + +#define IS_I2S_WS_FORMAT(FORMAT) (((FORMAT) == I2S_WS_PHILIPS) || \ + ((FORMAT) == I2S_WS_DSP)) +/** + * @} + */ + +/** @defgroup I2S_registers + * @{ + */ +#define I2S_Register_CTRL ((uint8_t)0x00) +#define I2S_Register_INTR_STAT ((uint8_t)0x04) +#define I2S_Register_SRR ((uint8_t)0x08) +#define I2S_Register_CID_CTRL ((uint8_t)0x0C) +#define I2S_Register_TFIFO_STAT ((uint8_t)0x10) +#define I2S_Register_RFIFO_STAT ((uint8_t)0x14) +#define I2S_Register_TFIFO_CTRL ((uint8_t)0x18) +#define I2S_Register_RFIFO_CTRL ((uint8_t)0x1C) +#define I2S_Register_DEV_CONF ((uint8_t)0x20) +#define I2S_Register_POLL_STAT ((uint8_t)0x24) + +#define IS_I2S_REGISTER(REGISTER) (((REGISTER) == I2S_Register_CTRL ) || \ + ((REGISTER) == I2S_Register_INTR_STAT ) || \ + ((REGISTER) == I2S_Register_SRR ) || \ + ((REGISTER) == I2S_Register_CID_CTRL ) || \ + ((REGISTER) == I2S_Register_TFIFO_STAT) || \ + ((REGISTER) == I2S_Register_RFIFO_STAT) || \ + ((REGISTER) == I2S_Register_TFIFO_CTRL) || \ + ((REGISTER) == I2S_Register_RFIFO_CTRL) || \ + ((REGISTER) == I2S_Register_DEV_CONF ) || \ + ((REGISTER) == I2S_Register_POLL_STAT )) +/** + * @} + */ + +/** @defgroup I2S_interrupts_definition + * @{ + */ +#define I2S_IT_TDATAUNDERR I2S_INTR_STAT_TDATAUNDERR +#define I2S_IT_RDATAOVRERR I2S_INTR_STAT_RDATAOVRERR +#define I2S_IT_TFIFOEMPTY I2S_INTR_STAT_TFIFOEMPTY +#define I2S_IT_TFIFOAEMPTY I2S_INTR_STAT_TFIFOAEMPTY +#define I2S_IT_TFIFOFULL I2S_INTR_STAT_TFIFOFULL +#define I2S_IT_TFIFOAFULL I2S_INTR_STAT_TFIFOAFULL +#define I2S_IT_RFIFOEMPTY I2S_INTR_STAT_RFIFOEMPTY +#define I2S_IT_RFIFOAEMPTY I2S_INTR_STAT_RFIFOAEMPTY +#define I2S_IT_RFIFOFULL I2S_INTR_STAT_RFIFOFULL +#define I2S_IT_RFIFOAFULL I2S_INTR_STAT_RFIFOAFULL + +#define IS_I2S_CLEAR_IT(IT) ((((IT) & (uint32_t)0xFFFF00EE) == 0x00) && ((IT) != 0x00)) + +#define IS_I2S_GET_IT(IT) (((IT) == I2S_IT_TDATAUNDERR) || ((IT) == I2S_IT_RDATAOVRERR) || \ + ((IT) == I2S_IT_TFIFOEMPTY) || ((IT) == I2S_IT_TFIFOAEMPTY) || \ + ((IT) == I2S_IT_TFIFOFULL) || ((IT) == I2S_IT_TFIFOAFULL) || \ + ((IT) == I2S_IT_RFIFOEMPTY) || ((IT) == I2S_IT_RFIFOAEMPTY) || \ + ((IT) == I2S_IT_RFIFOFULL) || ((IT) == I2S_IT_RFIFOAFULL)) +/** + * @} + */ + +/** @defgroup I2S_FIFO_IT_MASK + * @{ + */ +#define I2S_TFIFOEMPTY_MASK I2S_CID_CTRL_TFIFOEMPTYMASK +#define I2S_TFIFOAEMPTY_MASK I2S_CID_CTRL_TFIFOAEMPTYMASK +#define I2S_TFIFOFULL_MASK I2S_CID_CTRL_TFIFOFULLMASK +#define I2S_TFIFOAFULL_MASK I2S_CID_CTRL_TFIFOAFULLMASK +#define I2S_RFIFOEMPTY_MASK I2S_CID_CTRL_RFIFOEMPTYMASK +#define I2S_RFIFOAEMPTY_MASK I2S_CID_CTRL_RFIFOAEMPTYMASK +#define I2S_RFIFOFULL_MASK I2S_CID_CTRL_RFIFOFULLMASK +#define I2S_RFIFOAFULL_MASK I2S_CID_CTRL_RFIFOAFULLMASK + +#define IS_I2S_FIFO_IT_MASK(IT_MASK) (((IT_MASK) == I2S_TFIFOEMPTY_MASK) || \ + ((IT_MASK) == I2S_TFIFOAEMPTY_MASK) || \ + ((IT_MASK) == I2S_TFIFOFULL_MASK) || \ + ((IT_MASK) == I2S_TFIFOAFULL_MASK) || \ + ((IT_MASK) == I2S_RFIFOEMPTY_MASK) || \ + ((IT_MASK) == I2S_RFIFOAEMPTY_MASK) || \ + ((IT_MASK) == I2S_RFIFOFULL_MASK) || \ + ((IT_MASK) == I2S_RFIFOAFULL_MASK)) +/** + * @} + */ + +/** @defgroup I2S_DATA_IT_MASK + * @{ + */ +#define I2S_0_MASK I2S_CID_CTRL_I2SMASK0 +#define I2S_1_MASK I2S_CID_CTRL_I2SMASK1 + +#define IS_I2S_DATA_IT_MASK(IT_MASK) (((IT_MASK) == I2S_0_MASK) || \ + ((IT_MASK) == I2S_1_MASK)) +/** + * @} + */ + +/** @defgroup I2S_POLL_STAT + * @{ + */ +#define I2S_STAT_TFIFOEMPTY I2S_POLL_STAT_TXEMPTY +#define I2S_STAT_TFIFOAEMPTY I2S_POLL_STAT_TXAEMPTY +#define I2S_STAT_TXUNDERRUN I2S_POLL_STAT_TXUNDERRUN +#define I2S_STAT_RFIFOFULL I2S_POLL_STAT_RXFULL +#define I2S_STAT_RFIFOAFULL I2S_POLL_STAT_RXAFULL +#define I2S_STAT_RXOVERRUN I2S_POLL_STAT_RXOVERRUN + +#define IS_I2S_GET_STAT(STAT) (((STAT) == I2S_STAT_TFIFOEMPTY) || \ + ((STAT) == I2S_STAT_TFIFOAEMPTY) || \ + ((STAT) == I2S_STAT_TXUNDERRUN) || \ + ((STAT) == I2S_STAT_RFIFOFULL) || \ + ((STAT) == I2S_STAT_RFIFOAFULL) || \ + ((STAT) == I2S_STAT_RXOVERRUN)) +/** + * @} + */ +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup I2S_Exported_Functions + * @{ + */ + +/* Initialization and Configuration functions *********************************/ +void I2S_DeInit(I2S_TypeDef* I2Sx); +void I2S_Init(I2S_TypeDef* I2Sx, I2S_InitTypeDef* I2S_InitStruct); +void I2S_StructInit(I2S_InitTypeDef* I2S_InitStruct); +void I2S_ChannelConfig(I2S_TypeDef* I2Sx, uint32_t CHy, FunctionalState NewState); +void I2S_ChannelTranRecConfig(I2S_TypeDef* I2Sx, uint32_t CHy_TRANREC, uint32_t I2S_TranRec); +void I2S_LoopBackCmd(I2S_TypeDef* I2Sx, FunctionalState NewState); +void I2S_SFRResetCmd(I2S_TypeDef* I2Sx); +void I2S_TranMasterSlaveConfig(I2S_TypeDef* I2Sx, uint32_t I2S_MS); +void I2S_RecMasterSlaveConfig(I2S_TypeDef* I2Sx, uint32_t I2S_MS); +void I2S_TranSyncResetCmd(I2S_TypeDef* I2Sx, FunctionalState NewState); +void I2S_RecSyncResetCmd(I2S_TypeDef* I2Sx, FunctionalState NewState); +void I2S_TranSyncLoopBackCmd(I2S_TypeDef* I2Sx, FunctionalState NewState); +void I2S_RecSyncLoopBackCmd(I2S_TypeDef* I2Sx, FunctionalState NewState); +void I2S_TranSampleRateConfig(I2S_TypeDef* I2Sx, uint16_t SAMPLE_RATE); +void I2S_TranSampleResolutionConfig(I2S_TypeDef* I2Sx, uint8_t RESOLUTION); +void I2S_RecSampleRateConfig(I2S_TypeDef* I2Sx, uint16_t SAMPLE_RATE); +void I2S_RecSampleResolutionConfig(I2S_TypeDef* I2Sx, uint8_t RESOLUTION); +void I2S_ChannelClockConfig(I2S_TypeDef* I2Sx, uint32_t CHy_CLOCK, FunctionalState NewState); +void I2S_TranSyncUnitCmd(I2S_TypeDef* I2Sx, FunctionalState NewState); +void I2S_RecSyncUnitCmd(I2S_TypeDef* I2Sx, FunctionalState NewState); +void I2S_StandardConfig(I2S_TypeDef* I2Sx, uint32_t Standard); +void I2S_TranSckPolarConfig(I2S_TypeDef* I2Sx, uint8_t I2S_SCK_Polar); +void I2S_RecSckPolarConfig(I2S_TypeDef* I2Sx, uint8_t I2S_SCK_Polar); +void I2S_TranWSPolarConfig(I2S_TypeDef* I2Sx, uint8_t I2S_WS_Polar); +void I2S_RecWSPolarConfig(I2S_TypeDef* I2Sx, uint8_t I2S_WS_Polar); +void I2S_TranAPBAlignConfig(I2S_TypeDef* I2Sx, uint8_t I2S_Align); +void I2S_RecAPBAlignConfig(I2S_TypeDef* I2Sx, uint8_t I2S_Align); +void I2S_TranI2SAlignConfig(I2S_TypeDef* I2Sx, uint8_t I2S_Align); +void I2S_RecI2SAlignConfig(I2S_TypeDef* I2Sx, uint8_t I2S_Align); +void I2S_TranDataWSDelConfig(I2S_TypeDef* I2Sx, uint8_t I2S_Tran_Data_WS_Del); +void I2S_RecDataWSDelConfig(I2S_TypeDef* I2Sx, uint8_t I2S_Rec_Data_WS_Del); +void I2S_TranWSFormatConfig(I2S_TypeDef* I2Sx, uint8_t I2S_WS_Format); +void I2S_RecWSFormatConfig(I2S_TypeDef* I2Sx, uint8_t I2S_WS_Format); + +/* TX/RX FIFO control functions ***********************************************/ +void I2S_TFIFOResetCmd(I2S_TypeDef* I2Sx); +void I2S_RFIFOResetCmd(I2S_TypeDef* I2Sx); +uint8_t I2S_GetTranFIFOLevel(I2S_TypeDef* I2Sx); +uint8_t I2S_GetRecFIFOLevel(I2S_TypeDef* I2Sx); +void I2S_TFIFOAEmptyThresholdConfig(I2S_TypeDef* I2Sx, uint8_t FIFO_Threshold); +void I2S_TFIFOAFullThresholdConfig(I2S_TypeDef* I2Sx, uint8_t FIFO_Threshold); +void I2S_RFIFOAEmptyThresholdConfig(I2S_TypeDef* I2Sx, uint8_t FIFO_Threshold); +void I2S_RFIFOAFullThresholdConfig(I2S_TypeDef* I2Sx, uint8_t FIFO_Threshold); + +/* I2S registers management functions *****************************************/ +uint32_t I2S_ReadRegister(I2S_TypeDef* I2Sx, uint8_t I2S_Register); + +/* Data transfers management functions ****************************************/ +void I2S_SendData(I2S_TypeDef* I2Sx, uint32_t Data); +uint32_t I2S_ReceiveData(I2S_TypeDef* I2Sx); + +/* Interrupts and flags management functions **********************************/ +void I2S_AllITMaskCmd(I2S_TypeDef* I2Sx, FunctionalState NewState); +void I2S_FIFOITConfig(I2S_TypeDef* I2Sx, uint32_t I2S_IT_Mask, FunctionalState NewState); +void I2S_DataITConfig(I2S_TypeDef* I2Sx, uint32_t I2S_IT_Mask, FunctionalState NewState); +ITStatus I2S_GetITStatus(I2S_TypeDef* I2Sx, uint32_t I2S_IT); +void I2S_ClearITPendingBit(I2S_TypeDef* I2Sx, uint32_t I2S_IT); +uint8_t I2S_GetUnderrunCode(I2S_TypeDef* I2Sx); +uint8_t I2S_GetOverrunCode(I2S_TypeDef* I2Sx); +FlagStatus I2S_GetPollStatus(I2S_TypeDef* I2Sx, uint32_t I2S_Stat); + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /*__FT32F4XX_I2S_H */ + +/************************ (C) COPYRIGHT FMD *****END OF FILE*******************/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_iwdg.h b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_iwdg.h new file mode 100644 index 00000000000..c40f08c9c3d --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_iwdg.h @@ -0,0 +1,121 @@ +/** + ****************************************************************************** + * @file ft32f4xx_iwdg.h + * @author FMD AE + * @brief This file contains all the functions prototypes for the IWDG + * firmware library. + * @version V1.0.0 + * @data 2025-03-05 + ****************************************************************************** + */ + + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __FT32F407XE_IWDG_H +#define __FT32F407XE_IWDG_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx.h" + + +/** @addtogroup IWDG + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup IWDG_Exported_Constants + * @{ + */ + +/** @defgroup IWDG_WriteAccess + * @{ + */ + +#define IWDG_WriteAccess_Enable ((uint16_t)0x5555) +#define IWDG_WriteAccess_Disable ((uint16_t)0x0000) +#define IS_IWDG_WRITE_ACCESS(ACCESS) (((ACCESS) == IWDG_WriteAccess_Enable) || \ + ((ACCESS) == IWDG_WriteAccess_Disable)) +/** + * @} + */ + +/** @defgroup IWDG_prescaler + * @{ + */ + +#define IWDG_Prescaler_4 ((uint8_t)0x00) +#define IWDG_Prescaler_8 ((uint8_t)0x01) +#define IWDG_Prescaler_16 ((uint8_t)0x02) +#define IWDG_Prescaler_32 ((uint8_t)0x03) +#define IWDG_Prescaler_64 ((uint8_t)0x04) +#define IWDG_Prescaler_128 ((uint8_t)0x05) +#define IWDG_Prescaler_256 ((uint8_t)0x06) +#define IS_IWDG_PRESCALER(PRESCALER) (((PRESCALER) == IWDG_Prescaler_4) || \ + ((PRESCALER) == IWDG_Prescaler_8) || \ + ((PRESCALER) == IWDG_Prescaler_16) || \ + ((PRESCALER) == IWDG_Prescaler_32) || \ + ((PRESCALER) == IWDG_Prescaler_64) || \ + ((PRESCALER) == IWDG_Prescaler_128)|| \ + ((PRESCALER) == IWDG_Prescaler_256)) +/** + * @} + */ + +/** @defgroup IWDG_Flag + * @{ + */ + +#define IWDG_FLAG_PVU IWDG_SR_PVU +#define IWDG_FLAG_RVU IWDG_SR_RVU +#define IWDG_FLAG_WVU IWDG_SR_WVU +#define IS_IWDG_FLAG(FLAG) (((FLAG) == IWDG_FLAG_PVU) || ((FLAG) == IWDG_FLAG_RVU) || \ + ((FLAG) == IWDG_FLAG_WVU)) + +#define IS_IWDG_RELOAD(RELOAD) ((RELOAD) <= 0xFFF) + +#define IS_IWDG_WINDOW_VALUE(VALUE) ((VALUE) <= 0xFFF) +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +/* Prescaler and Counter configuration functions ******************************/ +void IWDG_WriteAccessCmd(uint16_t IWDG_WriteAccess); +void IWDG_SetPrescaler(uint8_t IWDG_Prescaler); +void IWDG_SetReload(uint16_t Reload); +void IWDG_ReloadCounter(void); +void IWDG_SetWindowValue(uint16_t WindowValue); + +/* IWDG activation function ***************************************************/ +void IWDG_Enable(void); + +/* Flag management function ***************************************************/ +FlagStatus IWDG_GetFlagStatus(uint16_t IWDG_FLAG); + +#ifdef __cplusplus +} +#endif + +#endif /* __FT32F4XX_IWDG_H */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_lptim.h b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_lptim.h new file mode 100644 index 00000000000..2f847d93334 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_lptim.h @@ -0,0 +1,410 @@ +/** + ****************************************************************************** + * @file ft32f4xx_lptim.h + * @author FMD AE + * @brief This file contains all the functions prototypes for the LPTIM + * firmware library. + * @version V1.0.0 + * @data 2025-03-31 + ****************************************************************************** + */ + + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __FT32F4XX_LPTIM_H +#define __FT32F4XX_LPTIM_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx.h" + +/** @addtogroup LPTIM + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** + * @brief LPTIM Init structure definition + */ + +typedef struct +{ + uint32_t Source; /*!< Selects the clock source. + This parameter can be a value of @ref LPTIM_Clock_Source */ + + uint32_t Prescaler; /*!< Specifies the counter clock Prescaler. + This parameter can be a value of @ref LPTIM_Clock_Prescaler */ + + uint32_t Polarity; /*!< Selects the polarity of the active edge for the counter unit + if the ULPTIM input is selected. + Note: This parameter is used only when Ultra low power clock source is used. + Note: If the polarity is configured on 'both edges', an auxiliary clock + (one of the Low power oscillator) must be active. + This parameter can be a value of @ref LPTIM_Clock_Polarity */ + + uint32_t Clock_SampleTime; /*!< Selects the clock sampling time to configure the clock glitch filter. + Note: This parameter is used only when Ultra low power clock source is used. + This parameter can be a value of @ref LPTIM_Clock_Sample_Time */ + + uint32_t Trigger_Source; /*!< Selects the Trigger source. + This parameter can be a value of @ref LPTIM_Trigger_Source */ + + uint32_t Trigegr_ActiveEdge; /*!< Selects the Trigger active edge. + Note: This parameter is used only when an external trigger is used. + This parameter can be a value of @ref LPTIM_External_Trigger_Polarity */ + + uint32_t Trigg_SampleTime; /*!< Selects the trigger sampling time to configure the clock glitch filter. + Note: This parameter is used only when an external trigger is used. + This parameter can be a value of @ref LPTIM_Trigger_Sample_Time */ + + uint32_t OutputPolarity; /*!< Specifies the Output polarity. + This parameter can be a value of @ref LPTIM_Output_Polarity */ + + uint32_t UpdateMode; /*!< Specifies whether the update of the autoreload and the compare + values is done immediately or after the end of current period. + This parameter can be a value of @ref LPTIM_Updating_Mode */ + + uint32_t CounterSource; /*!< Specifies whether the counter is incremented each internal event + or each external event. + This parameter can be a value of @ref LPTIM_Counter_Source */ + + uint32_t Input1Source; /*!< Specifies source selected for input1 (GPIO or comparator output). + This parameter can be a value of @ref LPTIM_Input1_Source */ + + uint32_t Input2Source; /*!< Specifies source selected for input2 (GPIO or comparator output). + Note: This parameter is used only for encoder feature so is used only + for LPTIM1 instance. + This parameter can be a value of @ref LPTIM_Input2_Source */ +} LPTIM_InitTypeDef; + + + + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup LPTIM_Exported_Constants + * @{ + */ + +/** @defgroup LPTIM_Clock_Source LPTIM Clock Source + * @{ + */ +#define LPTIM_CLOCKSOURCE_APBCLOCK_LPOSC 0x00000000U +#define LPTIM_CLOCKSOURCE_ULPTIM LPTIM_CFGR_CKSEL +#define IS_LPTIM_CLOCK_SOURCE(SOURCE) (((SOURCE) == LPTIM_CLOCKSOURCE_ULPTIM) || \ + ((SOURCE) == LPTIM_CLOCKSOURCE_APBCLOCK_LPOSC)) +/** + * @} + */ + +/** @defgroup LPTIM_Clock_Prescaler LPTIM Clock Prescaler + * @{ + */ +#define LPTIM_PRESCALER_DIV1 0x00000000U +#define LPTIM_PRESCALER_DIV2 LPTIM_CFGR_PRESC_0 +#define LPTIM_PRESCALER_DIV4 LPTIM_CFGR_PRESC_1 +#define LPTIM_PRESCALER_DIV8 (LPTIM_CFGR_PRESC_0 | LPTIM_CFGR_PRESC_1) +#define LPTIM_PRESCALER_DIV16 LPTIM_CFGR_PRESC_2 +#define LPTIM_PRESCALER_DIV32 (LPTIM_CFGR_PRESC_0 | LPTIM_CFGR_PRESC_2) +#define LPTIM_PRESCALER_DIV64 (LPTIM_CFGR_PRESC_1 | LPTIM_CFGR_PRESC_2) +#define LPTIM_PRESCALER_DIV128 LPTIM_CFGR_PRESC +#define IS_LPTIM_CLOCK_PRESCALER(PRESCALER) (((PRESCALER) == LPTIM_PRESCALER_DIV1 ) || \ + ((PRESCALER) == LPTIM_PRESCALER_DIV2 ) || \ + ((PRESCALER) == LPTIM_PRESCALER_DIV4 ) || \ + ((PRESCALER) == LPTIM_PRESCALER_DIV8 ) || \ + ((PRESCALER) == LPTIM_PRESCALER_DIV16 ) || \ + ((PRESCALER) == LPTIM_PRESCALER_DIV32 ) || \ + ((PRESCALER) == LPTIM_PRESCALER_DIV64 ) || \ + ((PRESCALER) == LPTIM_PRESCALER_DIV128)) + +/** + * @} + */ + +/** @defgroup LPTIM_Clock_Polarity LPTIM Clock Polarity + * @{ + */ +#define LPTIM_CLOCKPOLARITY_RISING 0x00000000U +#define LPTIM_CLOCKPOLARITY_FALLING LPTIM_CFGR_CKPOL_0 +#define LPTIM_CLOCKPOLARITY_RISING_FALLING LPTIM_CFGR_CKPOL_1 +#define IS_LPTIM_CLOCK_POLARITY(POLARITY) (((POLARITY) == LPTIM_CLOCKPOLARITY_RISING) || \ + ((POLARITY) == LPTIM_CLOCKPOLARITY_FALLING) || \ + ((POLARITY) == LPTIM_CLOCKPOLARITY_RISING_FALLING)) + +/** + * @} + */ + +/** @defgroup LPTIM_Clock_Sample_Time LPTIM Clock Sample Time + * @{ + */ +#define LPTIM_CLOCKSAMPLETIME_DIRECTTRANSITION 0x00000000U +#define LPTIM_CLOCKSAMPLETIME_2TRANSITIONS LPTIM_CFGR_CKFLT_0 +#define LPTIM_CLOCKSAMPLETIME_4TRANSITIONS LPTIM_CFGR_CKFLT_1 +#define LPTIM_CLOCKSAMPLETIME_8TRANSITIONS LPTIM_CFGR_CKFLT +#define IS_LPTIM_CLOCK_SAMPLE_TIME(SAMPLETIME) (((SAMPLETIME) == LPTIM_CLOCKSAMPLETIME_DIRECTTRANSITION) || \ + ((SAMPLETIME) == LPTIM_CLOCKSAMPLETIME_2TRANSITIONS) || \ + ((SAMPLETIME) == LPTIM_CLOCKSAMPLETIME_4TRANSITIONS) || \ + ((SAMPLETIME) == LPTIM_CLOCKSAMPLETIME_8TRANSITIONS)) + +/** + * @} + */ + +/** @defgroup LPTIM_Trigger_Source LPTIM Trigger Source + * @{ + */ +//#define LPTIM_TRIGSOURCE_SOFTWARE 0x0000FFFFU +#define LPTIM_TRIGSOURCE_0 0x00000000U +#define LPTIM_TRIGSOURCE_1 LPTIM_CFGR_TRIGSEL_0 +#define LPTIM_TRIGSOURCE_2 LPTIM_CFGR_TRIGSEL_1 +#define LPTIM_TRIGSOURCE_3 (LPTIM_CFGR_TRIGSEL_0 | LPTIM_CFGR_TRIGSEL_1) +#define LPTIM_TRIGSOURCE_4 LPTIM_CFGR_TRIGSEL_2 +#define LPTIM_TRIGSOURCE_5 (LPTIM_CFGR_TRIGSEL_0 | LPTIM_CFGR_TRIGSEL_2) +#define LPTIM_TRIGSOURCE_6 (LPTIM_CFGR_TRIGSEL_1 | LPTIM_CFGR_TRIGSEL_2) +#define LPTIM_TRIGSOURCE_7 (LPTIM_CFGR_TRIGSEL_0 | LPTIM_CFGR_TRIGSEL_1 | LPTIM_CFGR_TRIGSEL_2) +#define LPTIM_TRIGSOURCE_8 LPTIM_CFGR_TRIGSEL_3 +#define LPTIM_TRIGSOURCE_9 (LPTIM_CFGR_TRIGSEL_0 | LPTIM_CFGR_TRIGSEL_3) +#define LPTIM_TRIGSOURCE_10 (LPTIM_CFGR_TRIGSEL_1 | LPTIM_CFGR_TRIGSEL_3) +#define LPTIM_TRIGSOURCE_11 (LPTIM_CFGR_TRIGSEL_0 |LPTIM_CFGR_TRIGSEL_1 | LPTIM_CFGR_TRIGSEL_3) +#define LPTIM_TRIGSOURCE_12 (LPTIM_CFGR_TRIGSEL_2 | LPTIM_CFGR_TRIGSEL_3) +#define IS_LPTIM_TRG_SOURCE(TRIG) (((TRIG) == LPTIM_TRIGSOURCE_0) || \ + ((TRIG) == LPTIM_TRIGSOURCE_1) || \ + ((TRIG) == LPTIM_TRIGSOURCE_2) || \ + ((TRIG) == LPTIM_TRIGSOURCE_3) || \ + ((TRIG) == LPTIM_TRIGSOURCE_4) || \ + ((TRIG) == LPTIM_TRIGSOURCE_5) || \ + ((TRIG) == LPTIM_TRIGSOURCE_6) || \ + ((TRIG) == LPTIM_TRIGSOURCE_7) || \ + ((TRIG) == LPTIM_TRIGSOURCE_8) || \ + ((TRIG) == LPTIM_TRIGSOURCE_9) || \ + ((TRIG) == LPTIM_TRIGSOURCE_10)|| \ + ((TRIG) == LPTIM_TRIGSOURCE_11)|| \ + ((TRIG) == LPTIM_TRIGSOURCE_12)) + +/** + * @} + */ + +/** @defgroup LPTIM_External_Trigger_Polarity LPTIM External Trigger Polarity + * @{ + */ +#define LPTIM_SOFTWARE 0x00000000 +#define LPTIM_ACTIVEEDGE_RISING LPTIM_CFGR_TRIGEN_0 +#define LPTIM_ACTIVEEDGE_FALLING LPTIM_CFGR_TRIGEN_1 +#define LPTIM_ACTIVEEDGE_RISING_FALLING LPTIM_CFGR_TRIGEN +#define IS_LPTIM_EXT_TRG_POLARITY(POLARITY) (((POLARITY) == LPTIM_SOFTWARE ) || \ + ((POLARITY) == LPTIM_ACTIVEEDGE_RISING ) || \ + ((POLARITY) == LPTIM_ACTIVEEDGE_FALLING ) || \ + ((POLARITY) == LPTIM_ACTIVEEDGE_RISING_FALLING )) + +/** + * @} + */ + +/** @defgroup LPTIM_Trigger_Sample_Time LPTIM Trigger Sample Time + * @{ + */ +#define LPTIM_TRIGSAMPLETIME_DIRECTTRANSITION 0x00000000U +#define LPTIM_TRIGSAMPLETIME_2TRANSITIONS LPTIM_CFGR_TRGFLT_0 +#define LPTIM_TRIGSAMPLETIME_4TRANSITIONS LPTIM_CFGR_TRGFLT_1 +#define LPTIM_TRIGSAMPLETIME_8TRANSITIONS LPTIM_CFGR_TRGFLT +#define IS_LPTIM_TRIG_SAMPLE_TIME(SAMPLETIME) (((SAMPLETIME) == LPTIM_TRIGSAMPLETIME_DIRECTTRANSITION) || \ + ((SAMPLETIME) == LPTIM_TRIGSAMPLETIME_2TRANSITIONS ) || \ + ((SAMPLETIME) == LPTIM_TRIGSAMPLETIME_4TRANSITIONS ) || \ + ((SAMPLETIME) == LPTIM_TRIGSAMPLETIME_8TRANSITIONS )) + + +/** + * @} + */ + +/** @defgroup LPTIM_Output_Polarity LPTIM Output Polarity + * @{ + */ + +#define LPTIM_OUTPUTPOLARITY_HIGH 0x00000000U +#define LPTIM_OUTPUTPOLARITY_LOW LPTIM_CFGR_WAVPOL +#define IS_LPTIM_OUTPUT_POLARITY(POLARITY) (((POLARITY) == LPTIM_OUTPUTPOLARITY_LOW ) || \ + ((POLARITY) == LPTIM_OUTPUTPOLARITY_HIGH)) + +/** + * @} + */ + +/** @defgroup LPTIM_Updating_Mode LPTIM Updating Mode + * @{ + */ + +#define LPTIM_UPDATE_IMMEDIATE 0x00000000U +#define LPTIM_UPDATE_ENDOFPERIOD LPTIM_CFGR_PRELOAD +#define IS_LPTIM_UPDATE_MODE(MODE) (((MODE) == LPTIM_UPDATE_IMMEDIATE) || \ + ((MODE) == LPTIM_UPDATE_ENDOFPERIOD)) +/** + * @} + */ + +/** @defgroup LPTIM_Counter_Source LPTIM Counter Source + * @{ + */ + +#define LPTIM_COUNTERSOURCE_INTERNAL 0x00000000U +#define LPTIM_COUNTERSOURCE_EXTERNAL LPTIM_CFGR_COUNTMODE +#define IS_LPTIM_COUNTER_SOURCE(SOURCE) (((SOURCE) == LPTIM_COUNTERSOURCE_INTERNAL) || \ + ((SOURCE) == LPTIM_COUNTERSOURCE_EXTERNAL)) +/** + * @} + */ + +/** @defgroup LPTIM_Input1_Source LPTIM Input1 Source + * @{ + */ + +#define LPTIM_INPUT1SOURCE_GPIO 0x00000000U +#define LPTIM_INPUT1SOURCE_COMP1 LPTIM_OR_IN1_0 +#define LPTIM_INPUT1SOURCE_COMP3 (LPTIM_OR_IN1_1 | LPTIM_OR_IN1_0) +#define LPTIM_INPUT1SOURCE_COMP5 (LPTIM_OR_IN1_2 | LPTIM_OR_IN1_0) +#define LPTIM_INPUT1SOURCE_COMP5_1 (LPTIM_OR_IN1_2 | LPTIM_OR_IN1_1 | LPTIM_OR_IN1_0) +#define IS_LPTIM_INPUT1_SOURCE(SOURCE) (((SOURCE) == LPTIM_INPUT1SOURCE_GPIO) || \ + ((SOURCE) == LPTIM_INPUT1SOURCE_COMP1) || \ + ((SOURCE) == LPTIM_INPUT1SOURCE_COMP3) || \ + ((SOURCE) == LPTIM_INPUT1SOURCE_COMP5) || \ + ((SOURCE) == LPTIM_INPUT1SOURCE_COMP5_1)) + +/** + * @} + */ + +/** @defgroup LPTIM_Input2_Source LPTIM Input2 Source + * @{ + */ + +#define LPTIM_INPUT2SOURCE_GPIO 0x00000000U +#define LPTIM_INPUT2SOURCE_COMP2 LPTIM_OR_IN2_0 +#define LPTIM_INPUT2SOURCE_COMP4 (LPTIM_OR_IN2_1 | LPTIM_OR_IN2_0) +#define LPTIM_INPUT2SOURCE_COMP6 (LPTIM_OR_IN2_2 | LPTIM_OR_IN2_0) +#define LPTIM_INPUT2SOURCE_COMP6_1 (LPTIM_OR_IN2_2 | LPTIM_OR_IN2_1 | LPTIM_OR_IN2_0) +#define IS_LPTIM_INPUT2_SOURCE(SOURCE) (((SOURCE) == LPTIM_INPUT2SOURCE_GPIO) || \ + ((SOURCE) == LPTIM_INPUT2SOURCE_COMP2) || \ + ((SOURCE) == LPTIM_INPUT2SOURCE_COMP4) || \ + ((SOURCE) == LPTIM_INPUT2SOURCE_COMP6) || \ + ((SOURCE) == LPTIM_INPUT2SOURCE_COMP6_1)) +/** + * @} + */ + +/** @defgroup LPTIM_Flag_Definition LPTIM Flags Definition + * @{ + */ + +#define LPTIM_FLAG_DOWN ((uint32_t)0x00000040) +#define LPTIM_FLAG_UP ((uint32_t)0x00000020) +#define LPTIM_FLAG_ARROK ((uint32_t)0x00000010) +#define LPTIM_FLAG_CMPOK ((uint32_t)0x00000008) +#define LPTIM_FLAG_EXTTRIG ((uint32_t)0x00000004) +#define LPTIM_FLAG_ARRM ((uint32_t)0x00000002) +#define LPTIM_FLAG_CMPM ((uint32_t)0x00000001) +/** + * @} + */ + +/** @defgroup LPTIM_Interrupts_Definition LPTIM Interrupts Definition + * @{ + */ +#define LPTIM_IT_DOWNIE ((uint32_t)0x00000040) +#define LPTIM_IT_UPIE ((uint32_t)0x00000020) +#define LPTIM_IT_ARROKIE ((uint32_t)0x00000010) +#define LPTIM_IT_CMPOKIE ((uint32_t)0x00000008) +#define LPTIM_IT_EXTTRIGIE ((uint32_t)0x00000004) +#define LPTIM_IT_ARRMIE ((uint32_t)0x00000002) +#define LPTIM_IT_CMPMIE ((uint32_t)0x00000001) +/** + * @} + */ + +#define IS_LPTIM_AUTORELOAD(AUTORELOAD) ((AUTORELOAD) <= 0x0000FFFFUL) + +#define IS_LPTIM_COMPARE(COMPARE) ((COMPARE) <= 0x0000FFFFUL) + +#define IS_LPTIM_PERIOD(PERIOD) ((PERIOD) <= 0x0000FFFFUL) + +#define IS_LPTIM_PULSE(PULSE) ((PULSE) <= 0x0000FFFFUL) + + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +/* Initialization and Configuration functions *********************************/ +void LPTIM_DeInit(void); +void LPTIM_Init(LPTIM_InitTypeDef *LPTIM_InitStruct); +void LPTIM_StructInit(LPTIM_InitTypeDef *LPTIM_InitStruct); + +/* Reading/Write operation functions ************************************************/ +uint32_t LPTIM_ReadCounter(void); +uint32_t LPTIM_ReadAutoReload(void); +uint32_t LPTIM_ReadCompare(void); +void LPTIM_Write_ARRRegister(uint32_t Period); +void LPTIM_Write_CMPRegister(uint32_t Pulse); +void LPTIM_Preload_Config(FunctionalState NewState); + +/* Start/Stop operation functions *********************************************/ +/* ################################# PWM Mode ################################*/ +/* Blocking mode: Polling */ +void LPTIM_PWM_Start(uint32_t Period, uint32_t Pulse); +void LPTIM_PWM_Stop(void); + +/* ############################# One Pulse Mode ##############################*/ +/* Blocking mode: Polling */ +void LPTIM_OnePulse_Start(uint32_t Period, uint32_t Pulse); +void LPTIM_OnePulse_Stop(void); + +/* ############################## Set once Mode ##############################*/ +/* Blocking mode: Polling */ +void LPTIM_SetOnce_Start(uint32_t Period, uint32_t Pulse); +void LPTIM_SetOnce_Stop(void); + +/* ############################### Encoder Mode ##############################*/ +/* Blocking mode: Polling */ +void LPTIM_Encoder_Start(uint32_t Period); +void LPTIM_Encoder_Stop(void); + +/* ############################# Time out Mode ##############################*/ +/* Blocking mode: Polling */ +void LPTIM_TimeOut_Start(uint32_t Period, uint32_t Timeout); +void LPTIM_TimeOut_Stop(void); + +/* ############################## Counter Mode ###############################*/ +/* Blocking mode: Polling */ +void LPTIM_Counter_Start(uint32_t Period); +void LPTIM_Counter_Stop(void); + +/* LPTIM Reset ****************************************************************/ +void LPTIM_RSTARE(FunctionalState NewState); +void LPTIM_COUNTRST(void); + +/* LPTIM IRQ functions *******************************************************/ +void LPTIM_ITConfig(uint32_t LPTIM_IT, FunctionalState NewState); +uint32_t LPTIM_GetStatus(uint32_t LPTIM_ISR_FLAG); +void LPTIM_ClearFlag(uint32_t flag); +#ifdef __cplusplus +} +#endif + +#endif /*__FT32F4XX_LPTIM_H */ + +/** + * @} + */ + +/** + * @} + */ + + diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_misc.h b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_misc.h new file mode 100644 index 00000000000..526f78b2959 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_misc.h @@ -0,0 +1,177 @@ +/** + ****************************************************************************** + * @file ft32f4xx_misc.h + * @author FMD AE + * @brief This file contains all the functions prototypes for the miscellaneous + * firmware library functions (add-on to CMSIS functions). + * @version V1.0.0 + * @data 2025-07-01 + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __FT32F4XX_MISC_H +#define __FT32F4XX_MISC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @addtogroup MISC + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** + * @brief NVIC Init Structure definition + */ + +typedef struct +{ + uint8_t NVIC_IRQChannel; /*!< Specifies the IRQ channel to be enabled or disabled. + This parameter can be an enumerator of @ref IRQn_Type + enumeration (For the complete STM32 Devices IRQ Channels + list, please refer to stm32f4xx.h file) */ + + uint8_t NVIC_IRQChannelPreemptionPriority; /*!< Specifies the pre-emption priority for the IRQ channel + specified in NVIC_IRQChannel. This parameter can be a value + between 0 and 15 as described in the table @ref MISC_NVIC_Priority_Table + A lower priority value indicates a higher priority */ + + uint8_t NVIC_IRQChannelSubPriority; /*!< Specifies the subpriority level for the IRQ channel specified + in NVIC_IRQChannel. This parameter can be a value + between 0 and 15 as described in the table @ref MISC_NVIC_Priority_Table + A lower priority value indicates a higher priority */ + + FunctionalState NVIC_IRQChannelCmd; /*!< Specifies whether the IRQ channel defined in NVIC_IRQChannel + will be enabled or disabled. + This parameter can be set either to ENABLE or DISABLE */ +} NVIC_InitTypeDef; + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup MISC_Exported_Constants + * @{ + */ + +/** @defgroup MISC_Vector_Table_Base + * @{ + */ + +#define NVIC_VectTab_RAM ((uint32_t)0x20000000) +#define NVIC_VectTab_FLASH ((uint32_t)0x08000000) +#define IS_NVIC_VECTTAB(VECTTAB) (((VECTTAB) == NVIC_VectTab_RAM) || \ + ((VECTTAB) == NVIC_VectTab_FLASH)) +/** + * @} + */ + +/** @defgroup MISC_System_Low_Power + * @{ + */ + +#define NVIC_LP_SEVONPEND ((uint8_t)0x10) +#define NVIC_LP_SLEEPDEEP ((uint8_t)0x04) +#define NVIC_LP_SLEEPONEXIT ((uint8_t)0x02) +#define IS_NVIC_LP(LP) (((LP) == NVIC_LP_SEVONPEND) || \ + ((LP) == NVIC_LP_SLEEPDEEP) || \ + ((LP) == NVIC_LP_SLEEPONEXIT)) +/** + * @} + */ + +/** @defgroup MISC_Preemption_Priority_Group + * @{ + */ + +#define NVIC_PriorityGroup_0 ((uint32_t)0x700) /*!< 0 bits for pre-emption priority + 4 bits for subpriority */ +#define NVIC_PriorityGroup_1 ((uint32_t)0x600) /*!< 1 bits for pre-emption priority + 3 bits for subpriority */ +#define NVIC_PriorityGroup_2 ((uint32_t)0x500) /*!< 2 bits for pre-emption priority + 2 bits for subpriority */ +#define NVIC_PriorityGroup_3 ((uint32_t)0x400) /*!< 3 bits for pre-emption priority + 1 bits for subpriority */ +#define NVIC_PriorityGroup_4 ((uint32_t)0x300) /*!< 4 bits for pre-emption priority + 0 bits for subpriority */ + +#define IS_NVIC_PRIORITY_GROUP(GROUP) (((GROUP) == NVIC_PriorityGroup_0) || \ + ((GROUP) == NVIC_PriorityGroup_1) || \ + ((GROUP) == NVIC_PriorityGroup_2) || \ + ((GROUP) == NVIC_PriorityGroup_3) || \ + ((GROUP) == NVIC_PriorityGroup_4)) + +#define IS_NVIC_PREEMPTION_PRIORITY(PRIORITY) ((PRIORITY) < 0x10) + +#define IS_NVIC_SUB_PRIORITY(PRIORITY) ((PRIORITY) < 0x10) + +#define IS_NVIC_OFFSET(OFFSET) ((OFFSET) < 0x000FFFFF) + +/** + * @} + */ + +/** @defgroup MISC_SysTick_clock_source + * @{ + */ + +#define SysTick_CLKSource_HCLK_Div8 ((uint32_t)0xFFFFFFFB) +#define SysTick_CLKSource_HCLK ((uint32_t)0x00000004) +#define IS_SYSTICK_CLK_SOURCE(SOURCE) (((SOURCE) == SysTick_CLKSource_HCLK) || \ + ((SOURCE) == SysTick_CLKSource_HCLK_Div8)) +/** + * @} + */ + + +/** + * @} + */ + +/** @defgroup TICK_FREQ Tick Frequency + * @{ + */ +typedef enum +{ + TICK_FREQ_10HZ = 100U, + TICK_FREQ_100HZ = 10U, + TICK_FREQ_1KHZ = 1U, + TICK_FREQ_DEFAULT = TICK_FREQ_1KHZ +} TickFreqTypeDef; +/** + * @} + */ +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup); +void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct); +void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset); +void NVIC_SystemLPConfig(uint8_t LowPowerMode, FunctionalState NewState); +void InitTick(uint32_t TickPriority, uint32_t SubPriority); +void IncTick(void); +uint32_t GetTick(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __FT32F4XX_MISC_H */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_opamp.h b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_opamp.h new file mode 100644 index 00000000000..3756b5bd4d9 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_opamp.h @@ -0,0 +1,363 @@ +/** + ****************************************************************************** + * @file ft32f4xx_opamp.c + * @author FMD AE + * @brief This file provides firmware functions to manage the following + * functionalities of the comparators (OPA1 and OPA2) peripheral + * applicable only on FT32F030 devices: + * + Comparators configuration + * + Window mode control + * @version V1.0.0 + * @data 2025-03-31 + ****************************************************************************** + */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __FT32F4XX_OPAMP_H +#define __FT32F4XX_OPAMP_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx.h" +/* Exported types ------------------------------------------------------------*/ +/** @defgroup opamp Exported_Types opamp Exported Types + * @{ + */ +/** + * @brief opamp Init structure definition + */ +typedef struct +{ + + uint32_t OPA_VPSEL; /*!< Select the 1 level positive input of the OPA. + This parameter can be a value of @ref OPA_VPSEL */ + + uint32_t OPA_VMSEL; /*!< Select the 1 level negative input of the OPA. + This parameter can be a value of @ref OPA_VMSEL */ + + uint32_t OPA_VPSSEL; /*!< Select the 2 level positive input of the OPA. + This parameter can be a value of @ref OPA_VPSSEL */ + + uint32_t OPA_VMSSEL; /*!< Select the 2 level negative input of the OPA. + This parameter can be a value of @ref OPA_VMSSEL */ + + uint32_t T8_CM; /*!< Select the VM SEL of 1 or 2 level input by time8. + This parameter can be a value of @ref T8_CM*/ + + uint32_t T1_CM; /*!< Select the VM SEL of 1 or 2 level input by time1. + This parameter can be a value of @ref T1_CM */ + + uint32_t OPAHSM; /*!< Select the high or low speed of the OPA. + This parameter can be a value of @ref OPAHSM*/ + + uint32_t OPINTOEN; /*!< Select the output to pad or ADC inside. + This parameter can be a value of @ref OPINTOEN */ + + uint32_t O2PADSEL; /*!< Select the output pad of the OPA1 or OPA2. + This parameter can be a value of @ref O2PADSEL*/ + + uint32_t OPA_PGAGAIN; /*!< Select the amplification value. + This parameter can be a value of @ref OPA_PGAGAIN */ + +} OPA_InitTypeDef; + + +/** @defgroup OPAMP_Selection + * @{ + */ +#define OPAMP_1 ((uint32_t)0x00000001) /*!< OPAMP1 Selection */ +#define OPAMP_2 ((uint32_t)0x00000010) /*!< OPAMP2 Selection */ +#define OPAMP_3 ((uint32_t)0x00000100) /*!< OPAMP3 Selection */ + +#define IS_OPAX_PERIPH(PERIPH) (((PERIPH) == OPAMP_1) || \ + ((PERIPH) == OPAMP_2) || \ + ((PERIPH) == OPAMP_3)) + + +/** @defgroup OPA_VPSEL + * @{ + */ +#define OPA1_VIP_SEL_PA0 ((uint32_t)0x00000000) /*opamp1*/ +#define OPA1_VIP_SEL_PC3 ((uint32_t)0x00000002) +#define OPA1_VIP_SEL_PA6 ((uint32_t)0x00000004) +#define OPA1_VIP_SEL_PA2 ((uint32_t)0x00000006) +#define OPA1_VIP_SEL_DAC1 ((uint32_t)0x00000008) +#define OPA1_VIP_SEL_TRIM ((uint32_t)0x0000000a) +#define OPA1_VIP_SEL_VSSA ((uint32_t)0x0000000c) + +#define OPA2_VIP_SEL_PA6 ((uint32_t)0x00000000) /*opamp2*/ +#define OPA2_VIP_SEL_PB1 ((uint32_t)0x00000002) +#define OPA2_VIP_SEL_TRIM ((uint32_t)0x0000000a) +#define OPA2_VIP_SEL_VSSA ((uint32_t)0x0000000c) + +#define OPA3_VIP_SEL_PB11 ((uint32_t)0x00000000) /*opamp3*/ +#define OPA3_VIP_SEL_PB2 ((uint32_t)0x00000002) +#define OPA3_VIP_SEL_PC5 ((uint32_t)0x00000004) +#define OPA3_VIP_SEL_DAC2 ((uint32_t)0x00000008) +#define OPA3_VIP_SEL_TRIM ((uint32_t)0x0000000a) +#define OPA3_VIP_SEL_VSSA ((uint32_t)0x0000000c) + +#define IS_OPA_VIP_SEL(INPUT) (((INPUT) ==OPA1_VIP_SEL_PA0 ) || \ + ((INPUT) ==OPA1_VIP_SEL_PC3 ) || \ + ((INPUT) ==OPA1_VIP_SEL_PA6 ) || \ + ((INPUT) ==OPA1_VIP_SEL_PA2 ) || \ + ((INPUT) ==OPA1_VIP_SEL_DAC1 ) || \ + ((INPUT) ==OPA1_VIP_SEL_TRIM ) || \ + ((INPUT) ==OPA1_VIP_SEL_VSSA ) || \ + ((INPUT) ==OPA2_VIP_SEL_PA6 ) || \ + ((INPUT) ==OPA2_VIP_SEL_PB1 ) || \ + ((INPUT) ==OPA2_VIP_SEL_TRIM ) || \ + ((INPUT) ==OPA2_VIP_SEL_VSSA ) || \ + ((INPUT) ==OPA3_VIP_SEL_PB11 ) || \ + ((INPUT) ==OPA3_VIP_SEL_PB2 ) || \ + ((INPUT) ==OPA3_VIP_SEL_PC5 ) || \ + ((INPUT) ==OPA3_VIP_SEL_DAC2 ) || \ + ((INPUT) ==OPA3_VIP_SEL_TRIM ) || \ + ((INPUT) ==OPA3_VIP_SEL_VSSA ) ) + +/** @defgroup OPA_VMSEL + * @{ + */ +#define OPA1_VIM_SEL_PA1 ((uint32_t)0x00000000) /*opamp1*/ +#define OPA1_VIM_SEL_PC2 ((uint32_t)0x00000010) +#define OPA1_VIM_SEL_PA2 ((uint32_t)0x00000020) +#define OPA1_VIM_SEL_PA4 ((uint32_t)0x00000030) +#define OPA1_VIM_SEL_FOLLOW ((uint32_t)0x00000040) +#define OPA1_VIM_SEL_PGA ((uint32_t)0x00000050) + +#define OPA2_VIM_SEL_PA7 ((uint32_t)0x00000000) /*opamp2*/ +#define OPA2_VIM_SEL_PA4 ((uint32_t)0x00000010) +#define OPA2_VIM_SEL_FOLLOW ((uint32_t)0x00000040) +#define OPA2_VIM_SEL_PGA ((uint32_t)0x00000050) + +#define OPA3_VIM_SEL_PB11 ((uint32_t)0x00000000) /*opamp3*/ +#define OPA3_VIM_SEL_PB2 ((uint32_t)0x00000010) +#define OPA3_VIM_SEL_PC5 ((uint32_t)0x00000020) +#define OPA3_VIM_SEL_FOLLOW ((uint32_t)0x00000040) +#define OPA3_VIM_SEL_PGA ((uint32_t)0x00000050) + +#define IS_OPA_VIM_SEL(INPUT) (((INPUT)== OPA1_VIM_SEL_PA1 ) || \ + ((INPUT) == OPA1_VIM_SEL_PC2 ) || \ + ((INPUT) == OPA1_VIM_SEL_PA2 ) || \ + ((INPUT) == OPA1_VIM_SEL_PA4 ) || \ + ((INPUT) == OPA1_VIM_SEL_FOLLOW ) || \ + ((INPUT) == OPA1_VIM_SEL_PGA ) || \ + ((INPUT) == OPA2_VIM_SEL_PA7 ) || \ + ((INPUT) == OPA2_VIM_SEL_PA4 ) || \ + ((INPUT) == OPA2_VIM_SEL_FOLLOW ) || \ + ((INPUT) == OPA2_VIM_SEL_PGA ) || \ + ((INPUT) == OPA3_VIM_SEL_PB11 ) || \ + ((INPUT) == OPA3_VIM_SEL_PB2 ) || \ + ((INPUT) == OPA3_VIM_SEL_PC5 ) || \ + ((INPUT) == OPA3_VIM_SEL_FOLLOW ) || \ + ((INPUT) == OPA3_VIM_SEL_PGA )) + + +/** @defgroup OPA_VPSSEL + * @{ + */ +#define OPA1_VIPS_SEL_PA0 ((uint32_t)0x00000000) /*opamp1*/ +#define OPA1_VIPS_SEL_PC3 ((uint32_t)0x00000004) +#define OPA1_VIPS_SEL_PA6 ((uint32_t)0x00000008) +#define OPA1_VIPS_SEL_PA2 ((uint32_t)0x0000000c) +#define OPA1_VIPS_SEL_DAC1 ((uint32_t)0x00000010) +#define OPA1_VIPS_SEL_VSSA ((uint32_t)0x0000001c) + +#define OPA2_VIPS_SEL_PA6 ((uint32_t)0x00000000) /*opamp2*/ +#define OPA2_VIPS_SEL_PB1 ((uint32_t)0x00000002) +#define OPA2_VIPS_SEL_VSSA ((uint32_t)0x0000001c) + +#define OPA3_VIPS_SEL_PB11 ((uint32_t)0x00000000) /*opamp3*/ +#define OPA3_VIPS_SEL_PB2 ((uint32_t)0x00000002) +#define OPA3_VIPS_SEL_PC5 ((uint32_t)0x00000004) +#define OPA3_VIPS_SEL_DAC2 ((uint32_t)0x00000008) +#define OPA3_VIPS_SEL_VSSA ((uint32_t)0x0000000c) + +#define IS_OPA_VIPS_SEL(INPUT) (((INPUT) ==OPA1_VIPS_SEL_PA0 ) || \ + ((INPUT) ==OPA1_VIPS_SEL_PC3 ) || \ + ((INPUT) ==OPA1_VIPS_SEL_PA6 ) || \ + ((INPUT) ==OPA1_VIPS_SEL_PA2 ) || \ + ((INPUT) ==OPA1_VIPS_SEL_DAC1) || \ + ((INPUT) ==OPA1_VIPS_SEL_VSSA) || \ + ((INPUT) ==OPA2_VIPS_SEL_PA6) || \ + ((INPUT) ==OPA2_VIPS_SEL_PB1) || \ + ((INPUT) ==OPA2_VIPS_SEL_VSSA) || \ + ((INPUT) ==OPA3_VIPS_SEL_PB11) || \ + ((INPUT) ==OPA3_VIPS_SEL_PB2) || \ + ((INPUT) ==OPA3_VIPS_SEL_PC5) || \ + ((INPUT) ==OPA3_VIPS_SEL_DAC2) || \ + ((INPUT) ==OPA3_VIPS_SEL_VSSA)) + +/** @defgroup OPA_VMSSEL + * @{ + */ +#define OPA1_VIMS_SEL_00 ((uint32_t)0x00000000) /*opamp1*/ +#define OPA1_VIMS_SEL_01 ((uint32_t)0x00000001) +#define OPA1_VIMS_SEL_10 ((uint32_t)0x00000002) +#define OPA1_VIMS_SEL_11 ((uint32_t)0x00000003) + +#define OPA2_VIMS_SEL_00 ((uint32_t)0x00000000) /*opamp2*/ +#define OPA2_VIMS_SEL_01 ((uint32_t)0x00000001) +#define OPA2_VIMS_SEL_10 ((uint32_t)0x00000002) +#define OPA2_VIMS_SEL_11 ((uint32_t)0x00000003) + +#define OPA3_VIMS_SEL_00 ((uint32_t)0x00000000) /*opamp3*/ +#define OPA3_VIMS_SEL_01 ((uint32_t)0x00000001) +#define OPA3_VIMS_SEL_10 ((uint32_t)0x00000002) +#define OPA3_VIMS_SEL_11 ((uint32_t)0x00000003) + +#define IS_OPA_VIMS_SEL(INPUT) (((INPUT)==OPA1_VIMS_SEL_00) || \ + ((INPUT) ==OPA1_VIMS_SEL_01) || \ + ((INPUT) ==OPA1_VIMS_SEL_10) || \ + ((INPUT) ==OPA1_VIMS_SEL_11) || \ + ((INPUT) ==OPA2_VIMS_SEL_00) || \ + ((INPUT) ==OPA2_VIMS_SEL_01) || \ + ((INPUT) ==OPA2_VIMS_SEL_10) || \ + ((INPUT) ==OPA2_VIMS_SEL_11) || \ + ((INPUT) ==OPA3_VIMS_SEL_00) || \ + ((INPUT) ==OPA3_VIMS_SEL_01) || \ + ((INPUT) ==OPA3_VIMS_SEL_10) || \ + ((INPUT) ==OPA3_VIMS_SEL_11)) + + +/** @defgroup T8_CM + * @{ + */ +#define OPAMP_TIM8_EN ((uint32_t)0x00000000) /*!< DISABLE tim8 */ +#define OPAMP_TIM8_DIS ((uint32_t)0x00000040) /*!< ENABLE tim8 to AUTOchange */ + +#define IS_OPAX_TIM8_EN(SEL) (((SEL) == OPAMP_TIM8_EN) || \ + ((SEL) == OPAMP_TIM8_DIS)) + +/** @defgroup T1_CM + * @{ + */ +#define OPAMP_TIM1_EN ((uint32_t)0x00000000) /*!< DISABLE tim1 */ +#define OPAMP_TIM1_DIS ((uint32_t)0x00000020) /*!< ENABLE tim1 to AUTOchange */ + +#define IS_OPAX_TIM1_EN(SEL) (((SEL) == OPAMP_TIM1_EN) || \ + ((SEL) == OPAMP_TIM1_DIS)) + + + +/** @defgroup OPAHSM + * @{ + */ +#define OPAHSM_ENABLE ((uint32_t)0x00000080) +#define OPAHSM_DISABLE ((uint32_t)0x00000000) +#define IS_OPAX_OPAHSM(OPAHSM) (((OPAHSM) == OPAHSM_ENABLE ) || \ + ((OPAHSM) == OPAHSM_DISABLE)) + +/** @defgroup OPINTOEN + * @{ + */ +#define OPINTOEN_ENABLE ((uint32_t)0x00000100)//to ADC +#define OPINTOEN_DISABLE ((uint32_t)0x00000000)//to output pad and need O2PADSEL to select +#define IS_OPAX_OPINTOEN(OPINTOEN) (((OPINTOEN) == OPAHSM_ENABLE ) || \ + ((OPINTOEN) == OPAHSM_DISABLE)) + +/** @defgroup O2PADSEL + * @{ + */ +#define O2PADSEL_SEL_PAD1 ((uint32_t)0x00000200)//select pad1 +#define O2PADSEL_SEL_PAD2 ((uint32_t)0x00000000)//select pad2 +#define IS_OPAX_O2PADSEL(O2PADSEL) (((O2PADSEL) == O2PADSEL_SEL_PAD1 ) || \ + ((O2PADSEL) == O2PADSEL_SEL_PAD2)) + +/** @defgroup OPA_PGAGAIN + * @{ + */ +#define OPA_PGAGAIN_GAIN_P2 ((uint32_t)0x00000000) +#define OPA_PGAGAIN_GAIN_P4 ((uint32_t)0x00004000) +#define OPA_PGAGAIN_GAIN_P8 ((uint32_t)0x00008000) +#define OPA_PGAGAIN_GAIN_P16 ((uint32_t)0x0000C000) +#define OPA_PGAGAIN_GAIN_P32 ((uint32_t)0x00010000) +#define OPA_PGAGAIN_GAIN_P64 ((uint32_t)0x00014000) + +#define OPA_PGAGAIN_GAIN_M2_VINM0 ((uint32_t)0x00020000) +#define OPA_PGAGAIN_GAIN_M4_VINM0 ((uint32_t)0x00024000) +#define OPA_PGAGAIN_GAIN_M8_VINM0 ((uint32_t)0x00028000) +#define OPA_PGAGAIN_GAIN_M16_VINM0 ((uint32_t)0x0002c000) +#define OPA_PGAGAIN_GAIN_M32_VINM0 ((uint32_t)0x00030000) +#define OPA_PGAGAIN_GAIN_M64_VINM0 ((uint32_t)0x00034000) + +#define OPA_PGAGAIN_GAIN_FILTER_P2 ((uint32_t)0x00040000) +#define OPA_PGAGAIN_GAIN_FILTER_P4 ((uint32_t)0x00044000) +#define OPA_PGAGAIN_GAIN_FILTER_P8 ((uint32_t)0x00048000) +#define OPA_PGAGAIN_GAIN_FILTER_P16 ((uint32_t)0x0004c000) +#define OPA_PGAGAIN_GAIN_FILTER_P32 ((uint32_t)0x00050000) +#define OPA_PGAGAIN_GAIN_FILTER_P64 ((uint32_t)0x00054000) + +#define OPA_PGAGAIN_GAIN_M2_VINM0_VINM1FIL ((uint32_t)0x00060000) +#define OPA_PGAGAIN_GAIN_M4_VINM0_VINM1FIL ((uint32_t)0x00064000) +#define OPA_PGAGAIN_GAIN_M8_VINM0_VINM1FIL ((uint32_t)0x00068000) +#define OPA_PGAGAIN_GAIN_M16_VINM0_VINM1FIL ((uint32_t)0x0006c000) +#define OPA_PGAGAIN_GAIN_M32_VINM0_VINM1FIL ((uint32_t)0x00070000) +#define OPA_PGAGAIN_GAIN_M64_VINM0_VINM1FIL ((uint32_t)0x00074000) + +#define IS_OPA_PGAGAIN(INPUT) (((INPUT)==OPA_PGAGAIN_GAIN_P2 ) || \ + ((INPUT)==OPA_PGAGAIN_GAIN_P4 ) || \ + ((INPUT)==OPA_PGAGAIN_GAIN_P8 ) || \ + ((INPUT)==OPA_PGAGAIN_GAIN_P16 ) || \ + ((INPUT)==OPA_PGAGAIN_GAIN_P32 ) || \ + ((INPUT)==OPA_PGAGAIN_GAIN_P64 ) || \ + ((INPUT)==OPA_PGAGAIN_GAIN_M2_VINM0 ) || \ + ((INPUT)==OPA_PGAGAIN_GAIN_M4_VINM0 ) || \ + ((INPUT)==OPA_PGAGAIN_GAIN_M8_VINM0 ) || \ + ((INPUT)==OPA_PGAGAIN_GAIN_M16_VINM0 ) || \ + ((INPUT)==OPA_PGAGAIN_GAIN_M32_VINM0 ) || \ + ((INPUT)==OPA_PGAGAIN_GAIN_M64_VINM0 ) || \ + ((INPUT)==OPA_PGAGAIN_GAIN_FILTER_P2 ) || \ + ((INPUT)==OPA_PGAGAIN_GAIN_FILTER_P4 ) || \ + ((INPUT)==OPA_PGAGAIN_GAIN_FILTER_P8 ) || \ + ((INPUT)==OPA_PGAGAIN_GAIN_FILTER_P16 ) || \ + ((INPUT)==OPA_PGAGAIN_GAIN_FILTER_P32 ) || \ + ((INPUT)==OPA_PGAGAIN_GAIN_FILTER_P64 ) || \ + ((INPUT)==OPA_PGAGAIN_GAIN_M2_VINM0_VINM1FIL ) || \ + ((INPUT)==OPA_PGAGAIN_GAIN_M4_VINM0_VINM1FIL ) || \ + ((INPUT)==OPA_PGAGAIN_GAIN_M8_VINM0_VINM1FIL ) || \ + ((INPUT)==OPA_PGAGAIN_GAIN_M16_VINM0_VINM1FIL) || \ + ((INPUT)==OPA_PGAGAIN_GAIN_M32_VINM0_VINM1FIL) || \ + ((INPUT)==OPA_PGAGAIN_GAIN_M64_VINM0_VINM1FIL)) + + + +/** @defgroup OPAMP_CALSEL_SEL + * @{ + */ +#define OPAMP_VDDA003_CAL ((uint32_t)0x00000000) /*!< Selection:0.03VDDA */ +#define OPAMP_PMOS_CAL ((uint32_t)0x00001000) /*!< PMOS Selection:0.1VDDA */ +#define OPAMP_VDDA05_CAL ((uint32_t)0x00002000) /*!< Selection:0.5VDDA */ +#define OPAMP_NMOS_CAL ((uint32_t)0x00003000) /*!< NMOS Selection:0.9VDDA */ + +#define IS_OPAX_NPMOS(VOL) (((VOL) ==OPAMP_VDDA003_CAL ) || \ + ((VOL) ==OPAMP_PMOS_CAL ) || \ + ((VOL) ==OPAMP_VDDA05_CAL) || \ + ((VOL) ==OPAMP_NMOS_CAL )) + + +/* Initialization and Configuration functions *********************************/ +void OPA_Init(OPA_InitTypeDef* OPA_InitStruct, uint32_t OPAMP_Selection); +void OPA_DeInit(uint32_t OPAMP_Selection); +void OPA_Cmd(uint32_t OPAMP_Selection, FunctionalState NewState); +/* Function used to set the COMP configuration to the default reset state ****/ +void OPAMP_Calibration(uint32_t OPAMP_Selection); + + +#ifdef __cplusplus +} +#endif + +#endif /* __FT32F0XX_OPAMP_H */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_pcd_ex_hs.h b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_pcd_ex_hs.h new file mode 100644 index 00000000000..babff4e00f4 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_pcd_ex_hs.h @@ -0,0 +1,66 @@ +/** + ****************************************************************************** + * @file ft32f4xx_pcd_ex_hs.h + * @author FMD XA + * @brief This file contains all the functions prototypes for the + * >>->-USB_OTG_HS firmware library. + * @version V1.0.0 + * @data 2025-03-31 + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __FT32F4XX_PCD_EX_HS_H +#define __FT32F4XX_PCD_EX_HS_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx_usb_hs.h" + +#if defined (USB_OTG_HS) +/** @addtogroup ft32f4xx Drive + * @ + */ + +/** @addtogroup PCD_HS + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup PCD_HS_Exported_Types PCD Exported Types + * @{ + */ + +/** @defgroup PCD_HS_Exported_Types_Group1 PCD State Structure definition + * @{ + */ +/** @addtogroup PCDEx_Exported_Functions PCDEx Exported Functions + * @{ + */ +/** @addtogroup PCDEx_Exported_Functions_Group1 Peripheral Control functions + * @{ + */ + +#if defined (USB_OTG_HS) +void PCDEx_HS_SetTxFiFo(uint8_t fifo, uint16_t size); +void PCDEx_HS_SetRxFiFo(uint16_t size); +#endif /* defined (USB_OTG_HS) */ + + + +/** + * @} + */ +#endif /* defined (USB_OTG_HS) */ + +#ifdef __cplusplus +} +#endif + + +#endif /* FT32F4XX_PCD_HS_H */ + +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_pcd_fs.h b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_pcd_fs.h new file mode 100644 index 00000000000..abe78f1f5ed --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_pcd_fs.h @@ -0,0 +1,186 @@ +/** + ****************************************************************************** + * @file ft32f4xx_pcd_fs.h + * @author FMD XA + * @brief This file contains all the functions prototypes for the + * >>->-USB_OTG_FS firmware library. + * @version V1.0.0 + * @data 2025-06-04 + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __FT32F4XX_PCD_FS_H +#define __FT32F4XX_PCD_FS_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx_usb_fs.h" + +#if defined (USB_OTG_FS) + + +/* Exported types ------------------------------------------------------------*/ + +#if defined (USB_OTG_FS) +void PCD_FS_SetTxFiFo(uint8_t fifo, uint16_t size, uint8_t dpb); +void PCD_FS_SetRxFiFo(uint8_t fifo, uint16_t size, uint8_t dpb); +#endif /* defined (USB_OTG_FS) */ + + +/** + * @brief PCD state structure definition + */ + +typedef enum +{ + PCD_FS_STATE_RESET = 0x00, + PCD_FS_STATE_READY = 0x01, + PCD_FS_STATE_ERROR = 0x02, + PCD_FS_STATE_BUSY = 0x03, + PCD_FS_STATE_TIMEOUT = 0x04 +} PCD_FS_StateTypeDef; + + + +#if defined (USB_OTG_FS) +typedef USB_OTG_FS_CfgTypeDef PCD_FS_InitTypeDef; +typedef USB_OTG_FS_DEPTypeDef PCD_FS_EPTypeDef; +typedef USB_FS_LockTypeDef PCD_FS_LockTypeDef; +typedef USB_OTG_FS_CtlStateTypeDef PCD_FS_CtlStateTypeDef; +#endif /* defined (USB_OTG_FS) */ + +/** + * @} + */ + +/** @brief PCD Handle Structure definition + * @{ + */ +typedef struct +{ + PCD_FS_InitTypeDef Init; /*!< PCD required parameters */ + __IO uint8_t USB_Address;/*!< USB Address */ + PCD_FS_EPTypeDef IN_ep[16]; /*!< IN endpoint parameters */ + PCD_FS_EPTypeDef OUT_ep[16]; /*!< OUT endpoint parameters */ + PCD_FS_CtlStateTypeDef ctrl_state; + PCD_FS_LockTypeDef Lock; /*!< PCD peripheral status */ + __IO PCD_FS_StateTypeDef State; /*!< PCD communication state */ + __IO uint32_t ErrorCode; /*!< PCD Error code */ + uint32_t Setup[2]; /*!< Setup packet buffer */ + uint32_t FrameNumber;/*!< Store Current Frame number*/ + void *pData; /*!< Pointer Stack Handler */ +} PCD_FS_HandleTypeDef; +/** + * @} + */ + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ + +#define PCD_SPEED_FULL USB_FS_SPEED + +/* Exported macro ------------------------------------------------------------*/ + +#define __USB_OTG_FS_WAKEUP_EXTI_ENABLE_IT() EXTI->IMR |= USB_OTG_FS_WAKEUP_EXTI_LINE +#define __USB_OTG_FS_WAKEUP_EXTI_DISABLE_IT() EXTI->IMR &= ~(USB_OTG_FS_WAKEUP_EXTI_LINE) +#define __USB_OTG_FS_WAKEUP_EXTI_GET_FLAG() EXTI->PR & (USB_OTG_FS_WAKEUP_EXTI_LINE) +#define __USB_OTG_FS_WAKEUP_EXTI_CLEAR_FLAG() EXTI->PR = USB_OTG_FS_WAKEUP_EXTI_LINE + +#define __USB_OTG_FS_WAKEUP_EXTI_ENABLE_RISING_EDGE() \ + do { \ + EXTI->FTSR &= ~(USB_OTG_FS_WAKEUP_EXTI_LINE); \ + EXTI->RTSR |= USB_OTG_FS_WAKEUP_EXTI_LINE; \ + } while(0U) + + +/* Exported functions --------------------------------------------------------*/ + +USB_FS_StatusTypeDef PCD_FS_Init(PCD_FS_HandleTypeDef *hpcd); +USB_FS_StatusTypeDef PCD_FS_DeInit(PCD_FS_HandleTypeDef *hpcd); +void PCD_FS_SetISO(uint8_t ep_num, uint8_t state); +void PCD_FS_SetMaxPkt(uint8_t ep_num, uint16_t size); + +void PCD_FS_MspInit(PCD_FS_HandleTypeDef *hpcd); +void PCD_FS_MspDeInit(PCD_FS_HandleTypeDef *hpcd); + + +/* I/O operation functions ***************************************************/ + +USB_FS_StatusTypeDef PCD_FS_Start(PCD_FS_HandleTypeDef *hpcd); +USB_FS_StatusTypeDef PCD_FS_Stop(PCD_FS_HandleTypeDef *hpcd); + +/* Non-Blocking mode: Interrupt */ +void PCD_FS_IRQHandler(PCD_FS_HandleTypeDef *hpcd); +void PCD_FS_EP0_IRQHandler(PCD_FS_HandleTypeDef *hpcd); +void PCD_FS_TXEP_IRQHandler(PCD_FS_HandleTypeDef *hpcd, uint32_t epnum); +void PCD_FS_RXEP_IRQHandler(PCD_FS_HandleTypeDef *hpcd, uint32_t epnum); +void PCD_FS_WKUP_IRQHandler(void); + +void PCD_FS_SOFCallback(PCD_FS_HandleTypeDef *hpcd); +void PCD_FS_SetupStageCallback(PCD_FS_HandleTypeDef *hpcd); +void PCD_FS_ResetCallback(PCD_FS_HandleTypeDef *hpcd); +void PCD_FS_SuspendCallback(PCD_FS_HandleTypeDef *hpcd); +void PCD_FS_ResumeCallback(PCD_FS_HandleTypeDef *hpcd); +void PCD_FS_ConnectCallback(PCD_FS_HandleTypeDef *hpcd); +void PCD_FS_DisconnectCallback(PCD_FS_HandleTypeDef *hpcd); +void PCD_FS_SessionCallback(PCD_FS_HandleTypeDef *hpcd); +void PCD_FS_VBusErrCallback(PCD_FS_HandleTypeDef *hpcd); +void PCD_FS_OVERRUNCallback(PCD_FS_HandleTypeDef *hpcd); +void PCD_FS_UNDERRUNCallback(PCD_FS_HandleTypeDef *hpcd); +void PCD_FS_DERRCallback(PCD_FS_HandleTypeDef *hpcd); + +void PCD_FS_DataOutStageCallback(PCD_FS_HandleTypeDef *hpcd, uint8_t epnum); +void PCD_FS_DataInStageCallback(PCD_FS_HandleTypeDef *hpcd, uint8_t epnum); + +/* Peripheral Control functions **********************************************/ + +USB_FS_StatusTypeDef PCD_FS_DevDisconnect(PCD_FS_HandleTypeDef *hpcd); +USB_FS_StatusTypeDef PCD_FS_SetAddress(PCD_FS_HandleTypeDef *hpcd, uint8_t address); +USB_FS_StatusTypeDef PCD_FS_EP_Open(PCD_FS_HandleTypeDef *hpcd, uint8_t ep_addr, uint16_t ep_mps, uint8_t ep_type); +USB_FS_StatusTypeDef PCD_FS_Ep_Close(PCD_FS_HandleTypeDef *hpcd, uint8_t ep_addr); +void PCD_FS_Ep_Receive(PCD_FS_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len); +void PCD_FS_Ep_Transmit(PCD_FS_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len); +USB_FS_StatusTypeDef PCD_FS_EP_SetStall(PCD_FS_HandleTypeDef *hpcd, uint8_t ep_addr); +USB_FS_StatusTypeDef PCD_FS_EP_ClrStall(PCD_FS_HandleTypeDef *hpcd, uint8_t ep_addr); +USB_FS_StatusTypeDef PCD_FS_EP_Flush(PCD_FS_HandleTypeDef *hpcd, uint8_t ep_addr); +USB_FS_StatusTypeDef PCD_FS_EP_Abort(PCD_FS_HandleTypeDef *hpcd, uint8_t ep_addr); +void PCD_FS_ActivateRemoteWakeup(void); +void PCD_FS_DeActivateRemoteWakeup(void); + +uint32_t PCD_FS_EP_GetRxCount(const PCD_FS_HandleTypeDef *hpcd, uint8_t ep_addr); +USB_FS_StatusTypeDef PCD_FS_EP_Close(PCD_FS_HandleTypeDef *hpcd, uint8_t ep_addr); +void PCD_FS_EP_Receive(PCD_FS_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len); +void PCD_FS_EP_Transmit(PCD_FS_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len); +/* Peripheral State functions ************************************************/ + +PCD_FS_StateTypeDef PCD_FS_GetState(PCD_FS_HandleTypeDef const *hpcd); + + +/* Private constants ---------------------------------------------------------*/ + + +#if defined (USB_OTG_FS) +#define USB_OTG_FS_WAKEUP_EXTI_LINE (0x1U << 18) /*!< USB FS EXTI Line WakeUp Interrupt */ +#endif /* defined (USB_OTG_FS) */ + + + +/* Private constants ---------------------------------------------------------*/ + + +#endif /* defined (USB_OTG_FS) */ + +#ifdef __cplusplus +} +#endif + +#endif /* FT32F4XX_PCD_FS_H */ + +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_pcd_hs.h b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_pcd_hs.h new file mode 100644 index 00000000000..520a5c73280 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_pcd_hs.h @@ -0,0 +1,304 @@ +/** + ****************************************************************************** + * @file ft32f4xx_pcd_hs.h + * @author FMD XA + * @brief This file contains all the functions prototypes for the + * >>->-USB_OTG_HS firmware library. + * @version V1.0.0 + * @data 2025-03-31 + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __FT32F4XX_PCD_HS_H +#define __FT32F4XX_PCD_HS_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx_usb_hs.h" + +#if defined (USB_OTG_HS) +/** @addtogroup ft32f4xx Drive + * @ + */ + +/** @addtogroup PCD_HS + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup PCD_HS_Exported_Types PCD Exported Types + * @{ + */ + +/** @defgroup PCD_HS_Exported_Types_Group1 PCD State Structure definition + * @{ + */ + +/** + * @brief PCD state structure definition + */ + +typedef enum +{ + PCD_HS_STATE_RESET = 0x00, + PCD_HS_STATE_READY = 0x01, + PCD_HS_STATE_ERROR = 0x02, + PCD_HS_STATE_BUSY = 0x03, + PCD_HS_STATE_TIMEOUT = 0x04 +} PCD_HS_StateTypeDef; + + + +#if defined (USB_OTG_HS) +typedef USB_OTG_HS_GlobalTypeDef PCD_HS_TypeDef; +typedef USB_OTG_HS_CfgTypeDef PCD_HS_InitTypeDef; +typedef USB_OTG_HS_EPTypeDef PCD_HS_EPTypeDef; +typedef USB_HS_LockTypeDef PCD_HS_LockTypeDef; +#endif /* defined (USB_OTG_HS) */ + +/** + * @} + */ + +/** @brief PCD Handle Structure definition + * @{ + */ +typedef struct +{ + PCD_HS_InitTypeDef Init; /*!< PCD required parameters */ + __IO uint8_t USB_Address;/*!< USB Address */ + PCD_HS_EPTypeDef IN_ep[16]; /*!< IN endpoint parameters */ + PCD_HS_EPTypeDef OUT_ep[16]; /*!< OUT endpoint parameters */ + PCD_HS_LockTypeDef Lock; /*!< PCD peripheral status */ + __IO PCD_HS_StateTypeDef State; /*!< PCD communication state */ + __IO uint32_t ErrorCode; /*!< PCD Error code */ + uint32_t Setup[2]; /*!< Setup packet buffer */ + uint32_t FrameNumber;/*!< Store Current Frame number*/ + void *pData; /*!< Pointer Stack Handler */ +} PCD_HS_HandleTypeDef; +/** + * @} + */ + +/* Include PCD Extended module */ +#include "ft32f4xx_pcd_ex_hs.h" + + + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup PCD_HS_Exported_Constants PCD Exported Constants + * @{ + */ + +/** @defgroup PCD_Speed PCD Speed + * @{ + */ +#define PCD_SPEED_HIGH USBD_HS_SPEED +#define PCD_SPEED_HIGH_IN_FULL USBD_HSINFS_SPEED +#define PCD_SPEED_FULL USBD_FS_SPEED +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup PCD_HS_Exported_Macros PCD Exported Macros + * @brief macros to handle interrupts and specific clock configurations + * @{ + */ +#define __PCD_HS_ENABLE() (void)USB_HS_EnableGlobalInt () +#define __PCD_HS_DISABLE() (void)USB_HS_DisableGlobalInt () + +#define __PCD_HS_GET_FLAG(__INTERRUPT__) ((USB_HS_ReadInterrupts()\ + & (__INTERRUPT__)) == (__INTERRUPT__)) +#define __PCD_HS_GET_CH_FLAG(__chnum__, __INTERRUPT__) \ + ((USB_HS_ReadChInterrupts((__chnum__))\ + & (__INTERRUPT__)) == (__INTERRUPT__)) +#define __PCD_HS_CLEAR_FLAG(__INTERRUPT__) ((USB_HS->GINTSTS) = (__INTERRUPT__)) +#define __PCD_HS_IS_INVALID_INTERRUPT() (USB_HS_ReadInterrupts() == 0U) + +#define __PCD_HS_UNGATE_PHYCLOCK() \ + *(__IO uint32_t *)((uint32_t)OTG_HS_BASE + USB_OTG_HS_PCGCCTL_BASE) &= ~(OTG_HS_PCGCCTL_STOPCLK) + +#define __PCD_HS_GATE_PHYCLOCK() \ + *(__IO uint32_t *)((uint32_t)OTG_HS_BASE + USB_OTG_HS_PCGCCTL_BASE) |= OTG_HS_PCGCCTL_STOPCLK + +#define __PCD_HS_IS_PHY_SUSPENDED() \ + ((*(__IO uint32_t *)((uint32_t)OTG_HS_BASE + USB_OTG_HS_PCGCCTL_BASE)) & 0x10U) + +#define __USB_OTG_HS_WAKEUP_EXTI_ENABLE_IT() EXTI->IMR |= USB_OTG_HS_WAKEUP_EXTI_LINE +#define __USB_OTG_HS_WAKEUP_EXTI_DISABLE_IT() EXTI->IMR &= ~(USB_OTG_HS_WAKEUP_EXTI_LINE) +#define __USB_OTG_HS_WAKEUP_EXTI_GET_FLAG() EXTI->PR & (USB_OTG_HS_WAKEUP_EXTI_LINE) +#define __USB_OTG_HS_WAKEUP_EXTI_CLEAR_FLAG() EXTI->PR = USB_OTG_HS_WAKEUP_EXTI_LINE + +#define __USB_OTG_HS_WAKEUP_EXTI_ENABLE_RISING_EDGE() \ + do { \ + EXTI->FTSR &= ~(USB_OTG_HS_WAKEUP_EXTI_LINE); \ + EXTI->RTSR |= USB_OTG_HS_WAKEUP_EXTI_LINE; \ + } while(0U) + + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup PCD_HS_Exported_Functions PCD Exported Functions + * @{ + */ + +/** @defgroup PCD_HS_Exported_Functions_Group1 Initialization and de-initialization functions + * @{ + */ +USB_HS_StatusTypeDef PCD_HS_Init(PCD_HS_HandleTypeDef *hpcd); +USB_HS_StatusTypeDef PCD_HS_DeInit(PCD_HS_HandleTypeDef *hpcd); + +void PCD_HS_MspInit(PCD_HS_HandleTypeDef *hpcd); +void PCD_HS_MspDeInit(PCD_HS_HandleTypeDef *hpcd); + +/** + * @} + */ + +/* I/O operation functions ***************************************************/ +/** @addtogroup PCD_Exported_Functions_Group2 Input and Output operation functions + * @{ + */ +USB_HS_StatusTypeDef PCD_HS_Start(PCD_HS_HandleTypeDef *hpcd); +USB_HS_StatusTypeDef PCD_HS_Stop(PCD_HS_HandleTypeDef *hpcd); + +/* Non-Blocking mode: Interrupt */ +void PCD_HS_IRQHandler(PCD_HS_HandleTypeDef *hpcd); +void PCD_HS_WKUP_IRQHandler(void); + +void PCD_HS_SOFCallback(PCD_HS_HandleTypeDef *hpcd); +void PCD_HS_SetupStageCallback(PCD_HS_HandleTypeDef *hpcd); +void PCD_HS_ResetCallback(PCD_HS_HandleTypeDef *hpcd); +void PCD_HS_SuspendCallback(PCD_HS_HandleTypeDef *hpcd); +void PCD_HS_ResumeCallback(PCD_HS_HandleTypeDef *hpcd); +void PCD_HS_ConnectCallback(PCD_HS_HandleTypeDef *hpcd); +void PCD_HS_DisconnectCallback(PCD_HS_HandleTypeDef *hpcd); + +void PCD_HS_DataOutStageCallback(PCD_HS_HandleTypeDef *hpcd, uint8_t epnum); +void PCD_HS_DataInStageCallback(PCD_HS_HandleTypeDef *hpcd, uint8_t epnum); +void PCD_HS_ISOOUTIncompleteCallback(PCD_HS_HandleTypeDef *hpcd, uint8_t epnum); +void PCD_HS_ISOINIncompleteCallback(PCD_HS_HandleTypeDef *hpcd, uint8_t epnum); +void USBD_SET_ADDR_Callback(PCD_HS_HandleTypeDef *hpcd); + +/** + * @} + */ + +/* Peripheral Control functions **********************************************/ +/** @addtogroup PCD_HS_Exported_Functions_Group3 Peripheral Control functions + * @{ + */ +USB_HS_StatusTypeDef PCD_HS_DevConnect(PCD_HS_HandleTypeDef *hpcd); +USB_HS_StatusTypeDef PCD_HS_DevDisconnect(PCD_HS_HandleTypeDef *hpcd); +USB_HS_StatusTypeDef PCD_HS_SetAddress(PCD_HS_HandleTypeDef *hpcd, uint8_t address); +USB_HS_StatusTypeDef PCD_HS_EP_Open(PCD_HS_HandleTypeDef *hpcd, uint8_t ep_addr, uint16_t ep_mps, uint8_t ep_type); +USB_HS_StatusTypeDef PCD_HS_Ep_Close(PCD_HS_HandleTypeDef *hpcd, uint8_t ep_addr); +void PCD_HS_Ep_Receive(PCD_HS_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len); +void PCD_HS_Ep_Transmit(PCD_HS_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len); +USB_HS_StatusTypeDef PCD_HS_EP_SetStall(PCD_HS_HandleTypeDef *hpcd, uint8_t ep_addr); +USB_HS_StatusTypeDef PCD_HS_EP_ClrStall(PCD_HS_HandleTypeDef *hpcd, uint8_t ep_addr); +USB_HS_StatusTypeDef PCD_HS_EP_Flush(PCD_HS_HandleTypeDef *hpcd, uint8_t ep_addr); +USB_HS_StatusTypeDef PCD_HS_EP_Abort(PCD_HS_HandleTypeDef *hpcd, uint8_t ep_addr); +void PCD_HS_ActivateRemoteWakeup(void); +void PCD_HS_DeActivateRemoteWakeup(void); + +void PCD_HS_SetTestMode(uint8_t testmode); + +uint32_t PCD_HS_EP_GetRxCount(PCD_HS_HandleTypeDef const *hpcd, uint8_t ep_addr); +USB_HS_StatusTypeDef PCD_HS_EP_Close(PCD_HS_HandleTypeDef *hpcd, uint8_t ep_addr); +void PCD_HS_EP_Transmit(PCD_HS_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len); +void PCD_HS_EP_Receive(PCD_HS_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len); +/** + * @} + */ + +/* Peripheral State functions ************************************************/ +/** @addtogroup PCD_Exported_Functions_Group4 Peripheral State functions + * @{ + */ +PCD_HS_StateTypeDef PCD_HS_GetState(PCD_HS_HandleTypeDef const *hpcd); + +/** + * @} + */ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup PCD_Private_Constants PCD Private Constants + * @{ + */ +/** @defgroup USB_EXTI_Line_Interrupt USB EXTI line interrupt + * @{ + */ +#if defined (USB_OTG_HS) +#define USB_OTG_HS_WAKEUP_EXTI_LINE (0x1U << 20) /*!< USB HS EXTI Line WakeUp Interrupt */ +#endif /* defined (USB_OTG_HS) */ + + +/** + * @} + */ + + +#if defined (USB_OTG_HS) +#ifndef USB_OTG_DOEPINT_OTEPSPR +#define USB_OTG_DOEPINT_OTEPSPR (0x1UL << 5) /*!< Status Phase Received interrupt */ +#endif /* defined USB_OTG_DOEPINT_OTEPSPR */ + +#ifndef USB_OTG_DOEPMSK_OTEPSPRM +#define USB_OTG_DOEPMSK_OTEPSPRM (0x1UL << 5) /*!< Setup Packet Received interrupt mask */ +#endif /* defined USB_OTG_DOEPMSK_OTEPSPRM */ + +#ifndef USB_OTG_DOEPINT_NAK +#define USB_OTG_DOEPINT_NAK (0x1UL << 13) /*!< NAK interrupt */ +#endif /* defined USB_OTG_DOEPINT_NAK */ + +#ifndef USB_OTG_DOEPMSK_NAKM +#define USB_OTG_DOEPMSK_NAKM (0x1UL << 13) /*!< OUT Packet NAK interrupt mask */ +#endif /* defined USB_OTG_DOEPMSK_NAKM */ + +#ifndef USB_OTG_DOEPINT_STPKTRX +#define USB_OTG_DOEPINT_STPKTRX (0x1UL << 15) /*!< Setup Packet Received interrupt */ +#endif /* defined USB_OTG_DOEPINT_STPKTRX */ + +#ifndef USB_OTG_DOEPMSK_NYETM +#define USB_OTG_DOEPMSK_NYETM (0x1UL << 14) /*!< Setup Packet Received interrupt mask */ +#endif /* defined USB_OTG_DOEPMSK_NYETM */ +#endif /* defined (USB_OTG_HS) */ + + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup PCD_Private_Macros PCD Private Constants + * @{ + */ +/** + * @} + */ + +/** + * @} + */ +#endif /* defined (USB_OTG_HS) */ + +#ifdef __cplusplus +} +#endif + + +#endif /* FT32F4XX_PCD_HS_H */ + +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_pwr.h b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_pwr.h new file mode 100644 index 00000000000..29acde4f759 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_pwr.h @@ -0,0 +1,251 @@ +/** + ****************************************************************************** + * @file ft32f4xx_pwr.h + * @author Rwang + * @brief This file contains all the functions prototypes for the PWR firmware + * library. + * @version V1.0.0 + * @data 2025-03-24 + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __FT32F4XX_PWR_H +#define __FT32F4XX_PWR_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx.h" + + + +/** @addtogroup PWR + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup PWR_Exported_Constants + * @{ + */ + +/** @defgroup PWR_Vbat_charge_Resistance_Choose + * @{ + */ + +#define PWR_Vbat_Charge_5k ((uint32_t)0x00000000) +#define PWR_Vbat_Charge_1point5k ((uint32_t)0x00000001) + +#define IS_PWR_VBAT_RES(RES) (((RES) == PWR_Vbat_Charge_5k) || \ + ((RES) == PWR_Vbat_Charge_1point5k) ) +/** + * @} + */ + +/** @defgroup PWR_Vos_Level_Choose + * @{ + */ + +#define PWR_VosLevel_0 PWR_CR_VOS_0 +#define PWR_VosLevel_1 PWR_CR_VOS_1 +#define PWR_VosLevel_2 PWR_CR_VOS_2 +#define PWR_VosLevel_3 PWR_CR_VOS_3 +#define IS_PWR_VOS_LEVEL(LEVEL) (((LEVEL) == PWR_VosLevel_0) || \ + ((LEVEL) == PWR_VosLevel_1) || \ + ((LEVEL) == PWR_VosLevel_2) || \ + ((LEVEL) == PWR_VosLevel_3) ) +/** + * @} + */ + +/** @defgroup PWR_PVDR_detection_level + * @brief + * @{ + */ +#define PWR_PVDRLevel_0 PWR_CR_PLSR_0 +#define PWR_PVDRLevel_1 PWR_CR_PLSR_1 +#define PWR_PVDRLevel_2 PWR_CR_PLSR_2 +#define PWR_PVDRLevel_3 PWR_CR_PLSR_3 +#define PWR_PVDRLevel_4 PWR_CR_PLSR_4 +#define PWR_PVDRLevel_5 PWR_CR_PLSR_5 +#define PWR_PVDRLevel_6 PWR_CR_PLSR_6 +#define PWR_PVDRLevel_7 PWR_CR_PLSR_7 + +#define IS_PWR_PVDR_LEVEL(LEVEL) (((LEVEL) == PWR_PVDRLevel_0) || ((LEVEL) == PWR_PVDRLevel_1)|| \ + ((LEVEL) == PWR_PVDRLevel_2) || ((LEVEL) == PWR_PVDRLevel_3)|| \ + ((LEVEL) == PWR_PVDRLevel_4) || ((LEVEL) == PWR_PVDRLevel_5)|| \ + ((LEVEL) == PWR_PVDRLevel_6) || ((LEVEL) == PWR_PVDRLevel_7) ) +/** + * @} + */ + +/** @defgroup PWR_PVDF_detection_level + * @brief + * @{ + */ +#define PWR_PVDFLevel_0 PWR_CR_PLSF_0 +#define PWR_PVDFLevel_1 PWR_CR_PLSF_1 +#define PWR_PVDFLevel_2 PWR_CR_PLSF_2 +#define PWR_PVDFLevel_3 PWR_CR_PLSF_3 +#define PWR_PVDFLevel_4 PWR_CR_PLSF_4 +#define PWR_PVDFLevel_5 PWR_CR_PLSF_5 +#define PWR_PVDFLevel_6 PWR_CR_PLSF_6 +#define PWR_PVDFLevel_7 PWR_CR_PLSF_7 + +#define IS_PWR_PVDF_LEVEL(LEVEL) (((LEVEL) == PWR_PVDFLevel_0) || ((LEVEL) == PWR_PVDFLevel_1)|| \ + ((LEVEL) == PWR_PVDFLevel_2) || ((LEVEL) == PWR_PVDFLevel_3)|| \ + ((LEVEL) == PWR_PVDFLevel_4) || ((LEVEL) == PWR_PVDFLevel_5)|| \ + ((LEVEL) == PWR_PVDFLevel_6) || ((LEVEL) == PWR_PVDFLevel_7) ) +/** + * @} + */ + +/** @defgroup PWR_WakeUp_Pins + * @{ + */ + +#define PWR_WakeUpPin_1 PWR_CSR_EWUP_PA0 +#define PWR_WakeUpPin_2 PWR_CSR_EWUP_PC13 +#define PWR_WakeUpPin_3 PWR_CSR_EWUP_PA2 +#define IS_PWR_WAKEUP_PIN(PIN) (((PIN) == PWR_WakeUpPin_1) || ((PIN) == PWR_WakeUpPin_2) || \ + ((PIN) == PWR_WakeUpPin_3)) +/** + * @} + */ + +/** @defgroup PWR_Regulator_state_is_Sleep_STOP_mode + * @{ + */ +#define PWR_Regulator_ON ((uint32_t)0x00000000) +#define PWR_Regulator_LowPower PWR_CR_LPDS +#define IS_PWR_REGULATOR(REGULATOR) (((REGULATOR) == PWR_Regulator_ON) || \ + ((REGULATOR) == PWR_Regulator_LowPower)) +/** + * @} + */ + + +/** @defgroup PWR_Sleep_mode_entry + * @{ + */ +#define PWR_SleepEntry_WFI ((uint8_t)0x01) +#define PWR_SleepEntry_WFE ((uint8_t)0x02) +#define PWR_SleepEntry_SLEEPONEXIT ((uint8_t)0x03) +#define IS_PWR_SLEEP_ENTRY(ENTRY) (((ENTRY) == PWR_SleepEntry_WFI) || ((ENTRY) == PWR_SleepEntry_WFE) || \ + ((ENTRY) == PWR_SleepEntry_SLEEPONEXIT)) +/** + * @} + */ + +/** @defgroup PWR_Stop_mode_entry + * @{ + */ +#define PWR_StopEntry_WFI ((uint8_t)0x01) +#define PWR_StopEntry_WFE ((uint8_t)0x02) +#define IS_PWR_STOP_ENTRY(ENTRY) (((ENTRY) == PWR_StopEntry_WFI) || ((ENTRY) == PWR_StopEntry_WFE)) +/** + * @} + */ + +/** @defgroup PWR_Standby_mode_entry + * @{ + */ +#define PWR_StandbyEntry_WFI ((uint8_t)0x01) +#define PWR_StandbyEntry_WFE ((uint8_t)0x02) +#define IS_PWR_STANDBY_ENTRY(ENTRY) (((ENTRY) == PWR_StandbyEntry_WFI) || ((ENTRY) == PWR_StandbyEntry_WFE)) +/** + * @} + */ + + + +/** @defgroup PWR_Flag + * @{ + */ +#define PWR_FLAG_WU PWR_CSR_WUF +#define PWR_FLAG_SB PWR_CSR_SBF +#define PWR_FLAG_PVDO PWR_CSR_PVDO +#define PWR_FLAG_BRR PWR_CSR_BRR +#define PWR_FLAG_VREFINTRDY PWR_CSR_VOSRDY +#define IS_PWR_GET_FLAG(FLAG) (((FLAG) == PWR_FLAG_WU) || ((FLAG) == PWR_FLAG_SB) || \ + ((FLAG) == PWR_FLAG_PVDO) || ((FLAG) == PWR_FLAG_BRR) || \ + ((FLAG) == PWR_FLAG_VREFINTRDY)) +/** + * @} + */ + +/** @defgroup PWR_Flag_Clear + * @{ + */ +#define PWR_FLAG_CWU PWR_CR_CWUF +#define PWR_FLAG_CSB PWR_CR_CSBF +#define IS_PWR_CLEAR_FLAG(FLAG) (((FLAG) == PWR_FLAG_CWU) || \ + ((FLAG) == PWR_FLAG_CSB)) +/** + * @} + */ + + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +/* Function used to set the PWR configuration to the default reset state ******/ +void PWR_DeInit(void); + +/* Vbat charge and charge resistance choose function ******/ +void PWR_VbatCharge(FunctionalState NewState); +void PWR_VbatResConfig(uint32_t PWR_VbatRes); + +/* Main Voltage Regulator choose function ******/ +void PWR_VosLevelConfig(uint32_t PWR_VosLevel); + +/* Backup Domain Access function **********************************************/ +void PWR_BackupAccessCmd(FunctionalState NewState); + +/* PVD configuration functions ************************************************/ +void PWR_PVDEnable(FunctionalState NewState); +void PWR_PVDRLevelConfig(uint32_t PWR_PVDRLevel); +void PWR_PVDFLevelConfig(uint32_t PWR_PVDFLevel); + +/* PDROFF enable functions ************************************************/ +void PWR_PdroffEnable(FunctionalState NewState); + +/* WakeUp pins configuration functions ****************************************/ +void PWR_WakeUpPinCmd(uint32_t PWR_WakeUpPin, FunctionalState NewState); + +/* Backup Regulator Enable ************************************************/ +void PWR_BreEnable(FunctionalState NewState); + +/* Low Power modes configuration functions ************************************/ +void PWR_EnterSleepMode(uint8_t PWR_SleepEntry); +void PWR_EnterStopMode(uint32_t PWR_Regulator, uint8_t PWR_StopEntry); +void PWR_EnterStandbyMode(uint8_t PWR_StandbyEntry); + +/* Flags management functions *************************************************/ +FlagStatus PWR_GetFlagStatus(uint32_t PWR_FLAG); +void PWR_ClearFlag(uint32_t PWR_FLAG); + +#ifdef __cplusplus +} +#endif + +#endif /* __FT32F0XX_PWR_H */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_qspi.h b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_qspi.h new file mode 100644 index 00000000000..b5935e6854b --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_qspi.h @@ -0,0 +1,732 @@ +/** + ****************************************************************************** + * @file ft32f4xx_qspi.h + * @author FMD AE + * @brief This file contains all the functions prototypes for the QSPI + * firmware library. + * @version V1.0.0 + * @data 2025-03-06 + ****************************************************************************** + */ + + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __FT32F4XX_QSPI_H +#define __FT32F4XX_QSPI_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx.h" + + +/** @addtogroup QSPI + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** + * @brief QSPI Init structure definition + */ + +typedef struct +{ + + uint32_t QSPI_Protocol; /*!< Specifies which QSPI serial proptocol is selected. + This parameter can be a value of @ref QSPI_Protocol_Sel . */ + + uint32_t QSPI_Direction; /*!< Specifies the QSPI transfer mode. + This parameter can be a value of @ref QSPI_data_direction. */ + + uint32_t QSPI_SSTE; /*!< Specifies the QSPI NCSX Toggle Enable. + This parameter can be a value of @ref QSPI_SSTE_Enable . */ + + uint32_t QSPI_DataSize; /*!< Specifies the QSPI data size. + This parameter can be a value of @ref QSPI_data_size. */ + + uint32_t QSPI_SCPOL; /*!< Specifies the serial clock steady state. + This parameter can be a value of @ref QSPI_Clock_Polarity. */ + + uint32_t QSPI_SCPHA; /*!< Specifies the clock active edge for the bit capture. + This parameter can be a value of @ref QSPI_Clock_Phase */ + + uint32_t QSPI_SER; /*!< Specifies which NCSx line is selected. + This parameter can be a value of @ref QSPI_SER_SEL. */ + + uint32_t QSPI_BaudRatePrescaler; /*!< Specifies the Baud Rate prescaler value which will be + used to configure the transmit and receive SCK clock. + This parameter can be a value (15-bits) between 0x0 and 0xEFFF. + @note The communication clock is derived from the master + clock. The slave clock does not need to be set. */ + + uint32_t QSPI_CS_MIN_HIGH; /*!< Specifies the CS mini high time + This parameter can be a value (8 bits) between 0x0 and 0xF. */ + + uint32_t QSPI_DataMode; /* Specifies the Data Mode (used for dummy cycles and data phases) + This parameter can be a value of @ref QSPI_DataMode */ + +} QSPI_InitTypeDef; + + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup SPI_Exported_Constants + * @{ + */ + + +/** @defgroup + * @{ + */ + +#define QSPI_STANDARD ((uint32_t)0x00000000) +#define QSPI_DUAL ((uint32_t)0x00400000) +#define QSPI_QUAD ((uint32_t)0x00800000) +#define IS_QSPI_DATA_MODE(MODE) (((MODE) == QSPI_STANDARD) || \ + ((MODE) == QSPI_DUAL) || \ + ((MODE) == QSPI_QUAD)) +/** + * @} + */ + +/** @defgroup QSPI_SER_SEL + * @{ + */ + +#define QSPI_NCS0 ((uint32_t)0x00000001) +#define QSPI_NCS1 ((uint32_t)0x00000002) +#define IS_QSPI_SER_SEL(MODE) (((MODE) == QSPI_NCS0) || \ + ((MODE) == QSPI_NCS1)) +/** + * @} + */ + +/** @defgroup QSPI_data_direction + * @{ + */ + +#define QSPI_DIRECTION_Tx_AND_Rx ((uint32_t)0x00000000) +#define QSPI_DIRECTION_Tx_ONLY ((uint32_t)0x00000400) +#define QSPI_DIRECTION_Rx_ONLY ((uint32_t)0x00000800) +#define QSPI_DIRECTION_EEPROM_READ ((uint32_t)0x00000C00) +#define IS_QSPI_DIRECTION_MODE(MODE) (((MODE) == QSPI_DIRECTION_Tx_AND_Rx) || \ + ((MODE) == QSPI_DIRECTION_Tx_ONLY) || \ + ((MODE) == QSPI_DIRECTION_Rx_ONLY) || \ + ((MODE) == QSPI_DIRECTION_EEPROM_READ)) +/** + * @} + */ + +/** @defgroup QSPI_SSTE_Enable + * @{ + */ + +#define QSPI_SSTE_TOGGLE_DIS ((uint32_t)0x00000000) +#define QSPI_SSTE_TOGGLE_EN ((uint32_t)0x00004000) +#define IS_QSPI_SSTE(MODE) (((MODE) == QSPI_TOGGLE_DIS) || \ + ((MODE) == QSPI_TOGGLE_EN)) +/** + * @} + */ + + + +/** @defgroup QSPI_data_size + * @{ + */ + +#define QSPI_DATASIZE_4B ((uint32_t)0x00000003) +#define QSPI_DATASIZE_5B ((uint32_t)0x00000004) +#define QSPI_DATASIZE_6B ((uint32_t)0x00000005) +#define QSPI_DATASIZE_7B ((uint32_t)0x00000006) +#define QSPI_DATASIZE_8B ((uint32_t)0x00000007) +#define QSPI_DATASIZE_9B ((uint32_t)0x00000008) +#define QSPI_DATASIZE_10B ((uint32_t)0x00000009) +#define QSPI_DATASIZE_11B ((uint32_t)0x0000000a) +#define QSPI_DATASIZE_12B ((uint32_t)0x0000000b) +#define QSPI_DATASIZE_13B ((uint32_t)0x0000000c) +#define QSPI_DATASIZE_14B ((uint32_t)0x0000000d) +#define QSPI_DATASIZE_15B ((uint32_t)0x0000000e) +#define QSPI_DATASIZE_16B ((uint32_t)0x0000000f) +#define QSPI_DATASIZE_17B ((uint32_t)0x00000010) +#define QSPI_DATASIZE_18B ((uint32_t)0x00000011) +#define QSPI_DATASIZE_19B ((uint32_t)0x00000012) +#define QSPI_DATASIZE_20B ((uint32_t)0x00000013) +#define QSPI_DATASIZE_21B ((uint32_t)0x00000014) +#define QSPI_DATASIZE_22B ((uint32_t)0x00000015) +#define QSPI_DATASIZE_23B ((uint32_t)0x00000016) +#define QSPI_DATASIZE_24B ((uint32_t)0x00000017) +#define QSPI_DATASIZE_25B ((uint32_t)0x00000018) +#define QSPI_DATASIZE_26B ((uint32_t)0x00000019) +#define QSPI_DATASIZE_27B ((uint32_t)0x0000001a) +#define QSPI_DATASIZE_28B ((uint32_t)0x0000001b) +#define QSPI_DATASIZE_29B ((uint32_t)0x0000001c) +#define QSPI_DATASIZE_30B ((uint32_t)0x0000001d) +#define QSPI_DATASIZE_31B ((uint32_t)0x0000001e) +#define QSPI_DATASIZE_32B ((uint32_t)0x0000001f) +#define IS_QSPI_DATA_SIZE(SIZE) (((SIZE) == QSPI_DATASIZE_4B) || \ + ((SIZE) == QSPI_DATASIZE_5B) || \ + ((SIZE) == QSPI_DATASIZE_6B) || \ + ((SIZE) == QSPI_DATASIZE_7B) || \ + ((SIZE) == QSPI_DATASIZE_8B) || \ + ((SIZE) == QSPI_DATASIZE_9B) || \ + ((SIZE) == QSPI_DATASIZE_10B) || \ + ((SIZE) == QSPI_DATASIZE_11B) || \ + ((SIZE) == QSPI_DATASIZE_12B) || \ + ((SIZE) == QSPI_DATASIZE_13B) || \ + ((SIZE) == QSPI_DATASIZE_14B) || \ + ((SIZE) == QSPI_DATASIZE_15B) || \ + ((SIZE) == QSPI_DATASIZE_16B) || \ + ((SIZE) == QSPI_DATASIZE_17B) || \ + ((SIZE) == QSPI_DATASIZE_18B) || \ + ((SIZE) == QSPI_DATASIZE_19B) || \ + ((SIZE) == QSPI_DATASIZE_20B) || \ + ((SIZE) == QSPI_DATASIZE_21B) || \ + ((SIZE) == QSPI_DATASIZE_22B) || \ + ((SIZE) == QSPI_DATASIZE_23B) || \ + ((SIZE) == QSPI_DATASIZE_24B) || \ + ((SIZE) == QSPI_DATASIZE_25B) || \ + ((SIZE) == QSPI_DATASIZE_26B) || \ + ((SIZE) == QSPI_DATASIZE_27B) || \ + ((SIZE) == QSPI_DATASIZE_28B) || \ + ((SIZE) == QSPI_DATASIZE_29B) || \ + ((SIZE) == QSPI_DATASIZE_30B) || \ + ((SIZE) == QSPI_DATASIZE_31B) || \ + ((SIZE) == QSPI_DATASIZE_32B)) +/** + * @} + */ + +/** @defgroup QSPI_Microwire_CFS + * @{ + */ +#define QSPI_CFS_1B ((uint32_t)0x00000000) +#define QSPI_CFS_2B ((uint32_t)0x00010000) +#define QSPI_CFS_3B ((uint32_t)0x00020000) +#define QSPI_CFS_4B ((uint32_t)0x00030000) +#define QSPI_CFS_5B ((uint32_t)0x00040000) +#define QSPI_CFS_6B ((uint32_t)0x00050000) +#define QSPI_CFS_7B ((uint32_t)0x00060000) +#define QSPI_CFS_8B ((uint32_t)0x00070000) +#define QSPI_CFS_9B ((uint32_t)0x00080000) +#define QSPI_CFS_10B ((uint32_t)0x00090000) +#define QSPI_CFS_11B ((uint32_t)0x000a0000) +#define QSPI_CFS_12B ((uint32_t)0x000b0000) +#define QSPI_CFS_13B ((uint32_t)0x000c0000) +#define QSPI_CFS_14B ((uint32_t)0x000d0000) +#define QSPI_CFS_15B ((uint32_t)0x000e0000) +#define QSPI_CFS_16B ((uint32_t)0x000f0000) +#define IS_QSPI_CFS_SIZE(SIZE) (((SIZE) == QSPI_CFS_1B) || \ + ((SIZE) == QSPI_CFS_2B) || \ + ((SIZE) == QSPI_CFS_3B) || \ + ((SIZE) == QSPI_CFS_4B) || \ + ((SIZE) == QSPI_CFS_5B) || \ + ((SIZE) == QSPI_CFS_6B) || \ + ((SIZE) == QSPI_CFS_7B) || \ + ((SIZE) == QSPI_CFS_8B) || \ + ((SIZE) == QSPI_CFS_9B) || \ + ((SIZE) == QSPI_CFS_10B) || \ + ((SIZE) == QSPI_CFS_11B) || \ + ((SIZE) == QSPI_CFS_12B) || \ + ((SIZE) == QSPI_CFS_13B) || \ + ((SIZE) == QSPI_CFS_14B) || \ + ((SIZE) == QSPI_CFS_15B) || \ + ((SIZE) == QSPI_CFS_16B)) + +/** + * @} + */ + + +/** @defgroup QSPI_Clock_Polarity + * @{ + */ + +#define QSPI_SCPOL_LOW ((uint32_t)0x00000000) +#define QSPI_SCPOL_HIGH ((uint32_t)0x00000200) +#define IS_QSPI_SCPOL(SCPOL) (((SCPOL) == QSPI_CPOL_LOW) || \ + ((SCPOL) == QSPI_CPOL_HIGH)) +/** + * @} + */ + +/** @defgroup QSPI_Clock_Phase + * @{ + */ + +#define QSPI_SCPHA_1EDGE ((uint32_t)0x00000000) +#define QSPI_SCPHA_2EDGE ((uint32_t)0x00000100) +#define IS_QSPI_SCPHA(SCPHA) (((SCPHA) == QSPI_CPHA_1EDGE) || \ + ((SCPHA) == QSPI_CPHA_2EDGE)) +/** + * @} + */ + +/** @defgroup QSPI_Protocol_Sel + * @{ + */ + +#define QSPI_PROTOCOL_SPI ((uint32_t)0x00000000) +#define QSPI_PROTOCOL_SSP ((uint32_t)0x00000040) +#define QSPI_PROTOCOL_MICROWIRE ((uint32_t)0x00000080) +#define IS_QSPI_PROPTOCOL(PROTOCOL) (((PROTOCOL) == QSPI_PROTOCOL_QSPI) || \ + ((PROTOCOL) == QSPI_PROTOCOL_SSP) || \ + ((PROTOCOL) == QSPI_Protocol_MICROWIRE)) +/** + * @} + */ + +/** @defgroup QSPI_Opration_Mode + * @{ + */ + +#define QSPI_NORMAL_MODE ((uint32_t)0x00000000) +#define QSPI_TESTING_MODE ((uint32_t)0x00002000) +#define IS_QSPI_OPERATION_MODE(MODE) (((MODE) == QSPI_NORMAL_MODE) || \ + ((MODE) == QSPI_TESTING_MODE)) +/** + * @} + */ + +/** @defgroup QSPI_TDMA_EN + * @{ + */ + +#define QSPI_TDMA_DIS ((uint32_t)0x00000000) +#define QSPI_TDMA_EN ((uint32_t)0x00000002) +#define IS_QSPI_TDMA_MODE(MODE) (((MODE) == QSPI_TDMA_DIS) || \ + ((MODE) == QSPI_TDMA_EN)) +/** + * @} + */ + +/** @defgroup QSPI_RDMA_EN + * @{ + */ + +#define QSPI_RDMA_DIS ((uint32_t)0x00000000) +#define QSPI_RDMA_EN ((uint32_t)0x00000001) +#define IS_QSPI_RDMA_MODE(MODE) (((MODE) == QSPI_RDMA_DIS) || \ + ((MODE) == QSPI_RDMA_EN)) +/** + * @} + */ + +/** @defgroup QSPI_Clk_Loop_EN + * @{ + */ + +#define QSPI_CLK_LOOP_DIS ((uint32_t)0x00000000) +#define QSPI_CLK_LOOP_EN ((uint32_t)0x04000000) +#define IS_QSPI_CLK_LOOP_EN(MODE) (((MODE) == QSPI_CLK_LOOP_DIS) || \ + ((MODE) == QSPI_CLK_LOOP_EN)) +/** + * @} + */ + +/** @defgroup QSPI_Read_strobe_En. + * @{ + */ +#define QSPI_READ_STROBE_DIS ((uint32_t)0x00000000) +#define QSPI_READ_STROBE_EN ((uint32_t)0x00040000) +#define IS_QSPI_RXDS_EN(MODE) (((MODE) == QSPI_READ_STROBE_DIS) || \ + ((MODE) == QSPI_READ_STROBE_EN)) + +/** + * @} + */ + +/** @defgroup QSPI_Variable_Laten + * @{ + */ +#define QSPI_VARIABLE_LATEN_DIS ((uint32_t)0x00000000) +#define QSPI_VARIABLE_LATEN_EN ((uint32_t)0x00800000) +#define IS_QSPI_VL_EN(MODE) (((MODE) == QSPI_VARIABLE_LATEN_DIS) || \ + ((MODE) == QSPI_VARIABLE_LATEN_EN)) + +/** + * @} + */ + +/** @defgroup QSPI_Sample_Edge. + * @{ + */ +#define QSPI_SAMPLE_POSEDGE ((uint32_t)0x00000000) +#define QSPI_SAMPLE_NEGEDGE ((uint32_t)0x00010000) +#define IS_QSPI_SAMPLE_DLY_EDGE(MODE) (((MODE) == QSPI_SAMPLE_POSEDGE) || \ + ((MODE) == QSPI_SAMPLE_NEGEDGE)) +/** + * @} + */ + +/** @defgroup QSPI_InstructionSize + * @{ + */ +#define QSPI_INSTRUCTION_0B ((uint32_t)0x00000000) +#define QSPI_INSTRUCTION_4B ((uint32_t)0x00000100) +#define QSPI_INSTRUCTION_8B ((uint32_t)0x00000200) +#define QSPI_INSTRUCTION_16B ((uint32_t)0x00000300) +#define IS_QSPI_INSTRUCTIONSIZE(SIZE) (((SIZE) == QSPI_INSTRUCTION_0B) || \ + ((SIZE) == QSPI_INSTRUCTION_4B) || \ + ((SIZE) == QSPI_INSTRUCTION_8B) || \ + ((SIZE) == QSPI_INSTRUCTION_16B)) +/** + * @} + */ + +/** @defgroup QSPI_AddressSize + * @{ + */ +#define QSPI_ADDRESS_0B ((uint32_t)0x00000000) +#define QSPI_ADDRESS_4B ((uint32_t)0x00000004) +#define QSPI_ADDRESS_8B ((uint32_t)0x00000008) +#define QSPI_ADDRESS_12B ((uint32_t)0x0000000c) +#define QSPI_ADDRESS_16B ((uint32_t)0x00000010) +#define QSPI_ADDRESS_20B ((uint32_t)0x00000014) +#define QSPI_ADDRESS_24B ((uint32_t)0x00000018) +#define QSPI_ADDRESS_28B ((uint32_t)0x0000001c) +#define QSPI_ADDRESS_32B ((uint32_t)0x00000020) +#define QSPI_ADDRESS_36B ((uint32_t)0x00000024) +#define QSPI_ADDRESS_40B ((uint32_t)0x00000028) +#define QSPI_ADDRESS_44B ((uint32_t)0x0000002c) +#define QSPI_ADDRESS_48B ((uint32_t)0x00000030) +#define QSPI_ADDRESS_52B ((uint32_t)0x00000034) +#define QSPI_ADDRESS_56B ((uint32_t)0x00000038) +#define QSPI_ADDRESS_60B ((uint32_t)0x0000003c) +#define IS_QSPI_ADDRESSSIZE(SIZE) (((SIZE) == QSPI_ADDRESS_0B) || \ + ((SIZE) == QSPI_ADDRESS_4B) || \ + ((SIZE) == QSPI_ADDRESS_8B) || \ + ((SIZE) == QSPI_ADDRESS_12B) || \ + ((SIZE) == QSPI_ADDRESS_16B) || \ + ((SIZE) == QSPI_ADDRESS_20B) || \ + ((SIZE) == QSPI_ADDRESS_24B) || \ + ((SIZE) == QSPI_ADDRESS_28B) || \ + ((SIZE) == QSPI_ADDRESS_32B) || \ + ((SIZE) == QSPI_ADDRESS_36B) || \ + ((SIZE) == QSPI_ADDRESS_40B) || \ + ((SIZE) == QSPI_ADDRESS_44B) || \ + ((SIZE) == QSPI_ADDRESS_48B) || \ + ((SIZE) == QSPI_ADDRESS_52B) || \ + ((SIZE) == QSPI_ADDRESS_56B) || \ + ((SIZE) == QSPI_ADDRESS_60B)) +/** + * @} + */ + +/** @defgroup QSPI_ModeBitsSize + * @{ + */ +#define QSPI_MODEBITS_2B ((uint32_t)0x00000000) +#define QSPI_MODEBITS_4B ((uint32_t)0x04000000) +#define QSPI_MODEBITS_8B ((uint32_t)0x08000000) +#define QSPI_MODEBITS_16B ((uint32_t)0x0c000000) +#define IS_QSPI_MODEBITSSIZE(SIZE) (((SIZE) == QSPI_MODEBITS_2B) || \ + ((SIZE) == QSPI_MODEBITS_4B) || \ + ((SIZE) == QSPI_MODEBITS_8B) || \ + ((SIZE) == QSPI_MODEBITS_16B)) +/** + * @} + */ +/** @defgroup QSPI_XIPInstructionEn + * @{ + */ +#define QSPI_INSTRUCTION_DIS ((uint32_t)0x00000000) +#define QSPI_INSTRUCTION_EN ((uint32_t)0x00100000) +#define IS_QSPI_INSTRUCTION(MODE) (((MODE) == QSPI_INSTRUCTION_DIS) || \ + ((MODE) == QSPI_INSTRUCTION_EN)) +/** + * @} + */ + +/** @defgroup QSPI_ModeBitsEn + * @{ + */ +#define QSPI_MODEBITS_DIS ((uint32_t)0x00000000) +#define QSPI_MODEBITS_EN ((uint32_t)0x00000080) +#define IS_QSPI_MODEBITS(MODE) (((MODE) == QSPI_MODEBITS_DIS) || \ + ((MODE) == QSPI_MODEBITS_EN)) +/** + * @} + */ + +/** @defgroup QSPI_transType + * @{ + */ +#define QSPI_TRANSTYPE_STAND ((uint32_t)0x00000000) +#define QSPI_TRANSTYPE_MIX ((uint32_t)0x00000001) +#define QSPI_TRANSTYPE_FRF ((uint32_t)0x00000002) +#define IS_QSPI_TRANSTYPE(MODE) (((MODE) == QSPI_TRANSTYPE_STAND) || \ + ((MODE) == QSPI_TRANSTYPE_MIX) || \ + ((MODE) == QSPI_TRANSTYPE_FRF)) +/** + * @} + */ + +/** @defgroup QSPI_ClkstretchEn + * @{ + */ +#define QSPI_CLKSTRETCH_DIS ((uint32_t)0x00000000) +#define QSPI_CLKSTRETCH_EN ((uint32_t)0x40000000) +#define IS_QSPI_CLKSTRETCH(MODE) (((MODE) == QSPI_CLKSTRETCH_DIS) || \ + ((MODE) == QSPI_CLKSTRETCH_EN)) +/** + * @} + */ + +/** @defgroup QSPI_DdrMode + * @{ + */ +#define QSPI_DDRMODE_DIS ((uint32_t)0x00000000) +#define QSPI_DDRMODE_EN ((uint32_t)0x00010000) +#define IS_QSPI_DDRMODE(MODE) (((MODE) == QSPI_DDRMODE_DIS) || \ + ((MODE) == QSPI_DDRMODE_EN)) +/** + * @} + */ + +/** @defgroup QSPI_InstDdrMode + * @{ + */ +#define QSPI_INSTDDRMODE_DIS ((uint32_t)0x00000000) +#define QSPI_INSTDDRMODE_EN ((uint32_t)0x00020000) +#define IS_QSPI_INSTDDRMODE(MODE) (((MODE) == QSPI_INSTDDRMODE_DIS) || \ + ((MODE) == QSPI_INSTDDRMODE_EN)) +/** + * @} + */ + +/** @defgroup QSPI_XIP_DFS + * @{ + */ +#define QSPI_XIP_DFS_DIS ((uint32_t)0x00000000) +#define QSPI_XIP_DFS_EN ((uint32_t)0x00080000) +#define IS_QSPI_XIP_DFS(MODE) (((MODE) == QSPI_XIP_DFS_DIS) || \ + ((MODE) == QSPI_XIP_DFS_EN)) +/** + * @} + */ + +/** @defgroup QSPI_XIP_Cont + * @{ + */ +#define QSPI_XIP_CONT_DIS ((uint32_t)0x00000000) +#define QSPI_XIP_CONT_EN ((uint32_t)0x00200000) +#define IS_QSPI_XIP_CONT(MODE) (((MODE) == QSPI_XIP_CONT_DIS) || \ + ((MODE) == QSPI_XIP_CONT_EN)) +/** + * @} + */ + +/** @defgroup QSPI_MicroHand + * @{ + */ +#define QSPI_MICROHAND_DIS ((uint32_t)0x00000000) +#define QSPI_MICROHAND_EN ((uint32_t)0x00000004) +#define IS_QSPI_MICROHAND(MODE) (((MODE) == QSPI_MICROHAND_DIS) || \ + ((MODE) == QSPI_MICROHAND_EN)) +/** + * @} + */ + +/** @defgroup QSPI_MicroDir + * @{ + */ +#define QSPI_MICRODIR_Rx ((uint32_t)0x00000000) +#define QSPI_MICRODIR_Tx ((uint32_t)0x00000002) +#define IS_QSPI_MICRODIR(MODE) (((MODE) == QSPI_MICRODIR_Rx) || \ + ((MODE) == QSPI_MICRODIR_Tx)) +/** + * @} + */ + +/** @defgroup QSPI_MicroTrans + * @{ + */ +#define QSPI_MICROTRANS_NSEQ ((uint32_t)0x00000000) +#define QSPI_MICROTRANS_SEQ ((uint32_t)0x00000001) +#define IS_QSPI_MICROTRANS(MODE) (((MODE) == QSPI_MICROTRANS_NSE) || \ + ((MODE) == QSPI_MICROTRANS_SEQ)) +/** + * @} + */ + +/** @defgroup QSPI_DMAReq + * @{ + */ +#define QSPI_DMAReq_Tx ((uint32_t)0x00000002) +#define QSPI_DMAReq_Rx ((uint32_t)0x00000001) +#define IS_QSPI_DMA_REQ(MODE) (((MODE) == QSPI_DMAReq_Tx) || \ + ((MODE) == QSPI_DMAReq_Rx)) +/** + * @} + */ + + +#define IS_QSPI_DATANUMBER(SIZE) ((SIZE) <= 0xFFFFFFFF) +#define IS_QSPI_BR(BR) ((BR) <= 0x7FFF) + + +#define IS_QSPI_RX_FIFO_THRESHOLD(RFT) ((RFT) <= 0xFU) +#define IS_QSPI_TX_FIFO_THRESHOLD(TFT) ((TFT) <= 0xFU) +#define IS_QSPI_TX_FIFO_STARTLEVEL(TST) ((TST) <= 0xFU) + +#define IS_QSPI_DMA_RX_DATA_LEVEL(LEVEL) ((LEVEL) <= 0xFU) +#define IS_QSPI_DMA_TX_DATA_LEVEL(LEVEL) ((LEVEL) <= 0xFU) + +#define IS_QSPI_WAITCYCLES(NUM) ((NUM) <= 0x1FU) + +#define IS_QSPI_XIP_INST(INST) ((INST) <= 0xFFFF) +#define IS_QSPI_XIP_MODEBITS(MODE) ((MODE) <= 0xFFFF) +#define IS_QSPI_XIP_TIMOUT(TIME) ((TIME) <= 0xFFU) +#define IS_QSPI_DDR_DRIVE_EDGE(TDE) ((TDE) <= 0xFFU) +#define IS_QSPI_SAMPLE_DLY(DLY) ((DLY) <= 0xFFU) +/** @defgroup QSPI_interrupts_definition + * @{ + */ + +#define QSPI_IT_TXEIM ((uint8_t)0x01) +#define QSPI_IT_TXOIM ((uint8_t)0x02) +#define QSPI_IT_RXUIM ((uint8_t)0x04) +#define QSPI_IT_RXOIM ((uint8_t)0x08) +#define QSPI_IT_RXFIM ((uint8_t)0x10) +#define QSPI_IT_TXUIM ((uint8_t)0x80) + +#define IS_QSPI_CONFIG_IT(IT) (((IT) == QSPI_IT_TXEIM) || \ + ((IT) == QSPI_IT_TXOIM) || \ + ((IT) == QSPI_IT_RXUIM) || \ + ((IT) == QSPI_IT_RXOIM) || \ + ((IT) == QSPI_IT_RXFIM) || \ + ((IT) == QSPI_IT_TXUIM)) + +/** + * @} + */ + + +/** @defgroup QSPI_flags_definition + * @{ + */ +#define QSPI_STATE_BUSY ((uint8_t) 0x01) +#define QSPI_STATE_TFNF ((uint8_t) 0x02) +#define QSPI_STATE_TFE ((uint8_t) 0x04) +#define QSPI_STATE_RFNE ((uint8_t) 0x08) +#define QSPI_STATE_RFF ((uint8_t) 0x10) + +#define QSPI_FLAG_TXEIS ((uint8_t)0x01) +#define QSPI_FLAG_TXOIS ((uint8_t)0x02) +#define QSPI_FLAG_RXUIS ((uint8_t)0x04) +#define QSPI_FLAG_RXOIS ((uint8_t)0x08) +#define QSPI_FLAG_RXFIS ((uint8_t)0x10) +#define QSPI_FLAG_TXUIS ((uint8_t)0x80) + +#define QSPI_FLAG_TXEIR ((uint8_t)0x01) +#define QSPI_FLAG_TXOIR ((uint8_t)0x02) +#define QSPI_FLAG_RXUIR ((uint8_t)0x04) +#define QSPI_FLAG_RXOIR ((uint8_t)0x08) +#define QSPI_FLAG_RXFIR ((uint8_t)0x10) +#define QSPI_FLAG_TXUIR ((uint8_t)0x80) + +#define QSPI_FLAG_TXEICR ((uint8_t)0x01) +#define QSPI_FLAG_RXOICR ((uint8_t)0x01) +#define QSPI_FLAG_RXUICR ((uint8_t)0x01) +#define QSPI_FLAG_ICR ((uint8_t)0x01) + + +#define IS_QSPI_TXE_CLEAR_FLAG(FLAG) (((FLAG) == QSPI_FLAG_TXEICR)) +#define IS_QSPI_RXO_CLEAR_FLAG(FLAG) (((FLAG) == QSPI_FLAG_RXOICR)) +#define IS_QSPI_RXU_CLEAR_FLAG(FLAG) (((FLAG) == QSPI_FLAG_RXUICR)) +#define IS_QSPI_CLEAR_FLAG(FLAG) (((FLAG) == QSPI_FLAG_ICR)) + +#define IS_QSPI_BeforMaskInterruptStatus(ST) (((ST) == QSPI_FLAG_TXEIR) || ((ST) == QSPI_FLAG_TXOIR) || \ + ((ST) == QSPI_FLAG_RXUIR) || ((ST) == QSPI_FLAG_RXOIR) || \ + ((ST) == QSPI_FLAG_RXFIR) || ((ST) == QSPI_FLAG_TXUIR)) + +#define IS_QSPI_AfterMaskInterruptStatus(ST) (((ST) == QSPI_FLAG_TXEIS) || ((ST) == QSPI_FLAG_TXEIS) || \ + ((ST) == QSPI_FLAG_RXUIS) || ((ST) == QSPI_FLAG_RXOIS) || \ + ((ST) == QSPI_FLAG_RXFIS) || ((ST) == QSPI_FLAG_TXUIS)) + +/** + * @} + */ + + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +/* Initialization and Configuration functions *********************************/ +void QSPI_DeInit(void); +void QSPI_Init(QSPI_InitTypeDef *QSPI_InitStruct, uint16_t Br); +void QSPI_StructInit(QSPI_InitTypeDef *QSPI_InitStruct); + +/* QSPI Mode Configuration functions ******************************************/ +void QSPI_TestMode_Enable(FunctionalState NewState); +void QSPI_MicroWireMode_Config(uint32_t MHS, uint32_t MDD, uint32_t MWMOD, uint32_t FrameSize, FunctionalState NewState); +void QSPI_EnCmd(FunctionalState NewState); +void QSPI_TIModeCmd(FunctionalState NewState); +void QSPI_SSTEModeCmd(FunctionalState NewState); +void QSPI_LineCfg(uint32_t LINE); +void QSPI_TransMode(uint32_t TRANS); +void QSPI_WaitCyclesConfig(uint32_t NUMBER); +void QSPI_TransTypeConfig(uint32_t TRANSTYPE); + +/* Data transfers functions ***************************************************/ +void QSPI_SendData(uint32_t Data); +uint32_t QSPI_ReceiveData(void); +void QSPI_DataSizeConfig(uint16_t QSPI_DataSize); +void QSPI_DataNumberConfig(uint32_t QSPI_NDF); + +void QSPI_RxFIFOThresholdConfig(uint16_t QSPI_RxFIFOThreshold); +void QSPI_TxFIFOThresholdConfig(uint16_t QSPI_TxFIFOStart, uint16_t QSPI_TxFIFOThreshold); + +/* DMA transfers management functions *****************************************/ +void QSPI_DMACmd(uint32_t QSPI_DMAReq, FunctionalState NewState); +void QSPI_DMA_Tx_DATALEVELCmd(uint32_t QSPI_DMATxDLevel); +void QSPI_DMA_Rx_DATALEVELCmd(uint32_t QSPI_DMARxDLevel); + +/* XIP transfers functions ****************************************************/ +void QSPI_XIP_INSTCmd(uint32_t INSTRUCTION_L, FunctionalState NewState); +void QSPI_XIP_INST_Config(uint32_t QSPI_XIP_INSTCfg); +void QSPI_ADDRCfg(uint32_t ADDR_L); +void QSPI_XIP_ModeBitsCmd(uint32_t MODEBITS, uint32_t MD_SIZE, FunctionalState NewState); +void QSPI_Ddrcmd(uint32_t Ddr_TXD, FunctionalState NewState); +void QSPI_InstDdrcmd(FunctionalState NewState); +void QSPI_XIP_ContinuousCmd(uint32_t TIMOUT, FunctionalState NewState); +void QSPI_XIP_DFSHCCmd(FunctionalState NewState); + +/* other receive data fonfigure function **************************************/ +void QSPI_CLK_LOOPCmd(FunctionalState NewState); +void QSPI_RX_SAMPLEDLYConfig(uint32_t SE, uint32_t RSD); +void QSPI_RXDSConfig(uint32_t RXDS_VL_EN, FunctionalState NewState); +void QSPI_CLK_StretchCmd(FunctionalState NewState); + +/* Interrupts and flags management functions **********************************/ +void QSPI_ITConfig(uint32_t QSPI_IT, FunctionalState NewState); +uint32_t QSPI_GetStatus(uint16_t QSPI_SR_FLAG); +uint32_t QSPI_GetAfterMaskInterruptStatus(uint16_t QSPI_ISR_FLAG); +uint32_t QSPI_GetBeforeMaskInterruptStatus(uint16_t QSPI_RISR_FLAG); +void QSPI_ClearTxFIFOErrorInterrupt(void); +void QSPI_ClearRxFIFOOverflowInterrupt(void); +void QSPI_ClearRxFIFOUnderflowInterrupt(void); +void QSPI_ClearFIFOFlowInterrupt(void); + +#ifdef __cplusplus +} +#endif + +#endif /*__FT32F4XX_QSPI_H */ + +/** + * @} + */ + +/** + * @} + */ + + diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_rcc.h b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_rcc.h new file mode 100644 index 00000000000..2421ed8889a --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_rcc.h @@ -0,0 +1,1096 @@ +/** + ****************************************************************************** + * @file ft32f4xx_rcc.h + * @author Rwang + * @brief This file contains all the functions prototypes for the RCC + * firmware library. + * @version V1.0.0 + * @data 2025-03-03 + ****************************************************************************** + */ + + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __FT32F0XX_RCC_H +#define __FT32F0XX_RCC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx.h" + +/** @addtogroup RCC + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +typedef struct +{ + uint32_t SYSCLK_Frequency; + uint32_t HCLK_Frequency; + uint32_t PCLK_Frequency; + uint32_t PLLQ_Frequency; + uint32_t PLLR_Frequency; + uint32_t P2CLK_Frequency; + uint32_t PLL2Q_Frequency; + uint32_t PLL2R_Frequency; + uint32_t QSPICLK_Frequency; + uint32_t ADCCLK_Frequency; + uint32_t CANCLK_Frequency; + uint32_t LPTIMCLK_Frequency; + uint32_t I2C3CLK_Frequency; + uint32_t I2C2CLK_Frequency; + uint32_t I2C1CLK_Frequency; + uint32_t LPUARTCLK_Frequency; + uint32_t PWMCLK_Frequency; + uint32_t EQEPCLK_Frequency; + uint32_t ECAPCLK_Frequency; + uint32_t I2SCLK_Frequency; +} RCC_ClocksTypeDef; + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup RCC_Exported_Constants + * @{ + */ +#define RCC_FLAG_PLL2RDY ((uint32_t)0x08000000) +#define RCC_FLAG_PLLRDY ((uint32_t)0x02000000) +#define RCC_FLAG_HSERDY ((uint32_t)0x00020000) +#define RCC_FLAG_HSIRDY ((uint32_t)0x00000002) +#define RCC_FLAG_HSI48RDY ((uint32_t)0x00020000) +#define RCC_FLAG_LSERDY ((uint32_t)0x00000002) +#define RCC_FLAG_LPWRRSTF ((uint32_t)0x80000000) +#define RCC_FLAG_WWDGRSTF ((uint32_t)0x40000000) +#define RCC_FLAG_IWDGRSTF ((uint32_t)0x20000000) +#define RCC_FLAG_SFTRSTF ((uint32_t)0x10000000) +#define RCC_FLAG_PORRSTF ((uint32_t)0x08000000) +#define RCC_FLAG_PINRSTF ((uint32_t)0x04000000) +#define RCC_FLAG_RMVF ((uint32_t)0x01000000) +#define RCC_FLAG_LSIRDY ((uint32_t)0x00000002) +#define IS_RCC_FLAG(FLAG) (((FLAG) == RCC_FLAG_PLL2RDY) || ((FLAG) == RCC_FLAG_PLLRDY) || \ + ((FLAG) == RCC_FLAG_HSERDY) || ((FLAG) == RCC_FLAG_HSIRDY) || \ + ((FLAG) == RCC_FLAG_HSI48RDY) || ((FLAG) == RCC_FLAG_LSERDY) || \ + ((FLAG) == RCC_FLAG_LPWRRSTF) || ((FLAG) == RCC_FLAG_WWDGRSTF) || \ + ((FLAG) == RCC_FLAG_IWDGRSTF) || ((FLAG) == RCC_FLAG_SFTRSTF) || \ + ((FLAG) == RCC_FLAG_PORRSTF) || ((FLAG) == RCC_FLAG_PINRSTF) || \ + ((FLAG) == RCC_FLAG_RMVF) || ((FLAG) == RCC_FLAG_LSIRDY)) + +#define RCC_FLAG_REG_CR ((uint8_t)0x00) +#define RCC_FLAG_REG_CR2 ((uint8_t)0x01) +#define RCC_FLAG_REG_BDCR ((uint8_t)0x02) +#define RCC_FLAG_REG_CSR ((uint8_t)0x03) +#define IS_RCC_FLAG_REG(REG) (((REG) == RCC_FLAG_REG_CR) || ((REG) == RCC_FLAG_REG_CR2) || \ + ((REG) == RCC_FLAG_REG_BDCR) || ((REG) == RCC_FLAG_REG_CSR)) + +#define IS_RCC_HSI_CALIBRATION_VALUE(VALUE) ((VALUE) <= 0x0000001F) + + +#define IS_RCC_HSI48_CALIBRATION_VALUE(VALUE) ((VALUE) <= 0x000001FF) + + + +//RCC_CR_REG +#define RCC_SEL_PLL ((uint32_t)0x00000000) +#define RCC_SEL_PLL2 ((uint32_t)0x00000001) +#define IS_RCC_SEL(SEL) (((SEL) == RCC_SEL_PLL) || \ + ((SEL) == RCC_SEL_PLL2)) + + + +#define RCC_HSE_OFF ((uint32_t)0x00000000) +#define RCC_HSE_ON ((uint32_t)0x00010000) +#define RCC_HSE_Bypass ((uint32_t)0x00050000) +#define IS_RCC_HSE(HSE) (((HSE) == RCC_HSE_OFF) || \ + ((HSE) == RCC_HSE_ON) || \ + ((HSE) == RCC_HSE_Bypass) ) + +#define RCC_HSI_OFF ((uint8_t)0x00) +#define RCC_HSI_ON ((uint8_t)0x01) +#define IS_RCC_HSI(HSI) (((HSI) == RCC_HSI_OFF) || \ + ((HSI) == RCC_HSI_ON) ) + +//RCC_PLLCFGR_REG +//PLLRCLK=((VCO/(PLLR+1)) +#define IS_RCC_PLLR_VALUE(VALUE) ((VALUE) <= (uint32_t)0x00000007) + +#define RCC_PLLR_OFF ((uint32_t)0x00000000) +#define RCC_PLLR_ON ((uint32_t)0x00000001) +#define IS_RCC_PLLR(PLLR) (((PLLR) == RCC_PLLR_OFF) || \ + ((PLLR) == RCC_PLLR_ON) ) + +//PLLQCLK=((VCO/(PLLQ+1)) +#define IS_RCC_PLLQ_VALUE(VALUE) ((VALUE) <= (uint32_t)0x0000000F) + +#define RCC_PLLQ_OFF ((uint32_t)0x00000000) +#define RCC_PLLQ_ON ((uint32_t)0x00000001) +#define IS_RCC_PLLQ(PLLQ) (((PLLQ) == RCC_PLLQ_OFF) || \ + ((PLLQ) == RCC_PLLQ_ON) ) + +//PLLPCLK=((VCO/(PLLP+1)) +#define IS_RCC_PLLP_VALUE(VALUE) ((VALUE) <= (uint32_t)0x00000007) + +#define RCC_PLLP_OFF ((uint32_t)0x00000000) +#define RCC_PLLP_ON ((uint32_t)0x00000001) +#define IS_RCC_PLLP(PLLP) (((PLLP) == RCC_PLLP_OFF) || \ + ((PLLP) == RCC_PLLP_ON) ) + +//RCC_PLL_Clock_Source PLLCLK_INPUT=HSE/HSI +#define RCC_PLLSource_HSI ((uint32_t)0x00000000) +#define RCC_PLLSource_HSE ((uint32_t)0x00000001) +#define IS_RCC_PLLSRC(SRC) (((SRC) == RCC_PLLSource_HSI) || \ + ((SRC) == RCC_PLLSource_HSE)) + +// RCC_PLLN_Factor VCO_OUTCLK=VCO_IN*PLLN +#define IS_RCC_PLLN_VALUE(VALUE) ((VALUE) <= (uint32_t)0x000000FF) + +//VCO_OUT=PLL_IN*(PLLN/PLLM) +#define IS_RCC_PLLM_VALUE(VALUE) ((VALUE) <= (uint32_t)0x0000001F) + +/** + * @} + */ + +//RCC_PLL2CFGR_REG +//PLL2RCLK=((VCO/(PLL2R+1)) +#define IS_RCC_PLL2R_VALUE(VALUE) ((VALUE) <= (uint32_t)0x00000007) + +#define RCC_PLL2R_OFF ((uint32_t)0x00000000) +#define RCC_PLL2R_ON ((uint32_t)0x00000001) +#define IS_RCC_PLL2R(PLL2R) (((PLL2R) == RCC_PLL2R_OFF) || \ + ((PLL2R) == RCC_PLL2R_ON) ) + +//PLL2QCLK=((VCO/(PLL2Q+1)) +#define IS_RCC_PLL2Q_VALUE(VALUE) ((VALUE) <= (uint32_t)0x0000000F) + +#define RCC_PLL2Q_OFF ((uint32_t)0x00000000) +#define RCC_PLL2Q_ON ((uint32_t)0x00000001) +#define IS_RCC_PLL2Q(PLL2Q) (((PLL2Q) == RCC_PLL2Q_OFF) || \ + ((PLL2Q) == RCC_PLL2Q_ON) ) + +//RCC_PLL2_Clock_Source PLL2CLK_INPUT=HSE/HSI +#define RCC_PLL2Source_HSI ((uint32_t)0x00000000) +#define RCC_PLL2Source_HSE ((uint32_t)0x00000001) +#define IS_RCC_PLL2SRC(SRC) (((SRC) == RCC_PLL2Source_HSI) || \ + ((SRC) == RCC_PLL2Source_HSE) ) + +// RCC_PLL2N_Factor VCO_OUTCLK=VCO_IN*PLL2N +#define IS_RCC_PLL2N_VALUE(VALUE) ((VALUE) <= (uint32_t)0x000000FF) + +//VCO_OUT=PLL_IN*(PLL2N/PLL2M) +#define IS_RCC_PLL2M_VALUE(VALUE) ((VALUE) <= (uint32_t)0x0000001F) +/** + * @} + */ + +/** @defgroup RCC_MCOSource_Select + * @{ + */ +#define RCC_MCOSource_NoClock ((uint32_t)0x00000000) +#define RCC_MCOSource_SYSCLK ((uint32_t)0x01000000) +#define RCC_MCOSource_PLL2R ((uint32_t)0x02000000) +#define RCC_MCOSource_HSI16 ((uint32_t)0x03000000) +#define RCC_MCOSource_HSE ((uint32_t)0x04000000) +#define RCC_MCOSource_PLLP ((uint32_t)0x05000000) +#define RCC_MCOSource_LSI ((uint32_t)0x06000000) +#define RCC_MCOSource_LSE ((uint32_t)0x07000000) +#define RCC_MCOSource_HSI48 ((uint32_t)0x08000000) +#define IS_RCC_MCO_SOURCE(SRC) (((SRC) == RCC_MCOSource_NoClock) || ((SRC) == RCC_MCOSource_SYSCLK) || \ + ((SRC) == RCC_MCOSource_PLL2R) || ((SRC) == RCC_MCOSource_HSI16) || \ + ((SRC) == RCC_MCOSource_HSE) || ((SRC) == RCC_MCOSource_PLLP) || \ + ((SRC) == RCC_MCOSource_LSI) || ((SRC) == RCC_MCOSource_LSE) || \ + ((SRC) == RCC_MCOSource_HSI48)) +/** + * @} + */ + +/** @defgroup RCC_MCOPrescaler_Select + * @{ + */ +#define RCC_MCOPrescaler_1 ((uint32_t)0x00000000) +#define RCC_MCOPrescaler_2 ((uint32_t)0x10000000) +#define RCC_MCOPrescaler_4 ((uint32_t)0x20000000) +#define RCC_MCOPrescaler_8 ((uint32_t)0x30000000) +#define RCC_MCOPrescaler_16 ((uint32_t)0x40000000) +#define RCC_MCOPrescaler_32 ((uint32_t)0x50000000) +#define RCC_MCOPrescaler_64 ((uint32_t)0x60000000) +#define RCC_MCOPrescaler_128 ((uint32_t)0x70000000) +#define IS_RCC_MCO_PRESCALER(PRE) (((PRE) == RCC_MCOPrescaler_1) || ((PRE) == RCC_MCOPrescaler_2) || \ + ((PRE) == RCC_MCOPrescaler_4) || ((PRE) == RCC_MCOPrescaler_8) || \ + ((PRE) == RCC_MCOPrescaler_16) || ((PRE) == RCC_MCOPrescaler_32) || \ + ((PRE) == RCC_MCOPrescaler_64) || ((PRE) == RCC_MCOPrescaler_128)) +/** + * @} + */ + +/** @defgroup RCC_apbclk_division_factor(APBCLK=HCLK/DIV) + * @{ + */ +#define RCC_HCLK_DIV1 ((uint32_t)0x00000000) +#define RCC_HCLK_DIV2 ((uint32_t)0x00000004) +#define RCC_HCLK_DIV4 ((uint32_t)0x00000005) +#define RCC_HCLK_DIV8 ((uint32_t)0x00000006) +#define RCC_HCLK_DIV16 ((uint32_t)0x00000007) +#define IS_RCC_PCLK(PCLK) (((PCLK) == RCC_HCLK_DIV1) || ((PCLK) == RCC_HCLK_DIV2) || \ + ((PCLK) == RCC_HCLK_DIV4) || ((PCLK) == RCC_HCLK_DIV8) || \ + ((PCLK) == RCC_HCLK_DIV16)) +/** + * @} + */ + +/** @defgroup RCC_AHB_Clock_Source(HCLK=SYSCLK/HPREDIV) + * @{ + */ + +#define RCC_SYSCLK_DIV1 RCC_CFGR_HPRE_DIV1 +#define RCC_SYSCLK_DIV2 RCC_CFGR_HPRE_DIV2 +#define RCC_SYSCLK_DIV4 RCC_CFGR_HPRE_DIV4 +#define RCC_SYSCLK_DIV8 RCC_CFGR_HPRE_DIV8 +#define RCC_SYSCLK_DIV16 RCC_CFGR_HPRE_DIV16 +#define RCC_SYSCLK_DIV64 RCC_CFGR_HPRE_DIV64 +#define RCC_SYSCLK_DIV128 RCC_CFGR_HPRE_DIV128 +#define RCC_SYSCLK_DIV256 RCC_CFGR_HPRE_DIV256 +#define RCC_SYSCLK_DIV512 RCC_CFGR_HPRE_DIV512 +#define IS_RCC_HCLK(HCLK) (((HCLK) == RCC_SYSCLK_DIV1) || ((HCLK) == RCC_SYSCLK_DIV2) || \ + ((HCLK) == RCC_SYSCLK_DIV4) || ((HCLK) == RCC_SYSCLK_DIV8) || \ + ((HCLK) == RCC_SYSCLK_DIV16) || ((HCLK) == RCC_SYSCLK_DIV64) || \ + ((HCLK) == RCC_SYSCLK_DIV128) || ((HCLK) == RCC_SYSCLK_DIV256) || \ + ((HCLK) == RCC_SYSCLK_DIV512)) +/** + * @} + */ + +/** @defgroup RCC_SYSCLK_SOURCE + * @{ + */ + +#define RCC_SYSCLKSource_HSI16 RCC_CFGR_SW_HSI +#define RCC_SYSCLKSource_HSE RCC_CFGR_SW_HSE +#define RCC_SYSCLKSource_PLLCLK RCC_CFGR_SW_PLL +#define IS_RCC_SYSCLK_SOURCE(SRC) (((SRC) == RCC_SYSCLKSource_HSI16) || \ + ((SRC) == RCC_SYSCLKSource_HSE) || \ + ((SRC) == RCC_SYSCLKSource_PLLCLK)) +/** + * @} + */ + +//RCC_CIR_REG +/** @defgroup RCC_Interrupt_Source + * @{ + */ +#define RCC_ITCLR_CSS RCC_CIR_CSSC +#define RCC_ITCLR_PLL2RDY RCC_CIR_PLL2RDYC +#define RCC_ITCLR_PLLRDY RCC_CIR_PLLRDYC +#define RCC_ITCLR_HSERDY RCC_CIR_HSERDYC +#define RCC_ITCLR_HSI48RDY RCC_CIR_HSI48RDYC +#define RCC_ITCLR_HSIRDY RCC_CIR_HSIRDYC +#define RCC_ITCLR_LSERDY RCC_CIR_LSERDYC +#define RCC_ITCLR_LSIRDY RCC_CIR_LSIRDYC +#define IS_RCC_ITCLR(ITCLR) (((ITCLR) == RCC_ITCLR_LSIRDY) || ((ITCLR) == RCC_ITCLR_LSERDY) || \ + ((ITCLR) == RCC_ITCLR_HSIRDY) || ((ITCLR) == RCC_ITCLR_HSI48RDY) || \ + ((ITCLR) == RCC_ITCLR_HSERDY) || ((ITCLR) == RCC_ITCLR_PLLRDY) || \ + ((ITCLR) == RCC_ITCLR_PLL2RDY) || ((ITCLR) == RCC_ITCLR_CSS)) + +#define RCC_ITEN_PLL2RDY RCC_CIR_PLL2RDYIE +#define RCC_ITEN_PLLRDY RCC_CIR_PLLRDYIE +#define RCC_ITEN_HSERDY RCC_CIR_HSERDYIE +#define RCC_ITEN_HSI48RDY RCC_CIR_HSI48RDYIE +#define RCC_ITEN_HSIRDY RCC_CIR_HSIRDYIE +#define RCC_ITEN_LSERDY RCC_CIR_LSERDYIE +#define RCC_ITEN_LSIRDY RCC_CIR_LSIRDYIE +#define IS_RCC_ITEN(ITEN) (((ITEN) == RCC_ITEN_LSIRDY) || ((ITEN) == RCC_ITEN_LSERDY) || \ + ((ITEN) == RCC_ITEN_HSIRDY) || ((ITEN) == RCC_ITEN_HSI48RDY) || \ + ((ITEN) == RCC_ITEN_HSERDY) || ((ITEN) == RCC_ITEN_PLLRDY) || \ + ((ITEN) == RCC_ITEN_PLL2RDY)) + +#define RCC_ITFLAG_CSS RCC_CIR_CSSF +#define RCC_ITFLAG_PLL2RDY RCC_CIR_PLL2RDYF +#define RCC_ITFLAG_PLLRDY RCC_CIR_PLLRDYF +#define RCC_ITFLAG_HSERDY RCC_CIR_HSERDYF +#define RCC_ITFLAG_HSI48RDY RCC_CIR_HSI48RDYF +#define RCC_ITFLAG_HSIRDY RCC_CIR_HSIRDYF +#define RCC_ITFLAG_LSERDY RCC_CIR_LSERDYF +#define RCC_ITFLAG_LSIRDY RCC_CIR_LSIRDYF +#define IS_RCC_ITFLAG(ITFLAG) (((ITFLAG) == RCC_ITFLAG_LSIRDY) || ((ITFLAG) == RCC_ITFLAG_LSERDY) || \ + ((ITFLAG) == RCC_ITFLAG_HSIRDY) || ((ITFLAG) == RCC_ITFLAG_HSI48RDY) || \ + ((ITFLAG) == RCC_ITFLAG_HSERDY) || ((ITFLAG) == RCC_ITFLAG_PLLRDY) || \ + ((ITFLAG) == RCC_ITFLAG_PLL2RDY) || ((ITFLAG) == RCC_ITFLAG_CSS)) +/** + * @} + */ + +//RCC_AHB1/2/3_PERIPH_RSTR_REG +/** @defgroup RCC_AHB1/2/3_Peripherals_Reset + * @{ + */ +#define RCC_AHB1PeriphRst_USBOTGHS RCC_AHB1RSTR_OTGHSRST +#define RCC_AHB1PeriphRst_ETHMAC RCC_AHB1RSTR_ETHMACRST +#define RCC_AHB1PeriphRst_DMA2 RCC_AHB1RSTR_DMA2RST +#define RCC_AHB1PeriphRst_DMA1 RCC_AHB1RSTR_DMA1RST +#define RCC_AHB1PeriphRst_CRC RCC_AHB1RSTR_CRCRST +#define RCC_AHB1PeriphRst_GPIOH RCC_AHB1RSTR_GPIOHRST +#define RCC_AHB1PeriphRst_GPIOE RCC_AHB1RSTR_GPIOERST +#define RCC_AHB1PeriphRst_GPIOD RCC_AHB1RSTR_GPIODRST +#define RCC_AHB1PeriphRst_GPIOC RCC_AHB1RSTR_GPIOCRST +#define RCC_AHB1PeriphRst_GPIOB RCC_AHB1RSTR_GPIOBRST +#define RCC_AHB1PeriphRst_GPIOA RCC_AHB1RSTR_GPIOARST +#define IS_RCC_AHB1RST_PERIPH(PERIPH) (((PERIPH) == RCC_AHB1PeriphRst_USBOTGHS) || ((PERIPH) == RCC_AHB1PeriphRst_ETHMAC) || \ + ((PERIPH) == RCC_AHB1PeriphRst_DMA2) || ((PERIPH) == RCC_AHB1PeriphRst_DMA1) || \ + ((PERIPH) == RCC_AHB1PeriphRst_CRC) || ((PERIPH) == RCC_AHB1PeriphRst_GPIOH) || \ + ((PERIPH) == RCC_AHB1PeriphRst_GPIOE) || ((PERIPH) == RCC_AHB1PeriphRst_GPIOD) || \ + ((PERIPH) == RCC_AHB1PeriphRst_GPIOC) || ((PERIPH) == RCC_AHB1PeriphRst_GPIOB) || \ + ((PERIPH) == RCC_AHB1PeriphRst_GPIOA)) + +#define RCC_AHB2PeriphRst_USBOTGFS RCC_AHB2RSTR_OTGFSRST +#define RCC_AHB2PeriphRst_RNG RCC_AHB2RSTR_RNGRST +#define IS_RCC_AHB2RST_PERIPH(PERIPH) (((PERIPH) == RCC_AHB2PeriphRst_USBOTGFS) || ((PERIPH) == RCC_AHB2PeriphRst_RNG)) + +#define RCC_AHB3PeriphRst_QSPI RCC_AHB3RSTR_QSPIRST +#define RCC_AHB3PeriphRst_FMC RCC_AHB3RSTR_FMCRST +#define IS_RCC_AHB3RST_PERIPH(PERIPH) (((PERIPH) == RCC_AHB3PeriphRst_QSPI) || ((PERIPH) == RCC_AHB3PeriphRst_FMC)) +/** + * @} + */ + +//RCC_APB1/2_PERIPH_RSTR_REG +/** @defgroup RCC_APB1/2_Peripherals_Reset + * @{ + */ +#define RCC_APB1PeriphRst_UART7 RCC_APB1RSTR_UART7RST +#define RCC_APB1PeriphRst_DAC RCC_APB1RSTR_DACRST +#define RCC_APB1PeriphRst_PWR RCC_APB1RSTR_PWRRST +#define RCC_APB1PeriphRst_CAN4 RCC_APB1RSTR_CAN4RST +#define RCC_APB1PeriphRst_CAN3 RCC_APB1RSTR_CAN3RST +#define RCC_APB1PeriphRst_CAN2 RCC_APB1RSTR_CAN2RST +#define RCC_APB1PeriphRst_CAN1 RCC_APB1RSTR_CAN1RST +#define RCC_APB1PeriphRst_I2C3 RCC_APB1RSTR_I2C3RST +#define RCC_APB1PeriphRst_I2C2 RCC_APB1RSTR_I2C2RST +#define RCC_APB1PeriphRst_I2C1 RCC_APB1RSTR_I2C1RST +#define RCC_APB1PeriphRst_UART5 RCC_APB1RSTR_UART5RST +#define RCC_APB1PeriphRst_UART4 RCC_APB1RSTR_UART4RST +#define RCC_APB1PeriphRst_UART3 RCC_APB1RSTR_UART3RST +#define RCC_APB1PeriphRst_UART2 RCC_APB1RSTR_UART2RST +#define RCC_APB1PeriphRst_LPUART RCC_APB1RSTR_LPUARTRST +#define RCC_APB1PeriphRst_SPI3 RCC_APB1RSTR_SPI3RST +#define RCC_APB1PeriphRst_SPI2 RCC_APB1RSTR_SPI2RST +#define RCC_APB1PeriphRst_I2S3 RCC_APB1RSTR_I2S3RST +#define RCC_APB1PeriphRst_I2S2 RCC_APB1RSTR_I2S2RST +#define RCC_APB1PeriphRst_WWDG RCC_APB1RSTR_WWDGRST +#define RCC_APB1PeriphRst_AC97 RCC_APB1RSTR_AC97RST +#define RCC_APB1PeriphRst_CRS RCC_APB1RSTR_CRSRST +#define RCC_APB1PeriphRst_TIM14 RCC_APB1RSTR_TIM14RST +#define RCC_APB1PeriphRst_TIM13 RCC_APB1RSTR_TIM13RST +#define RCC_APB1PeriphRst_TIM12 RCC_APB1RSTR_TIM12RST +#define RCC_APB1PeriphRst_TIM7 RCC_APB1RSTR_TIM7RST +#define RCC_APB1PeriphRst_TIM6 RCC_APB1RSTR_TIM6RST +#define RCC_APB1PeriphRst_TIM5 RCC_APB1RSTR_TIM5RST +#define RCC_APB1PeriphRst_TIM4 RCC_APB1RSTR_TIM4RST +#define RCC_APB1PeriphRst_TIM3 RCC_APB1RSTR_TIM3RST +#define RCC_APB1PeriphRst_TIM2 RCC_APB1RSTR_TIM2RST +#define IS_RCC_APB1RST_PERIPH(PERIPH) (((PERIPH) == RCC_APB1PeriphRst_UART7) || ((PERIPH) == RCC_APB1PeriphRst_DAC) || \ + ((PERIPH) == RCC_APB1PeriphRst_PWR) || ((PERIPH) == RCC_APB1PeriphRst_CAN4) || \ + ((PERIPH) == RCC_APB1PeriphRst_CAN3) || ((PERIPH) == RCC_APB1PeriphRst_CAN2) || \ + ((PERIPH) == RCC_APB1PeriphRst_CAN1) || ((PERIPH) == RCC_APB1PeriphRst_I2C3) || \ + ((PERIPH) == RCC_APB1PeriphRst_I2C2) || ((PERIPH) == RCC_APB1PeriphRst_I2C1) || \ + ((PERIPH) == RCC_APB1PeriphRst_UART5) || ((PERIPH) == RCC_APB1PeriphRst_UART4) || \ + ((PERIPH) == RCC_APB1PeriphRst_UART3) || ((PERIPH) == RCC_APB1PeriphRst_UART2) || \ + ((PERIPH) == RCC_APB1PeriphRst_LPUART) || ((PERIPH) == RCC_APB1PeriphRst_SPI3) || \ + ((PERIPH) == RCC_APB1PeriphRst_SPI2) || ((PERIPH) == RCC_APB1PeriphRst_I2S3) || \ + ((PERIPH) == RCC_APB1PeriphRst_I2S2) || ((PERIPH) == RCC_APB1PeriphRst_WWDG) || \ + ((PERIPH) == RCC_APB1PeriphRst_AC97) || ((PERIPH) == RCC_APB1PeriphRst_CRS) || \ + ((PERIPH) == RCC_APB1PeriphRst_TIM14) || ((PERIPH) == RCC_APB1PeriphRst_TIM13) || \ + ((PERIPH) == RCC_APB1PeriphRst_TIM12) || ((PERIPH) == RCC_APB1PeriphRst_TIM7) || \ + ((PERIPH) == RCC_APB1PeriphRst_TIM6) || ((PERIPH) == RCC_APB1PeriphRst_TIM5) || \ + ((PERIPH) == RCC_APB1PeriphRst_TIM4) || ((PERIPH) == RCC_APB1PeriphRst_TIM3) || \ + ((PERIPH) == RCC_APB1PeriphRst_TIM2)) + +#define RCC_APB2PeriphRst_EQEP RCC_APB2RSTR_EQEPRST +#define RCC_APB2PeriphRst_ECAP RCC_APB2RSTR_ECAPRST +#define RCC_APB2PeriphRst_EPWM4 RCC_APB2RSTR_EPWM4RST +#define RCC_APB2PeriphRst_EPWM3 RCC_APB2RSTR_EPWM3RST +#define RCC_APB2PeriphRst_EPWM2 RCC_APB2RSTR_EPWM2RST +#define RCC_APB2PeriphRst_EPWM1 RCC_APB2RSTR_EPWM1RST +#define RCC_APB2PeriphRst_TIM11 RCC_APB2RSTR_TIM11RST +#define RCC_APB2PeriphRst_TIM10 RCC_APB2RSTR_TIM10RST +#define RCC_APB2PeriphRst_TIM9 RCC_APB2RSTR_TIM9RST +#define RCC_APB2PeriphRst_LPTIM RCC_APB2RSTR_LPTIMRST +#define RCC_APB2PeriphRst_SYSCFG RCC_APB2RSTR_SYSCFGRST +#define RCC_APB2PeriphRst_SPI1 RCC_APB2RSTR_SPI1RST +#define RCC_APB2PeriphRst_SDIO RCC_APB2RSTR_SDIORST +#define RCC_APB2PeriphRst_SPD RCC_APB2RSTR_SPDRST +#define RCC_APB2PeriphRst_ADC RCC_APB2RSTR_ADCRST +#define RCC_APB2PeriphRst_USART6 RCC_APB2RSTR_USART6RST +#define RCC_APB2PeriphRst_USART1 RCC_APB2RSTR_USART1RST +#define RCC_APB2PeriphRst_TIM8 RCC_APB2RSTR_TIM8RST +#define RCC_APB2PeriphRst_TIM1 RCC_APB2RSTR_TIM1RST +#define IS_RCC_APB2RST_PERIPH(PERIPH) (((PERIPH) == RCC_APB2PeriphRst_EQEP) || ((PERIPH) == RCC_APB2PeriphRst_ECAP) || \ + ((PERIPH) == RCC_APB2PeriphRst_EPWM4) || ((PERIPH) == RCC_APB2PeriphRst_EPWM3) || \ + ((PERIPH) == RCC_APB2PeriphRst_EPWM2) || ((PERIPH) == RCC_APB2PeriphRst_EPWM1) || \ + ((PERIPH) == RCC_APB2PeriphRst_TIM11) || ((PERIPH) == RCC_APB2PeriphRst_TIM10) || \ + ((PERIPH) == RCC_APB2PeriphRst_TIM9) || ((PERIPH) == RCC_APB2PeriphRst_LPTIM) || \ + ((PERIPH) == RCC_APB2PeriphRst_SYSCFG) || ((PERIPH) == RCC_APB2PeriphRst_SPI1) || \ + ((PERIPH) == RCC_APB2PeriphRst_SDIO) || ((PERIPH) == RCC_APB2PeriphRst_SPD) || \ + ((PERIPH) == RCC_APB2PeriphRst_ADC) || ((PERIPH) == RCC_APB2PeriphRst_USART6) || \ + ((PERIPH) == RCC_APB2PeriphRst_USART1) || ((PERIPH) == RCC_APB2PeriphRst_TIM8) || \ + ((PERIPH) == RCC_APB2PeriphRst_TIM1)) +/** + * @} + */ + +//RCC_AHB1/2/3_PERIPH_CLKEN_REG +/** @defgroup RCC_AHB1/2/3_Peripherals_Clken + * @{ + */ +#define RCC_AHB1Periph_USBOTGHS RCC_AHB1ENR_OTGHSEN +#define RCC_AHB1Periph_ETHMACPTP RCC_AHB1ENR_ETHMACPTPEN +#define RCC_AHB1Periph_ETHMACRX RCC_AHB1ENR_ETHMACRXEN +#define RCC_AHB1Periph_ETHMACTX RCC_AHB1ENR_ETHMACTXEN +#define RCC_AHB1Periph_ETHMAC RCC_AHB1ENR_ETHMACEN +#define RCC_AHB1Periph_DMA2 RCC_AHB1ENR_DMA2EN +#define RCC_AHB1Periph_DMA1 RCC_AHB1ENR_DMA1EN +#define RCC_AHB1Periph_CCMDATARAM RCC_AHB1ENR_CCMDATARAMEN +#define RCC_AHB1Periph_BKPSRAM RCC_AHB1ENR_BKPSRAMEN +#define RCC_AHB1Periph_CRC RCC_AHB1ENR_CRCEN +#define RCC_AHB1Periph_GPIOH RCC_AHB1ENR_GPIOHEN +#define RCC_AHB1Periph_GPIOE RCC_AHB1ENR_GPIOEEN +#define RCC_AHB1Periph_GPIOD RCC_AHB1ENR_GPIODEN +#define RCC_AHB1Periph_GPIOC RCC_AHB1ENR_GPIOCEN +#define RCC_AHB1Periph_GPIOB RCC_AHB1ENR_GPIOBEN +#define RCC_AHB1Periph_GPIOA RCC_AHB1ENR_GPIOAEN +#define IS_RCC_AHB1_PERIPH(PERIPH) (((PERIPH) == RCC_AHB1Periph_USBOTGHS) || ((PERIPH) == RCC_AHB1Periph_ETHMACPTP) || \ + ((PERIPH) == RCC_AHB1Periph_ETHMACRX) || ((PERIPH) == RCC_AHB1Periph_ETHMACTX) || \ + ((PERIPH) == RCC_AHB1Periph_ETHMAC) || ((PERIPH) == RCC_AHB1Periph_DMA2) || \ + ((PERIPH) == RCC_AHB1Periph_DMA1) || ((PERIPH) == RCC_AHB1Periph_CCMDATARAM) || \ + ((PERIPH) == RCC_AHB1Periph_BKPSRAM) || ((PERIPH) == RCC_AHB1Periph_CRC) || \ + ((PERIPH) == RCC_AHB1Periph_GPIOH) || ((PERIPH) == RCC_AHB1Periph_GPIOE) || \ + ((PERIPH) == RCC_AHB1Periph_GPIOD) || ((PERIPH) == RCC_AHB1Periph_GPIOC) || \ + ((PERIPH) == RCC_AHB1Periph_GPIOB) || ((PERIPH) == RCC_AHB1Periph_GPIOA)) + +#define RCC_AHB2Periph_USBOTGFS RCC_AHB2ENR_OTGFSEN +#define RCC_AHB2periph_RNG RCC_AHB2ENR_RNGEN +#define IS_RCC_AHB2_PERIPH(PERIPH) (((PERIPH) == RCC_AHB2Periph_USBOTGFS) || ((PERIPH) == RCC_AHB2periph_RNG)) + +#define RCC_AHB3Periph_QSPI RCC_AHB3ENR_QSPIEN +#define RCC_AHB3Periph_FMC RCC_AHB3ENR_FMCEN +#define IS_RCC_AHB3_PERIPH(PERIPH) (((PERIPH) == RCC_AHB3Periph_QSPI) || ((PERIPH) == RCC_AHB3Periph_FMC)) +/** + * @} + */ + +//RCC_APB1/2_PERIPH_CLKEN_REG +/** @defgroup RCC_APB1/2_Peripherals_Clken + * @{ + */ +#define RCC_APB1Periph_UART7 RCC_APB1ENR_UART7EN +#define RCC_APB1Periph_RAMP RCC_APB1ENR_RAMPEN +#define RCC_APB1Periph_DAC RCC_APB1ENR_DACEN +#define RCC_APB1Periph_PWR RCC_APB1ENR_PWREN +#define RCC_APB1Periph_CAN4 RCC_APB1ENR_CAN4EN +#define RCC_APB1Periph_CAN3 RCC_APB1ENR_CAN3EN +#define RCC_APB1Periph_CAN2 RCC_APB1ENR_CAN2EN +#define RCC_APB1Periph_CAN1 RCC_APB1ENR_CAN1EN +#define RCC_APB1Periph_I2C3 RCC_APB1ENR_I2C3EN +#define RCC_APB1Periph_I2C2 RCC_APB1ENR_I2C2EN +#define RCC_APB1Periph_I2C1 RCC_APB1ENR_I2C1EN +#define RCC_APB1Periph_UART5 RCC_APB1ENR_UART5EN +#define RCC_APB1Periph_UART4 RCC_APB1ENR_UART4EN +#define RCC_APB1Periph_UART3 RCC_APB1ENR_UART3EN +#define RCC_APB1Periph_UART2 RCC_APB1ENR_UART2EN +#define RCC_APB1Periph_LPUART RCC_APB1ENR_LPUARTEN +#define RCC_APB1Periph_SPI3 RCC_APB1ENR_SPI3EN +#define RCC_APB1Periph_SPI2 RCC_APB1ENR_SPI2EN +#define RCC_APB1Periph_I2S3 RCC_APB1ENR_I2S3EN +#define RCC_APB1Periph_I2S2 RCC_APB1ENR_I2S2EN +#define RCC_APB1Periph_WWDG RCC_APB1ENR_WWDGEN +#define RCC_APB1Periph_AC97 RCC_APB1ENR_AC97EN +#define RCC_APB1Periph_CRS RCC_APB1ENR_CRSEN +#define RCC_APB1Periph_TIM14 RCC_APB1ENR_TIM14EN +#define RCC_APB1Periph_TIM13 RCC_APB1ENR_TIM13EN +#define RCC_APB1Periph_TIM12 RCC_APB1ENR_TIM12EN +#define RCC_APB1Periph_TIM7 RCC_APB1ENR_TIM7EN +#define RCC_APB1Periph_TIM6 RCC_APB1ENR_TIM6EN +#define RCC_APB1Periph_TIM5 RCC_APB1ENR_TIM5EN +#define RCC_APB1Periph_TIM4 RCC_APB1ENR_TIM4EN +#define RCC_APB1Periph_TIM3 RCC_APB1ENR_TIM3EN +#define RCC_APB1Periph_TIM2 RCC_APB1ENR_TIM2EN +#define IS_RCC_APB1_PERIPH(PERIPH) (((PERIPH) == RCC_APB1Periph_UART7) || ((PERIPH) == RCC_APB1Periph_RAMP) || \ + ((PERIPH) == RCC_APB1Periph_DAC) || ((PERIPH) == RCC_APB1Periph_PWR) || \ + ((PERIPH) == RCC_APB1Periph_CAN4) || ((PERIPH) == RCC_APB1Periph_CAN3) || \ + ((PERIPH) == RCC_APB1Periph_CAN2) || ((PERIPH) == RCC_APB1Periph_CAN1) || \ + ((PERIPH) == RCC_APB1Periph_I2C3) || ((PERIPH) == RCC_APB1Periph_I2C2) || \ + ((PERIPH) == RCC_APB1Periph_I2C1) || ((PERIPH) == RCC_APB1Periph_UART5) || \ + ((PERIPH) == RCC_APB1Periph_UART4) || ((PERIPH) == RCC_APB1Periph_UART3) || \ + ((PERIPH) == RCC_APB1Periph_UART2) || ((PERIPH) == RCC_APB1Periph_LPUART)|| \ + ((PERIPH) == RCC_APB1Periph_SPI3) || ((PERIPH) == RCC_APB1Periph_SPI2) || \ + ((PERIPH) == RCC_APB1Periph_I2S3) || ((PERIPH) == RCC_APB1Periph_I2S2) || \ + ((PERIPH) == RCC_APB1Periph_WWDG) || ((PERIPH) == RCC_APB1Periph_AC97) || \ + ((PERIPH) == RCC_APB1Periph_CRS) || ((PERIPH) == RCC_APB1Periph_TIM14) || \ + ((PERIPH) == RCC_APB1Periph_TIM13) || ((PERIPH) == RCC_APB1Periph_TIM12) || \ + ((PERIPH) == RCC_APB1Periph_TIM7) || ((PERIPH) == RCC_APB1Periph_TIM6) || \ + ((PERIPH) == RCC_APB1Periph_TIM5) || ((PERIPH) == RCC_APB1Periph_TIM4) || \ + ((PERIPH) == RCC_APB1Periph_TIM3) || ((PERIPH) == RCC_APB1Periph_TIM2)) + +#define RCC_APB2Periph_TBCLK RCC_APB2ENR_TBCLKSYNC +#define RCC_APB2Periph_EQEP RCC_APB2ENR_EQEPEN +#define RCC_APB2Periph_ECAP RCC_APB2ENR_ECAPEN +#define RCC_APB2Periph_EPWM4 RCC_APB2ENR_EPWM4EN +#define RCC_APB2Periph_EPWM3 RCC_APB2ENR_EPWM3EN +#define RCC_APB2Periph_EPWM2 RCC_APB2ENR_EPWM2EN +#define RCC_APB2Periph_EPWM1 RCC_APB2ENR_EPWM1EN +#define RCC_APB2Periph_TIM11 RCC_APB2ENR_TIM11EN +#define RCC_APB2Periph_TIM10 RCC_APB2ENR_TIM10EN +#define RCC_APB2Periph_TIM9 RCC_APB2ENR_TIM9EN +#define RCC_APB2Periph_LPTIM RCC_APB2ENR_LPTIMEN +#define RCC_APB2Periph_SYSCFG RCC_APB2ENR_SYSCFGEN +#define RCC_APB2Periph_SPI1 RCC_APB2ENR_SPI1EN +#define RCC_APB2Periph_SDIO RCC_APB2ENR_SDIOEN +#define RCC_APB2Periph_SPD RCC_APB2ENR_SPDEN +#define RCC_APB2Periph_ADC RCC_APB2ENR_ADCEN +#define RCC_APB2Periph_USART6 RCC_APB2ENR_USART6EN +#define RCC_APB2Periph_USART1 RCC_APB2ENR_USART1EN +#define RCC_APB2Periph_TIM8 RCC_APB2ENR_TIM8EN +#define RCC_APB2Periph_TIM1 RCC_APB2ENR_TIM1EN +#define IS_RCC_APB2_PERIPH(PERIPH) (((PERIPH) == RCC_APB2Periph_TBCLK) || ((PERIPH) == RCC_APB2Periph_EQEP) || \ + ((PERIPH) == RCC_APB2Periph_ECAP) || ((PERIPH) == RCC_APB2Periph_EPWM4) || \ + ((PERIPH) == RCC_APB2Periph_EPWM3) || ((PERIPH) == RCC_APB2Periph_EPWM2) || \ + ((PERIPH) == RCC_APB2Periph_EPWM1) || ((PERIPH) == RCC_APB2Periph_TIM11) || \ + ((PERIPH) == RCC_APB2Periph_TIM10) || ((PERIPH) == RCC_APB2Periph_TIM9) || \ + ((PERIPH) == RCC_APB2Periph_LPTIM) || ((PERIPH) == RCC_APB2Periph_SYSCFG) || \ + ((PERIPH) == RCC_APB2Periph_SPI1) || ((PERIPH) == RCC_APB2Periph_SDIO) || \ + ((PERIPH) == RCC_APB2Periph_SPD) || ((PERIPH) == RCC_APB2Periph_ADC) || \ + ((PERIPH) == RCC_APB2Periph_USART6) || ((PERIPH) == RCC_APB2Periph_USART1) || \ + ((PERIPH) == RCC_APB2Periph_TIM8) || ((PERIPH) == RCC_APB2Periph_TIM1)) +/** + * @} + */ + +//RCC_AHB1/2/3_PERIPH_LPCLKEN_REG +/** @defgroup RCC_AHB1/2/3_Peripherals_Lpclken + * @{ + */ +#define RCC_AHB1PeriphLpen_USBOTGHS RCC_AHB1LPENR_OTGHSLPEN +#define RCC_AHB1PeriphLpen_ETHMACPTP RCC_AHB1LPENR_ETHMACPTPLPEN +#define RCC_AHB1PeriphLpen_ETHMACRX RCC_AHB1LPENR_ETHMACRXLPEN +#define RCC_AHB1PeriphLpen_ETHMACTX RCC_AHB1LPENR_ETHMACTXLPEN +#define RCC_AHB1PeriphLpen_ETHMAC RCC_AHB1LPENR_ETHMACLPEN +#define RCC_AHB1PeriphLpen_DMA2 RCC_AHB1LPENR_DMA2LPEN +#define RCC_AHB1PeriphLpen_DMA1 RCC_AHB1LPENR_DMA1LPEN +#define RCC_AHB1PeriphLpen_BKPSRAM RCC_AHB1LPENR_BKPSRAMLPEN +#define RCC_AHB1PeriphLpen_SRAM2 RCC_AHB1LPENR_SRAM2LPEN +#define RCC_AHB1PeriphLpen_SRAM1 RCC_AHB1LPENR_SRAM1LPEN +#define RCC_AHB1PeriphLpen_CRC RCC_AHB1LPENR_CRCLPEN +#define RCC_AHB1PeriphLpen_GPIOH RCC_AHB1LPENR_GPIOHLPEN +#define RCC_AHB1PeriphLpen_GPIOE RCC_AHB1LPENR_GPIOELPEN +#define RCC_AHB1PeriphLpen_GPIOD RCC_AHB1LPENR_GPIODLPEN +#define RCC_AHB1PeriphLpen_GPIOC RCC_AHB1LPENR_GPIOCLPEN +#define RCC_AHB1PeriphLpen_GPIOB RCC_AHB1LPENR_GPIOBLPEN +#define RCC_AHB1PeriphLpen_GPIOA RCC_AHB1LPENR_GPIOALPEN +#define IS_RCC_AHB1LP_PERIPH(PERIPH) (((PERIPH) == RCC_AHB1PeriphLpen_USBOTGHS) || ((PERIPH) == RCC_AHB1PeriphLpen_ETHMACPTP) || \ + ((PERIPH) == RCC_AHB1PeriphLpen_ETHMACRX) || ((PERIPH) == RCC_AHB1PeriphLpen_ETHMACTX) || \ + ((PERIPH) == RCC_AHB1PeriphLpen_ETHMAC) || ((PERIPH) == RCC_AHB1PeriphLpen_DMA2) || \ + ((PERIPH) == RCC_AHB1PeriphLpen_DMA1) || ((PERIPH) == RCC_AHB1PeriphLpen_BKPSRAM) || \ + ((PERIPH) == RCC_AHB1PeriphLpen_SRAM2) || ((PERIPH) == RCC_AHB1PeriphLpen_SRAM1) || \ + ((PERIPH) == RCC_AHB1PeriphLpen_CRC) || ((PERIPH) == RCC_AHB1PeriphLpen_GPIOH) || \ + ((PERIPH) == RCC_AHB1PeriphLpen_GPIOE) || ((PERIPH) == RCC_AHB1PeriphLpen_GPIOD) || \ + ((PERIPH) == RCC_AHB1PeriphLpen_GPIOC) || ((PERIPH) == RCC_AHB1PeriphLpen_GPIOB) || \ + ((PERIPH) == RCC_AHB1PeriphLpen_GPIOA)) + +#define RCC_AHB2PeriphLpen_USBOTGFS RCC_AHB2LPENR_OTGFSLPEN +#define RCC_AHB2PeriphLpen_RNG RCC_AHB2LPENR_RNGLPEN +#define IS_RCC_AHB2LP_PERIPH(PERIPH) (((PERIPH) == RCC_AHB2PeriphLpen_USBOTGFS) || ((PERIPH) == RCC_AHB2PeriphLpen_RNG)) + +#define RCC_AHB3PeriphLpen_QSPI RCC_AHB3LPENR_QSPILPEN +#define RCC_AHB3PeriphLpen_FMC RCC_AHB3LPENR_FMCLPEN +#define IS_RCC_AHB3LP_PERIPH(PERIPH) (((PERIPH) == RCC_AHB3PeriphLpen_QSPI) || ((PERIPH) == RCC_AHB3PeriphLpen_FMC)) +/** + * @} + */ + +//RCC_APB1/2_PERIPH_LPCLKEN_REG +/** @defgroup RCC_APB1/2_Peripherals_Lpclken + * @{ + */ +#define RCC_APB1PeriphLpen_UART7 RCC_APB1LPENR_UART7LPEN +#define RCC_APB1PeriphLpen_RAMP RCC_APB1LPENR_RAMPLPEN +#define RCC_APB1PeriphLpen_DAC RCC_APB1LPENR_DACLPEN +#define RCC_APB1PeriphLpen_PWR RCC_APB1LPENR_PWRLPEN +#define RCC_APB1PeriphLpen_CAN4 RCC_APB1LPENR_CAN4LPEN +#define RCC_APB1PeriphLpen_CAN3 RCC_APB1LPENR_CAN3LPEN +#define RCC_APB1PeriphLpen_CAN2 RCC_APB1LPENR_CAN2LPEN +#define RCC_APB1PeriphLpen_CAN1 RCC_APB1LPENR_CAN1LPEN +#define RCC_APB1PeriphLpen_I2C3 RCC_APB1LPENR_I2C3LPEN +#define RCC_APB1PeriphLpen_I2C2 RCC_APB1LPENR_I2C2LPEN +#define RCC_APB1PeriphLpen_I2C1 RCC_APB1LPENR_I2C1LPEN +#define RCC_APB1PeriphLpen_UART5 RCC_APB1LPENR_UART5LPEN +#define RCC_APB1PeriphLpen_UART4 RCC_APB1LPENR_UART4LPEN +#define RCC_APB1PeriphLpen_UART3 RCC_APB1LPENR_UART3LPEN +#define RCC_APB1PeriphLpen_UART2 RCC_APB1LPENR_UART2LPEN +#define RCC_APB1PeriphLpen_LPUART RCC_APB1LPENR_LPUARTLPEN +#define RCC_APB1PeriphLpen_SPI3 RCC_APB1LPENR_SPI3LPEN +#define RCC_APB1PeriphLpen_SPI2 RCC_APB1LPENR_SPI2LPEN +#define RCC_APB1PeriphLpen_I2S3 RCC_APB1LPENR_I2S3LPEN +#define RCC_APB1PeriphLpen_I2S2 RCC_APB1LPENR_I2S2LPEN +#define RCC_APB1PeriphLpen_WWDG RCC_APB1LPENR_WWDGLPEN +#define RCC_APB1PeriphLpen_AC97 RCC_APB1LPENR_AC97LPEN +#define RCC_APB1PeriphLpen_CRS RCC_APB1LPENR_CRSLPEN +#define RCC_APB1PeriphLpen_TIM14 RCC_APB1LPENR_TIM14LPEN +#define RCC_APB1PeriphLpen_TIM13 RCC_APB1LPENR_TIM13LPEN +#define RCC_APB1PeriphLpen_TIM12 RCC_APB1LPENR_TIM12LPEN +#define RCC_APB1PeriphLpen_TIM7 RCC_APB1LPENR_TIM7LPEN +#define RCC_APB1PeriphLpen_TIM6 RCC_APB1LPENR_TIM6LPEN +#define RCC_APB1PeriphLpen_TIM5 RCC_APB1LPENR_TIM5LPEN +#define RCC_APB1PeriphLpen_TIM4 RCC_APB1LPENR_TIM4LPEN +#define RCC_APB1PeriphLpen_TIM3 RCC_APB1LPENR_TIM3LPEN +#define RCC_APB1PeriphLpen_TIM2 RCC_APB1LPENR_TIM2LPEN +#define IS_RCC_APB1LP_PERIPH(PERIPH) (((PERIPH) == RCC_APB1PeriphLpen_UART7) || ((PERIPH) == RCC_APB1PeriphLpen_RAMP) || \ + ((PERIPH) == RCC_APB1PeriphLpen_DAC) || ((PERIPH) == RCC_APB1PeriphLpen_PWR) || \ + ((PERIPH) == RCC_APB1PeriphLpen_CAN4) || ((PERIPH) == RCC_APB1PeriphLpen_CAN3) || \ + ((PERIPH) == RCC_APB1PeriphLpen_CAN2) || ((PERIPH) == RCC_APB1PeriphLpen_CAN1) || \ + ((PERIPH) == RCC_APB1PeriphLpen_I2C3) || ((PERIPH) == RCC_APB1PeriphLpen_I2C2) || \ + ((PERIPH) == RCC_APB1PeriphLpen_I2C1) || ((PERIPH) == RCC_APB1PeriphLpen_UART5) || \ + ((PERIPH) == RCC_APB1PeriphLpen_UART4) || ((PERIPH) == RCC_APB1PeriphLpen_UART3) || \ + ((PERIPH) == RCC_APB1PeriphLpen_UART2) || ((PERIPH) == RCC_APB1PeriphLpen_LPUART)|| \ + ((PERIPH) == RCC_APB1PeriphLpen_SPI3) || ((PERIPH) == RCC_APB1PeriphLpen_SPI2) || \ + ((PERIPH) == RCC_APB1PeriphLpen_I2S3) || ((PERIPH) == RCC_APB1PeriphLpen_I2S2) || \ + ((PERIPH) == RCC_APB1PeriphLpen_WWDG) || ((PERIPH) == RCC_APB1PeriphLpen_AC97) || \ + ((PERIPH) == RCC_APB1PeriphLpen_CRS) || ((PERIPH) == RCC_APB1PeriphLpen_TIM14) || \ + ((PERIPH) == RCC_APB1PeriphLpen_TIM13) || ((PERIPH) == RCC_APB1PeriphLpen_TIM12) || \ + ((PERIPH) == RCC_APB1PeriphLpen_TIM7) || ((PERIPH) == RCC_APB1PeriphLpen_TIM6) || \ + ((PERIPH) == RCC_APB1PeriphLpen_TIM5) || ((PERIPH) == RCC_APB1PeriphLpen_TIM4) || \ + ((PERIPH) == RCC_APB1PeriphLpen_TIM3) || ((PERIPH) == RCC_APB1PeriphLpen_TIM2)) + +#define RCC_APB2PeriphLpen_EQEP RCC_APB2LPENR_EQEPLPEN +#define RCC_APB2PeriphLpen_ECAP RCC_APB2LPENR_ECAPLPEN +#define RCC_APB2PeriphLpen_EPWM4 RCC_APB2LPENR_EPWM4LPEN +#define RCC_APB2PeriphLpen_EPWM3 RCC_APB2LPENR_EPWM3LPEN +#define RCC_APB2PeriphLpen_EPWM2 RCC_APB2LPENR_EPWM2LPEN +#define RCC_APB2PeriphLpen_EPWM1 RCC_APB2LPENR_EPWM1LPEN +#define RCC_APB2PeriphLpen_TIM11 RCC_APB2LPENR_TIM11LPEN +#define RCC_APB2PeriphLpen_TIM10 RCC_APB2LPENR_TIM10LPEN +#define RCC_APB2PeriphLpen_TIM9 RCC_APB2LPENR_TIM9LPEN +#define RCC_APB2PeriphLpen_LPTIM RCC_APB2LPENR_LPTIMLPEN +#define RCC_APB2PeriphLpen_SYSCFG RCC_APB2LPENR_SYSCFGLPEN +#define RCC_APB2PeriphLpen_SPI1 RCC_APB2LPENR_SPI1LPEN +#define RCC_APB2PeriphLpen_SDIO RCC_APB2LPENR_SDIOLPEN +#define RCC_APB2PeriphLpen_SPD RCC_APB2LPENR_SPDLPEN +#define RCC_APB2PeriphLpen_ADC RCC_APB2LPENR_ADCLPEN +#define RCC_APB2PeriphLpen_USART6 RCC_APB2LPENR_USART6LPEN +#define RCC_APB2PeriphLpen_USART1 RCC_APB2LPENR_USART1LPEN +#define RCC_APB2PeriphLpen_TIM8 RCC_APB2LPENR_TIM8LPEN +#define RCC_APB2PeriphLpen_TIM1 RCC_APB2LPENR_TIM1LPEN +#define IS_RCC_APB2LP_PERIPH(PERIPH) (((PERIPH) == RCC_APB2PeriphLpen_EQEP) || ((PERIPH) == RCC_APB2PeriphLpen_ECAP) || \ + ((PERIPH) == RCC_APB2PeriphLpen_EPWM4) || ((PERIPH) == RCC_APB2PeriphLpen_EPWM3) || \ + ((PERIPH) == RCC_APB2PeriphLpen_EPWM2) || ((PERIPH) == RCC_APB2PeriphLpen_EPWM1) || \ + ((PERIPH) == RCC_APB2PeriphLpen_TIM11) || ((PERIPH) == RCC_APB2PeriphLpen_TIM10) || \ + ((PERIPH) == RCC_APB2PeriphLpen_TIM9) || ((PERIPH) == RCC_APB2PeriphLpen_LPTIM) || \ + ((PERIPH) == RCC_APB2PeriphLpen_SYSCFG) || ((PERIPH) == RCC_APB2PeriphLpen_SPI1) || \ + ((PERIPH) == RCC_APB2PeriphLpen_SDIO) || ((PERIPH) == RCC_APB2PeriphLpen_SPD) || \ + ((PERIPH) == RCC_APB2PeriphLpen_ADC) || ((PERIPH) == RCC_APB2PeriphLpen_USART6) || \ + ((PERIPH) == RCC_APB2PeriphLpen_USART1) || ((PERIPH) == RCC_APB2PeriphLpen_TIM8) || \ + ((PERIPH) == RCC_APB2PeriphLpen_TIM1)) +/** + * @} + */ + +/** @defgroup RCC_QSPI_clock_source + * @{ + */ +#define RCC_QSPICLK_SYSCLK ((uint32_t)0x00000000) +#define RCC_QSPICLK_HSI16 ((uint32_t)0x40000000) +#define RCC_QSPICLK_PLL1Q ((uint32_t)0x80000000) +#define IS_RCC_QSPICLK(QSPICLK) (((QSPICLK) == RCC_QSPICLK_SYSCLK) || ((QSPICLK) == RCC_QSPICLK_HSI16) || \ + ((QSPICLK) == RCC_QSPICLK_PLL1Q)) +/** + * @} + */ + +/** @defgroup RCC_ADC_clock_source + * @{ + */ +/* These defines are obsolete and kept for legacy purpose only. +Proper ADC clock selection is done within ADC driver by mean of the ADC_ClockModeConfig() function */ +#define RCC_ADCCLK_NOCLK ((uint32_t)0x00000000) +#define RCC_ADCCLK_PLL1R ((uint32_t)0x10000000) +#define RCC_ADCCLK_SYSCLK ((uint32_t)0x20000000) +#define IS_RCC_ADCCLK(ADCCLK) (((ADCCLK) == RCC_ADCCLK_NOCLK) || ((ADCCLK) == RCC_ADCCLK_PLL1R) || \ + ((ADCCLK) == RCC_ADCCLK_SYSCLK)) +/** + * @} + */ + +/** @defgroup RCC_CAN_clock_source + * @{ + */ +#define RCC_CANCLK_HCLK ((uint32_t)0x00000000) +#define RCC_CANCLK_HCLK_DIV2 ((uint32_t)0x08000000) +#define RCC_CANCLK_HCLK_DIV4 ((uint32_t)0x09000000) +#define RCC_CANCLK_HCLK_DIV8 ((uint32_t)0x0A000000) +#define RCC_CANCLK_HCLK_DIV16 ((uint32_t)0x0B000000) +#define RCC_CANCLK_HCLK_DIV32 ((uint32_t)0x0C000000) +#define IS_RCC_CANCLK(CANCLK) (((CANCLK) == RCC_CANCLK_HCLK) || ((CANCLK) == RCC_CANCLK_HCLK_DIV2) || \ + ((CANCLK) == RCC_CANCLK_HCLK_DIV4) || ((CANCLK) == RCC_CANCLK_HCLK_DIV8) || \ + ((CANCLK) == RCC_CANCLK_HCLK_DIV16) || ((CANCLK) == RCC_CANCLK_HCLK_DIV32)) +/** + * @} + */ + +/** @defgroup RCC_LPTIM_clock_source + * @{ + */ +#define RCC_LPTIMCLK_PCLK ((uint32_t)0x00000000) +#define RCC_LPTIMCLK_LSI ((uint32_t)0x00040000) +#define RCC_LPTIMCLK_HSI16 ((uint32_t)0x00080000) +#define RCC_LPTIMCLK_LSE ((uint32_t)0x000C0000) +#define IS_RCC_LPTIMCLK(LPTIMCLK) (((LPTIMCLK) == RCC_LPTIMCLK_PCLK) || ((LPTIMCLK) == RCC_LPTIMCLK_LSI) || \ + ((LPTIMCLK) == RCC_LPTIMCLK_HSI16) || ((LPTIMCLK) == RCC_LPTIMCLK_LSE)) +/** + * @} + */ + +/** @defgroup RCC_I2C3_clock_source + * @{ + */ +#define RCC_I2C3CLK_PCLK ((uint32_t)0x00000000) +#define RCC_I2C3CLK_SYSCLK ((uint32_t)0x00010000) +#define RCC_I2C3CLK_HSI16 ((uint32_t)0x00020000) +#define IS_RCC_I2C3CLK(I2C3CLK) (((I2C3CLK) == RCC_I2C3CLK_PCLK) || ((I2C3CLK) == RCC_I2C3CLK_SYSCLK) || \ + ((I2C3CLK) == RCC_I2C3CLK_HSI16)) +/** + * @} + */ + +/** @defgroup RCC_I2C2_clock_source + * @{ + */ +#define RCC_I2C2CLK_PCLK ((uint32_t)0x00000000) +#define RCC_I2C2CLK_SYSCLK ((uint32_t)0x00004000) +#define RCC_I2C2CLK_HSI16 ((uint32_t)0x00008000) +#define IS_RCC_I2C2CLK(I2C2CLK) (((I2C2CLK) == RCC_I2C2CLK_PCLK) || ((I2C2CLK) == RCC_I2C2CLK_SYSCLK) || \ + ((I2C2CLK) == RCC_I2C2CLK_HSI16)) +/** + * @} + */ + +/** @defgroup RCC_I2C1_clock_source + * @{ + */ +#define RCC_I2C1CLK_PCLK ((uint32_t)0x00000000) +#define RCC_I2C1CLK_SYSCLK ((uint32_t)0x00001000) +#define RCC_I2C1CLK_HSI16 ((uint32_t)0x00002000) +#define IS_RCC_I2C1CLK(I2C1CLK) (((I2C1CLK) == RCC_I2C1CLK_PCLK) || ((I2C1CLK) == RCC_I2C1CLK_SYSCLK) || \ + ((I2C1CLK) == RCC_I2C1CLK_HSI16)) +/** + * @} + */ + +/** @defgroup RCC_LPUART_clock_source + * @{ + */ +#define RCC_LPUARTCLK_PCLK ((uint32_t)0x00000000) +#define RCC_LPUARTCLK_LSE ((uint32_t)0x00000800) +#define IS_RCC_LPUARTCLK(LPUARTCLK) (((LPUARTCLK) == RCC_LPUARTCLK_PCLK) || ((LPUARTCLK) == RCC_LPUARTCLK_LSE)) +/** + * @} + */ + +/** @defgroup RCC_RNG_clock_div_factors + * @{ + */ +#define RCC_RNGCLK_DIV1 ((uint32_t)0x00000000) +#define RCC_RNGCLK_DIV2 ((uint32_t)0x00000100) +#define RCC_RNGCLK_DIV4 ((uint32_t)0x00000200) +#define RCC_RNGCLK_DIV8 ((uint32_t)0x00000300) +#define IS_RCC_RNGCLK_DIV(DIV) (((DIV) == RCC_RNGCLK_DIV1) || ((DIV) == RCC_RNGCLK_DIV2) || \ + ((DIV) == RCC_RNGCLK_DIV4) || ((DIV) == RCC_RNGCLK_DIV8)) +/** + * @} + */ + +/** @defgroup RCC_48M_clock_source + * @{ + */ +#define RCC_48MCLK_HSI48 ((uint32_t)0x00000000) +#define RCC_48MCLK_PLLQ ((uint32_t)0x00000080) +#define IS_RCC_48MCLK(RCC48MCLK) (((RCC48MCLK) == RCC_48MCLK_HSI48) || ((RCC48MCLK) == RCC_48MCLK_PLLQ)) +/** + * @} + */ + +/** @defgroup RCC_EPWM_clock_source + * @{ + */ +#define RCC_EPWMCLK_SYSCLK ((uint32_t)0x00000000) +#define RCC_EPWMCLK_SYSCLK_DIV2 ((uint32_t)0x00000020) +#define RCC_EPWMCLK_SYSCLK_DIV4 ((uint32_t)0x00000040) +#define IS_RCC_EPWMCLK(EPWMCLK) (((EPWMCLK) == RCC_EPWMCLK_SYSCLK) || ((EPWMCLK) == RCC_EPWMCLK_SYSCLK_DIV2) || \ + ((EPWMCLK) == RCC_EPWMCLK_SYSCLK_DIV4)) +/** + * @} + */ + +/** @defgroup RCC_EQEP_clock_source + * @{ + */ +#define RCC_EQEPCLK_SYSCLK ((uint32_t)0x00000000) +#define RCC_EQEPCLK_SYSCLK_DIV2 ((uint32_t)0x00000008) +#define RCC_EQEPCLK_SYSCLK_DIV4 ((uint32_t)0x00000010) +#define IS_RCC_EQEPCLK(EQEPCLK) (((EQEPCLK) == RCC_EQEPCLK_SYSCLK) || ((EQEPCLK) == RCC_EQEPCLK_SYSCLK_DIV2) || \ + ((EQEPCLK) == RCC_EQEPCLK_SYSCLK_DIV4)) +/** + * @} + */ + +/** @defgroup RCC_ECAP_clock_source + * @{ + */ +#define RCC_ECAPCLK_SYSCLK ((uint32_t)0x00000000) +#define RCC_ECAPCLK_SYSCLK_DIV2 ((uint32_t)0x00000002) +#define RCC_ECAPCLK_SYSCLK_DIV4 ((uint32_t)0x00000004) +#define IS_RCC_ECAPCLK(ECAPCLK) (((ECAPCLK) == RCC_ECAPCLK_SYSCLK) || ((ECAPCLK) == RCC_ECAPCLK_SYSCLK_DIV2) || \ + ((ECAPCLK) == RCC_ECAPCLK_SYSCLK_DIV4)) +/** + * @} + */ + +/** @defgroup RCC_I2S_clock_source + * @{ + */ +#define RCC_I2SCLK_PLL2Q ((uint32_t)0x00000000) +#define RCC_I2SCLK_I2S_CLKIN ((uint32_t)0x00000001) +#define IS_RCC_I2SCLK(I2SCLK) (((I2SCLK) == RCC_I2SCLK_PLL2Q) || ((I2SCLK) == RCC_I2SCLK_I2S_CLKIN)) +/** + * @} + */ + + +//RCC_BDCR_REG +/** @defgroup RCC_LSCO_clock_source + * @brief + * @{ + */ +#define RCC_LSCOCLK_LSE RCC_BDCR_LSCOSEL_LSE +#define RCC_LSCOCLK_LSI RCC_BDCR_LSCOSEL_LSI +#define IS_RCC_LSCOCLK_SRC(SRC) (((SRC) == RCC_LSCOCLK_LSE) || ((SRC) == RCC_LSCOCLK_LSI)) +/** + * @} + */ + +/** @defgroup RCC_LSCO_clock_enable + * @brief + * @{ + */ +#define RCC_LSCOCLK_OFF ((uint32_t)0x00000000) +#define RCC_LSCOCLK_ON ((uint32_t)0x01000000) +#define IS_RCC_LSCOCLK_STATUS(STATUS) (((STATUS) == RCC_LSCOCLK_OFF) || ((STATUS) == RCC_LSCOCLK_ON)) +/** + * @} + */ + +/** @defgroup RCC_RTC_soft_reset + * @brief + * @{ + */ +#define RCC_RTC_BDRST_OFF ((uint32_t)0x00000000) +#define RCC_RTC_BDRST_ON ((uint32_t)0x00010000) +#define IS_RCC_RTC_BDRST(BDRST) (((BDRST) == RCC_RTC_BDRST_OFF) || ((BDRST) == RCC_RTC_BDRST_ON)) +/** + * @} + */ + +/** @defgroup RCC_RTC_clock_enable + * @brief + * @{ + */ +#define RCC_RTCCLK_OFF ((uint32_t)0x00000000) +#define RCC_RTCCLK_ON ((uint32_t)0x00008000) +#define IS_RCC_RTCCLK_ENABLE(RTCCLK) (((RTCCLK) == RCC_RTCCLK_OFF) || ((RTCCLK) == RCC_RTCCLK_ON)) +/** + * @} + */ + +/** @defgroup RCC_RTC_clock_source + * @brief + * @{ + */ +#define RCC_RTCCLKSource_HSE_Div32 RCC_BDCR_RTCSEL_HSEDIV32 +#define RCC_RTCCLKSource_LSI RCC_BDCR_RTCSEL_LSI +#define RCC_RTCCLKSource_LSE RCC_BDCR_RTCSEL_LSE +#define IS_RCC_RTCCLK_SOURCE(SOURCE) (((SOURCE) == RCC_RTCCLKSource_HSE_Div32) || ((SOURCE) == RCC_RTCCLKSource_LSI) || \ + ((SOURCE) == RCC_RTCCLKSource_LSE)) +/** + * @} + */ + +/** @defgroup RCC_LSE_drv + * @brief + * @{ + */ +#define RCC_LSEDrive_Low ((uint32_t)0x00000000) +#define RCC_LSEDrive_MediumLow ((uint32_t)0x00000008) +#define RCC_LSEDrive_MediumHigh ((uint32_t)0x00000010) +#define RCC_LSEDrive_High ((uint32_t)0x00000018) +#define IS_RCC_LSE_DRIVE(DRIVE) (((DRIVE) == RCC_LSEDrive_Low) || ((DRIVE) == RCC_LSEDrive_MediumLow) || \ + ((DRIVE) == RCC_LSEDrive_MediumHigh) || ((DRIVE) == RCC_LSEDrive_High)) +/** + * @} + */ + +/** @defgroup RCC_LSE_config + * @brief + * @{ + */ +#define RCC_LSE_OFF ((uint32_t)0x00000000) +#define RCC_LSE_ON ((uint32_t)0x00000001) +#define RCC_LSE_BYP ((uint32_t)0x00000005) +#define IS_RCC_LSE(LSE) (((LSE) == RCC_LSE_OFF) || ((LSE) == RCC_LSE_ON) || \ + ((LSE) == RCC_LSE_BYP)) +/** + * @} + */ + + +/** @defgroup RCC_LSI_clock_enable + * @brief + * @{ + */ +#define RCC_LSI_OFF ((uint32_t)0x00000000) +#define RCC_LSI_ON ((uint32_t)0x00000001) +#define RCC_LSI_RDY ((uint32_t)0x00000002) +#define IS_RCC_LSI(LSI) (((LSI) == RCC_LSI_OFF) || ((LSI) == RCC_LSI_ON) || \ + ((LSI) == RCC_LSI_RDY)) +/** + * @} + */ + +//RCC_RAMCTL_REG +/** @defgroup RCC_RAMCTL_config + * @brief + * @{ + */ +#define RCC_DCACHE_CTL RCC_RAMCTL_DCHRAMSEL +#define RCC_ICACHE_CTL RCC_RAMCTL_ICHRAMSEL +#define RCC_ETHMAC_CTL RCC_RAMCTL_ETHRAMSEL +#define RCC_CAN_CTL RCC_RAMCTL_CANRAMSEL +#define RCC_USBHS_CTL RCC_RAMCTL_UHSRAMSEL +#define RCC_USBFS_CTL RCC_RAMCTL_UFSRAMSEL +#define IS_RCC_RAMCTL(CTL) (((CTL) == RCC_DCACHE_CTL) || ((CTL) == RCC_ICACHE_CTL) || \ + ((CTL) == RCC_ETHMAC_CTL) || ((CTL) == RCC_CAN_CTL) || \ + ((CTL) == RCC_USBHS_CTL) || ((CTL) == RCC_USBFS_CTL)) + +#define RCC_RAM_CTL_SELF ((uint32_t)0x00000000) +#define RCC_RAM_CTL_AHB ((uint32_t)0x00000001) +#define IS_RCC_RAMCTL_SEL(SEL) (((SEL) == RCC_RAM_CTL_SELF) || ((SEL) == RCC_RAM_CTL_AHB)) + +/** + * @} + */ + + + + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +/* Function used to set the RCC clock configuration to the default reset state */ +void RCC_DeInit(void); + +/* Internal/external clocks, PLL, CSS and MCO configuration functions *********/ +void RCC_HSEConfig(uint32_t RCC_HSE);/* Function used config hse */ +ErrorStatus RCC_WaitForHSEStartUp(void);/* Function used wait hserdy */ +void RCC_AdjustHSICalibrationValue(uint8_t HSICalibrationValue);/* Function usde hsi calibration value */ +void RCC_HSICmd(FunctionalState NewState);/* Function usde enable hsi */ +ErrorStatus RCC_WaitForHSIStartUp(void);/* Function used wait hsirdy */ +void RCC_AdjustHSI48CalibrationValue(uint32_t HSI48CalibrationValue);/* Function used hsi48 calibration value */ +void RCC_HSI48Cmd(FunctionalState NewState);/* Function used enable hsi48 */ +ErrorStatus RCC_WaitForHSI48StartUp(void);/* Function used wait hsi48rdy */ +void RCC_LSEConfig(uint32_t RCC_LSE);/* Function used config lse */ +ErrorStatus RCC_WaitForLSEStartUp(void);/* Function used wait lserdy */ +void RCC_LSEDriveConfig(uint32_t RCC_LSEDrive);/* Functoion usde config lse drive */ +void RCC_LSICmd(FunctionalState NewState);/* Function used enable lsi */ +ErrorStatus RCC_WaitForLSIStartUp(void);/* Function used wait lsirdy */ +/* Function used config pllsource, pllm and plln */ +void RCC_PLLVcoOutputConfig(uint32_t RCC_PLLSource, uint32_t RCC_PLLNul, uint32_t RCC_PLLMul); +void RCC_PLLROutputConfig(uint32_t RCC_PLLRStatus, uint32_t RCC_PLLR);/* Function used config pllren and pllr division value */ +void RCC_PLLQOutputConfig(uint32_t RCC_PLLQStatus, uint32_t RCC_PLLQ);/* Function used config pllqen and pllq division value */ +void RCC_PLLPOutputConfig(uint32_t RCC_PLLPStatus, uint32_t RCC_PLLP);/* Function used config pllpen and pllp division value */ +/* Function used config pll2source, pll2m and pll2n */ +void RCC_PLL2VcoOutputConfig(uint32_t RCC_PLL2Source, uint32_t RCC_PLL2Nul, uint32_t RCC_PLL2Mul); +void RCC_PLL2ROutputConfig(uint32_t RCC_PLL2RStatus, uint32_t RCC_PLL2R);/* Function used config pll2ren and pll2r division value */ +void RCC_PLL2QOutputConfig(uint32_t RCC_PLL2QStatus, uint32_t RCC_PLL2Q);/* Function used config pll2qen and pll2q division value */ +void RCC_PLLCmd(uint32_t RCC_PLLSelect, FunctionalState NewState);/* Function used enable pll and pll2 */ +ErrorStatus RCC_WaitForPLLStartUp(void);/* Function used wait pllrdy */ +ErrorStatus RCC_WaitForPLL2StartUp(void);/* Function used wait pll2rdy */ +void RCC_ClockSecuritySystemCmd(FunctionalState NewState);/* Function used enable css */ +void RCC_MCOConfig(uint32_t RCC_MCOSource, uint32_t RCC_MCOPrescaler); /* Function used config MCO source and prescaler */ + +/* System, AHB and APB busses clocks configuration functions ******************/ +void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource);/* Function used config sysclk's source */ +uint32_t RCC_GetSYSCLKSource(void);/* Function usde get sysclk's source */ +void RCC_HCLKConfig(uint32_t RCC_SYSCLK);/* Function used config hclk's frequence */ +void RCC_PCLK1Config(uint32_t RCC_HCLK1);/* Function used config pclk1's frequence */ +void RCC_PCLK2Config(uint32_t RCC_HCLK2);/* Function used config pclk2's frequence */ +void RCC_QSPICLKConfig(uint32_t RCC_QSPICLK); /* Function used config qspi clk */ +void RCC_ADCCLKConfig(uint32_t RCC_ADCCLK); /* Function used config adc123 clk */ +void RCC_CANCLKConfig(uint32_t RCC_CANCLK); /* Function used config can clk */ +void RCC_LPTIMCLKConfig(uint32_t RCC_LPTIMCLK); /* Function used config lptim clk */ +void RCC_I2C3CLKConfig(uint32_t RCC_I2C3CLK); /* Function used config i2c3 clk */ +void RCC_I2C2CLKConfig(uint32_t RCC_I2C2CLK); /* Function used config i2c2 clk */ +void RCC_I2C1CLKConfig(uint32_t RCC_I2C1CLK); /* Function used config i2c1 clk */ +void RCC_LPUARTCLKConfig(uint32_t RCC_LPUARTCLK);/* Function used config lpuart clk */ +void RCC_RNGCLKDIVConfig(uint32_t RCC_RNGCLKDIV);/* Function used config rng division */ +void RCC_48MCLKConfig(uint32_t RCC_48MCLK);/* Function used config 48MCLK's source */ +void RCC_EPWMCLKConfig(uint32_t RCC_EPWMCLK);/* Function used config EPWM source */ +void RCC_EQEPCLKConfig(uint32_t RCC_EQEPCLK);/* Function used config EQEP source */ +void RCC_ECAPCLKConfig(uint32_t RCC_ECAPCLK);/* Function used config ECAP source */ +void RCC_I2SCLKConfig(uint32_t RCC_I2SCLK);/* Function used config I2S source */ +void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks); + +/* Peripheral clocks configuration functions **********************************/ +void RCC_LSCOCLKConfig(uint32_t RCC_LSCOCLKSource); +void RCC_LSCOCLKCmd(FunctionalState NewState); +void RCC_RTCCLKConfig(uint32_t RCC_RTCCLKSource); +void RCC_RTCCLKCmd(FunctionalState NewState); +void RCC_BackupResetCmd(FunctionalState NewState); +void RCC_AHB1PeriphClockCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState); +void RCC_AHB2PeriphClockCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState); +void RCC_AHB3PeriphClockCmd(uint32_t RCC_AHB3Periph, FunctionalState NewState); +void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState); +void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState); +void RCC_AHB1PeriphLpenCmd(uint32_t RCC_AHB1PeriphLpen, FunctionalState NewState); +void RCC_AHB2PeriphLpenCmd(uint32_t RCC_AHB2PeriphLpen, FunctionalState NewState); +void RCC_AHB3PeriphLpenCmd(uint32_t RCC_AHB3PeriphLpen, FunctionalState NewState); +void RCC_APB1PeriphLpenCmd(uint32_t RCC_APB1PeriphLpen, FunctionalState NewState); +void RCC_APB2PeriphLpenCmd(uint32_t RCC_APB2PeriphLpen, FunctionalState NewState); +void RCC_AHB1PeriphResetCmd(uint32_t RCC_AHB1PeriphRst, FunctionalState NewState); +void RCC_AHB2PeriphResetCmd(uint32_t RCC_AHB2PeriphRst, FunctionalState NewState); +void RCC_AHB3PeriphResetCmd(uint32_t RCC_AHB3PeriphRst, FunctionalState NewState); +void RCC_APB1PeriphResetCmd(uint32_t RCC_APB1PeriphRst, FunctionalState NewState); +void RCC_APB2PeriphResetCmd(uint32_t RCC_APB2PeriphRst, FunctionalState NewState); + + + +/* Interrupts and flags management functions **********************************/ +FlagStatus RCC_GetFlagStatus(uint8_t RCC_FLAG_REG, uint32_t RCC_FLAG); +void RCC_ClrRstFlag(void); +void RCC_ITConfig(uint32_t RCC_IT, FunctionalState NewState); +ITStatus RCC_GetITStatus(uint32_t RCC_IT_FLAG); +void RCC_ClearITPendingBit(uint32_t RCC_IT_CLR); +void RCC_RamCtrlSel(uint32_t RCC_RAM_CTL, uint32_t RCC_RAM_CTL_SEL); + +#ifdef __cplusplus +} +#endif + +#endif /* __FT32F0XX_RCC_H */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_rng.h b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_rng.h new file mode 100644 index 00000000000..6f577639d8e --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_rng.h @@ -0,0 +1,47 @@ +/** + ****************************************************************************** + * @file ft32f4xx_rng.h + * @author FMD AE + * @brief This file contains all the functions prototypes for the rng + * firmware library. + * @version V1.0.0 + * @data 2025-03-06 + ****************************************************************************** + */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __FT32F4XX_RNG_H +#define __FT32F4XX_RNG_H + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "ft32f4xx.h" + +void RNG_Init(); +void RNG_DeInit(FunctionalState NewState); + +uint32_t RNG_GenerateRandomNumber(); +void RNG_IT(FunctionalState NewState); +uint8_t RNG_get_error_status(); + +#ifdef __cplusplus +} +#endif + +#endif /* __FT32F0XX_RNG_H */ + +/** + * @} + */ +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ + + + + + + + + + diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_rtc.h b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_rtc.h new file mode 100644 index 00000000000..f99a7d21f63 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_rtc.h @@ -0,0 +1,911 @@ +/** + ****************************************************************************** + * @file ft32f4xx_rtc.h + * @author Rwang + * @brief This file contains all the functions prototypes for the RTC firmware + * library. + * @version V1.0.0 + * @data 2025-03-24 + ****************************************************************************** + */ + + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __FT32F4XX_RTC_H +#define __FT32F4XX_RTC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx.h" +#include "ft32f407xe.h" + + + +/** @addtogroup RTC + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** + * @brief RTC Init structures definition + */ +typedef struct +{ + uint32_t RTC_HourFormat; /*!< Specifies the RTC Hour Format. + This parameter can be a value of @ref RTC_Hour_Formats */ + + uint32_t RTC_AsynchPrediv; /*!< Specifies the RTC Asynchronous Predivider value. + This parameter must be set to a value lower than 0x7F */ + + uint32_t RTC_SynchPrediv; /*!< Specifies the RTC Synchronous Predivider value. + This parameter must be set to a value lower than 0x1FFF */ +} RTC_InitTypeDef; + +/** + * @brief RTC Time structure definition + */ +typedef struct +{ + uint8_t RTC_Hours; /*!< Specifies the RTC Time Hour. + This parameter must be set to a value in the 0-12 range + if the RTC_HourFormat_12 is selected or 0-23 range if + the RTC_HourFormat_24 is selected. */ + + uint8_t RTC_Minutes; /*!< Specifies the RTC Time Minutes. + This parameter must be set to a value in the 0-59 range. */ + + uint8_t RTC_Seconds; /*!< Specifies the RTC Time Seconds. + This parameter must be set to a value in the 0-59 range. */ + + uint8_t RTC_H12; /*!< Specifies the RTC AM/PM Time. + This parameter can be a value of @ref RTC_AM_PM_Definitions */ +} RTC_TimeTypeDef; + +/** + * @brief RTC Date structure definition + */ +typedef struct +{ + uint8_t RTC_WeekDay; /*!< Specifies the RTC Date WeekDay. + This parameter can be a value of @ref RTC_WeekDay_Definitions */ + + uint8_t RTC_Month; /*!< Specifies the RTC Date Month. + This parameter can be a value of @ref RTC_Month_Date_Definitions */ + + uint8_t RTC_Date; /*!< Specifies the RTC Date. + This parameter must be set to a value in the 1-31 range. */ + + uint8_t RTC_Year; /*!< Specifies the RTC Date Year. + This parameter must be set to a value in the 0-99 range. */ +} RTC_DateTypeDef; + +/** + * @brief RTC Alarm structure definition + */ +typedef struct +{ + RTC_TimeTypeDef RTC_AlarmTime; /*!< Specifies the RTC Alarm Time members. */ + + uint32_t RTC_AlarmMask; /*!< Specifies the RTC Alarm Masks. + This parameter can be a value of @ref RTC_AlarmMask_Definitions */ + + uint32_t RTC_AlarmDateWeekDaySel; /*!< Specifies the RTC Alarm is on Date or WeekDay. + This parameter can be a value of @ref RTC_AlarmDateWeekDay_Definitions */ + + uint8_t RTC_AlarmDateWeekDay; /*!< Specifies the RTC Alarm Date/WeekDay. + This parameter must be set to a value in the 1-31 range + if the Alarm Date is selected. + This parameter can be a value of @ref RTC_WeekDay_Definitions + if the Alarm WeekDay is selected. */ +} RTC_AlarmTypeDef; + + + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup RTC_Exported_Constants + * @{ + */ + + +/** @defgroup RTC_Hour_Formats + * @{ + */ +#define RTC_HourFormat_24 ((uint32_t)0x00000000) +#define RTC_HourFormat_12 RTC_CR_FMT +#define IS_RTC_HOUR_FORMAT(FORMAT) (((FORMAT) == RTC_HourFormat_12) || \ + ((FORMAT) == RTC_HourFormat_24)) +/** + * @} + */ + +/** @defgroup RTC_Asynchronous_Predivider PREDIV_A[6:0] + * @{ + */ +#define IS_RTC_ASYNCH_PREDIV(PREDIV) ((PREDIV) <= 0x7F) +/** + * @} + */ + + +/** @defgroup RTC_Synchronous_Predivider PREDIV_S[14:0] + * @{ + */ +#define IS_RTC_SYNCH_PREDIV(PREDIV) ((PREDIV) <= 0x7FFF) +/** + * @} + */ + +/** @defgroup RTC_Weakup_counter WUT[15:0] + * @{ + */ +#define IS_RTC_WeakUp_CNT(CNT) ((CNT) <= 0xFFFF) +/** + * @} + */ + + +/** @defgroup RTC_Time_Definitions + * @{ + */ +#define IS_RTC_HOUR12(HOUR) (((HOUR) > 0) && ((HOUR) <= 12)) +#define IS_RTC_HOUR24(HOUR) ((HOUR) <= 23) +#define IS_RTC_MINUTES(MINUTES) ((MINUTES) <= 59) +#define IS_RTC_SECONDS(SECONDS) ((SECONDS) <= 59) +/** + * @} + */ + +/** @defgroup RTC_AM_PM_Definitions + * @{ + */ +#define RTC_H12_AM ((uint32_t)0x00000000) +#define RTC_H12_PM ((uint32_t)0x00000001) +#define IS_RTC_H12(PM) (((PM) == RTC_H12_AM) || ((PM) == RTC_H12_PM)) +/** + * @} + */ + +/** @defgroup RTC_Year_Date_Definitions + * @{ + */ +#define IS_RTC_YEAR(YEAR) ((YEAR) <= 99) +/** + * @} + */ + +/** @defgroup RTC_Month_Date_Definitions + * @{ + */ +#define RTC_Month_January ((uint8_t)0x01) +#define RTC_Month_February ((uint8_t)0x02) +#define RTC_Month_March ((uint8_t)0x03) +#define RTC_Month_April ((uint8_t)0x04) +#define RTC_Month_May ((uint8_t)0x05) +#define RTC_Month_June ((uint8_t)0x06) +#define RTC_Month_July ((uint8_t)0x07) +#define RTC_Month_August ((uint8_t)0x08) +#define RTC_Month_September ((uint8_t)0x09) +#define RTC_Month_October ((uint8_t)0x10) +#define RTC_Month_November ((uint8_t)0x11) +#define RTC_Month_December ((uint8_t)0x12) +#define IS_RTC_MONTH(MONTH) (((MONTH) >= 1) && ((MONTH) <= 12)) +#define IS_RTC_DATE(DATE) (((DATE) >= 1) && ((DATE) <= 31)) +/** + * @} + */ + +/** @defgroup RTC_WeekDay_Definitions + * @{ + */ +#define RTC_Weekday_Monday ((uint8_t)0x01) +#define RTC_Weekday_Tuesday ((uint8_t)0x02) +#define RTC_Weekday_Wednesday ((uint8_t)0x03) +#define RTC_Weekday_Thursday ((uint8_t)0x04) +#define RTC_Weekday_Friday ((uint8_t)0x05) +#define RTC_Weekday_Saturday ((uint8_t)0x06) +#define RTC_Weekday_Sunday ((uint8_t)0x07) +#define IS_RTC_WEEKDAY(WEEKDAY) (((WEEKDAY) == RTC_Weekday_Monday) || \ + ((WEEKDAY) == RTC_Weekday_Tuesday) || \ + ((WEEKDAY) == RTC_Weekday_Wednesday) || \ + ((WEEKDAY) == RTC_Weekday_Thursday) || \ + ((WEEKDAY) == RTC_Weekday_Friday) || \ + ((WEEKDAY) == RTC_Weekday_Saturday) || \ + ((WEEKDAY) == RTC_Weekday_Sunday) ) +/** + * @} + */ + +/** @defgroup RTC_Alarm_Definitions + * @{ + */ +#define IS_RTC_ALARM_DATE_WEEKDAY_DATE(DATE) (((DATE) > 0) && ((DATE) <= 31)) +#define IS_RTC_ALARM_DATE_WEEKDAY_WEEKDAY(WEEKDAY) (((WEEKDAY) == RTC_Weekday_Monday) || \ + ((WEEKDAY) == RTC_Weekday_Tuesday) || \ + ((WEEKDAY) == RTC_Weekday_Wednesday) || \ + ((WEEKDAY) == RTC_Weekday_Thursday) || \ + ((WEEKDAY) == RTC_Weekday_Friday) || \ + ((WEEKDAY) == RTC_Weekday_Saturday) || \ + ((WEEKDAY) == RTC_Weekday_Sunday) ) +/** + * @} + */ + + +/** @defgroup RTC_AlarmDateWeekDay_Definitions + * @{ + */ +#define RTC_AlarmDateWeekDaySel_Date ((uint32_t)0x00000000) +#define RTC_AlarmDateWeekDaySel_WeekDay RTC_ALRMAR_WDSEL + +#define IS_RTC_ALARM_DATE_WEEKDAY_SEL(SEL) (((SEL) == RTC_AlarmDateWeekDaySel_Date) || \ + ((SEL) == RTC_AlarmDateWeekDaySel_WeekDay) ) +/** + * @} + */ + + +/** @defgroup RTC_AlarmMask_Definitions + * @{ + */ +#define RTC_AlarmMask_None ((uint32_t)0x00000000) +#define RTC_AlarmMask_DateWeekDay ((uint32_t)0x80000000) +#define RTC_AlarmMask_Hours ((uint32_t)0x00800000) +#define RTC_AlarmMask_Minutes ((uint32_t)0x00008000) +#define RTC_AlarmMask_Seconds ((uint32_t)0x00000080) +#define RTC_AlarmMask_All ((uint32_t)0x80808080) +#define IS_RTC_ALARM_MASK(MASK) (((MASK) & 0x7F7F7F7F) == (uint32_t)RESET) +/** + * @} + */ + +/** @defgroup RTC_Alarm_Definitions(RTC_ALARMA or RTC_ALARMB) + * @{ + */ +#define RTC_Alarm_A ((uint32_t)0x00000100) +#define RTC_Alarm_B ((uint32_t)0x00000200) +#define IS_RTC_ALARM(ALARM) (((ALARM) == RTC_Alarm_A) || ((ALARM) == RTC_Alarm_B)) +#define IS_RTC_CMD_ALARM(ALARM) ((((ALARM) & (RTC_Alarm_A)) != (uint32_t)RESET) || \ + (((ALARM) & (RTC_Alarm_B)) != (uint32_t)RESET) ) +/** + * @} + */ + +/** @defgroup RTC_Alarm_Sub_Seconds_Masks Definitions. + * @{ + */ +#define RTC_AlarmSubSecondMask_All ((uint8_t)0x00) /*!< All Alarm SS fields are masked. + There is no comparison on sub second for Alarm */ +#define RTC_AlarmSubSecondMask_SS14_1 ((uint8_t)0x01) /*!< SS[14:1] are don't care in Alarm + comparison. Only SS[0] is compared. */ +#define RTC_AlarmSubSecondMask_SS14_2 ((uint8_t)0x02) /*!< SS[14:2] are don't care in Alarm + comparison. Only SS[1:0] are compared */ +#define RTC_AlarmSubSecondMask_SS14_3 ((uint8_t)0x03) /*!< SS[14:3] are don't care in Alarm + comparison. Only SS[2:0] are compared */ +#define RTC_AlarmSubSecondMask_SS14_4 ((uint8_t)0x04) /*!< SS[14:4] are don't care in Alarm + comparison. Only SS[3:0] are compared */ +#define RTC_AlarmSubSecondMask_SS14_5 ((uint8_t)0x05) /*!< SS[14:5] are don't care in Alarm + comparison. Only SS[4:0] are compared */ +#define RTC_AlarmSubSecondMask_SS14_6 ((uint8_t)0x06) /*!< SS[14:6] are don't care in Alarm + comparison. Only SS[5:0] are compared */ +#define RTC_AlarmSubSecondMask_SS14_7 ((uint8_t)0x07) /*!< SS[14:7] are don't care in Alarm + comparison. Only SS[6:0] are compared */ +#define RTC_AlarmSubSecondMask_SS14_8 ((uint8_t)0x08) /*!< SS[14:8] are don't care in Alarm + comparison. Only SS[7:0] are compared */ +#define RTC_AlarmSubSecondMask_SS14_9 ((uint8_t)0x09) /*!< SS[14:9] are don't care in Alarm + comparison. Only SS[8:0] are compared */ +#define RTC_AlarmSubSecondMask_SS14_10 ((uint8_t)0x0A) /*!< SS[14:10] are don't care in Alarm + comparison. Only SS[9:0] are compared */ +#define RTC_AlarmSubSecondMask_SS14_11 ((uint8_t)0x0B) /*!< SS[14:11] are don't care in Alarm + comparison. Only SS[10:0] are compared */ +#define RTC_AlarmSubSecondMask_SS14_12 ((uint8_t)0x0C) /*!< SS[14:12] are don't care in Alarm + comparison.Only SS[11:0] are compared */ +#define RTC_AlarmSubSecondMask_SS14_13 ((uint8_t)0x0D) /*!< SS[14:13] are don't care in Alarm + comparison. Only SS[12:0] are compared */ +#define RTC_AlarmSubSecondMask_SS14 ((uint8_t)0x0E) /*!< SS[14] is don't care in Alarm + comparison.Only SS[13:0] are compared */ +#define RTC_AlarmSubSecondMask_None ((uint8_t)0x0F) /*!< SS[14:0] are compared and must match + to activate alarm. */ +#define IS_RTC_ALARM_SUB_SECOND_MASK(MASK) (((MASK) == RTC_AlarmSubSecondMask_All) || \ + ((MASK) == RTC_AlarmSubSecondMask_SS14_1) || \ + ((MASK) == RTC_AlarmSubSecondMask_SS14_2) || \ + ((MASK) == RTC_AlarmSubSecondMask_SS14_3) || \ + ((MASK) == RTC_AlarmSubSecondMask_SS14_4) || \ + ((MASK) == RTC_AlarmSubSecondMask_SS14_5) || \ + ((MASK) == RTC_AlarmSubSecondMask_SS14_6) || \ + ((MASK) == RTC_AlarmSubSecondMask_SS14_7) || \ + ((MASK) == RTC_AlarmSubSecondMask_SS14_8) || \ + ((MASK) == RTC_AlarmSubSecondMask_SS14_9) || \ + ((MASK) == RTC_AlarmSubSecondMask_SS14_10) || \ + ((MASK) == RTC_AlarmSubSecondMask_SS14_11) || \ + ((MASK) == RTC_AlarmSubSecondMask_SS14_12) || \ + ((MASK) == RTC_AlarmSubSecondMask_SS14_13) || \ + ((MASK) == RTC_AlarmSubSecondMask_SS14) || \ + ((MASK) == RTC_AlarmSubSecondMask_None) ) +/** + * @} + */ + +/** @defgroup RTC_Alarm_Sub_Seconds_Value + * @{ + */ +#define IS_RTC_ALARM_SUB_SECOND_VALUE(VALUE) ((VALUE) <= 0x00007FFF) +/** + * @} + */ + +/** + * @} + */ +/** @defgroup RTC_Time_Stamp_Edges_definitions + * @{ + */ +#define RTC_TimeStampEdge_Rising ((uint32_t)0x00000000) +#define RTC_TimeStampEdge_Falling ((uint32_t)0x00000008) +#define IS_RTC_TIMESTAMP_EDGE(EDGE) (((EDGE) == RTC_TimeStampEdge_Rising) || \ + ((EDGE) == RTC_TimeStampEdge_Falling) ) +/** + * @} + */ + +/** @defgroup RTC_Output_selection_Definitions + * @{ + */ +#define RTC_Output_Disable ((uint32_t)0x00000000) +#define RTC_Output_AlarmA ((uint32_t)0x00200000) +#define RTC_Output_AlarmB ((uint32_t)0x00400000) +#define RTC_Output_WakeUp ((uint32_t)0x00600000) +#define IS_RTC_OUTPUT(OUTPUT) (((OUTPUT) == RTC_Output_Disable) || \ + ((OUTPUT) == RTC_Output_AlarmA) || \ + ((OUTPUT) == RTC_Output_AlarmB) || \ + ((OUTPUT) == RTC_Output_WakeUp) ) +/** + * @} + */ + +/** @defgroup RTC_Output_Polarity_Definitions + * @{ + */ +#define RTC_OutputPolarity_High ((uint32_t)0x00000000) +#define RTC_OutputPolarity_Low ((uint32_t)0x00100000) +#define IS_RTC_OUTPUT_POL(POL) (((POL) == RTC_OutputPolarity_High) || \ + ((POL) == RTC_OutputPolarity_Low)) +/** + * @} + */ + + +/** @defgroup RTC_Calib_Output_selection_Definitions + * @{ + */ +#define RTC_CalibOutput_512Hz ((uint32_t)0x00000000) +#define RTC_CalibOutput_1Hz ((uint32_t)0x00080000) +#define IS_RTC_CALIB_OUTPUT(OUTPUT) (((OUTPUT) == RTC_CalibOutput_512Hz) || \ + ((OUTPUT) == RTC_CalibOutput_1Hz)) +/** + * @} + */ + +/** @defgroup RTC_Rough_Calib_Symbol_selection_Definitions + * @{ + */ +#define RTC_RoughCalibSymbol_Positive ((uint32_t)0x00000000) +#define RTC_RoughCalibSymbol_Negative ((uint32_t)0x00000080) +#define IS_RTC_ROUGH_CALIB_SYMBOL(SYMBOL) (((SYMBOL) == RTC_RoughCalibSymbol_Positive) || \ + ((SYMBOL) == RTC_RoughCalibSymbol_Negative)) +/** + * @} + */ + +/** @defgroup RTC_Rough_Calib_Dc_Value + * @{ + */ +#define IS_RTC_ROUGH_CALIB_DC_VALUE(VALUE) ((VALUE) <= 0x0000001F) +/** + * @} + */ + + +/** @defgroup RTC_Smooth_calib_period_Definitions + * @{ + */ +#define RTC_SmoothCalibPeriod_32sec ((uint32_t)0x00000000) /*!< if RTCCLK = 32768 Hz, Smooth calibation + period is 32s, else 2exp20 RTCCLK seconds */ +#define RTC_SmoothCalibPeriod_16sec ((uint32_t)0x00002000) /*!< if RTCCLK = 32768 Hz, Smooth calibation + period is 16s, else 2exp19 RTCCLK seconds */ +#define RTC_SmoothCalibPeriod_8sec ((uint32_t)0x00004000) /*!< if RTCCLK = 32768 Hz, Smooth calibation + period is 8s, else 2exp18 RTCCLK seconds */ +#define IS_RTC_SMOOTH_CALIB_PERIOD(PERIOD) (((PERIOD) == RTC_SmoothCalibPeriod_32sec) || \ + ((PERIOD) == RTC_SmoothCalibPeriod_16sec) || \ + ((PERIOD) == RTC_SmoothCalibPeriod_8sec) ) +/** + * @} + */ + +/** @defgroup RTC_Smooth_calib_Plus_pulses_Definitions + * @{ + */ +#define RTC_SmoothCalibPlusPulses_Set ((uint32_t)0x00008000) /*!< The number of RTCCLK pulses added + during a X -second window = Y - CALM[8:0]. + with Y = 512, 256, 128 when X = 32, 16, 8 */ +#define RTC_SmoothCalibPlusPulses_Reset ((uint32_t)0x00000000) /*!< The number of RTCCLK pulses subbstited + during a 32-second window = CALM[8:0]. */ +#define IS_RTC_SMOOTH_CALIB_PLUS(PLUS) (((PLUS) == RTC_SmoothCalibPlusPulses_Set) || \ + ((PLUS) == RTC_SmoothCalibPlusPulses_Reset) ) +/** + * @} + */ + +/** @defgroup RTC_Smooth_calib_Minus_pulses_Definitions + * @{ + */ +#define IS_RTC_SMOOTH_CALIB_MINUS(VALUE) ((VALUE) <= 0x000001FF) +/** + * @} + */ + +/** @defgroup RTC_DayLightSaving_Definitions + * @{ + */ +#define RTC_DayLightSaving_SUB1H ((uint32_t)0x00020000) +#define RTC_DayLightSaving_ADD1H ((uint32_t)0x00010000) +#define IS_RTC_DAYLIGHT_SAVING(SAVING) (((SAVING) == RTC_DayLightSaving_SUB1H) || \ + ((SAVING) == RTC_DayLightSaving_ADD1H)) + +#define RTC_StoreOperation_Reset ((uint32_t)0x00000000) +#define RTC_StoreOperation_Set ((uint32_t)0x00040000) +#define IS_RTC_STORE_OPERATION(OPERATION) (((OPERATION) == RTC_StoreOperation_Reset) || \ + ((OPERATION) == RTC_StoreOperation_Set) ) +/** + * @} + */ + +/** @defgroup RTC_Tamper_Trigger1_Definitions + * @{ + */ +#define RTC_TamperTrigger_RisingEdge ((uint32_t)0x00000000) +#define RTC_TamperTrigger_FallingEdge ((uint32_t)0x00000002) +#define RTC_TamperTrigger_LowLevel ((uint32_t)0x00000000) +#define RTC_TamperTrigger_HighLevel ((uint32_t)0x00000002) +#define IS_RTC_TAMPER_TRIGGER(TRIGGER) (((TRIGGER) == RTC_TamperTrigger_RisingEdge) || \ + ((TRIGGER) == RTC_TamperTrigger_FallingEdge) || \ + ((TRIGGER) == RTC_TamperTrigger_LowLevel) || \ + ((TRIGGER) == RTC_TamperTrigger_HighLevel) ) +/** + * @} + */ + + +/** @defgroup RTC_Tamper_Filter_Definitions + * @{ + */ +#define RTC_TamperFilter_Disable ((uint32_t)0x00000000) /*!< Tamper filter is disabled */ + +#define RTC_TamperFilter_2Sample ((uint32_t)0x00000800) /*!< Tamper is activated after 2 + consecutive samples at the active level */ +#define RTC_TamperFilter_4Sample ((uint32_t)0x00001000) /*!< Tamper is activated after 4 + consecutive samples at the active level */ +#define RTC_TamperFilter_8Sample ((uint32_t)0x00001800) /*!< Tamper is activated after 8 + consecutive samples at the active leve. */ +#define IS_RTC_TAMPER_FILTER(FILTER) (((FILTER) == RTC_TamperFilter_Disable) || \ + ((FILTER) == RTC_TamperFilter_2Sample) || \ + ((FILTER) == RTC_TamperFilter_4Sample) || \ + ((FILTER) == RTC_TamperFilter_8Sample)) +/** + * @} + */ + +/** @defgroup RTC_Tamper_Sampling_Frequencies_Definitions + * @{ + */ +#define RTC_TamperSamplingFreq_RTCCLK_Div32768 ((uint32_t)0x00000000) /*!< Tamper inputs sampled frequency = RTCCLK/32768 */ +#define RTC_TamperSamplingFreq_RTCCLK_Div16384 ((uint32_t)0x00000100) /*!< Tamper inputs sampled frequency = RTCCLK/16384 */ +#define RTC_TamperSamplingFreq_RTCCLK_Div8192 ((uint32_t)0x00000200) /*!< Tamper inputs sampled frequency = RTCCLK/8192 */ +#define RTC_TamperSamplingFreq_RTCCLK_Div4096 ((uint32_t)0x00000300) /*!< Tamper inputs sampled frequency = RTCCLK/4096 */ +#define RTC_TamperSamplingFreq_RTCCLK_Div2048 ((uint32_t)0x00000400) /*!< Tamper inputs sampled frequency = RTCCLK/2048 */ +#define RTC_TamperSamplingFreq_RTCCLK_Div1024 ((uint32_t)0x00000500) /*!< Tamper inputs sampled frequency = RTCCLK/1024 */ +#define RTC_TamperSamplingFreq_RTCCLK_Div512 ((uint32_t)0x00000600) /*!< Tamper inputs sampled frequency = RTCCLK/512 */ +#define RTC_TamperSamplingFreq_RTCCLK_Div256 ((uint32_t)0x00000700) /*!< Tamper inputs sampled frequency = RTCCLK/256 */ +#define IS_RTC_TAMPER_SAMPLING_FREQ(FREQ) (((FREQ) ==RTC_TamperSamplingFreq_RTCCLK_Div32768) || \ + ((FREQ) ==RTC_TamperSamplingFreq_RTCCLK_Div16384) || \ + ((FREQ) ==RTC_TamperSamplingFreq_RTCCLK_Div8192) || \ + ((FREQ) ==RTC_TamperSamplingFreq_RTCCLK_Div4096) || \ + ((FREQ) ==RTC_TamperSamplingFreq_RTCCLK_Div2048) || \ + ((FREQ) ==RTC_TamperSamplingFreq_RTCCLK_Div1024) || \ + ((FREQ) ==RTC_TamperSamplingFreq_RTCCLK_Div512) || \ + ((FREQ) ==RTC_TamperSamplingFreq_RTCCLK_Div256) ) +/** + * @} + */ + +/** @defgroup RTC_Tamper_Pin_Precharge_Duration_Definitions +* @{ +*/ +#define RTC_TamperPrechargeDuration_1RTCCLK ((uint32_t)0x00000000) /*!< Tamper pins are precharged 1 RTCCLK */ +#define RTC_TamperPrechargeDuration_2RTCCLK ((uint32_t)0x00002000) /*!< Tamper pins are precharged 2 RTCCLK */ +#define RTC_TamperPrechargeDuration_4RTCCLK ((uint32_t)0x00004000) /*!< Tamper pins are precharged 4 RTCCLK */ +#define RTC_TamperPrechargeDuration_8RTCCLK ((uint32_t)0x00006000) /*!< Tamper pins are precharged 8 RTCCLK */ + +#define IS_RTC_TAMPER_PRECHARGE_DURATION(DURATION) (((DURATION) == RTC_TamperPrechargeDuration_1RTCCLK) || \ + ((DURATION) == RTC_TamperPrechargeDuration_2RTCCLK) || \ + ((DURATION) == RTC_TamperPrechargeDuration_4RTCCLK) || \ + ((DURATION) == RTC_TamperPrechargeDuration_8RTCCLK) ) +/** + * @} + */ + +/** @defgroup RTC_Tamper_Pins_Definitions + * @{ + */ +#define RTC_Tamper_1 RTC_TAFCR_TAMP1E /*!< Tamper detection enable for input tamper 1 */ +#define RTC_Tamper_2 RTC_TAFCR_TAMP2E /*!< Tamper detection enable for input tamper 2 */ +#define IS_RTC_TAMPER(TAMPER) ((((TAMPER) & (uint32_t)0xFFFFFFF6) == 0x00) && ((TAMPER) != (uint32_t)RESET)) +/** + * @} + */ + +/** @defgroup RTC_Output_Type_ALARM_OUT + * @{ + */ +#define RTC_OutputType_OpenDrain ((uint32_t)0x00000000) +#define RTC_OutputType_PushPull ((uint32_t)0x00040000) +#define IS_RTC_OUTPUT_TYPE(TYPE) (((TYPE) == RTC_OutputType_OpenDrain) || \ + ((TYPE) == RTC_OutputType_PushPull)) +#define RTC_PC13_OutputType_GPIO ((uint32_t)0x00000000) +#define RTC_PC13_OutputType_PushPull ((uint32_t)0x00080000) +#define IS_RTC_PC13_OUTPUT_TYPE(TYPE) (((TYPE) == RTC_PC13_OutputType_GPIO) || \ + ((TYPE) == RTC_PC13_OutputType_PushPull)) +/** + * @} + */ + +/** @defgroup RTC_Pc15_Output_Type_Data + * @{ + */ +#define RTC_PC15_OutputType_GPIO ((uint32_t)0x00000000) +#define RTC_PC15_OutputType_PushPull ((uint32_t)0x00800000) +#define IS_RTC_PC15_OUTPUT_TYPE(TYPE) (((TYPE) == RTC_PC15_OutputType_GPIO) || \ + ((TYPE) == RTC_PC15_OutputType_PushPull)) +#define RTC_PC15_OutputData_0 ((uint32_t)0x00000000) +#define RTC_PC15_OutputData_1 ((uint32_t)0x00400000) +#define IS_RTC_PC15_OUTPUT_DATA(DATA) (((DATA) == RTC_PC15_OutputData_0) || \ + ((DATA) == RTC_PC15_OutputData_1)) +/** + * @} + */ + +/** @defgroup RTC_Pc14_Output_Type_Data + * @{ + */ +#define RTC_PC14_OutputType_GPIO ((uint32_t)0x00000000) +#define RTC_PC14_OutputType_PushPull ((uint32_t)0x00200000) +#define IS_RTC_PC14_OUTPUT_TYPE(TYPE) (((TYPE) == RTC_PC14_OutputType_GPIO) || \ + ((TYPE) == RTC_PC14_OutputType_PushPull)) +#define RTC_PC14_OutputData_0 ((uint32_t)0x00000000) +#define RTC_PC14_OutputData_1 ((uint32_t)0x00100000) +#define IS_RTC_PC14_OUTPUT_DATA(DATA) (((DATA) == RTC_PC14_OutputData_0) || \ + ((DATA) == RTC_PC14_OutputData_1)) +/** + * @} + */ + +/** @defgroup RTC_Add_1_Second_Parameter_Definitions + * @{ + */ +#define RTC_ShiftAdd1S_Reset ((uint32_t)0x00000000) +#define RTC_ShiftAdd1S_Set ((uint32_t)0x80000000) +#define IS_RTC_SHIFT_ADD1S(SEL) (((SEL) == RTC_ShiftAdd1S_Reset) || \ + ((SEL) == RTC_ShiftAdd1S_Set)) +/** + * @} + */ + +/** @defgroup RTC_Substract_Fraction_Of_Second_Value + * @{ + */ +#define IS_RTC_SHIFT_SUBFS(FS) ((FS) <= 0x00007FFF) +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup RTC_Input_parameter_format_definitions + * @{ + */ +#define RTC_Format_BIN ((uint32_t)0x000000000) +#define RTC_Format_BCD ((uint32_t)0x000000001) +#define IS_RTC_FORMAT(FORMAT) (((FORMAT) == RTC_Format_BIN) || ((FORMAT) == RTC_Format_BCD)) + +/** + * @} + */ + +/** @defgroup RTC_Flags_Definitions + * @{ + */ +#define RTC_FLAG_RECALPF RTC_ISR_RECALPF +#define RTC_FLAG_TAMP2F RTC_ISR_TAMP2F +#define RTC_FLAG_TAMP1F RTC_ISR_TAMP1F +#define RTC_FLAG_TSOVF RTC_ISR_TSOVF +#define RTC_FLAG_TSF RTC_ISR_TSF +#define RTC_FLAG_WUTF RTC_ISR_WUTF +#define RTC_FLAG_ALRBF RTC_ISR_ALRBF +#define RTC_FLAG_ALRAF RTC_ISR_ALRAF +#define RTC_FLAG_INITF RTC_ISR_INITF +#define RTC_FLAG_RSF RTC_ISR_RSF +#define RTC_FLAG_INITS RTC_ISR_INITS +#define RTC_FLAG_SHPF RTC_ISR_SHPF +#define RTC_FLAG_WUTWF RTC_ISR_WUTWF +#define RTC_FLAG_ALRBWF RTC_ISR_ALRBWF +#define RTC_FLAG_ALRAWF RTC_ISR_ALRAWF + +#define IS_RTC_GET_FLAG(FLAG) (((FLAG) == RTC_FLAG_RECALPF) || ((FLAG) == RTC_FLAG_TAMP2F) || \ + ((FLAG) == RTC_FLAG_TAMP1F) || ((FLAG) == RTC_FLAG_TSOVF) || \ + ((FLAG) == RTC_FLAG_TSF) || ((FLAG) == RTC_FLAG_WUTF) || \ + ((FLAG) == RTC_FLAG_ALRBF) || ((FLAG) == RTC_FLAG_ALRAF) || \ + ((FLAG) == RTC_FLAG_INITF) || ((FLAG) == RTC_FLAG_RSF) || \ + ((FLAG) == RTC_FLAG_INITS) || ((FLAG) == RTC_FLAG_SHPF) || \ + ((FLAG) == RTC_FLAG_WUTWF) || ((FLAG) == RTC_FLAG_ALRBWF) || \ + ((FLAG) == RTC_FLAG_ALRAWF)) +#define IS_RTC_CLEAR_FLAG(FLAG) (((FLAG) == RTC_FLAG_TAMP2F) || ((FLAG) == RTC_FLAG_TAMP1F) || \ + ((FLAG) == RTC_FLAG_TSOVF) || ((FLAG) == RTC_FLAG_TSF) || \ + ((FLAG) == RTC_FLAG_WUTF) || ((FLAG) == RTC_FLAG_ALRBF) || \ + ((FLAG) == RTC_FLAG_ALRAF) || ((FLAG) == RTC_FLAG_RSF) ) +/** + * @} + */ + +/** @defgroup RTC_Interrupts_Definitions + * @{ + */ +#define RTC_IT_TS_EN ((uint32_t)0x00008000) +#define RTC_IT_WUT_EN ((uint32_t)0x00004000) +#define RTC_IT_ALRB_EN ((uint32_t)0x00002000) +#define RTC_IT_ALRA_EN ((uint32_t)0x00001000) +#define RTC_IT_TAMP_EN ((uint32_t)0x00000004) /* Used only to Enable the Tamper Interrupt */ + + +#define IS_RTC_CONFIG_IT(IT) (((IT) == RTC_IT_TS_EN) || ((IT) == RTC_IT_WUT_EN) || \ + ((IT) == RTC_IT_ALRB_EN) || ((IT) == RTC_IT_ALRA_EN) || \ + ((IT) == RTC_IT_TAMP_EN)) +#define IS_RTC_GET_IT(IT) (((IT) == RTC_IT_TS_EN) || ((IT) == RTC_IT_WUT_EN) || \ + ((IT) == RTC_IT_ALRB_EN) || ((IT) == RTC_IT_ALRA_EN) || \ + ((IT) == RTC_IT_TAMP_EN)) + +#define RTC_IT_TAMP2_FLAG ((uint32_t)0x00008000) +#define RTC_IT_TAMP1_FLAG ((uint32_t)0x00004000) +#define RTC_IT_TS_FLAG ((uint32_t)0x00000800) +#define RTC_IT_WUT_FLAG ((uint32_t)0x00000400) +#define RTC_IT_ALRB_FLAG ((uint32_t)0x00000200) +#define RTC_IT_ALRA_FLAG ((uint32_t)0x00000100) + +#define IS_RTC_CLEAR_IT(IT) (((IT) == RTC_IT_TAMP2_FLAG) || ((IT) == RTC_IT_TAMP1_FLAG) || \ + ((IT) == RTC_IT_TS_FLAG) || ((IT) == RTC_IT_WUT_FLAG) || \ + ((IT) == RTC_IT_ALRB_FLAG) || ((IT) == RTC_IT_ALRB_FLAG)) +/** + * @} + */ + +/** @defgroup RTC_WeakUp_Clk_Choose + * @{ + */ +#define RTC_WeakUp_RTCCLK_Div16 ((uint32_t)0x00000000)/*auto weakup cnt clk use rtcclk/16*/ +#define RTC_WeakUp_RTCCLK_Div8 ((uint32_t)0x00000001)/*auto weakup cnt clk use rtcclk/8*/ +#define RTC_WeakUp_RTCCLK_Div4 ((uint32_t)0x00000002)/*auto weakup cnt clk use rtcclk/4*/ +#define RTC_WeakUp_RTCCLK_Div2 ((uint32_t)0x00000003)/*auto weakup cnt clk use rtcclk/2*/ +#define RTC_WeakUp_RTCCLK_CkSpre4 ((uint32_t)0x00000004)/*auto weakup cnt clk use ck_spre */ +#define RTC_WeakUp_RTCCLK_CkSpre5 ((uint32_t)0x00000005)/*auto weakup cnt clk use ck_spre */ +#define RTC_WeakUp_RTCCLK_CkSpre6 ((uint32_t)0x00000006)/*auto weakup cnt clk use ck_spre */ +#define RTC_WeakUp_RTCCLK_CkSpre7 ((uint32_t)0x00000007)/*auto weakup cnt clk use ck_spre */ + + +#define IS_RTC_WEAKUP_COUNT_FREQ(FREQ) (((FREQ) == RTC_WeakUp_RTCCLK_Div16) || ((FREQ) == RTC_WeakUp_RTCCLK_Div8) || \ + ((FREQ) == RTC_WeakUp_RTCCLK_Div4) || ((FREQ) == RTC_WeakUp_RTCCLK_Div2) || \ + ((FREQ) == RTC_WeakUp_RTCCLK_CkSpre4) || ((FREQ) == RTC_WeakUp_RTCCLK_CkSpre5) || \ + ((FREQ) == RTC_WeakUp_RTCCLK_CkSpre6) || ((FREQ) == RTC_WeakUp_RTCCLK_CkSpre7)) + +/** @defgroup RTC_Auto_Weakup_Count_Value + * @{ + */ +#define IS_RTC_WKUP_COUNTER(COUNTER) ((COUNTER) <= 0x0000FFFF) +/** + * @} + */ + +#define RTC_BackUp0Reg ((uint32_t)0x00000000)/*choose rtc_bkp0 register*/ +#define RTC_BackUp1Reg ((uint32_t)0x00000001)/*choose rtc_bkp1 register*/ +#define RTC_BackUp2Reg ((uint32_t)0x00000002)/*choose rtc_bkp2 register*/ +#define RTC_BackUp3Reg ((uint32_t)0x00000003)/*choose rtc_bkp3 register*/ +#define RTC_BackUp4Reg ((uint32_t)0x00000004)/*choose rtc_bkp4 register*/ +#define RTC_BackUp5Reg ((uint32_t)0x00000005)/*choose rtc_bkp5 register*/ +#define RTC_BackUp6Reg ((uint32_t)0x00000006)/*choose rtc_bkp6 register*/ +#define RTC_BackUp7Reg ((uint32_t)0x00000007)/*choose rtc_bkp7 register*/ +#define RTC_BackUp8Reg ((uint32_t)0x00000008)/*choose rtc_bkp8 register*/ +#define RTC_BackUp9Reg ((uint32_t)0x00000009)/*choose rtc_bkp9 register*/ +#define RTC_BackUp10Reg ((uint32_t)0x0000000A)/*choose rtc_bkp10 register*/ +#define RTC_BackUp11Reg ((uint32_t)0x0000000B)/*choose rtc_bkp11 register*/ +#define RTC_BackUp12Reg ((uint32_t)0x0000000C)/*choose rtc_bkp12 register*/ +#define RTC_BackUp13Reg ((uint32_t)0x0000000D)/*choose rtc_bkp13 register*/ +#define RTC_BackUp14Reg ((uint32_t)0x0000000E)/*choose rtc_bkp14 register*/ +#define RTC_BackUp15Reg ((uint32_t)0x0000000F)/*choose rtc_bkp15 register*/ +#define RTC_BackUp16Reg ((uint32_t)0x00000010)/*choose rtc_bkp16 register*/ +#define RTC_BackUp17Reg ((uint32_t)0x00000011)/*choose rtc_bkp17 register*/ +#define RTC_BackUp18Reg ((uint32_t)0x00000012)/*choose rtc_bkp18 register*/ +#define RTC_BackUp19Reg ((uint32_t)0x00000013)/*choose rtc_bkp19 register*/ + +#define IS_RTC_BACKUP_REG(REG) (((REG) == RTC_BackUp0Reg) || ((REG) == RTC_BackUp1Reg) || \ + ((REG) == RTC_BackUp2Reg) || ((REG) == RTC_BackUp3Reg) || \ + ((REG) == RTC_BackUp4Reg) || ((REG) == RTC_BackUp5Reg) || \ + ((REG) == RTC_BackUp6Reg) || ((REG) == RTC_BackUp7Reg) || \ + ((REG) == RTC_BackUp8Reg) || ((REG) == RTC_BackUp9Reg) || \ + ((REG) == RTC_BackUp10Reg) || ((REG) == RTC_BackUp11Reg) || \ + ((REG) == RTC_BackUp12Reg) || ((REG) == RTC_BackUp13Reg) || \ + ((REG) == RTC_BackUp14Reg) || ((REG) == RTC_BackUp15Reg) || \ + ((REG) == RTC_BackUp16Reg) || ((REG) == RTC_BackUp17Reg) || \ + ((REG) == RTC_BackUp18Reg) || ((REG) == RTC_BackUp19Reg)) + +/** @defgroup RTC_Backup_Data_Value + * @{ + */ +#define IS_RTC_BACKUP_DATA(DATA) ((DATA) <= 0xFFFFFFFF) +/** + * @} + */ + + + +/** + * @} + */ + + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ +/* Function used to set the RTC configuration to the default reset state *****/ +ErrorStatus RTC_DeInit(void);/* reset the rtc register */ + +/* Initialization and Configuration functions *********************************/ +void RTC_SetInit(RTC_InitTypeDef* RTC_InitStruct);/* config rtc's hour format,async and sync value struct */ +void RTC_StructInit(RTC_InitTypeDef* RTC_InitStruct);/* config rtc's hour format,async sync's specific value */ +void RTC_WriteProtectionCmd(FunctionalState NewState);/* Function used open rtc write protect */ +ErrorStatus RTC_EnterInitMode(void);/* Funtion used check enter initial mode if has error */ +void RTC_ExitInitMode(void);/* Function used exit initial mode */ +ErrorStatus RTC_WaitForSynchro(void);/* Function used wait calendar register be synchronized */ +void RTC_RefClockCmd(FunctionalState NewState);/* Function used enable reference clock detection */ +void RTC_BypassShadowCmd(FunctionalState NewState);/* Function used enable bypass */ + +/* Time and Date configuration functions **************************************/ +void RTC_SetTime(uint32_t RTC_Format, RTC_TimeTypeDef* RTC_TimeStruct);/* Function used set rtc time register */ +void RTC_TimeStructInit(RTC_TimeTypeDef* RTC_TimeStruct);/* Function used set rtc time struct */ +void RTC_GetTime(uint32_t RTC_Format, RTC_TimeTypeDef* RTC_TimeStruct);/* get the rtc time from the rtc_tr register */ +uint32_t RTC_GetSubSecond(void);/* Function used get the rtc sub-seconds */ +void RTC_SetDate(uint32_t RTC_Format, RTC_DateTypeDef* RTC_DateStruct);/* Function used set rtc date register*/ +void RTC_DateStructInit(RTC_DateTypeDef* RTC_DateStruct);/* Function used set rtc date struct */ +uint32_t RTC_GetDate(uint32_t RTC_Format, RTC_DateTypeDef* RTC_DateStruct);/* get the rtc date from the rtc_dr register */ + +/* Alarms (Alarm A and Alarm B) configuration functions **********************************/ +/* Function used config alarma/amarmb */ +void RTC_SetAlarm(uint32_t RTC_Format, uint32_t RTC_Alarm, RTC_AlarmTypeDef* RTC_AlarmStruct); +void RTC_AlarmStructInit(RTC_AlarmTypeDef* RTC_AlarmStruct);/*Function used set rtc alarm struct */ +/* Function used get alarma/amarmb */ +void RTC_GetAlarm(uint32_t RTC_Format, uint32_t RTC_Alarm, RTC_AlarmTypeDef* RTC_AlarmStruct); +void RTC_AlarmCmd(uint32_t RTC_Alarm, FunctionalState NewState);/* Function used alarm enable or disable */ +/* Function used config alarma/alarmb's subsecond */ +void RTC_AlarmSubSecondConfig(uint32_t RTC_Alarm, uint32_t RTC_AlarmSubSecondValue, uint8_t RTC_AlarmSubSecondMask); +/* Function used get alarma/alarmb's subsecond */ +uint32_t RTC_GetAlarmSubSecond(uint32_t RTC_Alarm); + +/* Daylight Saving configuration functions ************************************/ +/* Function used config DayLightSaving ADD1H/SUB1H and Storeoperation set/clear BKP*/ +void RTC_DayLightSavingConfig(uint32_t RTC_DayLightSaving, uint32_t RTC_StoreOperation); +uint32_t RTC_GetStoreOperation(void);/* Function used get StoreOperation RTC_CR[BKP]==0/1 */ + +/* Output pin Configuration function ******************************************/ +/* Function used config RTC_ALARM output select alraf/alrbf/wutf and polarity high/low*/ +void RTC_OutputConfig(uint32_t RTC_Output, uint32_t RTC_OutputPolarity); + +/* Smooth Calibration configuration functions ********************************/ +void RTC_CalibOutputCmd(FunctionalState NewState);/* Function used config RTC_CALIB output enable */ +void RTC_CalibOutputConfig(uint32_t RTC_CalibOutput);/* Function used config RTC_CALIB output 512Hz/1Hz */ +/* Function used config SmoothCalib CALP/CALW8/CALW16/CALM[8:0] */ +ErrorStatus RTC_SmoothCalibConfig(uint32_t RTC_SmoothCalibPeriod, + uint32_t RTC_SmoothCalibPlusPulses, + uint32_t RTC_SmouthCalibMinusPulsesValue); + +/* Rough Digtial Calibration configuration functions ********************************/ +/* Function used config DigtialRoughCalib DCS/DC[4:0] */ +void RTC_RoughCalibration(FunctionalState NewState);/* Function used rough calibration enable or disable */ +void RTC_RoughDigtialCalibConfig(uint32_t RTC_RoughCalibPolarity, + uint32_t RTC_RoughCalibMinusPulsesValue); + +/* TimeStamp configuration functions ******************************************/ +/* Function used Enable RTC_TimeStamp and config occur edge */ +void RTC_TimeStampCmd(uint32_t RTC_TimeStampEdge, FunctionalState NewState); +/* Function used get RTC_TimeStamp TS and TD Register's value */ +void RTC_GetTimeStamp(uint32_t RTC_Format, RTC_TimeTypeDef* RTC_StampTimeStruct, RTC_DateTypeDef* RTC_StampDateStruct); +/* Function used get RTC_TimeStamp SubSecond Register's value */ +uint32_t RTC_GetTimeStampSubSecond(void); + +/* Tampers configuration functions ********************************************/ +/* Function used config tamp1trg and tamp2trg is edge or level */ +void RTC_TamperTriggerConfig(uint32_t RTC_Tamper, uint32_t RTC_TamperTrigger); +/* Function used enable tamp1 and tamp2 */ +void RTC_TamperCmd(uint32_t RTC_Tamper, FunctionalState NewState); +/* Function used config tamp1 and tamp2's filter */ +void RTC_TamperFilterConfig(uint32_t RTC_TamperFilter); +/* Function used config tamp1 and tamp2's sampling frequence */ +void RTC_TamperSamplingFreqConfig(uint32_t RTC_TamperSamplingFreq); +/* Function used config tamp1 and tamp2's precharge time */ +void RTC_TamperPinsPrechargeDuration(uint32_t RTC_TamperPrechargeDuration); +/* Function used config tamp1 and tamp2 event as timestamp */ +void RTC_TimeStampOnTamperDetectionCmd(FunctionalState NewState); +/* Function used config tamp1 and tamp2 pull_up forbidden */ +void RTC_TamperPullUpCmd(FunctionalState NewState); + +/* Output Type Config configuration functions *********************************/ +/* Function used config RTC_ALARM(PC13) output type*/ +void RTC_OutputTypeConfig(uint32_t RTC_OutputType); +/* Function used config RTC_ALARM(PC13) mode*/ +void RTC_OutputModeConfig(uint32_t RTC_OutputMode); +/* Function used config pc15 output type and data */ +void RTC_Pc15_OutputTypeDataConfig(uint32_t RTC_Pc15_OutputType, uint32_t RTC_Pc15_OutputData); +/* Function used config pc14 output type and data */ +void RTC_Pc14_OutputTypeDataConfig(uint32_t RTC_Pc14_OutputType, uint32_t RTC_Pc14_OutputData); + +/* RTC_Shift_control_synchonisation_functions *********************************/ +/* Function used config shif control register add1s or substract a number of second */ +/* Return config status error or success */ +ErrorStatus RTC_SynchroShiftConfig(uint32_t RTC_ShiftAdd1S, uint32_t RTC_ShiftSubFS); + +/* Interrupts and flags management functions **********************************/ +/* Function used Enable rtc_ts/wut/alra/alrb/tamp interrupt */ +void RTC_ITConfig(uint32_t RTC_IT_ENABLE, FunctionalState NewState); +/* Function used get rtc_tsf/wutf/alraf/alrbf/tamp1f/tamp2f */ +FlagStatus RTC_GetFlagStatus(uint32_t RTC_FLAG); +/* Function used clear rtc_flag */ +void RTC_ClearFlag(uint32_t RTC_FLAG); +/* Function used get interrupt status */ +ITStatus RTC_GetITStatus(uint32_t RTC_IT_ENABLE); +/* Function used clear interrupt flag */ +void RTC_ClearITPendingBit(uint32_t RTC_IT_FLAG); + +/* Auto Weakup Config configuration functions **********************************/ +/* Function used Enable Auto WeakUp */ +void RTC_WeakUpCmd(FunctionalState NewState); +/* Function used set RTC Auto WeakUp Counter Register's value */ +void RTC_SetWeakUpCounter(uint32_t RTC_WeakUp_Counter); +/* Function used get RTC Auto WeakUp Counter Register's value */ +uint32_t RTC_GetWeakUpCounter(void); +/* Function used config Auto WeakUp Count frequence */ +void RTC_WeakUpCountFreqConfig(uint32_t RTC_WeakUpCountFreq); + +/* Backup Data Config configuration functions **********************************/ +/* Function used config backup register */ +void RTC_BackUpRegConfig(uint32_t RTC_BackUpReg, uint32_t RTC_BackUpRegData); +/* Function used get RTC_BackUp Register's value */ +uint32_t RTC_GetBackUpReg(uint32_t RTC_BackUpReg); + + + +#ifdef __cplusplus +} +#endif + +#endif /*__FT32F4XX_RTC_H */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_sdio.h b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_sdio.h new file mode 100644 index 00000000000..3ff67c69b77 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_sdio.h @@ -0,0 +1,1155 @@ +/** + ****************************************************************************** + * @file ft32f4xx_sdio.h + ****************************************************************************** +**/ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __FT32F4XX_SDIO_H +#define __FT32F4XX_SDIO_H + +#ifdef __cplusplus +extern "C" { +#endif + +/*!< Includes ----------------------------------------------------------------*/ +#include "ft32f4xx.h" + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/** @defgroup SDIO_CTRL_Register **/ +/** @defgroup SDIO_OD_PULLUP + * @{ + */ +#define SDIO_OD_PULLUP_DISABLE ((uint32_t)0x00) +#define SDIO_OD_PULLUP_ENABLE SDIO_CTRL_ENABLE_OD_PULLUP + +#define IS_SDIO_OD_PULLUP(PULLUP) (((PULLUP) == SDIO_OD_PULLUP_DISABLE) || \ + ((PULLUP) == SDIO_OD_PULLUP_ENABLE)) + +/** @defgroup SDIO_Read_Wait + * @{ + */ +#define SDIO_READ_WAIT_DISABLE ((uint32_t)0x00) +#define SDIO_READ_WAIT_ENABLE SDIO_CTRL_READ_WAIT + +#define IS_SDIO_READWAIT_MODE(MODE) (((MODE) == SDIO_READ_WAIT_DISABLE) || \ + ((MODE) == SDIO_READ_WAIT_ENABLE)) + +/** @defgroup SDIO_dma_enable + * @{ + */ +#define SDIO_DMA_ENABLE_DISABLE ((uint32_t)0x00) +#define SDIO_DMA_ENABLE_ENABLE SDIO_CTRL_DMA_ENABLE + +#define IS_SDIO_DMA_ENABLE(ENABLE) (((ENABLE) == SDIO_DMA_ENABLE_DISABLE) || \ + ((ENABLE) == SDIO_DMA_ENABLE_ENABLE)) + +/** @defgroup SDIO_INT_ENABLE + * @{ + */ +#define SDIO_INT_ENABLE_DISABLE ((uint32_t)0x00) +#define SDIO_INT_ENABLE_ENABLE SDIO_CTRL_INT_ENABLE + +#define IS_SDIO_INT_ENABLE(ENABLE) (((ENABLE) == SDIO_INT_ENABLE_DISABLE) || \ + ((ENABLE) == SDIO_INT_ENABLE_ENABLE)) + +/** @defgroup SDIO_FIFO_RESET + * @{ + */ +#define SDIO_FIFO_RESET_DISABLE ((uint32_t)0x00) +#define SDIO_FIFO_RESET_ENABLE SDIO_CTRL_FIFO_RESET + +#define IS_SDIO_FIFO_RESET(RESET) (((RESET) == SDIO_FIFO_RESET_DISABLE) || \ + ((RESET) == SDIO_FIFO_RESET_ENABLE)) + + +/** @defgroup SDIO_CONTROLLER_RESET + * @{ + */ +#define SDIO_CONTROLLER_RESET_DISABLE ((uint32_t)0x00) +#define SDIO_CONTROLLER_RESET_ENABLE SDIO_CTRL_CONTROLLER_RESET + +#define IS_SDIO_CONTROLLER_RESET(RESET) (((RESET) == SDIO_CONTROLLER_RESET_DISABLE) || \ + ((RESET) == SDIO_CONTROLLER_RESET_ENABLE)) + +/** @defgroup SDIO_PWREN_Register **/ +/** @defgroup SDIO_Power_ON + * @{ + */ +#define SDIO_POWER_ON_DISABLE ((uint32_t)0x00) +#define SDIO_POWER_ON_ENABLE SDIO_PWREN_POWER_ENABLE_0 + +#define IS_SDIO_POWER_ON(ON) (((ON) == SDIO_POWER_ON_DISABLE) || \ + ((ON) == SDIO_POWER_ON_ENABLE)) + +/** @defgroup SDIO_CLKDIV_Register **/ +/** @defgroup SDIO_Clock_Division + * @{ + */ +#define SDIO_CLKDIV1 ((uint32_t)0x00) +#define SDIO_CLKDIV2 ((uint32_t)0x01) +#define SDIO_CLKDIV4 ((uint32_t)0x02) +#define SDIO_CLKDIV6 ((uint32_t)0x03) +#define SDIO_CLKDIV8 ((uint32_t)0x04) +#define SDIO_CLKDIV10 ((uint32_t)0x05) +#define SDIO_CLKDIV12 ((uint32_t)0x06) +#define SDIO_CLKDIV14 ((uint32_t)0x07) +#define SDIO_CLKDIV16 ((uint32_t)0x08) +#define SDIO_CLKDIV18 ((uint32_t)0x09) +#define SDIO_CLKDIV20 ((uint32_t)0x0a) +#define SDIO_CLKDIV22 ((uint32_t)0x0b) +#define SDIO_CLKDIV24 ((uint32_t)0x0c) +#define SDIO_CLKDIV26 ((uint32_t)0x0d) +#define SDIO_CLKDIV28 ((uint32_t)0x0e) +#define SDIO_CLKDIV30 ((uint32_t)0x0f) +#define SDIO_CLKDIV32 ((uint32_t)0x10) +#define SDIO_CLKDIV34 ((uint32_t)0x11) +#define SDIO_CLKDIV36 ((uint32_t)0x12) +#define SDIO_CLKDIV38 ((uint32_t)0x13) +#define SDIO_CLKDIV40 ((uint32_t)0x14) +#define SDIO_CLKDIV42 ((uint32_t)0x15) +#define SDIO_CLKDIV44 ((uint32_t)0x16) +#define SDIO_CLKDIV46 ((uint32_t)0x17) +#define SDIO_CLKDIV48 ((uint32_t)0x18) +#define SDIO_CLKDIV50 ((uint32_t)0x19) +#define SDIO_CLKDIV52 ((uint32_t)0x1a) +#define SDIO_CLKDIV54 ((uint32_t)0x1b) +#define SDIO_CLKDIV56 ((uint32_t)0x1c) +#define SDIO_CLKDIV58 ((uint32_t)0x1d) +#define SDIO_CLKDIV60 ((uint32_t)0x1e) +#define SDIO_CLKDIV62 ((uint32_t)0x1f) +#define SDIO_CLKDIV64 ((uint32_t)0x20) +#define SDIO_CLKDIV66 ((uint32_t)0x21) +#define SDIO_CLKDIV68 ((uint32_t)0x22) +#define SDIO_CLKDIV70 ((uint32_t)0x23) +#define SDIO_CLKDIV72 ((uint32_t)0x24) +#define SDIO_CLKDIV74 ((uint32_t)0x25) +#define SDIO_CLKDIV76 ((uint32_t)0x26) +#define SDIO_CLKDIV78 ((uint32_t)0x27) +#define SDIO_CLKDIV80 ((uint32_t)0x28) +#define SDIO_CLKDIV82 ((uint32_t)0x29) +#define SDIO_CLKDIV84 ((uint32_t)0x2a) +#define SDIO_CLKDIV86 ((uint32_t)0x2b) +#define SDIO_CLKDIV88 ((uint32_t)0x2c) +#define SDIO_CLKDIV90 ((uint32_t)0x2d) +#define SDIO_CLKDIV92 ((uint32_t)0x2e) +#define SDIO_CLKDIV94 ((uint32_t)0x2f) +#define SDIO_CLKDIV96 ((uint32_t)0x30) +#define SDIO_CLKDIV98 ((uint32_t)0x31) +#define SDIO_CLKDIV100 ((uint32_t)0x32) +#define SDIO_CLKDIV102 ((uint32_t)0x33) +#define SDIO_CLKDIV104 ((uint32_t)0x34) +#define SDIO_CLKDIV106 ((uint32_t)0x35) +#define SDIO_CLKDIV108 ((uint32_t)0x36) +#define SDIO_CLKDIV110 ((uint32_t)0x37) +#define SDIO_CLKDIV112 ((uint32_t)0x38) +#define SDIO_CLKDIV114 ((uint32_t)0x39) +#define SDIO_CLKDIV116 ((uint32_t)0x3a) +#define SDIO_CLKDIV118 ((uint32_t)0x3b) +#define SDIO_CLKDIV120 ((uint32_t)0x3c) +#define SDIO_CLKDIV122 ((uint32_t)0x3d) +#define SDIO_CLKDIV124 ((uint32_t)0x3e) +#define SDIO_CLKDIV126 ((uint32_t)0x3f) +#define SDIO_CLKDIV128 ((uint32_t)0x40) +#define SDIO_CLKDIV130 ((uint32_t)0x41) +#define SDIO_CLKDIV132 ((uint32_t)0x42) +#define SDIO_CLKDIV134 ((uint32_t)0x43) +#define SDIO_CLKDIV136 ((uint32_t)0x44) +#define SDIO_CLKDIV138 ((uint32_t)0x45) +#define SDIO_CLKDIV140 ((uint32_t)0x46) +#define SDIO_CLKDIV142 ((uint32_t)0x47) +#define SDIO_CLKDIV144 ((uint32_t)0x48) +#define SDIO_CLKDIV146 ((uint32_t)0x49) +#define SDIO_CLKDIV148 ((uint32_t)0x4a) +#define SDIO_CLKDIV150 ((uint32_t)0x4b) +#define SDIO_CLKDIV152 ((uint32_t)0x4c) +#define SDIO_CLKDIV154 ((uint32_t)0x4d) +#define SDIO_CLKDIV156 ((uint32_t)0x4e) +#define SDIO_CLKDIV158 ((uint32_t)0x4f) +#define SDIO_CLKDIV160 ((uint32_t)0x50) +#define SDIO_CLKDIV162 ((uint32_t)0x51) +#define SDIO_CLKDIV164 ((uint32_t)0x52) +#define SDIO_CLKDIV166 ((uint32_t)0x53) +#define SDIO_CLKDIV168 ((uint32_t)0x54) +#define SDIO_CLKDIV170 ((uint32_t)0x55) +#define SDIO_CLKDIV172 ((uint32_t)0x56) +#define SDIO_CLKDIV174 ((uint32_t)0x57) +#define SDIO_CLKDIV176 ((uint32_t)0x58) +#define SDIO_CLKDIV178 ((uint32_t)0x59) +#define SDIO_CLKDIV180 ((uint32_t)0x5a) +#define SDIO_CLKDIV182 ((uint32_t)0x5b) +#define SDIO_CLKDIV184 ((uint32_t)0x5c) +#define SDIO_CLKDIV186 ((uint32_t)0x5d) +#define SDIO_CLKDIV188 ((uint32_t)0x5e) +#define SDIO_CLKDIV190 ((uint32_t)0x5f) +#define SDIO_CLKDIV192 ((uint32_t)0x60) +#define SDIO_CLKDIV194 ((uint32_t)0x61) +#define SDIO_CLKDIV196 ((uint32_t)0x62) +#define SDIO_CLKDIV198 ((uint32_t)0x63) +#define SDIO_CLKDIV200 ((uint32_t)0x64) +#define SDIO_CLKDIV202 ((uint32_t)0x65) +#define SDIO_CLKDIV204 ((uint32_t)0x66) +#define SDIO_CLKDIV206 ((uint32_t)0x67) +#define SDIO_CLKDIV208 ((uint32_t)0x68) +#define SDIO_CLKDIV210 ((uint32_t)0x69) +#define SDIO_CLKDIV212 ((uint32_t)0x6a) +#define SDIO_CLKDIV214 ((uint32_t)0x6b) +#define SDIO_CLKDIV216 ((uint32_t)0x6c) +#define SDIO_CLKDIV218 ((uint32_t)0x6d) +#define SDIO_CLKDIV220 ((uint32_t)0x6e) +#define SDIO_CLKDIV222 ((uint32_t)0x6f) +#define SDIO_CLKDIV224 ((uint32_t)0x70) +#define SDIO_CLKDIV226 ((uint32_t)0x71) +#define SDIO_CLKDIV228 ((uint32_t)0x72) +#define SDIO_CLKDIV230 ((uint32_t)0x73) +#define SDIO_CLKDIV232 ((uint32_t)0x74) +#define SDIO_CLKDIV234 ((uint32_t)0x75) +#define SDIO_CLKDIV236 ((uint32_t)0x76) +#define SDIO_CLKDIV238 ((uint32_t)0x77) +#define SDIO_CLKDIV240 ((uint32_t)0x78) +#define SDIO_CLKDIV242 ((uint32_t)0x79) +#define SDIO_CLKDIV244 ((uint32_t)0x7a) +#define SDIO_CLKDIV246 ((uint32_t)0x7b) +#define SDIO_CLKDIV248 ((uint32_t)0x7c) +#define SDIO_CLKDIV250 ((uint32_t)0x7d) +#define SDIO_CLKDIV252 ((uint32_t)0x7e) +#define SDIO_CLKDIV254 ((uint32_t)0x7f) +#define SDIO_CLKDIV256 ((uint32_t)0x80) +#define SDIO_CLKDIV258 ((uint32_t)0x81) +#define SDIO_CLKDIV260 ((uint32_t)0x82) +#define SDIO_CLKDIV262 ((uint32_t)0x83) +#define SDIO_CLKDIV264 ((uint32_t)0x84) +#define SDIO_CLKDIV266 ((uint32_t)0x85) +#define SDIO_CLKDIV268 ((uint32_t)0x86) +#define SDIO_CLKDIV270 ((uint32_t)0x87) +#define SDIO_CLKDIV272 ((uint32_t)0x88) +#define SDIO_CLKDIV274 ((uint32_t)0x89) +#define SDIO_CLKDIV276 ((uint32_t)0x8a) +#define SDIO_CLKDIV278 ((uint32_t)0x8b) +#define SDIO_CLKDIV280 ((uint32_t)0x8c) +#define SDIO_CLKDIV282 ((uint32_t)0x8d) +#define SDIO_CLKDIV284 ((uint32_t)0x8e) +#define SDIO_CLKDIV286 ((uint32_t)0x8f) +#define SDIO_CLKDIV288 ((uint32_t)0x90) +#define SDIO_CLKDIV290 ((uint32_t)0x91) +#define SDIO_CLKDIV292 ((uint32_t)0x92) +#define SDIO_CLKDIV294 ((uint32_t)0x93) +#define SDIO_CLKDIV296 ((uint32_t)0x94) +#define SDIO_CLKDIV298 ((uint32_t)0x95) +#define SDIO_CLKDIV300 ((uint32_t)0x96) +#define SDIO_CLKDIV302 ((uint32_t)0x97) +#define SDIO_CLKDIV304 ((uint32_t)0x98) +#define SDIO_CLKDIV306 ((uint32_t)0x99) +#define SDIO_CLKDIV308 ((uint32_t)0x9a) +#define SDIO_CLKDIV310 ((uint32_t)0x9b) +#define SDIO_CLKDIV312 ((uint32_t)0x9c) +#define SDIO_CLKDIV314 ((uint32_t)0x9d) +#define SDIO_CLKDIV316 ((uint32_t)0x9e) +#define SDIO_CLKDIV318 ((uint32_t)0x9f) +#define SDIO_CLKDIV320 ((uint32_t)0xa0) +#define SDIO_CLKDIV322 ((uint32_t)0xa1) +#define SDIO_CLKDIV324 ((uint32_t)0xa2) +#define SDIO_CLKDIV326 ((uint32_t)0xa3) +#define SDIO_CLKDIV328 ((uint32_t)0xa4) +#define SDIO_CLKDIV330 ((uint32_t)0xa5) +#define SDIO_CLKDIV332 ((uint32_t)0xa6) +#define SDIO_CLKDIV334 ((uint32_t)0xa7) +#define SDIO_CLKDIV336 ((uint32_t)0xa8) +#define SDIO_CLKDIV338 ((uint32_t)0xa9) +#define SDIO_CLKDIV340 ((uint32_t)0xaa) +#define SDIO_CLKDIV342 ((uint32_t)0xab) +#define SDIO_CLKDIV344 ((uint32_t)0xac) +#define SDIO_CLKDIV346 ((uint32_t)0xad) +#define SDIO_CLKDIV348 ((uint32_t)0xae) +#define SDIO_CLKDIV350 ((uint32_t)0xaf) +#define SDIO_CLKDIV352 ((uint32_t)0xb0) +#define SDIO_CLKDIV354 ((uint32_t)0xb1) +#define SDIO_CLKDIV356 ((uint32_t)0xb2) +#define SDIO_CLKDIV358 ((uint32_t)0xb3) +#define SDIO_CLKDIV360 ((uint32_t)0xb4) +#define SDIO_CLKDIV362 ((uint32_t)0xb5) +#define SDIO_CLKDIV364 ((uint32_t)0xb6) +#define SDIO_CLKDIV366 ((uint32_t)0xb7) +#define SDIO_CLKDIV368 ((uint32_t)0xb8) +#define SDIO_CLKDIV370 ((uint32_t)0xb9) +#define SDIO_CLKDIV372 ((uint32_t)0xba) +#define SDIO_CLKDIV374 ((uint32_t)0xbb) +#define SDIO_CLKDIV376 ((uint32_t)0xbc) +#define SDIO_CLKDIV378 ((uint32_t)0xbd) +#define SDIO_CLKDIV380 ((uint32_t)0xbe) +#define SDIO_CLKDIV382 ((uint32_t)0xbf) +#define SDIO_CLKDIV384 ((uint32_t)0xc0) +#define SDIO_CLKDIV386 ((uint32_t)0xc1) +#define SDIO_CLKDIV388 ((uint32_t)0xc2) +#define SDIO_CLKDIV390 ((uint32_t)0xc3) +#define SDIO_CLKDIV392 ((uint32_t)0xc4) +#define SDIO_CLKDIV394 ((uint32_t)0xc5) +#define SDIO_CLKDIV396 ((uint32_t)0xc6) +#define SDIO_CLKDIV398 ((uint32_t)0xc7) +#define SDIO_CLKDIV400 ((uint32_t)0xc8) +#define SDIO_CLKDIV402 ((uint32_t)0xc9) +#define SDIO_CLKDIV404 ((uint32_t)0xca) +#define SDIO_CLKDIV406 ((uint32_t)0xcb) +#define SDIO_CLKDIV408 ((uint32_t)0xcc) +#define SDIO_CLKDIV410 ((uint32_t)0xcd) +#define SDIO_CLKDIV412 ((uint32_t)0xce) +#define SDIO_CLKDIV414 ((uint32_t)0xcf) +#define SDIO_CLKDIV416 ((uint32_t)0xd0) +#define SDIO_CLKDIV418 ((uint32_t)0xd1) +#define SDIO_CLKDIV420 ((uint32_t)0xd2) +#define SDIO_CLKDIV422 ((uint32_t)0xd3) +#define SDIO_CLKDIV424 ((uint32_t)0xd4) +#define SDIO_CLKDIV426 ((uint32_t)0xd5) +#define SDIO_CLKDIV428 ((uint32_t)0xd6) +#define SDIO_CLKDIV430 ((uint32_t)0xd7) +#define SDIO_CLKDIV432 ((uint32_t)0xd8) +#define SDIO_CLKDIV434 ((uint32_t)0xd9) +#define SDIO_CLKDIV436 ((uint32_t)0xda) +#define SDIO_CLKDIV438 ((uint32_t)0xdb) +#define SDIO_CLKDIV440 ((uint32_t)0xdc) +#define SDIO_CLKDIV442 ((uint32_t)0xdd) +#define SDIO_CLKDIV444 ((uint32_t)0xde) +#define SDIO_CLKDIV446 ((uint32_t)0xdf) +#define SDIO_CLKDIV448 ((uint32_t)0xe0) +#define SDIO_CLKDIV450 ((uint32_t)0xe1) +#define SDIO_CLKDIV452 ((uint32_t)0xe2) +#define SDIO_CLKDIV454 ((uint32_t)0xe3) +#define SDIO_CLKDIV456 ((uint32_t)0xe4) +#define SDIO_CLKDIV458 ((uint32_t)0xe5) +#define SDIO_CLKDIV460 ((uint32_t)0xe6) +#define SDIO_CLKDIV462 ((uint32_t)0xe7) +#define SDIO_CLKDIV464 ((uint32_t)0xe8) +#define SDIO_CLKDIV466 ((uint32_t)0xe9) +#define SDIO_CLKDIV468 ((uint32_t)0xea) +#define SDIO_CLKDIV470 ((uint32_t)0xeb) +#define SDIO_CLKDIV472 ((uint32_t)0xec) +#define SDIO_CLKDIV474 ((uint32_t)0xed) +#define SDIO_CLKDIV476 ((uint32_t)0xee) +#define SDIO_CLKDIV478 ((uint32_t)0xef) +#define SDIO_CLKDIV480 ((uint32_t)0xf0) +#define SDIO_CLKDIV482 ((uint32_t)0xf1) +#define SDIO_CLKDIV484 ((uint32_t)0xf2) +#define SDIO_CLKDIV486 ((uint32_t)0xf3) +#define SDIO_CLKDIV488 ((uint32_t)0xf4) +#define SDIO_CLKDIV490 ((uint32_t)0xf5) +#define SDIO_CLKDIV492 ((uint32_t)0xf6) +#define SDIO_CLKDIV494 ((uint32_t)0xf7) +#define SDIO_CLKDIV496 ((uint32_t)0xf8) +#define SDIO_CLKDIV498 ((uint32_t)0xf9) +#define SDIO_CLKDIV500 ((uint32_t)0xfa) +#define SDIO_CLKDIV502 ((uint32_t)0xfb) +#define SDIO_CLKDIV504 ((uint32_t)0xfc) +#define SDIO_CLKDIV506 ((uint32_t)0xfd) +#define SDIO_CLKDIV508 ((uint32_t)0xfe) +#define SDIO_CLKDIV510 ((uint32_t)0xff) + +#define IS_SDIO_CLKDIV(CLKDIV) (((CLKDIV) == SDIO_CLKDIV1 ) || \ + ((CLKDIV) == SDIO_CLKDIV2 ) || \ + ((CLKDIV) == SDIO_CLKDIV4 ) || \ + ((CLKDIV) == SDIO_CLKDIV6 ) || \ + ((CLKDIV) == SDIO_CLKDIV8 ) || \ + ((CLKDIV) == SDIO_CLKDIV10 ) || \ + ((CLKDIV) == SDIO_CLKDIV12 ) || \ + ((CLKDIV) == SDIO_CLKDIV14 ) || \ + ((CLKDIV) == SDIO_CLKDIV16 ) || \ + ((CLKDIV) == SDIO_CLKDIV18 ) || \ + ((CLKDIV) == SDIO_CLKDIV20 ) || \ + ((CLKDIV) == SDIO_CLKDIV22 ) || \ + ((CLKDIV) == SDIO_CLKDIV24 ) || \ + ((CLKDIV) == SDIO_CLKDIV26 ) || \ + ((CLKDIV) == SDIO_CLKDIV28 ) || \ + ((CLKDIV) == SDIO_CLKDIV30 ) || \ + ((CLKDIV) == SDIO_CLKDIV32 ) || \ + ((CLKDIV) == SDIO_CLKDIV34 ) || \ + ((CLKDIV) == SDIO_CLKDIV36 ) || \ + ((CLKDIV) == SDIO_CLKDIV38 ) || \ + ((CLKDIV) == SDIO_CLKDIV40 ) || \ + ((CLKDIV) == SDIO_CLKDIV42 ) || \ + ((CLKDIV) == SDIO_CLKDIV44 ) || \ + ((CLKDIV) == SDIO_CLKDIV46 ) || \ + ((CLKDIV) == SDIO_CLKDIV48 ) || \ + ((CLKDIV) == SDIO_CLKDIV50 ) || \ + ((CLKDIV) == SDIO_CLKDIV52 ) || \ + ((CLKDIV) == SDIO_CLKDIV54 ) || \ + ((CLKDIV) == SDIO_CLKDIV56 ) || \ + ((CLKDIV) == SDIO_CLKDIV58 ) || \ + ((CLKDIV) == SDIO_CLKDIV60 ) || \ + ((CLKDIV) == SDIO_CLKDIV62 ) || \ + ((CLKDIV) == SDIO_CLKDIV64 ) || \ + ((CLKDIV) == SDIO_CLKDIV66 ) || \ + ((CLKDIV) == SDIO_CLKDIV68 ) || \ + ((CLKDIV) == SDIO_CLKDIV70 ) || \ + ((CLKDIV) == SDIO_CLKDIV72 ) || \ + ((CLKDIV) == SDIO_CLKDIV74 ) || \ + ((CLKDIV) == SDIO_CLKDIV76 ) || \ + ((CLKDIV) == SDIO_CLKDIV78 ) || \ + ((CLKDIV) == SDIO_CLKDIV80 ) || \ + ((CLKDIV) == SDIO_CLKDIV82 ) || \ + ((CLKDIV) == SDIO_CLKDIV84 ) || \ + ((CLKDIV) == SDIO_CLKDIV86 ) || \ + ((CLKDIV) == SDIO_CLKDIV88 ) || \ + ((CLKDIV) == SDIO_CLKDIV90 ) || \ + ((CLKDIV) == SDIO_CLKDIV92 ) || \ + ((CLKDIV) == SDIO_CLKDIV94 ) || \ + ((CLKDIV) == SDIO_CLKDIV96 ) || \ + ((CLKDIV) == SDIO_CLKDIV98 ) || \ + ((CLKDIV) == SDIO_CLKDIV100) || \ + ((CLKDIV) == SDIO_CLKDIV102) || \ + ((CLKDIV) == SDIO_CLKDIV104) || \ + ((CLKDIV) == SDIO_CLKDIV106) || \ + ((CLKDIV) == SDIO_CLKDIV108) || \ + ((CLKDIV) == SDIO_CLKDIV110) || \ + ((CLKDIV) == SDIO_CLKDIV112) || \ + ((CLKDIV) == SDIO_CLKDIV114) || \ + ((CLKDIV) == SDIO_CLKDIV116) || \ + ((CLKDIV) == SDIO_CLKDIV118) || \ + ((CLKDIV) == SDIO_CLKDIV120) || \ + ((CLKDIV) == SDIO_CLKDIV122) || \ + ((CLKDIV) == SDIO_CLKDIV124) || \ + ((CLKDIV) == SDIO_CLKDIV126) || \ + ((CLKDIV) == SDIO_CLKDIV128) || \ + ((CLKDIV) == SDIO_CLKDIV130) || \ + ((CLKDIV) == SDIO_CLKDIV132) || \ + ((CLKDIV) == SDIO_CLKDIV134) || \ + ((CLKDIV) == SDIO_CLKDIV136) || \ + ((CLKDIV) == SDIO_CLKDIV138) || \ + ((CLKDIV) == SDIO_CLKDIV140) || \ + ((CLKDIV) == SDIO_CLKDIV142) || \ + ((CLKDIV) == SDIO_CLKDIV144) || \ + ((CLKDIV) == SDIO_CLKDIV146) || \ + ((CLKDIV) == SDIO_CLKDIV148) || \ + ((CLKDIV) == SDIO_CLKDIV150) || \ + ((CLKDIV) == SDIO_CLKDIV152) || \ + ((CLKDIV) == SDIO_CLKDIV154) || \ + ((CLKDIV) == SDIO_CLKDIV156) || \ + ((CLKDIV) == SDIO_CLKDIV158) || \ + ((CLKDIV) == SDIO_CLKDIV160) || \ + ((CLKDIV) == SDIO_CLKDIV162) || \ + ((CLKDIV) == SDIO_CLKDIV164) || \ + ((CLKDIV) == SDIO_CLKDIV166) || \ + ((CLKDIV) == SDIO_CLKDIV168) || \ + ((CLKDIV) == SDIO_CLKDIV170) || \ + ((CLKDIV) == SDIO_CLKDIV172) || \ + ((CLKDIV) == SDIO_CLKDIV174) || \ + ((CLKDIV) == SDIO_CLKDIV176) || \ + ((CLKDIV) == SDIO_CLKDIV178) || \ + ((CLKDIV) == SDIO_CLKDIV180) || \ + ((CLKDIV) == SDIO_CLKDIV182) || \ + ((CLKDIV) == SDIO_CLKDIV184) || \ + ((CLKDIV) == SDIO_CLKDIV186) || \ + ((CLKDIV) == SDIO_CLKDIV188) || \ + ((CLKDIV) == SDIO_CLKDIV190) || \ + ((CLKDIV) == SDIO_CLKDIV192) || \ + ((CLKDIV) == SDIO_CLKDIV194) || \ + ((CLKDIV) == SDIO_CLKDIV196) || \ + ((CLKDIV) == SDIO_CLKDIV198) || \ + ((CLKDIV) == SDIO_CLKDIV200) || \ + ((CLKDIV) == SDIO_CLKDIV202) || \ + ((CLKDIV) == SDIO_CLKDIV204) || \ + ((CLKDIV) == SDIO_CLKDIV206) || \ + ((CLKDIV) == SDIO_CLKDIV208) || \ + ((CLKDIV) == SDIO_CLKDIV210) || \ + ((CLKDIV) == SDIO_CLKDIV212) || \ + ((CLKDIV) == SDIO_CLKDIV214) || \ + ((CLKDIV) == SDIO_CLKDIV216) || \ + ((CLKDIV) == SDIO_CLKDIV218) || \ + ((CLKDIV) == SDIO_CLKDIV220) || \ + ((CLKDIV) == SDIO_CLKDIV222) || \ + ((CLKDIV) == SDIO_CLKDIV224) || \ + ((CLKDIV) == SDIO_CLKDIV226) || \ + ((CLKDIV) == SDIO_CLKDIV228) || \ + ((CLKDIV) == SDIO_CLKDIV230) || \ + ((CLKDIV) == SDIO_CLKDIV232) || \ + ((CLKDIV) == SDIO_CLKDIV234) || \ + ((CLKDIV) == SDIO_CLKDIV236) || \ + ((CLKDIV) == SDIO_CLKDIV238) || \ + ((CLKDIV) == SDIO_CLKDIV240) || \ + ((CLKDIV) == SDIO_CLKDIV242) || \ + ((CLKDIV) == SDIO_CLKDIV244) || \ + ((CLKDIV) == SDIO_CLKDIV246) || \ + ((CLKDIV) == SDIO_CLKDIV248) || \ + ((CLKDIV) == SDIO_CLKDIV250) || \ + ((CLKDIV) == SDIO_CLKDIV252) || \ + ((CLKDIV) == SDIO_CLKDIV254) || \ + ((CLKDIV) == SDIO_CLKDIV256) || \ + ((CLKDIV) == SDIO_CLKDIV258) || \ + ((CLKDIV) == SDIO_CLKDIV260) || \ + ((CLKDIV) == SDIO_CLKDIV262) || \ + ((CLKDIV) == SDIO_CLKDIV264) || \ + ((CLKDIV) == SDIO_CLKDIV266) || \ + ((CLKDIV) == SDIO_CLKDIV268) || \ + ((CLKDIV) == SDIO_CLKDIV270) || \ + ((CLKDIV) == SDIO_CLKDIV272) || \ + ((CLKDIV) == SDIO_CLKDIV274) || \ + ((CLKDIV) == SDIO_CLKDIV276) || \ + ((CLKDIV) == SDIO_CLKDIV278) || \ + ((CLKDIV) == SDIO_CLKDIV280) || \ + ((CLKDIV) == SDIO_CLKDIV282) || \ + ((CLKDIV) == SDIO_CLKDIV284) || \ + ((CLKDIV) == SDIO_CLKDIV286) || \ + ((CLKDIV) == SDIO_CLKDIV288) || \ + ((CLKDIV) == SDIO_CLKDIV290) || \ + ((CLKDIV) == SDIO_CLKDIV282) || \ + ((CLKDIV) == SDIO_CLKDIV294) || \ + ((CLKDIV) == SDIO_CLKDIV296) || \ + ((CLKDIV) == SDIO_CLKDIV298) || \ + ((CLKDIV) == SDIO_CLKDIV300) || \ + ((CLKDIV) == SDIO_CLKDIV302) || \ + ((CLKDIV) == SDIO_CLKDIV304) || \ + ((CLKDIV) == SDIO_CLKDIV306) || \ + ((CLKDIV) == SDIO_CLKDIV308) || \ + ((CLKDIV) == SDIO_CLKDIV310) || \ + ((CLKDIV) == SDIO_CLKDIV312) || \ + ((CLKDIV) == SDIO_CLKDIV314) || \ + ((CLKDIV) == SDIO_CLKDIV316) || \ + ((CLKDIV) == SDIO_CLKDIV318) || \ + ((CLKDIV) == SDIO_CLKDIV320) || \ + ((CLKDIV) == SDIO_CLKDIV322) || \ + ((CLKDIV) == SDIO_CLKDIV324) || \ + ((CLKDIV) == SDIO_CLKDIV326) || \ + ((CLKDIV) == SDIO_CLKDIV328) || \ + ((CLKDIV) == SDIO_CLKDIV330) || \ + ((CLKDIV) == SDIO_CLKDIV332) || \ + ((CLKDIV) == SDIO_CLKDIV334) || \ + ((CLKDIV) == SDIO_CLKDIV336) || \ + ((CLKDIV) == SDIO_CLKDIV338) || \ + ((CLKDIV) == SDIO_CLKDIV340) || \ + ((CLKDIV) == SDIO_CLKDIV342) || \ + ((CLKDIV) == SDIO_CLKDIV344) || \ + ((CLKDIV) == SDIO_CLKDIV346) || \ + ((CLKDIV) == SDIO_CLKDIV348) || \ + ((CLKDIV) == SDIO_CLKDIV350) || \ + ((CLKDIV) == SDIO_CLKDIV352) || \ + ((CLKDIV) == SDIO_CLKDIV354) || \ + ((CLKDIV) == SDIO_CLKDIV356) || \ + ((CLKDIV) == SDIO_CLKDIV358) || \ + ((CLKDIV) == SDIO_CLKDIV360) || \ + ((CLKDIV) == SDIO_CLKDIV362) || \ + ((CLKDIV) == SDIO_CLKDIV364) || \ + ((CLKDIV) == SDIO_CLKDIV366) || \ + ((CLKDIV) == SDIO_CLKDIV368) || \ + ((CLKDIV) == SDIO_CLKDIV370) || \ + ((CLKDIV) == SDIO_CLKDIV372) || \ + ((CLKDIV) == SDIO_CLKDIV374) || \ + ((CLKDIV) == SDIO_CLKDIV376) || \ + ((CLKDIV) == SDIO_CLKDIV378) || \ + ((CLKDIV) == SDIO_CLKDIV380) || \ + ((CLKDIV) == SDIO_CLKDIV382) || \ + ((CLKDIV) == SDIO_CLKDIV384) || \ + ((CLKDIV) == SDIO_CLKDIV386) || \ + ((CLKDIV) == SDIO_CLKDIV388) || \ + ((CLKDIV) == SDIO_CLKDIV390) || \ + ((CLKDIV) == SDIO_CLKDIV392) || \ + ((CLKDIV) == SDIO_CLKDIV394) || \ + ((CLKDIV) == SDIO_CLKDIV396) || \ + ((CLKDIV) == SDIO_CLKDIV398) || \ + ((CLKDIV) == SDIO_CLKDIV400) || \ + ((CLKDIV) == SDIO_CLKDIV402) || \ + ((CLKDIV) == SDIO_CLKDIV404) || \ + ((CLKDIV) == SDIO_CLKDIV406) || \ + ((CLKDIV) == SDIO_CLKDIV408) || \ + ((CLKDIV) == SDIO_CLKDIV410) || \ + ((CLKDIV) == SDIO_CLKDIV412) || \ + ((CLKDIV) == SDIO_CLKDIV414) || \ + ((CLKDIV) == SDIO_CLKDIV416) || \ + ((CLKDIV) == SDIO_CLKDIV418) || \ + ((CLKDIV) == SDIO_CLKDIV420) || \ + ((CLKDIV) == SDIO_CLKDIV422) || \ + ((CLKDIV) == SDIO_CLKDIV424) || \ + ((CLKDIV) == SDIO_CLKDIV426) || \ + ((CLKDIV) == SDIO_CLKDIV428) || \ + ((CLKDIV) == SDIO_CLKDIV430) || \ + ((CLKDIV) == SDIO_CLKDIV432) || \ + ((CLKDIV) == SDIO_CLKDIV434) || \ + ((CLKDIV) == SDIO_CLKDIV436) || \ + ((CLKDIV) == SDIO_CLKDIV438) || \ + ((CLKDIV) == SDIO_CLKDIV440) || \ + ((CLKDIV) == SDIO_CLKDIV442) || \ + ((CLKDIV) == SDIO_CLKDIV444) || \ + ((CLKDIV) == SDIO_CLKDIV446) || \ + ((CLKDIV) == SDIO_CLKDIV448) || \ + ((CLKDIV) == SDIO_CLKDIV450) || \ + ((CLKDIV) == SDIO_CLKDIV452) || \ + ((CLKDIV) == SDIO_CLKDIV454) || \ + ((CLKDIV) == SDIO_CLKDIV456) || \ + ((CLKDIV) == SDIO_CLKDIV458) || \ + ((CLKDIV) == SDIO_CLKDIV460) || \ + ((CLKDIV) == SDIO_CLKDIV462) || \ + ((CLKDIV) == SDIO_CLKDIV464) || \ + ((CLKDIV) == SDIO_CLKDIV466) || \ + ((CLKDIV) == SDIO_CLKDIV468) || \ + ((CLKDIV) == SDIO_CLKDIV470) || \ + ((CLKDIV) == SDIO_CLKDIV472) || \ + ((CLKDIV) == SDIO_CLKDIV474) || \ + ((CLKDIV) == SDIO_CLKDIV476) || \ + ((CLKDIV) == SDIO_CLKDIV478) || \ + ((CLKDIV) == SDIO_CLKDIV480) || \ + ((CLKDIV) == SDIO_CLKDIV482) || \ + ((CLKDIV) == SDIO_CLKDIV484) || \ + ((CLKDIV) == SDIO_CLKDIV486) || \ + ((CLKDIV) == SDIO_CLKDIV488) || \ + ((CLKDIV) == SDIO_CLKDIV490) || \ + ((CLKDIV) == SDIO_CLKDIV492) || \ + ((CLKDIV) == SDIO_CLKDIV494) || \ + ((CLKDIV) == SDIO_CLKDIV496) || \ + ((CLKDIV) == SDIO_CLKDIV498) || \ + ((CLKDIV) == SDIO_CLKDIV500) || \ + ((CLKDIV) == SDIO_CLKDIV502) || \ + ((CLKDIV) == SDIO_CLKDIV504) || \ + ((CLKDIV) == SDIO_CLKDIV506) || \ + ((CLKDIV) == SDIO_CLKDIV508) || \ + ((CLKDIV) == SDIO_CLKDIV510)) + + +/** @defgroup SDIO_CLKENA_Register **/ +/** @defgroup SDIO_CCLK_ENABLE + * @{ + */ +#define SDIO_CCLK_ENABLE_DISABLE ((uint32_t)0x00) +#define SDIO_CCLK_ENABLE_ENABLE SDIO_CLKENA_CCLK_ENABLE_0 + +#define IS_SDIO_CCLK_ENABLE(ENABLE) (((ENABLE) == SDIO_CCLK_ENABLE_DISABLE) || \ + ((ENABLE) == SDIO_CCLK_ENABLE_ENABLE)) + + +/** @defgroup SDIO_TMOUT_Register **/ +/** @defgroup SDIO_response_timeout & SDIO_data_timeout + * @{ + */ +#define IS_SDIO_RESPONSE_TIMEOUT ((uint32_t)0x00000040) +#define IS_SDIO_DATA_TIMEOUT ((uint32_t)0xffffff00) +#define IS_SDIO_TIMEOUT(TIMEOUT) \ + ( \ + ((TIMEOUT) == SDIO_RESPONSE_TIMEOUT ) || \ + ((TIMEOUT) == SDIO_DATA_TIMEOUT ) || \ + ) + + +/** @defgroup SDIO_CTYPE_Register **/ +/** @defgroup SDIO_Card_Width + * @{ + */ +#define SDIO_CARD_WIDE_1B ((uint32_t)0x00) +#define SDIO_CARD_WIDE_4B SDIO_CTYPE_CARD0_WIDTH2 +#define SDIO_CARD_WIDE_8B SDIO_CTYPE_CARD0_WIDTH1 + +#define IS_SDIO_CARD_WIDE(WIDE) (((WIDE) == SDIO_CARD_WIDE_1B) || \ + ((WIDE) == SDIO_CARD_WIDE_4B) || \ + ((WIDE) == SDIO_CARD_WIDE_8B)) + + +/** @defgroup SDIO_BLKSIZ_Register **/ +/** @defgroup SDIO_Data_Block_Size Data Block Size + * @{ + */ +#define SDIO_DATABLOCK_SIZE_1B ((uint32_t)0x00000001) +#define SDIO_DATABLOCK_SIZE_2B ((uint32_t)0x00000002) +#define SDIO_DATABLOCK_SIZE_4B ((uint32_t)0x00000004) +#define SDIO_DATABLOCK_SIZE_8B ((uint32_t)0x00000008) +#define SDIO_DATABLOCK_SIZE_16B ((uint32_t)0x00000010) +#define SDIO_DATABLOCK_SIZE_32B ((uint32_t)0x00000020) +#define SDIO_DATABLOCK_SIZE_64B ((uint32_t)0x00000040) +#define SDIO_DATABLOCK_SIZE_128B ((uint32_t)0x00000080) +#define SDIO_DATABLOCK_SIZE_256B ((uint32_t)0x00000100) +#define SDIO_DATABLOCK_SIZE_512B ((uint32_t)0x00000200) + +#define IS_SDIO_BLOCK_SIZE(SIZE) (((SIZE) == SDIO_DATABLOCK_SIZE_1B) || \ + ((SIZE) == SDIO_DATABLOCK_SIZE_2B) || \ + ((SIZE) == SDIO_DATABLOCK_SIZE_4B) || \ + ((SIZE) == SDIO_DATABLOCK_SIZE_8B) || \ + ((SIZE) == SDIO_DATABLOCK_SIZE_16B) || \ + ((SIZE) == SDIO_DATABLOCK_SIZE_32B) || \ + ((SIZE) == SDIO_DATABLOCK_SIZE_64B) || \ + ((SIZE) == SDIO_DATABLOCK_SIZE_128B) || \ + ((SIZE) == SDIO_DATABLOCK_SIZE_256B) || \ + ((SIZE) == SDIO_DATABLOCK_SIZE_512B)) + + +/** @defgroup SDIO_BYTCCNT_Register **/ +/** @defgroup SDIO_Data_Byte_Count + * @{ + */ +#define IS_SDIO_DATA_BYTE_COUNT(COUNT) ((COUNT) <= 0xFFFFFFFFU) + + +/** @defgroup SDIO_INTMASK_Register **/ +/** @defgroup SDIO_Interrupt_Mask_sources Interrupt Sources Mask + * @{ + */ +#define SDIO_IT_MASK_CARDDETECT SDIO_INTMASK_CD_INT_MASK +#define SDIO_IT_MASK_RE SDIO_INTMASK_RE_INT_MASK +#define SDIO_IT_MASK_CMDDONE SDIO_INTMASK_CMD_INT_MASK +#define SDIO_IT_MASK_DTO SDIO_INTMASK_DTO_INT_MASK +#define SDIO_IT_MASK_TXDR SDIO_INTMASK_TXDR_INT_MASK +#define SDIO_IT_MASK_RXDR SDIO_INTMASK_RXDR_INT_MASK +#define SDIO_IT_MASK_RCRC SDIO_INTMASK_RCRC_INT_MASK +#define SDIO_IT_MASK_DCRC SDIO_INTMASK_DCRC_INT_MASK +#define SDIO_IT_MASK_RTO SDIO_INTMASK_RTO_INT_MASK +#define SDIO_IT_MASK_DRTO SDIO_INTMASK_DRTO_INT_MASK +#define SDIO_IT_MASK_HTO SDIO_INTMASK_HTO_INT_MASK +#define SDIO_IT_MASK_FRUN SDIO_INTMASK_FRUN_INT_MASK +#define SDIO_IT_MASK_HLE SDIO_INTMASK_HLE_INT_MASK +#define SDIO_IT_MASK_SBE SDIO_INTMASK_SBE_BCI_INT_MASK +#define SDIO_IT_MASK_ACD SDIO_INTMASK_ACD_INT_MASK +#define SDIO_IT_MASK_EBE SDIO_INTMASK_EBE_INT_MASK +#define SDIO_IT_MASK_SDIOIT SDIO_INTMASK_SDIO_INT_MASK_CARD0 + +#define IS_SDIO_IT_MASK(MASK) (((MASK)==SDIO_IT_MASK_CARDDETECT) || \ + ((MASK)==SDIO_IT_MASK_RE) || \ + ((MASK)==SDIO_IT_MASK_CMDDONE) || \ + ((MASK)==SDIO_IT_MASK_DTO) || \ + ((MASK)==SDIO_IT_MASK_TXDR ) || \ + ((MASK)==SDIO_IT_MASK_RXDR ) || \ + ((MASK)==SDIO_IT_MASK_RCRC ) || \ + ((MASK)==SDIO_IT_MASK_DCRC ) || \ + ((MASK)==SDIO_IT_MASK_RTO ) || \ + ((MASK)==SDIO_IT_MASK_DRTO ) || \ + ((MASK)==SDIO_IT_MASK_HTO ) || \ + ((MASK)==SDIO_IT_MASK_FRUN ) || \ + ((MASK)==SDIO_IT_MASK_HLE ) || \ + ((MASK)==SDIO_IT_MASK_SBE ) || \ + ((MASK)==SDIO_IT_MASK_ACD ) || \ + ((MASK)==SDIO_IT_MASK_EBE ) || \ + ((MASK)==SDIO_IT_MASK_SDIOIT)) + +/** @defgroup SDIO_MINTSTS_Register **/ +/** @defgroup SDIO_Interrupt_Flags + * @{ + */ +#define SDIO_IT_FLAG_CARDDETECT SDIO_MINTSTS_CARD_DETECT_INTERRUPT +#define SDIO_IT_FLAG_RE SDIO_MINTSTS_RESPONSE_ERROR_INTERRUPT +#define SDIO_IT_FLAG_CMDDONE SDIO_MINTSTS_COMMAND_DONE_INTERRUPT +#define SDIO_IT_FLAG_DTO SDIO_MINTSTS_DATA_TRANSFER_OVER_INTERRUPT +#define SDIO_IT_FLAG_TXDR SDIO_MINTSTS_TRANSMIT_RECEIVE_FIFO_DATA_INTERRUPT +#define SDIO_IT_FLAG_RXDR SDIO_MINTSTS_RECEIVE_FIFO_DATA_REQUEST_INTERRUPT +#define SDIO_IT_FLAG_RCRC SDIO_MINTSTS_RESPONSE_CRC_ERROR_INTERRUPT +#define SDIO_IT_FLAG_DCRC SDIO_MINTSTS_DATA_CRC_ERROR_INTERRUPT +#define SDIO_IT_FLAG_RTO SDIO_MINTSTS_RESPONSE_TIMEOUT_INTERRUPT +#define SDIO_IT_FLAG_DRTO SDIO_MINTSTS_DATA_READ_TIMEOUT_INTERRUPT +#define SDIO_IT_FLAG_HTO SDIO_MINTSTS_HOST_TIMEOUT_INTERRUPT +#define SDIO_IT_FLAG_FRUN SDIO_MINTSTS_FIFO_UNDER_OVER_RUN_INTERRUPT +#define SDIO_IT_FLAG_HLE SDIO_MINTSTS_HARDWARE_LOCKED_WRITE_INTERRUPT +#define SDIO_IT_FLAG_SBE SDIO_MINTSTS_BUSY_COMPLETE_INTERRUPT +#define SDIO_IT_FLAG_ACD SDIO_MINTSTS_AUTO_COMMAND_DONE_INTERRUPT +#define SDIO_IT_FLAG_EBE SDIO_MINTSTS_END_BIT_ERROR_INTERRUPT +#define SDIO_IT_FLAG_SDIOIT SDIO_MINTSTS_SDIO_INTERRUPT_CARD0 + +#define IS_SDIO_IT_FLAG(FLAG) (((FLAG)==SDIO_IT_FLAG_CARDDETECT) || \ + ((FLAG)==SDIO_IT_FLAG_RE) || \ + ((FLAG)==SDIO_IT_FLAG_CMDDONE) || \ + ((FLAG)==SDIO_IT_FLAG_DTO) || \ + ((FLAG)==SDIO_IT_FLAG_TXDR ) || \ + ((FLAG)==SDIO_IT_FLAG_RXDR ) || \ + ((FLAG)==SDIO_IT_FLAG_RCRC ) || \ + ((FLAG)==SDIO_IT_FLAG_DCRC ) || \ + ((FLAG)==SDIO_IT_FLAG_RTO ) || \ + ((FLAG)==SDIO_IT_FLAG_DRTO ) || \ + ((FLAG)==SDIO_IT_FLAG_HTO ) || \ + ((FLAG)==SDIO_IT_FLAG_FRUN ) || \ + ((FLAG)==SDIO_IT_FLAG_HLE ) || \ + ((FLAG)==SDIO_IT_FLAG_SBE ) || \ + ((FLAG)==SDIO_IT_FLAG_ACD ) || \ + ((FLAG)==SDIO_IT_FLAG_EBE ) || \ + ((FLAG)==SDIO_IT_FLAG_SDIOIT)) + + +/** @defgroup SDIO_RINTSTS_Register **/ +/** @defgroup SDIO_Interrupt_Clean + * @{ + */ +#define SDIO_IT_CLEAN_CARDDETECT SDIO_RINTSTS_CARD_DETECT_STATUS +#define SDIO_IT_CLEAN_RE SDIO_RINTSTS_RESPONSE_ERROR_STATUS +#define SDIO_IT_CLEAN_CMDDONE SDIO_RINTSTS_COMMAND_DONE_STATUS +#define SDIO_IT_CLEAN_DTO SDIO_RINTSTS_DATA_TRANSFER_OVER_STATUS +#define SDIO_IT_CLEAN_TXDR SDIO_RINTSTS_TRANSMIT_FIFO_DATA_REQUEST_STATUS +#define SDIO_IT_CLEAN_RXDR SDIO_RINTSTS_RECEIVE_FIFO_DATA_REQUEST_STATUS +#define SDIO_IT_CLEAN_RCRC SDIO_RINTSTS_RESPONSE_CRC_ERROR_STATUS +#define SDIO_IT_CLEAN_DCRC SDIO_RINTSTS_DATA_CRC_ERROR_STATUS +#define SDIO_IT_CLEAN_RTO SDIO_RINTSTS_RESPONSE_TIMEOUT_STATUS +#define SDIO_IT_CLEAN_DRTO SDIO_RINTSTS_DATA_READ_TIMEOUT_STATUS +#define SDIO_IT_CLEAN_HTO SDIO_RINTSTS_HOST_TIMEOUT_STATUS +#define SDIO_IT_CLEAN_FRUN SDIO_RINTSTS_FIFO_UNDER_OVER_RUN_STATUS +#define SDIO_IT_CLEAN_HLE SDIO_RINTSTS_HARDWARE_LOCKED_WRITE_STATUS +#define SDIO_IT_CLEAN_SBE SDIO_RINTSTS_BUSY_COMPLETE_STATUS +#define SDIO_IT_CLEAN_ACD SDIO_RINTSTS_AUTO_COMMAND_DONE_STATUS +#define SDIO_IT_CLEAN_EBE SDIO_RINTSTS_END_BIT_ERROR_STATUS +#define SDIO_IT_CLEAN_SDIOIT SDIO_RINTSTS_SDIO_INTERRUPT_CARD0 + +#define IS_SDIO_IT_CLEAN(CLEAN) (((CLEAN)==SDIO_IT_CLEAN_CARDDETECT) || \ + ((CLEAN)==SDIO_IT_CLEAN_RE) || \ + ((CLEAN)==SDIO_IT_CLEAN_CMDDONE) || \ + ((CLEAN)==SDIO_IT_CLEAN_DTO) || \ + ((CLEAN)==SDIO_IT_CLEAN_TXDR ) || \ + ((CLEAN)==SDIO_IT_CLEAN_RXDR ) || \ + ((CLEAN)==SDIO_IT_CLEAN_RCRC ) || \ + ((CLEAN)==SDIO_IT_CLEAN_DCRC ) || \ + ((CLEAN)==SDIO_IT_CLEAN_RTO ) || \ + ((CLEAN)==SDIO_IT_CLEAN_DRTO ) || \ + ((CLEAN)==SDIO_IT_CLEAN_HTO ) || \ + ((CLEAN)==SDIO_IT_CLEAN_FRUN ) || \ + ((CLEAN)==SDIO_IT_CLEAN_HLE ) || \ + ((CLEAN)==SDIO_IT_CLEAN_SBE ) || \ + ((CLEAN)==SDIO_IT_CLEAN_ACD ) || \ + ((CLEAN)==SDIO_IT_CLEAN_EBE ) || \ + ((CLEAN)==SDIO_IT_CLEAN_SDIOIT)) + + +/** @defgroup SDIO_CMDARG_Register **/ +/** @defgroup SDIO_Command_Argument + * @{ + */ +#define IS_SDIO_CMD_ARG(ARG) ((ARG) <= 0xFFFFFFFFU) + + +/** @defgroup SDIO_CMD_Register **/ +/** @defgroup SDIO_LL_CMD_START + * @{ + */ +#define SDIO_CMD_START_DISABLE ((uint32_t)0x00) +#define SDIO_CMD_START_ENABLE SDIO_CMD_START_CMD + +#define IS_SDIO_CMD_START(START) (((START) == SDIO_CMD_START_DISABLE) || \ + ((START) == SDIO_CMD_START_ENABLE)) + + +/** @defgroup SDIO_Use_hold_reg + * @{ + */ +#define SDIO_USE_HOLD_REG_DISABLE ((uint32_t)0x00) +#define SDIO_USE_HOLD_REG_ENABLE SDIO_CMD_USE_HOLD_REG + +#define IS_SDIO_USE_HOLD_REG(ENABLE) (((ENABLE) == SDIO_USE_HOLD_REG_DISABLE) || \ + ((ENABLE) == SDIO_USE_HOLD_REG_ENABLE)) + + +/** @defgroup SDIO_UPDATE_CLOCK_REGISTER_ONLY + * @{ + */ +#define SDIO_UPDATE_CLOCK_REGISTER_ONLY_DISABLE ((uint32_t)0x00) +#define SDIO_UPDATE_CLOCK_REGISTER_ONLY_ENABLE SDIO_CMD_UPDATE_CLOCK_REGISTERS_ONLY + +#define IS_SDIO_UPDATE_CLOCK_REGISTER_ONLY_ENABLE(ENABLE) (((ENABLE) == SDIO_UPDATE_CLOCK_REGISTER_ONLY_DISABLE) || \ + ((ENABLE) == SDIO_UPDATE_CLOCK_REGISTER_ONLY_ENABLE)) + +/** @defgroup SDIO_SEND_AUTO_STOP + * @{ + */ +#define SDIO_SEND_AUTO_STOP_DISABLE ((uint32_t)0x00) +#define SDIO_SEND_AUTO_STOP_ENABLE SDIO_CMD_SEND_AUTO_STOP + +#define IS_SDIO_SEND_AUTO_STOP_ENABLE(ENABLE) (((ENABLE) == SDIO_SEND_AUTO_STOP_DISABLE) || \ + ((ENABLE) == SDIO_SEND_AUTO_STOP_ENABLE)) + + +/** @defgroup SDIO_Transfer_Mode Block/stream + * @{ + */ +#define SDIO_TRANSFER_MODE_BLOCK ((uint32_t)0x00) +#define SDIO_TRANSFER_MODE_STREAM SDIO_CMD_TRANSFER_MODE + +#define IS_SDIO_TRANSFER_MODE(MODE) (((MODE) == SDIO_TRANSFER_MODE_BLOCK) || \ + ((MODE) == SDIO_TRANSFER_MODE_STREAM)) + +/** @defgroup SDIO_Transfer_Direction Read/Write + * @{ + */ +#define SDIO_TRANSFER_READ_FROM_CARD ((uint32_t)0x00) +#define SDIO_TRANSFER_WRITE_TO_CARD SDIO_CMD_READ_WRITE + +#define IS_SDIO_TRANSFER_DIR(DIR) (((DIR) == SDIO_TRANSFER_READ_FROM_CARD) || \ + ((DIR) == SDIO_TRANSFER_WRITE_TO_CARD)) + +/** @defgroup SDIO_Data_Expected + * @{ + */ +#define SDIO_DATA_EXPECTED_DISABLE ((uint32_t)0x00) +#define SDIO_DATA_EXPECTED_ENABLE SDIO_CMD_DATA_EXPECTED + +#define IS_SDIO_DATA_EXPECT(EXPECT) (((EXPECT) == SDIO_DATA_EXPECTED_DISABLE) || \ + ((EXPECT) == SDIO_DATA_EXPECTED_ENABLE)) + +/** @defgroup SDIO_Check_Response_CRC + * @{ + */ +#define SDIO_CHECK_RESPONSE_CRC_DISABLE ((uint32_t)0x00) +#define SDIO_CHECK_RESPONSE_CRC_ENABLE SDIO_CMD_CHECK_RESPONSE_CRC + +#define IS_SDIO_CHECK_RESPONSE_CRC(CRC) (((CRC) == SDIO_CHECK_RESPONSE_CRC_DISABLE) || \ + ((CRC) == SDIO_CHECK_RESPONSE_CRC_ENABLE)) + +/** @defgroup SDIO_Response_Length + * @{ + */ +#define SDIO_RESPONSE_SHORT ((uint32_t)0x00) +#define SDIO_RESPONSE_LONG SDIO_CMD_RESPONSE_LENGTH + +#define IS_SDIO_RESPONSE(RESPONSE) (((RESPONSE) == SDIO_RESPONSE_SHORT) || \ + ((RESPONSE) == SDIO_RESPONSE_LONG)) + +/** @defgroup SDIO_Response_Expect + * @{ + */ +#define SDIO_RESPONSE_EXPECT_DISABLE ((uint32_t)0x00) +#define SDIO_RESPONSE_EXPECT_ENABLE SDIO_CMD_RESPONSE_EXPECT + +#define IS_SDIO_RESPONSE_EXPECT(EXPECT) (((EXPECT) == SDIO_RESPONSE_EXPECT_DISABLE) || \ + ((EXPECT) == SDIO_RESPONSE_EXPECT_ENABLE)) + + +/** @defgroup SDIO_Command_Index Command Index + * @{ + */ +#define IS_SDIO_CMD_INDEX(INDEX) ((INDEX) < 0x40U) + + +/** @defgroup SDIO_STATUS_Register **/ +/** @defgroup SDIO_status + * @{ + */ +#define SDIO_STAT_FIFO_RX_WATERMARK SDIO_STATUS_FIFO_RX_WATERMARK +#define SDIO_STAT_FIFO_TX_WATERMARK SDIO_STATUS_FIFO_TX_WATERMARK +#define SDIO_STAT_FIFO_EMPTY SDIO_STATUS_FIFO_EMPTY +#define SDIO_STAT_FIFO_FULL SDIO_STATUS_FIFO_FULL +#define SDIO_STAT_FSM_IDLE ((uint32_t)0x00) +#define SDIO_STAT_FSM_SED_INIT_SEQ ((uint32_t)0x01) +#define SDIO_STAT_FSM_TX_CMD_START_BIT ((uint32_t)0x02) +#define SDIO_STAT_FSM_TX_CMD_TX_BIT ((uint32_t)0x03) +#define SDIO_STAT_FSM_TX_CMD_INDEX_ARG ((uint32_t)0x04) +#define SDIO_STAT_FSM_TX_CMD_CRC7 ((uint32_t)0x05) +#define SDIO_STAT_FSM_TX_CMD_END_BIT ((uint32_t)0x06) +#define SDIO_STAT_FSM_RX_RESP_START_BIT ((uint32_t)0x07) +#define SDIO_STAT_FSM_RX_RESP_IRQ ((uint32_t)0x08) +#define SDIO_STAT_FSM_RX_RESP_TX_BIT ((uint32_t)0x09) +#define SDIO_STAT_FSM_RX_RESP_CMD_IDX ((uint32_t)0x0a) +#define SDIO_STAT_FSM_RX_RESP_DATA ((uint32_t)0x0b) +#define SDIO_STAT_FSM_RX_RESP_CRC7 ((uint32_t)0x0c) +#define SDIO_STAT_FSM_RX_RESP_END_BIT ((uint32_t)0x0d) +#define SDIO_STAT_FSM_CMD_PATH_WAIT_NCC ((uint32_t)0x0e) +#define SDIO_STAT_FSM_WAIT ((uint32_t)0x0f) +#define SDIO_STAT_DATA_3_STATUS SDIO_STATUS_DATA_3_STATUS +#define SDIO_STAT_DATA_BUSY SDIO_STATUS_DATA_BUSY +#define SDIO_STAT_DATA_STATE_MC_BUSY SDIO_STATUS_DATA_STATE_MC_BUSY +#define SDIO_STAT_RESPONSE_INDEX SDIO_STATUS_RESPONSE_INDEX +#define SDIO_STAT_FIFO_COUNT SDIO_STATUS_FIFO_COUNT +#define SDIO_STAT_DMA_ACK SDIO_STATUS_DMA_ACK +#define SDIO_STAT_DMA_REQ SDIO_STATUS_DMA_REQ + +#define IS_SDIO_STATUS(STATUS) (((STATUS)==SDIO_STAT_FIFO_RX_WATERMARK ) || \ + ((STATUS)==SDIO_STAT_FIFO_TX_WATERMARK ) || \ + ((STATUS)==SDIO_STAT_FIFO_EMPTY ) || \ + ((STATUS)==SDIO_STAT_FIFO_FULL ) || \ + ((STATUS)==SDIO_STAT_FSM_IDLE ) || \ + ((STATUS)==SDIO_STAT_FSM_SED_INIT_SEQ ) || \ + ((STATUS)==SDIO_STAT_FSM_TX_CMD_START_BIT ) || \ + ((STATUS)==SDIO_STAT_FSM_TX_CMD_TX_BIT ) || \ + ((STATUS)==SDIO_STAT_FSM_TX_CMD_INDEX_ARG ) || \ + ((STATUS)==SDIO_STAT_FSM_TX_CMD_CRC7 ) || \ + ((STATUS)==SDIO_STAT_FSM_TX_CMD_END_BIT ) || \ + ((STATUS)==SDIO_STAT_FSM_RX_RESP_START_BIT) || \ + ((STATUS)==SDIO_STAT_FSM_RX_RESP_IRQ ) || \ + ((STATUS)==SDIO_STAT_FSM_RX_RESP_TX_BIT ) || \ + ((STATUS)==SDIO_STAT_FSM_RX_RESP_CMD_IDX ) || \ + ((STATUS)==SDIO_STAT_FSM_RX_RESP_DATA ) || \ + ((STATUS)==SDIO_STAT_FSM_RX_RESP_CRC7 ) || \ + ((STATUS)==SDIO_STAT_FSM_RX_RESP_END_BIT ) || \ + ((STATUS)==SDIO_STAT_FSM_CMD_PATH_WAIT_NCC) || \ + ((STATUS)==SDIO_STAT_FSM_WAIT ) || \ + ((STATUS)==SDIO_STAT_DATA_3_STATUS ) || \ + ((STATUS)==SDIO_STAT_DATA_BUSY ) || \ + ((STATUS)==SDIO_STAT_DATA_STATE_MC_BUSY ) || \ + ((STATUS)==SDIO_STAT_RESPONSE_INDEX ) || \ + ((STATUS)==SDIO_STAT_FIFO_COUNT ) || \ + ((STATUS)==SDIO_STAT_DMA_ACK ) || \ + ((STATUS)==SDIO_STAT_DMA_REQ )) + + +/** @defgroup SDIO_FIFOTH_Register **/ +/** @defgroup SDIO_RX&Tx_WMark + * @{ + */ +#define SDIO_RX_WATERMARK SDIO_FIFOTH_RX_WMark +#define SDIO_TX_WATERMARK SDIO_FIFOTH_TX_WMark + +#define IS_SDIO_FIFOTH_WATERMARK(WATERMARK) (((WATERMARK)==SDIO_RX_WATERMARK) || \ + ((WATERMARK)==SDIO_TX_WATERMARK)) + + + +/** @defgroup all of sdio registers **/ +/** @defgroup SDIO_ALL_Registers + * @{ + */ +#define SDIO_CTRL ((uint8_t)0x00) +#define SDIO_PWREN ((uint8_t)0x04) +#define SDIO_CLKDIV ((uint8_t)0x08) +#define SDIO_CLKSRC ((uint8_t)0x0C) +#define SDIO_CLKENA ((uint8_t)0x10) +#define SDIO_TMOUT ((uint8_t)0x14) +#define SDIO_CTYPE ((uint8_t)0x18) +#define SDIO_BLKSIZ ((uint8_t)0x1C) +#define SDIO_BYTCNT ((uint8_t)0x20) +#define SDIO_INTMASK ((uint8_t)0x24) +#define SDIO_CMDARG ((uint8_t)0x28) +#define SDIO_CMD ((uint8_t)0x2C) +#define SDIO_RESP0 ((uint8_t)0x30) +#define SDIO_RESP1 ((uint8_t)0x34) +#define SDIO_RESP2 ((uint8_t)0x38) +#define SDIO_RESP3 ((uint8_t)0x3C) +#define SDIO_MINTSTS ((uint8_t)0x40) +#define SDIO_RINTSTS ((uint8_t)0x44) +#define SDIO_STATUS ((uint8_t)0x48) +#define SDIO_FIFOTH ((uint8_t)0x4C) + +#define IS_SDIO_REGISTER(REGISTER) (((REGISTER) == SDIO_CTRL) || \ + ((REGISTER) == SDIO_PWREN) || \ + ((REGISTER) == SDIO_CLKDIV) || \ + ((REGISTER) == SDIO_CLKSRC) || \ + ((REGISTER) == SDIO_CLKENA) || \ + ((REGISTER) == SDIO_TMOUT) || \ + ((REGISTER) == SDIO_CTYPE) || \ + ((REGISTER) == SDIO_BLKSIZ) || \ + ((REGISTER) == SDIO_BYTCNT) || \ + ((REGISTER) == SDIO_INTMASK) || \ + ((REGISTER) == SDIO_CMDARG) || \ + ((REGISTER) == SDIO_CMD) || \ + ((REGISTER) == SDIO_RESP0) || \ + ((REGISTER) == SDIO_RESP1) || \ + ((REGISTER) == SDIO_RESP2) || \ + ((REGISTER) == SDIO_RESP3) || \ + ((REGISTER) == SDIO_MINTSTS) || \ + ((REGISTER) == SDIO_RINTSTS) || \ + ((REGISTER) == SDIO_STATUS) || \ + ((REGISTER) == SDIO_FIFOTH)) + + +/******************************************************************************************/ +/** + * @brief SDMMC Commands Index + */ +#define SDMMC_CMD_GO_IDLE_STATE 0U /*!< Resets the SD memory card. */ +#define SDMMC_CMD_SEND_OP_COND 1U /*!< Sends host capacity support information and activates the card's initialization process. */ +#define SDMMC_CMD_ALL_SEND_CID 2U /*!< Asks any card connected to the host to send the CID numbers on the CMD line. */ +#define SDMMC_CMD_SET_REL_ADDR 3U /*!< Asks the card to publish a new relative address (RCA). */ +#define SDMMC_CMD_SET_DSR 4U /*!< Programs the DSR of all cards. */ +#define SDMMC_CMD_SDMMC_SEN_OP_COND 5U /*!< Sends host capacity support information (HCS) and asks the accessed card to send its + operating condition register (OCR) content in the response on the CMD line. */ +#define SDMMC_CMD_HS_SWITCH 6U /*!< Checks switchable function (mode 0) and switch card function (mode 1). */ +#define SDMMC_CMD_SEL_DESEL_CARD 7U /*!< Selects the card by its own relative address and gets deselected by any other address */ +#define SDMMC_CMD_HS_SEND_EXT_CSD 8U /*!< Sends SD Memory Card interface condition, which includes host supply voltage information + and asks the card whether card supports voltage. */ +#define SDMMC_CMD_SEND_CSD 9U /*!< Addressed card sends its card specific data (CSD) on the CMD line. */ +#define SDMMC_CMD_SEND_CID 10U /*!< Addressed card sends its card identification (CID) on the CMD line. */ +#define SDMMC_CMD_READ_DAT_UNTIL_STOP 11U /*!< SD card doesn't support it. */ +#define SDMMC_CMD_STOP_TRANSMISSION 12U /*!< Forces the card to stop transmission. */ +#define SDMMC_CMD_SEND_STATUS 13U /*!< Addressed card sends its status register. */ +#define SDMMC_CMD_HS_BUSTEST_READ 14U /*!< Reserved */ +#define SDMMC_CMD_GO_INACTIVE_STATE 15U /*!< Sends an addressed card into the inactive state. */ +#define SDMMC_CMD_SET_BLOCKLEN 16U /*!< Sets the block length (in bytes for SDSC) for all following block commands + (read, write, lock). Default block length is fixed to 512 Bytes. Not effective + for SDHS and SDXC. */ +#define SDMMC_CMD_READ_SINGLE_BLOCK 17U /*!< Reads single block of size selected by SET_BLOCKLEN in case of SDSC, and a block of + fixed 512 bytes in case of SDHC and SDXC. */ +#define SDMMC_CMD_READ_MULT_BLOCK 18U /*!< Continuously transfers data blocks from card to host until interrupted by + STOP_TRANSMISSION command. */ +#define SDMMC_CMD_HS_BUSTEST_WRITE 19U /*!< 64 bytes tuning pattern is sent for SDR50 and SDR104. */ +#define SDMMC_CMD_WRITE_DAT_UNTIL_STOP 20U /*!< Speed class control command. */ +#define SDMMC_CMD_SET_BLOCK_COUNT 23U /*!< Specify block count for CMD18 and CMD25. */ +#define SDMMC_CMD_WRITE_SINGLE_BLOCK 24U /*!< Writes single block of size selected by SET_BLOCKLEN in case of SDSC, and a block of + fixed 512 bytes in case of SDHC and SDXC. */ +#define SDMMC_CMD_WRITE_MULT_BLOCK 25U /*!< Continuously writes blocks of data until a STOP_TRANSMISSION follows. */ +#define SDMMC_CMD_PROG_CID 26U /*!< Reserved for manufacturers. */ +#define SDMMC_CMD_PROG_CSD 27U /*!< Programming of the programmable bits of the CSD. */ +#define SDMMC_CMD_SET_WRITE_PROT 28U /*!< Sets the write protection bit of the addressed group. */ +#define SDMMC_CMD_CLR_WRITE_PROT 29U /*!< Clears the write protection bit of the addressed group. */ +#define SDMMC_CMD_SEND_WRITE_PROT 30U /*!< Asks the card to send the status of the write protection bits. */ +#define SDMMC_CMD_SD_ERASE_GRP_START 32U /*!< Sets the address of the first write block to be erased. (For SD card only). */ +#define SDMMC_CMD_SD_ERASE_GRP_END 33U /*!< Sets the address of the last write block of the continuous range to be erased. */ +#define SDMMC_CMD_ERASE_GRP_START 35U /*!< Sets the address of the first write block to be erased. Reserved for each command + system set by switch function command (CMD6). */ +#define SDMMC_CMD_ERASE_GRP_END 36U /*!< Sets the address of the last write block of the continuous range to be erased. + Reserved for each command system set by switch function command (CMD6). */ +#define SDMMC_CMD_ERASE 38U /*!< Reserved for SD security applications. */ +#define SDMMC_CMD_FAST_IO 39U /*!< SD card doesn't support it (Reserved). */ +#define SDMMC_CMD_GO_IRQ_STATE 40U /*!< SD card doesn't support it (Reserved). */ +#define SDMMC_CMD_LOCK_UNLOCK 42U /*!< Sets/resets the password or lock/unlock the card. The size of the data block is set by + the SET_BLOCK_LEN command. */ +#define SDMMC_CMD_APP_CMD 55U /*!< Indicates to the card that the next command is an application specific command rather + than a standard command. */ +#define SDMMC_CMD_GEN_CMD 56U /*!< Used either to transfer a data block to the card or to get a data block from the card + for general purpose/application specific commands. */ +#define SDMMC_CMD_NO_CMD 64U /*!< No command */ + +/** + * @brief Following commands are SD Card Specific commands. + * SDMMC_APP_CMD should be sent before sending these commands. + */ +#define SDMMC_CMD_APP_SD_SET_BUSWIDTH 6U /*!< (ACMD6) Defines the data bus width to be used for data transfer. The allowed data bus + widths are given in SCR register. */ +#define SDMMC_CMD_SD_APP_STATUS 13U /*!< (ACMD13) Sends the SD status. */ +#define SDMMC_CMD_SD_APP_SEND_NUM_WRITE_BLOCKS 22U /*!< (ACMD22) Sends the number of the written (without errors) write blocks. Responds with + 32bit+CRC data block. */ +#define SDMMC_CMD_SD_APP_OP_COND 41U /*!< (ACMD41) Sends host capacity support information (HCS) and asks the accessed card to + send its operating condition register (OCR) content in the response on the CMD line. */ +#define SDMMC_CMD_SD_APP_SET_CLR_CARD_DETECT 42U /*!< (ACMD42) Connect/Disconnect the 50 KOhm pull-up resistor on CD/DAT3 (pin 1) of the card */ +#define SDMMC_CMD_SD_APP_SEND_SCR 51U /*!< Reads the SD Configuration Register (SCR). */ +#define SDMMC_CMD_SDMMC_RW_DIRECT 52U /*!< For SD I/O card only, reserved for security specification. */ +#define SDMMC_CMD_SDMMC_RW_EXTENDED 53U /*!< For SD I/O card only, reserved for security specification. */ + +/** + * @brief Following commands are SD Card Specific security commands. + * SDMMC_CMD_APP_CMD should be sent before sending these commands. + */ +#define SDMMC_CMD_SD_APP_GET_MKB 43U +#define SDMMC_CMD_SD_APP_GET_MID 44U +#define SDMMC_CMD_SD_APP_SET_CER_RN1 45U +#define SDMMC_CMD_SD_APP_GET_CER_RN2 46U +#define SDMMC_CMD_SD_APP_SET_CER_RES2 47U +#define SDMMC_CMD_SD_APP_GET_CER_RES1 48U +#define SDMMC_CMD_SD_APP_SECURE_READ_MULTIPLE_BLOCK 18U +#define SDMMC_CMD_SD_APP_SECURE_WRITE_MULTIPLE_BLOCK 25U +#define SDMMC_CMD_SD_APP_SECURE_ERASE 38U +#define SDMMC_CMD_SD_APP_CHANGE_SECURE_AREA 49U +#define SDMMC_CMD_SD_APP_SECURE_WRITE_MKB 48U + + +/******************************************************************************************/ +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ +/* Configuration of the SDIO **********************************/ +void SDIO_DeInit(void); +void SDIO_odpullupConfig(uint32_t SDIO_odenable); +void SDIO_UseholdregConfig(uint32_t SDIO_Useholdregenable); +void SDIO_PowerEnableConfig(uint32_t SDIO_PowerEnable); +void SDIO_TimeOutConfig(uint32_t SDIO_TMOUTValue); +void SDIO_FifoThConfig(uint32_t SDIO_FIFOTHValue); +void SDIO_CardWidthConfig(uint32_t SDIO_CardWidth); +void SDIO_TransferModeConfig(uint32_t SDIO_TransferMode); +void SDIO_TransferDirectionConfig(uint32_t SDIO_ReadWrite); +void SDIO_DataExpectedConfig(uint32_t SDIO_DataExpected); +void SDIO_CheckResponseCRCConfig(uint32_t SDIO_CheckResponseCRC); +void SDIO_ResponseLengthConfig(uint32_t SDIO_ResponseLength); +void SDIO_ResponseLengthConfig(uint32_t SDIO_ResponseLength); +void SDIO_ResponseExpectConfig(uint32_t SDIO_ResponseExpect); +void SDIO_ChangeCardClock(uint32_t SDIO_Clkdiv); +void SDIO_SendCMD(uint32_t SDIO_CmdIndex); +void SDIO_CMDARGConfig(uint32_t SDIO_CmdArgument); +void SDIO_BlockSizeConfig(uint32_t SDIO_BlockSize); +void SDIO_ByteCountConfig(uint32_t SDIO_ByteCount); +void SDIO_ITConfig(uint32_t SDIO_IT); +FlagStatus SDIO_GetITFlag(uint32_t SDIO_FLAG); +void SDIO_ClearITFlag(uint32_t SDIO_FLAG); +uint32_t SDIO_GetFifoStatus(uint32_t SDIO_FIFOStatus); +uint32_t SDIO_GetStatus(uint32_t SDIO_Status); + +#ifdef __cplusplus +} +#endif + +#endif /* __FT32F4XX_SDIO_H */ + +/** + * @} + */ + + diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_spdif.h b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_spdif.h new file mode 100644 index 00000000000..c8be3507f15 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_spdif.h @@ -0,0 +1,151 @@ +/** + ****************************************************************************** + * @file ft32f4xx_spdif.h + * @author xcao + * @brief Header file of SPDIF module. + ****************************************************************************** + * @attention + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef FT32F4XX_SPDIF_H +#define FT32F4XX_SPDIF_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx.h" + +/** @addtogroup SPDIF + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup SPDIF_Exported_Types SPDIF Exported Types + * @{ + */ + +/** + * @brief SPDIF Init structure definition + */ + +typedef struct +{ + uint32_t StereoMode; /*!< Specifies whether the peripheral is in stereo or mono mode. + This parameter can be a value of @ref SPDIF_Stereo_Mode */ + + uint32_t ValidityBitMask; /*!< Specifies whether the frame is written or discarded. + This parameter can be a value of @ref SPDIF_V_Mask */ + + uint32_t ParityErrorMask; /*!< Specifies whether the parity error is checked. + This parameter can be a value of @ref SPDIF_PE_Mask */ + + uint16_t FifoAfullThreshold; /*!< Specifies read fifo almost full threshold. + This parameter can be a value of @ref SPDIF_FifoAF_THLD */ + + uint16_t FifoAemptyThreshold; /*!< Specifies read fifo almost empty threshold + This parameter can be a value of @ref SPDIF_FifoAE_THLD */ +} SPDIFRX_InitTypeDef; + + +/** + * @brief SPDIF handle Structure definition + */ +typedef struct +{ + SPDIF_TypeDef *Instance; /* SPDIFRX registers base address */ + + uint32_t *pRxBuffPtr; /* Pointer to SPDIF Rx transfer buffer */ + + + __IO uint16_t RxXferSize; /* SPDIF Rx transfer size */ + + __IO uint16_t RxXferCount; /* SPDIF 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) */ +} SPDIF_HandleTypeDef; + + + + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup SPDIF_Exported_Constants SPDIF Exported Constants + * @{ + */ + +/** @defgroup SPDIF_Stereo_Mode SPDIF Stereo Mode + * @{ + */ +#define SPDIF_STEREOMODE_DISABLE ((uint32_t)0x00000000U) +#define SPDIF_STEREOMODE_ENABLE ((uint32_t)SPDIF_CTRL_CHANNEL_MODE) +/** + * @} + */ + +/** @defgroup SPDIF_V_Mask SPDIF VALID Mask + * @{ + */ +#define SPDIF_VALIDITYMASK_OFF ((uint32_t)0x00000000U) +#define SPDIF_VALIDITYMASK_ON ((uint32_t)SPDIF_CTRL_VALIDITYCHECK) +/** + * @} + */ + +/** @defgroup SPDIF_PE_Mask SPDIF PARITYERROR Mask + * @{ + */ +#define SPDIF_PARITYERRORMASK_OFF ((uint32_t)0x00000000U) +#define SPDIF_PARITYERRORMASK_ON ((uint32_t)SPDIF_CTRL_PARITY_MASK) +/** + * @} + */ + + + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/** @defgroup SPDIF_Private_Macros SPDIF Private Macros + * @{ + */ + +#define IS_STEREO_MODE(MODE) (((MODE) == SPDIF_STEREOMODE_DISABLE) || \ + ((MODE) == SPDIF_STEREOMODE_ENABLE)) + +#define IS_VALIDITY_MASK(VAL) (((VAL) == SPDIF_VALIDITYMASK_OFF) || \ + ((VAL) == SPDIF_VALIDITYMASK_ON)) + +#define IS_PARITY_ERROR_MASK(VAL) (((VAL) == SPDIF_PARITYERRORMASK_OFF) || \ + ((VAL) == SPDIF_PARITYERRORMASK_ON)) +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + +/* Exported functions ---------------------------------------------------------*/ +/** @defgroup SPDIF_Exported_Functions SPDIF Exported Functions + * @{ + */ +void SPDIFRX_Init(SPDIF_HandleTypeDef *spdif, SPDIFRX_InitTypeDef *spdifrx_init); +void SPDIF_ReceiveDataFlow(SPDIF_HandleTypeDef *spdif, uint32_t *pData, uint16_t Size, + uint32_t Timeout); +void SPDIFRX_ReceiveDataFlow_IT(SPDIF_HandleTypeDef *spdif, uint32_t *pData, uint16_t Size, + uint32_t Timeout); +void SPDIF_MspInit(SPDIF_HandleTypeDef *spdif); +/** + * @} + */ + +#endif /* FT32F4XX_SPDIF_H */ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_spi.h b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_spi.h new file mode 100644 index 00000000000..9039eb5e573 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_spi.h @@ -0,0 +1,443 @@ +/** + ****************************************************************************** + * @file ft32f4xx_spi.h + * @author FMD AE + * @brief This file contains all the functions prototypes for the SPI + * firmware library. + * @version V1.0.0 + * @data 2025-03-06 + ****************************************************************************** + */ + + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __FT32F4XX_SPI_H +#define __FT32F4XX_SPI_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx.h" + + +/** @addtogroup SPI + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** + * @brief SPI Init structure definition + */ + +typedef struct +{ + uint16_t SPI_Direction; /*!< Specifies the SPI unidirectional or bidirectional data mode. + This parameter can be a value of @ref SPI_data_direction */ + + uint16_t SPI_Mode; /*!< Specifies the SPI mode (Master/Slave). + This parameter can be a value of @ref SPI_mode */ + + uint16_t SPI_DataSize; /*!< Specifies the SPI data size. + This parameter can be a value of @ref SPI_data_size */ + + uint16_t SPI_CPOL; /*!< Specifies the serial clock steady state. + This parameter can be a value of @ref SPI_Clock_Polarity */ + + uint16_t SPI_CPHA; /*!< Specifies the clock active edge for the bit capture. + This parameter can be a value of @ref SPI_Clock_Phase */ + + uint16_t SPI_NSS; /*!< Specifies whether the NSS signal is managed by + hardware (NSS pin) or by software using the SSI bit. + This parameter can be a value of @ref SPI_Slave_Select_management */ + + uint16_t SPI_BaudRatePrescaler; /*!< Specifies the Baud Rate prescaler value which will be + used to configure the transmit and receive SCK clock. + This parameter can be a value of @ref SPI_BaudRate_Prescaler + @note The communication clock is derived from the master + clock. The slave clock does not need to be set. */ + + uint16_t SPI_FirstBit; /*!< Specifies whether data transfers start from MSB or LSB bit. + This parameter can be a value of @ref SPI_MSB_LSB_transmission */ + + uint16_t SPI_CRCPolynomial; /*!< Specifies the polynomial used for the CRC calculation. */ +} SPI_InitTypeDef; + + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup SPI_Exported_Constants + * @{ + */ + +#define IS_SPI_ALL_PERIPH(PERIPH) (((PERIPH) == SPI1) || \ + ((PERIPH) == SPI2) || \ + ((PERIPH) == SPI3)) + +#define IS_SPI_1_PERIPH(PERIPH) (((PERIPH) == SPI1)) + +/** @defgroup SPI_data_direction + * @{ + */ + +#define SPI_Direction_2Lines_FullDuplex ((uint16_t)0x0000) +#define SPI_Direction_2Lines_RxOnly ((uint16_t)0x0400) +#define SPI_Direction_1Line_Rx ((uint16_t)0x8000) +#define SPI_Direction_1Line_Tx ((uint16_t)0xC000) +#define IS_SPI_DIRECTION_MODE(MODE) (((MODE) == SPI_Direction_2Lines_FullDuplex) || \ + ((MODE) == SPI_Direction_2Lines_RxOnly) || \ + ((MODE) == SPI_Direction_1Line_Rx) || \ + ((MODE) == SPI_Direction_1Line_Tx)) +/** + * @} + */ + +/** @defgroup SPI_mode + * @{ + */ + +#define SPI_Mode_Master ((uint16_t)0x0104) +#define SPI_Mode_Slave ((uint16_t)0x0000) +#define IS_SPI_MODE(MODE) (((MODE) == SPI_Mode_Master) || \ + ((MODE) == SPI_Mode_Slave)) +/** + * @} + */ + +/** @defgroup SPI_data_size + * @{ + */ + +#define SPI_DataSize_4b ((uint16_t)0x0300) +#define SPI_DataSize_5b ((uint16_t)0x0400) +#define SPI_DataSize_6b ((uint16_t)0x0500) +#define SPI_DataSize_7b ((uint16_t)0x0600) +#define SPI_DataSize_8b ((uint16_t)0x0700) +#define SPI_DataSize_9b ((uint16_t)0x0800) +#define SPI_DataSize_10b ((uint16_t)0x0900) +#define SPI_DataSize_11b ((uint16_t)0x0A00) +#define SPI_DataSize_12b ((uint16_t)0x0B00) +#define SPI_DataSize_13b ((uint16_t)0x0C00) +#define SPI_DataSize_14b ((uint16_t)0x0D00) +#define SPI_DataSize_15b ((uint16_t)0x0E00) +#define SPI_DataSize_16b ((uint16_t)0x0F00) +#define IS_SPI_DATA_SIZE(SIZE) (((SIZE) == SPI_DataSize_4b) || \ + ((SIZE) == SPI_DataSize_5b) || \ + ((SIZE) == SPI_DataSize_6b) || \ + ((SIZE) == SPI_DataSize_7b) || \ + ((SIZE) == SPI_DataSize_8b) || \ + ((SIZE) == SPI_DataSize_9b) || \ + ((SIZE) == SPI_DataSize_10b) || \ + ((SIZE) == SPI_DataSize_11b) || \ + ((SIZE) == SPI_DataSize_12b) || \ + ((SIZE) == SPI_DataSize_13b) || \ + ((SIZE) == SPI_DataSize_14b) || \ + ((SIZE) == SPI_DataSize_15b) || \ + ((SIZE) == SPI_DataSize_16b)) +/** + * @} + */ + +/** @defgroup SPI_CRC_length + * @{ + */ + +#define SPI_CRCLength_8b ((uint16_t)0x0000) +#define SPI_CRCLength_16b SPI_CR1_CRCL +#define IS_SPI_CRC_LENGTH(LENGTH) (((LENGTH) == SPI_CRCLength_8b) || \ + ((LENGTH) == SPI_CRCLength_16b)) +/** + * @} + */ + +/** @defgroup SPI_Clock_Polarity + * @{ + */ + +#define SPI_CPOL_Low ((uint16_t)0x0000) +#define SPI_CPOL_High SPI_CR1_CPOL +#define IS_SPI_CPOL(CPOL) (((CPOL) == SPI_CPOL_Low) || \ + ((CPOL) == SPI_CPOL_High)) +/** + * @} + */ + +/** @defgroup SPI_Clock_Phase + * @{ + */ + +#define SPI_CPHA_1Edge ((uint16_t)0x0000) +#define SPI_CPHA_2Edge SPI_CR1_CPHA +#define IS_SPI_CPHA(CPHA) (((CPHA) == SPI_CPHA_1Edge) || \ + ((CPHA) == SPI_CPHA_2Edge)) +/** + * @} + */ + +/** @defgroup SPI_Slave_Select_management + * @{ + */ + +#define SPI_NSS_Soft SPI_CR1_SSM +#define SPI_NSS_Hard ((uint16_t)0x0000) +#define IS_SPI_NSS(NSS) (((NSS) == SPI_NSS_Soft) || \ + ((NSS) == SPI_NSS_Hard)) +/** + * @} + */ + +/** @defgroup SPI_BaudRate_Prescaler + * @{ + */ + +#define SPI_BaudRatePrescaler_2 ((uint16_t)0x0000) +#define SPI_BaudRatePrescaler_4 ((uint16_t)0x0008) +#define SPI_BaudRatePrescaler_8 ((uint16_t)0x0010) +#define SPI_BaudRatePrescaler_16 ((uint16_t)0x0018) +#define SPI_BaudRatePrescaler_32 ((uint16_t)0x0020) +#define SPI_BaudRatePrescaler_64 ((uint16_t)0x0028) +#define SPI_BaudRatePrescaler_128 ((uint16_t)0x0030) +#define SPI_BaudRatePrescaler_256 ((uint16_t)0x0038) +#define IS_SPI_BAUDRATE_PRESCALER(PRESCALER) (((PRESCALER) == SPI_BaudRatePrescaler_2) || \ + ((PRESCALER) == SPI_BaudRatePrescaler_4) || \ + ((PRESCALER) == SPI_BaudRatePrescaler_8) || \ + ((PRESCALER) == SPI_BaudRatePrescaler_16) || \ + ((PRESCALER) == SPI_BaudRatePrescaler_32) || \ + ((PRESCALER) == SPI_BaudRatePrescaler_64) || \ + ((PRESCALER) == SPI_BaudRatePrescaler_128) || \ + ((PRESCALER) == SPI_BaudRatePrescaler_256)) +/** + * @} + */ + +/** @defgroup SPI_MSB_LSB_transmission + * @{ + */ + +#define SPI_FirstBit_MSB ((uint16_t)0x0000) +#define SPI_FirstBit_LSB SPI_CR1_LSBFIRST +#define IS_SPI_FIRST_BIT(BIT) (((BIT) == SPI_FirstBit_MSB) || \ + ((BIT) == SPI_FirstBit_LSB)) +/** + * @} + */ + +/** @defgroup SPI_FIFO_reception_threshold + * @{ + */ + +#define SPI_RxFIFOThreshold_HF ((uint16_t)0x0000) +#define SPI_RxFIFOThreshold_QF SPI_CR2_FRXTH +#define IS_SPI_RX_FIFO_THRESHOLD(THRESHOLD) (((THRESHOLD) == SPI_RxFIFOThreshold_HF) || \ + ((THRESHOLD) == SPI_RxFIFOThreshold_QF)) +/** + * @} + */ + +/** @defgroup SPI_DMA_transfer_requests + * @{ + */ + +#define SPI_DMAReq_Tx (SPI_CR2_TXDMAEN) +#define SPI_DMAReq_Rx (SPI_CR2_RXDMAEN) +#define IS_SPI_DMA_REQ(REQ) ((((REQ) & (uint16_t)0xFFFC) == 0x00) && ((REQ) != 0x00)) + +/** + * @} + */ + +/** @defgroup SPI_last_DMA_transfers + * @{ + */ + +#define SPI_LastDMATransfer_TxEvenRxEven ((uint16_t)0x0000) +#define SPI_LastDMATransfer_TxOddRxEven ((uint16_t)0x4000) +#define SPI_LastDMATransfer_TxEvenRxOdd ((uint16_t)0x2000) +#define SPI_LastDMATransfer_TxOddRxOdd ((uint16_t)0x6000) +#define IS_SPI_LAST_DMA_TRANSFER(TRANSFER) (((TRANSFER) == SPI_LastDMATransfer_TxEvenRxEven) || \ + ((TRANSFER) == SPI_LastDMATransfer_TxOddRxEven) || \ + ((TRANSFER) == SPI_LastDMATransfer_TxEvenRxOdd) || \ + ((TRANSFER) == SPI_LastDMATransfer_TxOddRxOdd)) +/** + * @} + */ +/** @defgroup SPI_NSS_internal_software_management + * @{ + */ + +#define SPI_NSSInternalSoft_Set SPI_CR1_SSI +#define SPI_NSSInternalSoft_Reset ((uint16_t)0xFEFF) +#define IS_SPI_NSS_INTERNAL(INTERNAL) (((INTERNAL) == SPI_NSSInternalSoft_Set) || \ + ((INTERNAL) == SPI_NSSInternalSoft_Reset)) +/** + * @} + */ + +/** @defgroup SPI_CRC_Transmit_Receive + * @{ + */ + +#define SPI_CRC_Tx ((uint8_t)0x00) +#define SPI_CRC_Rx ((uint8_t)0x01) +#define IS_SPI_CRC(CRC) (((CRC) == SPI_CRC_Tx) || ((CRC) == SPI_CRC_Rx)) +/** + * @} + */ + +/** @defgroup SPI_direction_transmit_receive + * @{ + */ + +#define SPI_Direction_Rx ((uint16_t)0xBFFF) +#define SPI_Direction_Tx ((uint16_t)0x4000) +#define IS_SPI_DIRECTION(DIRECTION) (((DIRECTION) == SPI_Direction_Rx) || \ + ((DIRECTION) == SPI_Direction_Tx)) +/** + * @} + */ + +/** @defgroup SPI_interrupts_definition + * @{ + */ + +#define SPI_IT_TXE ((uint8_t)0x71) +#define SPI_IT_RXNE ((uint8_t)0x60) +#define SPI_IT_ERR ((uint8_t)0x50) + +#define IS_SPI_CONFIG_IT(IT) (((IT) == SPI_IT_TXE) || \ + ((IT) == SPI_IT_RXNE) || \ + ((IT) == SPI_IT_ERR)) + +#define IT_UDR ((uint8_t)0x53) +#define SPI_IT_MODF ((uint8_t)0x55) +#define SPI_IT_OVR ((uint8_t)0x56) +#define SPI_IT_FRE ((uint8_t)0x58) + +#define IS_SPI_GET_IT(IT) (((IT) == SPI_IT_RXNE) || ((IT) == SPI_IT_TXE) || \ + ((IT) == SPI_IT_OVR) || ((IT) == SPI_IT_MODF) || \ + ((IT) == SPI_IT_FRE)|| ((IT) == IT_UDR)) +/** + * @} + */ + + +/** @defgroup SPI_transmission_fifo_status_level + * @{ + */ + +#define SPI_TransmissionFIFOStatus_Empty ((uint16_t)0x0000) +#define SPI_TransmissionFIFOStatus_1QuarterFull ((uint16_t)0x0800) +#define SPI_TransmissionFIFOStatus_HalfFull ((uint16_t)0x1000) +#define SPI_TransmissionFIFOStatus_Full ((uint16_t)0x1800) + +/** + * @} + */ + +/** @defgroup SPI_reception_fifo_status_level + * @{ + */ +#define SPI_ReceptionFIFOStatus_Empty ((uint16_t)0x0000) +#define SPI_ReceptionFIFOStatus_1QuarterFull ((uint16_t)0x0200) +#define SPI_ReceptionFIFOStatus_HalfFull ((uint16_t)0x0400) +#define SPI_ReceptionFIFOStatus_Full ((uint16_t)0x0600) + +/** + * @} + */ + + +/** @defgroup SPI_flags_definition + * @{ + */ + +#define SPI_FLAG_RXNE SPI_SR_RXNE +#define SPI_FLAG_TXE SPI_SR_TXE +#define SPI_FLAG_CRCERR SPI_SR_CRCERR +#define SPI_FLAG_MODF SPI_SR_MODF +#define SPI_FLAG_OVR SPI_SR_OVR +#define SPI_FLAG_BSY SPI_SR_BSY +#define SPI_FLAG_FRE SPI_SR_FRE + + + +#define IS_SPI_CLEAR_FLAG(FLAG) (((FLAG) == SPI_FLAG_CRCERR)) +#define IS_SPI_GET_FLAG(FLAG) (((FLAG) == SPI_FLAG_BUSY) || ((FLAG) == SPI_FLAG_OVR) || \ + ((FLAG) == SPI_FLAG_MODF) || ((FLAG) == SPI_FLAG_CRCERR) || \ + ((FLAG) == SPI_FLAG_TXE) || ((FLAG) == SPI_FLAG_RXNE)|| \ + ((FLAG) == SPI_FLAG_FRE)) +/** + * @} + */ + +/** @defgroup SPI_CRC_polynomial + * @{ + */ + +#define IS_SPI_CRC_POLYNOMIAL(POLYNOMIAL) ((POLYNOMIAL) >= 0x1) +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +/* Initialization and Configuration functions *********************************/ +void SPI_DeInit(SPI_TypeDef* SPIx); +void SPI_Init(SPI_TypeDef* SPIx, SPI_InitTypeDef* SPI_InitStruct); +void SPI_StructInit(SPI_InitTypeDef* SPI_InitStruct); +void SPI_TIModeCmd(SPI_TypeDef* SPIx, FunctionalState NewState); +void SPI_NSSPulseModeCmd(SPI_TypeDef* SPIx, FunctionalState NewState); +void SPI_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState); +void SPI_DataSizeConfig(SPI_TypeDef* SPIx, uint16_t SPI_DataSize); +void SPI_RxFIFOThresholdConfig(SPI_TypeDef* SPIx, uint16_t SPI_RxFIFOThreshold); +void SPI_BiDirectionalLineConfig(SPI_TypeDef* SPIx, uint16_t SPI_Direction); +void SPI_NSSInternalSoftwareConfig(SPI_TypeDef* SPIx, uint16_t SPI_NSSInternalSoft); +void SPI_SSOutputCmd(SPI_TypeDef* SPIx, FunctionalState NewState); + +/* Data transfers functions ***************************************************/ +void SPI_SendData8(SPI_TypeDef* SPIx, uint8_t Data); +void SPI_SendData16(SPI_TypeDef* SPIx, uint16_t Data); +uint8_t SPI_ReceiveData8(SPI_TypeDef* SPIx); +uint16_t SPI_ReceiveData16(SPI_TypeDef* SPIx); + +/* Hardware CRC Calculation functions *****************************************/ +void SPI_CRCLengthConfig(SPI_TypeDef* SPIx, uint16_t SPI_CRCLength); +void SPI_CalculateCRC(SPI_TypeDef* SPIx, FunctionalState NewState); +void SPI_TransmitCRC(SPI_TypeDef* SPIx); +uint16_t SPI_GetCRC(SPI_TypeDef* SPIx, uint8_t SPI_CRC); +uint16_t SPI_GetCRCPolynomial(SPI_TypeDef* SPIx); + +/* DMA transfers management functions *****************************************/ +void SPI_DMACmd(SPI_TypeDef* SPIx, uint16_t SPI_DMAReq, FunctionalState NewState); +void SPI_LastDMATransferCmd(SPI_TypeDef* SPIx, uint16_t SPI_LastDMATransfer); + +/* Interrupts and flags management functions **********************************/ +void SPI_ITConfig(SPI_TypeDef* SPIx, uint8_t SPI_IT, FunctionalState NewState); +uint16_t SPI_GetTransmissionFIFOStatus(SPI_TypeDef* SPIx); +uint16_t SPI_GetReceptionFIFOStatus(SPI_TypeDef* SPIx); +FlagStatus SPI_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_FLAG); +void SPI_ClearFlag(SPI_TypeDef* SPIx, uint16_t SPI_FLAG); +ITStatus SPI_GetITStatus(SPI_TypeDef* SPIx, uint8_t SPI_IT); + +#ifdef __cplusplus +} +#endif + +#endif /*__FT32F4XX_SPI_H */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_ssi.h b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_ssi.h new file mode 100644 index 00000000000..3f08728d0d4 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_ssi.h @@ -0,0 +1,625 @@ +/** + ****************************************************************************** + * @file ft32f4xx_hal_sai.h + * @author xcao + * @brief Header file of SSI module. + ****************************************************************************** + * @attention + * + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __FT32F4xx_SSI_H +#define __FT32F4xx_SSI_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx.h" + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup SSI_Exported_Types SSI Exported Types + * @{ + */ + +/** + * @brief State structures definition + */ +typedef enum +{ + SSI_STATE_RESET = 0x00U, /*!< SSI not yet initialized or disabled */ + SSI_STATE_READY = 0x01U, /*!< SSI initialized and ready for use */ + SSI_STATE_BUSY = 0x02U, /*!< SSI internal process is ongoing */ + SSI_STATE_BUSY_TX = 0x12U, /*!< Data transmission process is ongoing */ + SSI_STATE_BUSY_RX = 0x22U, /*!< Data reception process is ongoing */ + SSI_STATE_TIMEOUT = 0x03U, /*!< SSI timeout state */ + SSI_STATE_ERROR = 0x04U /*!< SSI error state */ +} SSI_StateTypeDef; + + +/** @defgroup SSI_Init_Structure_definition SSI Init Structure definition + * @brief SSI Init Structure definition + * @{ + */ +typedef struct +{ + uint32_t Mode; /*!< Specifies the SSI Mode. + This parameter can be a value of @ref SSI_MODE */ + + FunctionalState SyncMode; /*!< Configure the SSI synchronization Mode. */ + + FunctionalState TCHEN; /*!< Configure the SSI two-channel operation Mode. */ + + FunctionalState OVERSAMPLE; /*!< Configure the SSI oversample clk output. */ + + FunctionalState RFRCLKDIS; /*!< Configure the SSI receive frame clock disable + when ssi receive has been disabled */ + + FunctionalState TFRCLKDIS; /*!< Configure the SSI receive frame clock disable + when ssi transmit has been disabled */ + + uint32_t AC97FRDIV; /*!< Specifies the AC97 frame rate divider + This parameter can be a value from 0x00 - 0x3f + eg:0x01 = SSI will operate every 2 frames */ + + uint32_t AC97SLOTWIDTH; /*!< Specifies the AC97 frame slot data width + This parameter can be a value of @ref SSI_AC97SLOTWIDTH */ + + FunctionalState AC97RXTAGINFIFO; /*!< Configure the AC97 received tag data store to FIFO */ + + FunctionalState AC97VarMode; /*!< Configure the AC97 variable mode */ + +} SSI_InitTypeDef; +/** + * @} + */ + + +/** @defgroup SSI_TxInitType Structure_definition SSI Tx Init Structure definition + * @brief SSI Tx Init Structure definition + * @{ + */ +typedef struct +{ + FunctionalState FIFO0EN; /*!< Configure the SSI TX FIFO0 */ + + FunctionalState FIFO1EN; /*!< Configure the SSI TX FIFO1 */ + + uint32_t FIFO0WaterMark; /*!< Specifies the SSI FIFO WaterMark to determine the FIFO empty flag. + This parameter can be a value of @ref SSI_FIFO_WATERMARK */ + + uint32_t FIFO1WaterMark; /*!< Specifies the SSI FIFO WaterMark to determine the FIFO empty flag. + This parameter can be a value of @ref SSI_FIFO_WATERMARK */ + + uint32_t TxDataType; /*!< Specifies data transfers start from MSB or LSB bit and + data truncate high-order or truncate low-order. + This parameter can be a value of @ref SSI_TRANSDATA_TYPE */ + + uint32_t DataSize; /*!< Specifies the SSI WORD Data size. + This parameter can be a value of @ref SSI_DATA_SIZE */ + + uint32_t TxSlotMsk; /*!< Specifies the SSI frame slots mask. + This parameter can be a value of @ref SSI_SLOTMSK */ + + uint32_t AC97TxSlotEn; /*!< Specifies the SSI AC97 slots enable. + This parameter can be a value of @ref SSI_AC97SLOTEN + Only used for fixed mode */ + + uint32_t CODECCMDADDR; /*!< Specifies the SSI AC97 command addr slot + value Reference codec addr */ + + uint32_t CODECCMDDATA; /*!< Specifies the SSI AC97 data slot + value range can be 0x00000-0xfffff */ + + uint32_t FrameSyncPolarity; /*!< Specifies the SSI frame sync polarity + This parameter can be a value of @ref SSI_FRAMESYNC_POLARITY */ + + FunctionalState FrameSyncLenBit; /*!< Configure the SSI frame lenth for one-word or one-clock-bit */ + + FunctionalState FrameSyncEarly; /*!< Configure the SSI frame sync assert position */ + + FunctionalState FrameSyncFromExit; /*!< Configure the SSI frame sync from exit */ + + uint32_t FrameRate ; /*!< Specifies the SSI frame rate divide ration on the word clock. + In network mode , this ration sets the number of words of per frame. + In normal mode , specifies 5'b00000 equel to ratio of 1 provides continuous + periodic data word transfer.A bit-length frame sync must be used in this case. + this value range from 00000 to 11111 to control the nomber of words in a frame*/ + + FunctionalState TxClkFromExit; /*!< Configure the SSI Transmit Clock direction */ + + uint32_t TxClkPolarity; /*!< Specifies the SSI format of bit clock edge used to clock out data + This paramete can be a value of @ref SSI_CLOCK_POLARITY */ + + uint32_t FixedDivParam; /*!< Specifies fixed divider paramter + This parameter can be a value of @ref SSI_BITCLK_FIXDIV */ + + uint8_t CustomDivParam; /*!< Specifies custom divider parameter + This paramter from 1 to 256(PM = 0x00 to 0xFF) */ +} SSI_TxInitTypeDef; + +/** + * @} + */ + + +/** @defgroup SSI_RxInitType Structure_definition SSI Rx Init Structure definition + * @brief SSI Rx Init Structure definition + * @{ + */ +typedef struct +{ + FunctionalState FIFO0EN; /*!< Configure the SSI RX FIFO0 */ + + FunctionalState FIFO1EN; /*!< Configure the SSI RX FIFO1 */ + + uint32_t FIFO0WaterMark; /*!< Specifies the SSI FIFO WaterMark to determine the FIFO empty flag. + This parameter can be a value of @ref SSI_FIFO_WATERMARK */ + + uint32_t FIFO1WaterMark; /*!< Specifies the SSI FIFO WaterMark to determine the FIFO empty flag. + This parameter can be a value of @ref SSI_FIFO_WATERMARK */ + + uint32_t RxDataType; /*!< Specifies data transfers start from MSB or LSB bit and + data truncate high-order or truncate low-order. + This parameter can be a value of @ref SSI_TRANSDATA_TYPE */ + + uint32_t DataSize; /*!< Specifies the SSI WORD Data size. + This parameter can be a value of @ref SSI_DATA_SIZE */ + + uint32_t RxSlotMsk; /*!< Specifies the SSI frame slots mask. + This parameter can be a value of @ref SSI_SLOTMSK */ + + uint32_t FrameSyncPolarity; /*!< Specifies the SSI frame sync polarity + This parameter can be a value of @ref SSI_FRAMESYNC_POLARITY */ + + FunctionalState FrameSyncLenBit; /*!< Configure the SSI frame lenth for one-word or one-clock-bit */ + + FunctionalState FrameSyncEarly; /*!< Configure the SSI frame sync assert position */ + + FunctionalState FrameSyncFromExit; /*!< Configure the SSI frame sync from exit */ + + uint32_t FrameRate; /*!< Specifies the frame Rate */ + + FunctionalState RxClkFromExit; /*!< Configure the SSI Transmit Clock direction */ + + uint32_t RxClkPolarity; /*!< Specifies the SSI format of bit clock edge used to clock out data + This paramete can be a value of @ref SSI_CLOCK_POLARITY */ + + uint32_t FixedDivParam; /*!< Specifies fixed divider paramter + This parameter can be a value of @ref SSI_BITCLK_FIXDIV */ + + uint8_t CustomDivParam; /*!< Specifies custom divider parameter + This paramter from 1 to 256(PM = 0x00 to 0xFF) */ +} SSI_RxInitTypeDef; + +/** + * @} + */ + +/** @defgroup SSI_Handle_Structure_definition SSI Handle Structure definition + * @brief SSI handle Structure definition + * @{ + */ +typedef struct __SSI_HandleTypeDef +{ + SSI_TypeDef *Instance; /*!< SSI Blockx registers base address */ + + uint8_t *pBuffPtr0; /*!< Pointer to SSI transfer Buffer0 */ + + uint8_t *pBuffPtr1; /*!< Pointer to SSI transfer Buffer1 */ + + uint16_t XferSize0; /*!< SSI transfer size0 */ + + uint16_t XferSize1; /*!< SSI transfer size1 */ + + uint16_t XferCount0; /*!< SSI transfer counter0 */ + + uint16_t XferCount1; /*!< SSI transfer counter1 */ + + __IO SSI_StateTypeDef State; /*!< SSI communication state */ + + __IO uint32_t ErrorCode; /*!< SSI Error code */ + + +} SSI_HandleTypeDef; +/** + * @} + */ + + +/* Exported functions ---------------------------------------------------------*/ +/** @defgroup SSI_Exported_Functions SSI Exported Functions + * @{ + */ +void SSI_Init(SSI_HandleTypeDef *ssi, + SSI_InitTypeDef *ssi_init, + SSI_TxInitTypeDef *ssi_txinit, + SSI_RxInitTypeDef *ssi_rxinit); + +void SSI_Transmit(SSI_HandleTypeDef *ssi, + SSI_InitTypeDef *ssi_init, + SSI_TxInitTypeDef *ssi_txinit, + uint8_t *pData0, + uint8_t *pData1, + uint16_t Size0, + uint16_t Size1, + uint32_t Timeout); + +void SSI_Receive(SSI_HandleTypeDef *ssi, + SSI_InitTypeDef *ssi_init, + SSI_RxInitTypeDef *ssi_rxinit, + uint8_t *pData0, + uint8_t *pData1, + uint16_t Size0, + uint16_t Size1, + uint32_t Timeout); + +void TxConfigInit(SSI_HandleTypeDef *ssi, SSI_InitTypeDef *ssi_init, SSI_TxInitTypeDef *ssi_txinit); +void RxConfigInit(SSI_HandleTypeDef *ssi, SSI_RxInitTypeDef *ssi_rxinit); + +void SSI_MspInit(SSI_HandleTypeDef *ssi); +/** + * @} + */ + + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup SSI_Exported_Constants SSI Exported Constants + * @{ + */ +/** @defgroup SAI_Error_Code SAI Error Code + * @{ + */ +#define SSI_ERROR_NONE 0x00000000U /*!< No error */ +#define SSI_ERROR_OVR 0x00000001U /*!< Overrun Error */ +#define SSI_ERROR_UDR 0x00000002U /*!< Underrun error */ +#define SSI_ERROR_TIMEOUT 0x00000040U /*!< Timeout error */ +#define SSI_ERROR_DMA 0x00000080U /*!< DMA error */ +/** + * @} + */ + + +/** @defgroup SSI_BITCLK_FIXDIV Clock Divider Presets + * @{ + */ +//#define FIX_CLOCK_DIV2 0x00000000U /* Fixed 2x frequency division */ +#define FIX_CLOCK_DIV4 0x00000001U /* Fixed 4x frequency division */ +#define FIX_CLOCK_DIV16 0x00000003U /* Fixed 16x frequency division */ +#define FIX_CLOCK_DIV32 0x00000004U /* Fixed 32x frequency division */ +/** + * @} + */ + + +/** @defgroup SSI_MODE Presets + * @{ + */ +#define NET 0x00000001 +#define NORMAL 0x00000002 +#define I2S_MASTER 0x00000003 +#define I2S_SLAVE 0x00000004 +#define AC97 0x00000005 +/** + * @} + */ + +/** @defgroup I2S_MODE_PARAM Presets + * @{ + */ +#define I2S_MASTER_PARAM 0x00000020 +#define I2S_SLAVE_PARAM 0x00000040 +/** + * @} + */ + +/** @defgroup SSI_TRANSDATA_TYPE Presets + * @{ + */ +#define MSB_MSW 0x00000001 +#define MSB_LSW 0x00000002 +#define LSB_MSW 0x00000003 +//#define LSB_LSW 0x00000004 +/** + * @} + */ + +/** @defgroup SSI_FIFO_WATERMARK Presets + * @{ + */ +#define WATERMARKEQ0 0x00000000 +#define WATERMARKEQ1 0x00000001 +#define WATERMARKEQ2 0x00000002 +#define WATERMARKEQ3 0x00000003 +#define WATERMARKEQ4 0x00000004 +#define WATERMARKEQ5 0x00000005 +#define WATERMARKEQ6 0x00000006 +#define WATERMARKEQ7 0x00000007 +#define WATERMARKEQ8 0x00000008 +#define WATERMARKEQ9 0x00000009 +#define WATERMARKEQA 0x0000000A +#define WATERMARKEQB 0x0000000B +#define WATERMARKEQC 0x0000000C +#define WATERMARKEQD 0x0000000D +#define WATERMARKEQE 0x0000000E +#define WATERMARKEQF 0x0000000F +/** + * @} + */ + +/** @defgroup SSI_DATA_SIZE Presets + * @{ + */ +#define SSI_DATA_WL8 0x00000003 +#define SSI_DATA_WL10 0x00000004 +#define SSI_DATA_WL12 0x00000005 +#define SSI_DATA_WL16 0x00000007 +#define SSI_DATA_WL18 0x00000008 +#define SSI_DATA_WL20 0x00000009 +#define SSI_DATA_WL22 0x0000000A +#define SSI_DATA_WL24 0x0000000B +/** + * @} + */ + +/** @defgroup SSI_FRAME_LEGNTH Presets + * @{ + */ +#define SSI_FRAME_LEN0 0x00000000 /* bit-lenth frame sync must be used */ +#define SSI_FRAME_LEN1 0x00000100 +#define SSI_FRAME_LEN2 0x00000200 +#define SSI_FRAME_LEN3 0x00000300 +#define SSI_FRAME_LEN4 0x00000400 +#define SSI_FRAME_LEN5 0x00000500 +#define SSI_FRAME_LEN6 0x00000600 +#define SSI_FRAME_LEN7 0x00000700 +#define SSI_FRAME_LEN8 0x00000800 +#define SSI_FRAME_LEN9 0x00000900 +#define SSI_FRAME_LEN10 0x00000A00 +#define SSI_FRAME_LEN11 0x00000B00 +#define SSI_FRAME_LEN12 0x00000C00 +#define SSI_FRAME_LEN13 0x00000D00 +#define SSI_FRAME_LEN14 0x00000E00 +#define SSI_FRAME_LEN15 0x00000F00 +#define SSI_FRAME_LEN16 0x00001F00 +/** + * @} + */ + +/** @defgroup SSI_CLOCK_POLARITY Presets + * @{ + */ +#define RISINGEDGE 0x00000000 +#define FALLINGEDGE 0x00000001 +/** + * @} + */ + +/** @defgroup SSI_FRAMESYNC_POLARITY Presets + * @{ + */ +#define ACTIVEHIGH 0x00000000 +#define ACTIVELOW 0x00000001 +/** + * @} + */ + +/** @defgroup SSI_AC97SLOTWIDTH Presets + * @{ + */ +#define SLOTWIDEQ20 0x00000000 +#define SLOTWIDEQ16 0x00000001 +/** + * @} + */ + + +/** @defgroup SSI_SLOTMSK Presets + * @{ + */ +/*1 no data transmit in this time slot*/ +#define ENALLSLOTS 0x00000000 +#define ENSLOTS1 0xFFFFFFFE +#define ENSLOTS2 0xFFFFFFFD +#define ENSLOTS3 0xFFFFFFFB +#define ENSLOTS4 0xFFFFFFF7 +#define ENSLOTS5 0xFFFFFFEF +#define ENSLOTS6 0xFFFFFFDF +#define ENSLOTS7 0xFFFFFFBF +#define ENSLOTS8 0xFFFFFF7F +#define ENSLOTS9 0xFFFFFEFF +#define ENSLOTS10 0xFFFFFDFF +#define ENSLOTS11 0xFFFFFBFF +#define ENSLOTS12 0xFFFFF7FF +#define ENSLOTS13 0xFFFFEFFF +#define ENSLOTS14 0xFFFFDFFF +#define ENSLOTS15 0xFFFFBFFF +#define ENSLOTS16 0xFFFF7FFF +#define ENSLOTS17 0xFFFEFFFF +#define ENSLOTS18 0xFFFDFFFF +#define ENSLOTS19 0xFFFBFFFF +#define ENSLOTS20 0xFFF7FFFF +#define ENSLOTS21 0xFFEFFFFF +#define ENSLOTS22 0xFFDFFFFF +#define ENSLOTS23 0xFFBFFFFF +#define ENSLOTS24 0xFF7FFFFF +#define ENSLOTS25 0xFEFFFFFF +#define ENSLOTS26 0xFDFFFFFF +#define ENSLOTS27 0xFBFFFFFF +#define ENSLOTS28 0xF7FFFFFF +#define ENSLOTS29 0xEFFFFFFF +#define ENSLOTS30 0xDFFFFFFF +#define ENSLOTS31 0xBFFFFFFF +#define ENSLOTS32 0x7FFFFFFF +/** + * @} + */ + + +/** @defgroup SSI_AC97SLOTEN Presets + * @{ + */ +#define AC97SLOT0EN 0x00000004 +#define AC97SLOT1EN 0x00000008 +#define AC97SLOT2EN 0x00000010 +#define AC97SLOT3EN 0x00000020 +#define AC97SLOT4EN 0x00000040 +#define AC97SLOT5EN 0x00000080 +#define AC97SLOT6EN 0x00000100 +#define AC97SLOT7EN 0x00000200 +#define AC97SLOT8EN 0x00000400 +#define AC97SLOT9EN 0x00000800 +#define AC97SLOT10EN 0x00001000 +#define AC97SLOT11EN 0x00002000 +#define AC97SLOT12EN 0x00004000 +/** + * @} + */ + + +/** + * @} + */ + + +/* Private macros ------------------------------------------------------------*/ +/** @addtogroup SAI_Private_Macros + * @{ + */ +#define IS_SSI_MODE(MODE) (((MODE) == NET) ||\ + ((MODE) == NORMAL) ||\ + ((MODE) == I2S_MASTER) ||\ + ((MODE) == I2S_SLAVE) ||\ + ((MODE) == AC97)) + +#define IS_SSI_AC97SLOTWIDTH(SLOTWIDTH) (((SLOTWIDTH) == SLOTWIDEQ20) || \ + ((SLOTWIDTH) == SLOTWIDEQ16)) + + +#define IS_SSI_BITCLK_FIXDIV(FIXDIV) (((FIXDIV) == FIX_CLOCK_DIV4) || \ + ((FIXDIV) == FIX_CLOCK_DIV16) || \ + ((FIXDIV) == FIX_CLOCK_DIV32) \ + ) + +#define IS_SSI_DATA_SIZE(DATA_SIZE) (((DATA_SIZE) == SSI_DATA_WL8) || \ + ((DATA_SIZE) == SSI_DATA_WL10) || \ + ((DATA_SIZE) == SSI_DATA_WL12) || \ + ((DATA_SIZE) == SSI_DATA_WL14) || \ + ((DATA_SIZE) == SSI_DATA_WL16) || \ + ((DATA_SIZE) == SSI_DATA_WL18) || \ + ((DATA_SIZE) == SSI_DATA_WL20) || \ + ((DATA_SIZE) == SSI_DATA_WL22) || \ + ((DATA_SIZE) == SSI_DATA_WL24) \ + ) + +#define IS_SSI_FRAMELEN(FRLEN) (((FRLEN) == SSI_FRAME_LEN0) ||\ + ((FRLEN) == SSI_FRAME_LEN1 )||\ + ((FRLEN) == SSI_FRAME_LEN2 )||\ + ((FRLEN) == SSI_FRAME_LEN3 )||\ + ((FRLEN) == SSI_FRAME_LEN4 )||\ + ((FRLEN) == SSI_FRAME_LEN5 )||\ + ((FRLEN) == SSI_FRAME_LEN6 )||\ + ((FRLEN) == SSI_FRAME_LEN7 )||\ + ((FRLEN) == SSI_FRAME_LEN8 )||\ + ((FRLEN) == SSI_FRAME_LEN9 )||\ + ((FRLEN) == SSI_FRAME_LEN10 )||\ + ((FRLEN) == SSI_FRAME_LEN11 )||\ + ((FRLEN) == SSI_FRAME_LEN12 )||\ + ((FRLEN) == SSI_FRAME_LEN13 )||\ + ((FRLEN) == SSI_FRAME_LEN14 )||\ + ((FRLEN) == SSI_FRAME_LEN15 )||\ + ((FRLEN) == SSI_FRAME_LEN16 )) + + +#define IS_SSI_SLOTMSK(SLOTMSK) ( ((SLOTMSK) == ENALLSLOTS) || \ + ((SLOTMSK) == ENSLOTS0 ) || \ + ((SLOTMSK) == ENSLOTS1 ) || \ + ((SLOTMSK) == ENSLOTS2 ) || \ + ((SLOTMSK) == ENSLOTS3 ) || \ + ((SLOTMSK) == ENSLOTS4 ) || \ + ((SLOTMSK) == ENSLOTS5 ) || \ + ((SLOTMSK) == ENSLOTS6 ) || \ + ((SLOTMSK) == ENSLOTS7 ) || \ + ((SLOTMSK) == ENSLOTS8 ) || \ + ((SLOTMSK) == ENSLOTS9 ) || \ + ((SLOTMSK) == ENSLOTS10 ) || \ + ((SLOTMSK) == ENSLOTS11 ) || \ + ((SLOTMSK) == ENSLOTS12 ) || \ + ((SLOTMSK) == ENSLOTS13 ) || \ + ((SLOTMSK) == ENSLOTS14 ) || \ + ((SLOTMSK) == ENSLOTS15 ) || \ + ((SLOTMSK) == ENSLOTS16 ) || \ + ((SLOTMSK) == ENSLOTS17 ) || \ + ((SLOTMSK) == ENSLOTS18 ) || \ + ((SLOTMSK) == ENSLOTS19 ) || \ + ((SLOTMSK) == ENSLOTS20 ) || \ + ((SLOTMSK) == ENSLOTS21 ) || \ + ((SLOTMSK) == ENSLOTS22 ) || \ + ((SLOTMSK) == ENSLOTS23 ) || \ + ((SLOTMSK) == ENSLOTS24 ) || \ + ((SLOTMSK) == ENSLOTS25 ) || \ + ((SLOTMSK) == ENSLOTS26 ) || \ + ((SLOTMSK) == ENSLOTS27 ) || \ + ((SLOTMSK) == ENSLOTS28 ) || \ + ((SLOTMSK) == ENSLOTS29 ) || \ + ((SLOTMSK) == ENSLOTS30 ) || \ + ((SLOTMSK) == ENSLOTS31 )) + + +#define IS_SSI_AC97SLOTSEN(AC97SLOTEN) (((AC97SLOTEN) == AC97SLOT0EN ) ||\ + ((AC97SLOTEN) == AC97SLOT1EN ) ||\ + ((AC97SLOTEN) == AC97SLOT2EN ) ||\ + ((AC97SLOTEN) == AC97SLOT3EN ) ||\ + ((AC97SLOTEN) == AC97SLOT4EN ) ||\ + ((AC97SLOTEN) == AC97SLOT5EN ) ||\ + ((AC97SLOTEN) == AC97SLOT6EN ) ||\ + ((AC97SLOTEN) == AC97SLOT7EN ) ||\ + ((AC97SLOTEN) == AC97SLOT8EN ) ||\ + ((AC97SLOTEN) == AC97SLOT9EN ) ||\ + ((AC97SLOTEN) == AC97SLOT10EN) ||\ + ((AC97SLOTEN) == AC97SLOT11EN) ||\ + ((AC97SLOTEN) == AC97SLOT12EN)) + + +#define IS_SSI_TRANSDATA_TYPE(TRANSDATA) (((TRANSDATA) == MSB_MSW) || \ + ((TRANSDATA) == MSB_LSW) || \ + ((TRANSDATA) == LSB_MSW)\ + ) + +#define IS_SSI_FIFO_WATERMARK(WATERMARK) (((WATERMARK) == WATERMARKEQ0) || \ + ((WATERMARK) == WATERMARKEQ1) || \ + ((WATERMARK) == WATERMARKEQ2) || \ + ((WATERMARK) == WATERMARKEQ3) || \ + ((WATERMARK) == WATERMARKEQ4) || \ + ((WATERMARK) == WATERMARKEQ5) || \ + ((WATERMARK) == WATERMARKEQ6) || \ + ((WATERMARK) == WATERMARKEQ7) || \ + ((WATERMARK) == WATERMARKEQ8) || \ + ((WATERMARK) == WATERMARKEQ9) || \ + ((WATERMARK) == WATERMARKEQA) || \ + ((WATERMARK) == WATERMARKEQB) || \ + ((WATERMARK) == WATERMARKEQC) || \ + ((WATERMARK) == WATERMARKEQD) || \ + ((WATERMARK) == WATERMARKEQE) || \ + ((WATERMARK) == WATERMARKEQF)\ + ) + +#define IS_SSI_FRAMESYNC_POLARITY(FRPOLARITY) (((FRPOLARITY) == ACTIVEHIGH) || \ + ((FRPOLARITY) == ACTIVELOW)) + +#define IS_SSI_CLOCK_POLARITY(CKPOLARITY) (((CKPOLARITY) == RISINGEDGE) ||\ + ((CKPOLARITY) == FALLINGEDGE)) + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* FT32F4xx_SSI_H */ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_syscfg.h b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_syscfg.h new file mode 100644 index 00000000000..cd0aecb6d40 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_syscfg.h @@ -0,0 +1,275 @@ +/** + ****************************************************************************** + * @file ft32f4xx_syscfg.h + * @author FMD XA + * @brief This file contains all the functions prototypes for the SYSCFG firmware + * library. + * @version V1.0.0 + * @data 2025-04-08 + ****************************************************************************** + */ + + +/*!< Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __FT32F4XX_SYSCFG_H +#define __FT32F4XX_SYSCFG_H + +#ifdef __cplusplus +extern "C" { +#endif + +/*!< Includes ------------------------------------------------------------------*/ +#include "ft32f4xx.h" + + +/** @addtogroup SYSCFG + * @{ + */ +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup SYSCFG_Exported_Constants + * @{ + */ + +/** @defgroup SYSCFG_EXTI_Port_Sources + * @{ + */ +#define EXTI_PortSourceGPIOA ((uint8_t)0x00) +#define EXTI_PortSourceGPIOB ((uint8_t)0x01) +#define EXTI_PortSourceGPIOC ((uint8_t)0x02) +#define EXTI_PortSourceGPIOD ((uint8_t)0x03) +#define EXTI_PortSourceGPIOE ((uint8_t)0x04) +#define EXTI_PortSourceGPIOH ((uint8_t)0x07) + +#define IS_EXTI_PORT_SOURCE(PORTSOURCE) (((PORTSOURCE) == EXTI_PortSourceGPIOA) || \ + ((PORTSOURCE) == EXTI_PortSourceGPIOB) || \ + ((PORTSOURCE) == EXTI_PortSourceGPIOC) || \ + ((PORTSOURCE) == EXTI_PortSourceGPIOD) || \ + ((PORTSOURCE) == EXTI_PortSourceGPIOE) || \ + ((PORTSOURCE) == EXTI_PortSourceGPIOH)) +/** + * @} + */ + +/** @defgroup SYSCFG_EXTI_Pin_sources + * @{ + */ +#define EXTI_PinSource0 ((uint8_t)0x00) +#define EXTI_PinSource1 ((uint8_t)0x01) +#define EXTI_PinSource2 ((uint8_t)0x02) +#define EXTI_PinSource3 ((uint8_t)0x03) +#define EXTI_PinSource4 ((uint8_t)0x04) +#define EXTI_PinSource5 ((uint8_t)0x05) +#define EXTI_PinSource6 ((uint8_t)0x06) +#define EXTI_PinSource7 ((uint8_t)0x07) +#define EXTI_PinSource8 ((uint8_t)0x08) +#define EXTI_PinSource9 ((uint8_t)0x09) +#define EXTI_PinSource10 ((uint8_t)0x0A) +#define EXTI_PinSource11 ((uint8_t)0x0B) +#define EXTI_PinSource12 ((uint8_t)0x0C) +#define EXTI_PinSource13 ((uint8_t)0x0D) +#define EXTI_PinSource14 ((uint8_t)0x0E) +#define EXTI_PinSource15 ((uint8_t)0x0F) + +#define IS_EXTI_PIN_SOURCE(PINSOURCE) (((PINSOURCE) == EXTI_PinSource0) || \ + ((PINSOURCE) == EXTI_PinSource1) || \ + ((PINSOURCE) == EXTI_PinSource2) || \ + ((PINSOURCE) == EXTI_PinSource3) || \ + ((PINSOURCE) == EXTI_PinSource4) || \ + ((PINSOURCE) == EXTI_PinSource5) || \ + ((PINSOURCE) == EXTI_PinSource6) || \ + ((PINSOURCE) == EXTI_PinSource7) || \ + ((PINSOURCE) == EXTI_PinSource8) || \ + ((PINSOURCE) == EXTI_PinSource9) || \ + ((PINSOURCE) == EXTI_PinSource10) || \ + ((PINSOURCE) == EXTI_PinSource11) || \ + ((PINSOURCE) == EXTI_PinSource12) || \ + ((PINSOURCE) == EXTI_PinSource13) || \ + ((PINSOURCE) == EXTI_PinSource14) || \ + ((PINSOURCE) == EXTI_PinSource15)) +/** + * @} + */ + +/** @defgroup SYSCFG_Memory_Remap_Config + * @{ + */ +#define SYSCFG_MemoryRemap_Flash ((uint32_t)0x00) +#define SYSCFG_MemoryRemap_SystemMemory ((uint32_t)0x01) +#define SYSCFG_MemoryRemap_SRAM ((uint32_t)0x03) +#define SYSCFG_MemoryRemap_FMC1 ((uint32_t)0x02) +#define SYSCFG_MemoryRemap_FMC2 ((uint32_t)0x04) +#define SYSCFG_MemoryRemap_QSPI ((uint32_t)0x05) + + +#define IS_SYSCFG_MEMORY_REMAP(REMAP) (((REMAP) == SYSCFG_MemoryRemap_Flash) || \ + ((REMAP) == SYSCFG_MemoryRemap_SystemMemory) || \ + ((REMAP) == SYSCFG_MemoryRemap_SRAM) || \ + ((REMAP) == SYSCFG_MemoryRemap_FMC1) || \ + ((REMAP) == SYSCFG_MemoryRemap_FMC2) || \ + ((REMAP) == SYSCFG_MemoryRemap_QSPI) ) + +/** + * @} + */ + +/** @defgroup SYSCFG_FMC_Memory_mapping_swap_Config + * @{ + */ +#define SYSCFG_FMC_SWP_ENABLE SYSCFG_MEMRMP_SWP_FMC_MAP +#define SYSCFG_FMC_SWP_DISABLE SYSCFG_MEMRMP_SWP_FMC_NO + + +#define IS_SYSCFG_FMC_SWP(FMCCFG) (((FMCCFG) == SYSCFG_FMC_SWP_ENABLE) || \ + ((FMCCFG) == SYSCFG_FMC_SWP_DISABLE) ) + +/** + * @} + */ + +/** @defgroup SYSCFG_ETH_MII_RMII_Config + * @{ + */ +#define SYSCFG_ETH_MII_RMII_SEL_MII ((uint32_t)0x00) +#define SYSCFG_ETH_MII_RMII_SEL_RMII SYSCFG_PMC_MII_RMII_SEL + + +#define IS_SYSCFG_ETH_MII_RMII_SEL(ETHCFG) (((ETHCFG) == SYSCFG_ETH_MII_RMII_SEL_MII) || \ + ((ETHCFG) == SYSCFG_ETH_MII_RMII_SEL_RMII) ) + +/** + * @} + */ + + + +/** @defgroup SYSCFG_BoostEN_Config + * @{ + */ +#define SYSCFG_PMC_BoostEN_ENABLE SYSCFG_PMC_BOOSTEN +#define SYSCFG_PMC_BoostEN_DISABLE ((uint32_t)0x00) + +#define IS_SYSCFG_PMC_BoostEN(BOOSTCFG) (((BOOSTCFG) == SYSCFG_PMC_BoostEN_ENABLE) || \ + ((BOOSTCFG) == SYSCFG_PMC_BoostEN_DISABLE) ) + +/** + * @} + */ + + +/** @defgroup SYSCFG_I2C_FastModePlus_Config + * @{ + */ +#define SYSCFG_I2CFastModePlus_PB6 SYSCFG_PMC_I2C_PB6_FMP /* Enable Fast Mode Plus on PB6 */ +#define SYSCFG_I2CFastModePlus_PB7 SYSCFG_PMC_I2C_PB7_FMP /* Enable Fast Mode Plus on PB7 */ +#define SYSCFG_I2CFastModePlus_PB8 SYSCFG_PMC_I2C_PB8_FMP /* Enable Fast Mode Plus on PB8 */ +#define SYSCFG_I2CFastModePlus_PB9 SYSCFG_PMC_I2C_PB9_FMP /* Enable Fast Mode Plus on PB9 */ +#define SYSCFG_I2CFastModePlus_I2C1 SYSCFG_PMC_I2C1_FMP /* Enable Fast Mode Plus on PB10, PB11, PF6 and PF7*/ +#define SYSCFG_I2CFastModePlus_I2C2 SYSCFG_PMC_I2C2_FMP /* Enable Fast Mode Plus on I2C2 pins*/ +#define SYSCFG_I2CFastModePlus_I2C3 SYSCFG_PMC_I2C3_FMP /* Enable Fast Mode Plus on I2C3 pins*/ + +#define IS_SYSCFG_I2C_FMP(PIN) (((PIN) == SYSCFG_I2CFastModePlus_PB6) || \ + ((PIN) == SYSCFG_I2CFastModePlus_PB7) || \ + ((PIN) == SYSCFG_I2CFastModePlus_PB8) || \ + ((PIN) == SYSCFG_I2CFastModePlus_PB9) || \ + ((PIN) == SYSCFG_I2CFastModePlus_I2C1) || \ + ((PIN) == SYSCFG_I2CFastModePlus_I2C2) || \ + ((PIN) == SYSCFG_I2CFastModePlus_I2C3) ) + + +/** + * @} + */ + +/** @defgroup SYSCFG_Lock_Config + * @{ + */ +#define SYSCFG_Break_PVD SYSCFG_CFGR_PVD_LOCK /*!< Connects the PVD event to the Break Input of TIM1 */ +#define SYSCFG_Break_Lockup SYSCFG_CFGR_LOCKUP_LOCK /*!< Connects Lockup output of CortexM0 to the break input of TIM1 */ + +#define IS_SYSCFG_LOCK_CONFIG(CONFIG) (((CONFIG) == SYSCFG_Break_PVD) || \ + ((CONFIG) == SYSCFG_Break_Lockup)) + +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup SYSCFG_ISR_WRAPPER + * @{ + */ +#define SYSCFG_ITLINE0 ((uint32_t) 0x00000000) +#define SYSCFG_ITLINE1 ((uint32_t) 0x00000001) +#define SYSCFG_ITLINE2 ((uint32_t) 0x00000002) +#define SYSCFG_ITLINE3 ((uint32_t) 0x00000003) +#define SYSCFG_ITLINE4 ((uint32_t) 0x00000004) +#define SYSCFG_ITLINE5 ((uint32_t) 0x00000005) +#define SYSCFG_ITLINE6 ((uint32_t) 0x00000006) +#define SYSCFG_ITLINE7 ((uint32_t) 0x00000007) +#define SYSCFG_ITLINE8 ((uint32_t) 0x00000008) +#define SYSCFG_ITLINE9 ((uint32_t) 0x00000009) +#define SYSCFG_ITLINE10 ((uint32_t) 0x0000000A) +#define SYSCFG_ITLINE11 ((uint32_t) 0x0000000B) +#define SYSCFG_ITLINE12 ((uint32_t) 0x0000000C) +#define SYSCFG_ITLINE13 ((uint32_t) 0x0000000D) +#define SYSCFG_ITLINE14 ((uint32_t) 0x0000000E) +#define SYSCFG_ITLINE15 ((uint32_t) 0x0000000F) +#define SYSCFG_ITLINE16 ((uint32_t) 0x00000010) +#define SYSCFG_ITLINE17 ((uint32_t) 0x00000011) +#define SYSCFG_ITLINE18 ((uint32_t) 0x00000012) +#define SYSCFG_ITLINE19 ((uint32_t) 0x00000013) +#define SYSCFG_ITLINE20 ((uint32_t) 0x00000014) +#define SYSCFG_ITLINE21 ((uint32_t) 0x00000015) +#define SYSCFG_ITLINE22 ((uint32_t) 0x00000016) +#define SYSCFG_ITLINE23 ((uint32_t) 0x00000017) +#define SYSCFG_ITLINE24 ((uint32_t) 0x00000018) +#define SYSCFG_ITLINE25 ((uint32_t) 0x00000019) +#define SYSCFG_ITLINE26 ((uint32_t) 0x0000001A) +#define SYSCFG_ITLINE27 ((uint32_t) 0x0000001B) +#define SYSCFG_ITLINE28 ((uint32_t) 0x0000001C) +#define SYSCFG_ITLINE29 ((uint32_t) 0x0000001D) +#define SYSCFG_ITLINE30 ((uint32_t) 0x0000001E) +#define SYSCFG_ITLINE31 ((uint32_t) 0x0000001F) + +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +/* Function used to set the SYSCFG configuration to the default reset state **/ +void SYSCFG_DeInit(void); + +/* SYSCFG configuration functions *********************************************/ +void SYSCFG_MemoryRemapConfig(uint32_t SYSCFG_MemoryRemap); +void SYSCFG_FMCSWPConfig(uint32_t SYSCFG_FMCSWPCFG); +void SYSCFG_BoostENConfig(uint32_t SYSCFG_BoostENCFG); +void SYSCFG_I2CFastModePlusConfig(uint32_t SYSCFG_I2CFastModePlus, FunctionalState NewState); +void SYSCFG_MII_RMIIConfig(uint32_t SYSCFG_MII_RMIICFG); +void SYSCFG_EXTILineConfig(uint8_t EXTI_PortSourceGPIOx, uint8_t EXTI_PinSourcex); +void SYSCFG_BreakConfig(uint32_t SYSCFG_Break); + +#ifdef __cplusplus +} +#endif + +#endif /*__FT32F4XX_SYSCFG_H */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_tim.h b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_tim.h new file mode 100644 index 00000000000..de7c0d60fc1 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_tim.h @@ -0,0 +1,1609 @@ +/** + ****************************************************************************** + * @file ft32f4xx_tim.h + * @author FMD AE + * @brief This file contains all the functions prototypes for the TIM + * firmware library. + * @version V1.0.0 + * @date 2025-04-02 + ****************************************************************************** + */ + + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __FT32F4XX_TIM_H +#define __FT32F4XX_TIM_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx.h" + + +/** @addtogroup TIM + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** + * @brief TIM Time Base Init structure definition + * @note This sturcture is used with all TIMx. + */ + +typedef struct +{ + uint32_t TIM_Prescaler; /*!< Specifies the prescaler value used to divide the TIM clock. + This parameter can be a number between 0x0000 and 0xFFFF */ + + uint32_t TIM_CounterMode; /*!< Specifies the counter mode. + This parameter can be a value of @ref TIM_Counter_Mode */ + + uint32_t TIM_Period; /*!< Specifies the period value to be loaded into the active + Auto-Reload Register at the next update event. + This parameter must be a number between 0x0000 and 0xFFFF + @note The high 16-bit auto-reload value (TIM2 and TIM5 only) */ + + uint32_t TIM_ClockDivision; /*!< Specifies the clock division. + This parameter can be a value of @ref TIM_Clock_Division_CKD */ + + uint32_t TIM_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 + This parameter must be a number between 0x00 and 0xFF. + @note This parameter is valid only for TIM1 and TIM8. */ +} TIM_TimeBaseInitTypeDef; + +/** + * @brief TIM Output Compare Init structure definition + */ + +typedef struct +{ + uint32_t TIM_OCMode; /*!< Specifies the TIM mode. + This parameter can be a value of @ref TIM_Output_Compare_and_PWM_modes */ + + uint32_t TIM_OutputState; /*!< Specifies the TIM Output Compare state. + This parameter can be a value of @ref TIM_Output_Compare_state */ + + uint32_t TIM_OutputNState; /*!< Specifies the TIM complementary Output Compare state. + This parameter can be a value of @ref TIM_Output_Compare_N_state + @note This parameter is valid only for TIM1 and TIM8. */ + + uint32_t TIM_Pulse; /*!< Specifies the pulse value to be loaded into the Capture Compare Register. + This parameter can be a number between 0x0000 and 0xFFFF ( or 0xFFFFFFFF + for TIM2 and TIM5) */ + + uint32_t TIM_OCPolarity; /*!< Specifies the output polarity. + This parameter can be a value of @ref TIM_Output_Compare_Polarity */ + + uint32_t TIM_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 TIM1 and TIM8. */ + + uint32_t TIM_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 TIM1 and TIM8. */ + + uint32_t TIM_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 TIM1 and TIM8. */ +} TIM_OCInitTypeDef; + +/** + * @brief TIM Input Capture Init structure definition + */ + +typedef struct +{ + + uint32_t TIM_Channel; /*!< Specifies the TIM channel. + This parameter can be a value of @ref TIM_Channel */ + + uint32_t TIM_ICPolarity; /*!< Specifies the active edge of the input signal. + This parameter can be a value of @ref TIM_Input_Capture_Polarity */ + + uint32_t TIM_ICSelection; /*!< Specifies the input. + This parameter can be a value of @ref TIM_Input_Capture_Selection */ + + uint32_t TIM_ICPrescaler; /*!< Specifies the Input Capture Prescaler. + This parameter can be a value of @ref TIM_Input_Capture_Prescaler */ + + uint32_t TIM_ICFilter; /*!< Specifies the input capture filter. + This parameter can be a number between 0x0 and 0xF */ +} TIM_ICInitTypeDef; + +/** + * @brief TIM_BDTR structure definition + * @note This sturcture is used only with TIM1 and TIM8. + */ + +typedef struct +{ + + uint32_t TIM_OSSRState; /*!< Specifies the Off-State selection used in Run mode. + This parameter can be a value of @ref TIM_OSSR_Off_State_Selection_for_Run_mode_state */ + + uint32_t TIM_OSSIState; /*!< Specifies the Off-State used in Idle state. + This parameter can be a value of @ref TIM_OSSI_Off_State_Selection_for_Idle_mode_state */ + + uint32_t TIM_LOCKLevel; /*!< Specifies the LOCK level parameters. + This parameter can be a value of @ref TIM_Lock_level */ + + uint32_t TIM_DeadTime; /*!< Specifies the delay time between the switching-off and the + switching-on of the outputs. + This parameter can be a number between 0x00 and 0xFF */ + + uint32_t TIM_Break; /*!< Specifies whether the TIM Break input is enabled or not. + This parameter can be a value of @ref TIM_Break_Input_enable_disable */ + + uint32_t TIM_BreakPolarity; /*!< Specifies the TIM Break Input pin polarity. + This parameter can be a value of @ref TIM_Break_Polarity */ + + uint32_t TIM_BreakFilter; /*!< Specifies the break input filter. + This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */ + + uint32_t TIM_BreakBIDMode; /*!< Specifies the bidirectional function mode of the break input. + This parameter can be a value of @ref TIM_Break_Input_Bidirectional_Mode */ + + uint32_t TIM_AutomaticOutput; /*!< Specifies whether the TIM Automatic Output feature is enabled or not. + This parameter can be a value of @ref TIM_AOE_Bit_Set_Reset */ + + uint32_t TIM_CtrlPWMOutput; /*!< Specifies whether the TIM Control PWM Output feature is enabled or not. + This parameter can be a value of @ref TIM_MOE_Bit_Set_Reset */ +} TIM_BDTRInitTypeDef; + +/** + * @brief TIM Break input configuration + */ +typedef struct +{ + uint32_t TIM_Source; /*!< Specifies the source of the timer break input. + This parameter can be a value of @ref TIM_Break_Input_Source */ + uint32_t TIM_Enable; /*!< Specifies whether or not the break input source is enabled. + This parameter can be a value of @ref TIM_Break_Input_Source_Enable */ + uint32_t TIM_Polarity; /*!< Specifies the break input source polarity. + This parameter can be a value of @ref TIM_Break_Input_Source_Polarity */ +} TIM_BreakInputConfigTypeDef; + +/** + * + */ + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup TIM_Exported_constants + * @{ + */ + +#define IS_TIM_ALL_PERIPH(PERIPH) (((PERIPH) == TIM1 ) || \ + ((PERIPH) == TIM2 ) || \ + ((PERIPH) == TIM3 ) || \ + ((PERIPH) == TIM4 ) || \ + ((PERIPH) == TIM5 ) || \ + ((PERIPH) == TIM6 ) || \ + ((PERIPH) == TIM7 ) || \ + ((PERIPH) == TIM8 ) || \ + ((PERIPH) == TIM9 ) || \ + ((PERIPH) == TIM10) || \ + ((PERIPH) == TIM11) || \ + ((PERIPH) == TIM12) || \ + ((PERIPH) == TIM13) || \ + ((PERIPH) == TIM14)) + +/* LIST1: TIM 1 */ +#define IS_TIM_LIST1_PERIPH(PERIPH) ((PERIPH) == TIM1) + +/* LIST2: TIM 1 and 8 */ +#define IS_TIM_LIST2_PERIPH(PERIPH) (((PERIPH) == TIM1) || \ + ((PERIPH) == TIM8)) + +/* LIST3: TIM 1, 2, 3, 4, 5 and 8 */ +#define IS_TIM_LIST3_PERIPH(PERIPH) (((PERIPH) == TIM1) || \ + ((PERIPH) == TIM2) || \ + ((PERIPH) == TIM3) || \ + ((PERIPH) == TIM4) || \ + ((PERIPH) == TIM5) || \ + ((PERIPH) == TIM8)) + +/* LIST4: TIM 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13 and 14 */ +#define IS_TIM_LIST4_PERIPH(PERIPH) (((PERIPH) == TIM1 ) || \ + ((PERIPH) == TIM2 ) || \ + ((PERIPH) == TIM3 ) || \ + ((PERIPH) == TIM4 ) || \ + ((PERIPH) == TIM5 ) || \ + ((PERIPH) == TIM8 ) || \ + ((PERIPH) == TIM9 ) || \ + ((PERIPH) == TIM10) || \ + ((PERIPH) == TIM11) || \ + ((PERIPH) == TIM12) || \ + ((PERIPH) == TIM13) || \ + ((PERIPH) == TIM14)) + +/* LIST5: TIM 1, 2, 3, 4, 5, 8, 9 and 12 */ +#define IS_TIM_LIST5_PERIPH(PERIPH) (((PERIPH) == TIM1 ) || \ + ((PERIPH) == TIM2 ) || \ + ((PERIPH) == TIM3 ) || \ + ((PERIPH) == TIM4 ) || \ + ((PERIPH) == TIM5 ) || \ + ((PERIPH) == TIM8 ) || \ + ((PERIPH) == TIM9 ) || \ + ((PERIPH) == TIM12)) + +/* LIST6: TIM 1, 2, 3, 4, 5, 6, 7 and 8 */ +#define IS_TIM_LIST6_PERIPH(PERIPH) (((PERIPH) == TIM1) || \ + ((PERIPH) == TIM2) || \ + ((PERIPH) == TIM3) || \ + ((PERIPH) == TIM4) || \ + ((PERIPH) == TIM5) || \ + ((PERIPH) == TIM6) || \ + ((PERIPH) == TIM7) || \ + ((PERIPH) == TIM8)) + +/* LIST7: TIM 2 and 11 */ +#define IS_TIM_LIST7_PERIPH(PERIPH) (((PERIPH) == TIM2 ) || \ + ((PERIPH) == TIM11)) + +/** + * @} + */ + +/** @defgroup 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_Forced_Inactive TIM_CCMR1_OC1M_2 /*!< Force inactive level */ +#define TIM_OCMODE_Forced_Active (TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_0) /*!< Force active level */ +#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_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_2 | TIM_CCMR1_OC1M_0) /*!< Combined PWM mode 2 */ +#define TIM_OCMode_Asymmetric_PWM1 (TIM_CCMR1_OC1M_3 | TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1) /*!< Asymmetric PWM mode 1 */ +#define TIM_OCMode_Asymmetric_PWM2 TIM_CCMR1_OC1M /*!< Asymmetric PWM mode 2 */ +#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_Inactive) || \ + ((MODE) == TIM_OCMODE_Forced_Active ) || \ + ((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_OCM(MODE) (((MODE) == TIM_OCMode_Timing ) || \ + ((MODE) == TIM_OCMode_Active ) || \ + ((MODE) == TIM_OCMode_Inactive ) || \ + ((MODE) == TIM_OCMode_Toggle ) || \ + ((MODE) == TIM_OCMode_PWM1 ) || \ + ((MODE) == TIM_OCMode_PWM2 ) || \ + ((MODE) == TIM_ForcedAction_Active ) || \ + ((MODE) == TIM_ForcedAction_InActive)) +/** + * @} + */ + +/** @defgroup 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 */ +#define IS_TIM_OPM_MODE(MODE) (((MODE) == TIM_OPMode_Single ) || \ + ((MODE) == TIM_OPMode_Repetitive)) +/** + * @} + */ + +/** @defgroup TIM_Channel + * @{ + */ + +#define TIM_Channel_1 ((uint32_t)0x00000000) +#define TIM_Channel_2 ((uint32_t)0x00000004) +#define TIM_Channel_3 ((uint32_t)0x00000008) +#define TIM_Channel_4 ((uint32_t)0x0000000C) +#define TIM_Channel_5 ((uint32_t)0x00000010) +#define TIM_Channel_6 ((uint32_t)0x00000014) + +#define IS_TIM_CHANNEL(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)) + +#define IS_TIM_COMPLEMENTARY_CHANNEL(CHANNEL) (((CHANNEL) == TIM_Channel_1) || \ + ((CHANNEL) == TIM_Channel_2) || \ + ((CHANNEL) == TIM_Channel_3)) + +#define IS_TIM_2_TO_5_CHANNEL(CHANNEL) (((CHANNEL) == TIM_Channel_1) || \ + ((CHANNEL) == TIM_Channel_2) || \ + ((CHANNEL) == TIM_Channel_3) || \ + ((CHANNEL) == TIM_Channel_4)) + +#define IS_TIM_9_AND_12_CHANNEL(CHANNEL) (((CHANNEL) == TIM_Channel_1) || \ + ((CHANNEL) == TIM_Channel_2)) + +#define IS_TIM_10_11_13_14_CHANNEL(CHANNEL) (((CHANNEL) == TIM_Channel_1)) + +/** + * @} + */ + +/** @defgroup TIM_Clock_Division_CKD + * @{ + */ + +#define TIM_CKD_DIV1 0x00000000U /*!< Clock division: tDTS=tCK_INT */ +#define TIM_CKD_DIV2 TIM_CR1_CKD_0 /*!< Clock division: tDTS=2*tCK_INT */ +#define TIM_CKD_DIV4 TIM_CR1_CKD_1 /*!< Clock division: tDTS=4*tCK_INT */ +#define IS_TIM_CKD_DIV(DIV) (((DIV) == TIM_CKD_DIV1) || \ + ((DIV) == TIM_CKD_DIV2) || \ + ((DIV) == TIM_CKD_DIV4)) +/** + * @} + */ + +/** @defgroup 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 */ +#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) ) +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_Polarity + * @{ + */ + +#define TIM_OCPolarity_High 0x00000000U /*!< Capture/Compare 1 output Polarity */ +#define TIM_OCPolarity_Low TIM_CCER_CC1P /*!< Capture/Compare 1 output Polarity */ +#define IS_TIM_OC_POLARITY(POLARITY) (((POLARITY) == TIM_OCPolarity_High) || \ + ((POLARITY) == TIM_OCPolarity_Low)) +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_N_Polarity + * @{ + */ + +#define TIM_OCNPolarity_High 0x00000000U /*!< Capture/Compare complementary output polarity */ +#define TIM_OCNPolarity_Low TIM_CCER_CC1NP /*!< Capture/Compare complementary output polarity */ +#define IS_TIM_OCN_POLARITY(POLARITY) (((POLARITY) == TIM_OCNPolarity_High) || \ + ((POLARITY) == TIM_OCNPolarity_Low)) +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_state + * @{ + */ + +#define TIM_OutputState_Disable 0x00000000U /*!< Capture/Compare 1 output disable */ +#define TIM_OutputState_Enable TIM_CCER_CC1E /*!< Capture/Compare 1 output enable */ +#define IS_TIM_OUTPUT_STATE(STATE) (((STATE) == TIM_OutputState_Disable) || \ + ((STATE) == TIM_OutputState_Enable)) +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_N_state + * @{ + */ + +#define TIM_OutputNState_Disable 0x00000000U /*!< Capture/Compare 1 Complementary output disable */ +#define TIM_OutputNState_Enable TIM_CCER_CC1NE /*!< Capture/Compare 1 Complementary output enable */ +#define IS_TIM_OUTPUTN_STATE(STATE) (((STATE) == TIM_OutputNState_Disable) || \ + ((STATE) == TIM_OutputNState_Enable)) +/** + * @} + */ + +/** @defgroup TIM_Capture_Compare_state + * @{ + */ + +#define TIM_CCx_Disable 0x00000000U /*!< Capture/Compare 1 output disable */ +#define TIM_CCx_Enable TIM_CCER_CC1E /*!< Capture/Compare 1 output enable */ +#define IS_TIM_CCX(CCX) (((CCX) == TIM_CCx_Enable ) || \ + ((CCX) == TIM_CCx_Disable)) +/** + * @} + */ + +/** @defgroup TIM_Capture_Compare_N_state + * @{ + */ + +#define TIM_CCxN_Disable 0x00000000U /*!< Capture/Compare 1 Complementary output disable */ +#define TIM_CCxN_Enable TIM_CCER_CC1NE /*!< Capture/Compare 1 Complementary output enable */ +#define IS_TIM_CCXN(CCXN) (((CCXN) == TIM_CCxN_Enable ) || \ + ((CCXN) == TIM_CCxN_Disable)) +/** + * @} + */ + +/** @defgroup TIM_Break_Input_enable_disable + * @{ + */ + +#define TIM_Break_Enable TIM_BDTR_BKE /*!< Break input BRK is enabled */ +#define TIM_Break_Disable 0x00000000U /*!< Break input BRK is disabled */ +#define IS_TIM_BREAK_STATE(STATE) (((STATE) == TIM_Break_Enable ) || \ + ((STATE) == TIM_Break_Disable)) +/** + * @} + */ + +/** @defgroup TIM_Break_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 */ +#define IS_TIM_BREAK_POLARITY(POLARITY) (((POLARITY) == TIM_BreakPolarity_Low ) || \ + ((POLARITY) == TIM_BreakPolarity_High)) +/** + * @} + */ + +/** @defgroup TIM_Break_Input_Bidirectional_Mode TIM Break Input Bidirectional Function Mode + * @{ + */ + +#define TIM_Break_Bid_MODE_INPUT 0x00000000U /*!< Break input BRK in input mode */ +#define TIM_Break_Bid_MODE_BIDIRECTIONAL TIM_BDTR_BKBID /*!< Break input BRK in bidirectional mode */ +#define IS_TIM_BREAK_BID_MODE(MODE) ((MODE == TIM_Break_Bid_MODE_INPUT ) || \ + (MODE == TIM_Break_Bid_MODE_BIDIRECTIONAL)) + +/** + * @} + */ + +/** @defgroup TIM_AOE_Bit_Set_Reset + * @{ + */ + +#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 is active) */ +#define TIM_AutomaticOutput_Disable 0x00000000U /*!< MOE can be set only by software */ +#define IS_TIM_AUTOMATIC_OUTPUT_STATE(STATE) (((STATE) == TIM_AutomaticOutput_Enable ) || \ + ((STATE) == TIM_AutomaticOutput_Disable)) +/** + * @} + */ + +/** @defgroup TIM_MOE_Bit_Set_Reset + * @{ + */ + +#define TIM_ControlPWMOutput_Enable TIM_BDTR_MOE /*!< Enable TIM main output */ +#define TIM_ControlPWMOutput_Disable 0x00000000U /*!< Disable TIM main output */ +#define IS_TIM_CONTROL_PWM_OUTPUT_STATE(STATE) (((STATE) == TIM_ControlPWMOutput_Enable ) || \ + ((STATE) == TIM_ControlPWMOutput_Disable)) +/** + * @} + */ + +/** @defgroup 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 */ +#define IS_TIM_LOCK_LEVEL(LEVEL) (((LEVEL) == TIM_LOCKLevel_OFF) || \ + ((LEVEL) == TIM_LOCKLevel_1 ) || \ + ((LEVEL) == TIM_LOCKLevel_2 ) || \ + ((LEVEL) == TIM_LOCKLevel_3 )) +/** + * @} + */ + +/** @defgroup TIM_OSSI_Off_State_Selection_for_Idle_mode_state + * @{ + */ + +#define TIM_OSSIState_Enable TIM_BDTR_OSSI /*!< When inactive, OC/OCN outputs are enabled (still controlled by the timer) */ +#define TIM_OSSIState_Disable 0x00000000U /*!< When inactive, OC/OCN outputs are disabled (not controlled any longer by the timer) */ +#define IS_TIM_OSSI_STATE(STATE) (((STATE) == TIM_OSSIState_Enable ) || \ + ((STATE) == TIM_OSSIState_Disable)) +/** + * @} + */ + +/** @defgroup TIM_OSSR_Off_State_Selection_for_Run_mode_state + * @{ + */ + +#define TIM_OSSRState_Enable TIM_BDTR_OSSR /*!< When inactive, OC/OCN outputs are enabled (still controlled by the timer) */ +#define TIM_OSSRState_Disable 0x00000000U /*!< When inactive, OC/OCN outputs are disabled (not controlled any longer by the timer) */ +#define IS_TIM_OSSR_STATE(STATE) (((STATE) == TIM_OSSRState_Enable ) || \ + ((STATE) == TIM_OSSRState_Disable)) +/** + * @} + */ + +/** @defgroup 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 */ +#define IS_TIM_OCIDLE_STATE(STATE) (((STATE) == TIM_OCIdleState_Set ) || \ + ((STATE) == TIM_OCIdleState_Reset)) +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_N_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 */ +#define IS_TIM_OCNIDLE_STATE(STATE) (((STATE) == TIM_OCNIdleState_Set ) || \ + ((STATE) == TIM_OCNIdleState_Reset)) +/** + * @} + */ + +/** @defgroup TIM_Input_Capture_Polarity + * @{ + */ + +#define TIM_ICPolarity_Rising 0x00000000U /*!< Polarity for TIx source */ +#define TIM_ICPolarity_Falling TIM_CCER_CC1P /*!< Polarity for TIx source */ +#define TIM_ICPolarity_BothEdge (TIM_CCER_CC1P | TIM_CCER_CC1NP) /*!< Polarity for TIx source */ +#define IS_TIM_IC_POLARITY(POLARITY) (((POLARITY) == TIM_ICPolarity_Rising ) || \ + ((POLARITY) == TIM_ICPolarity_Falling ) || \ + ((POLARITY) == TIM_ICPolarity_BothEdge)) +/** + * @} + */ + +/** @defgroup 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. */ +#define IS_TIM_IC_SELECTION(SELECTION) (((SELECTION) == TIM_ICSelection_DirectTI ) || \ + ((SELECTION) == TIM_ICSelection_IndirectTI) || \ + ((SELECTION) == TIM_ICSelection_TRC )) +/** + * @} + */ + +/** @defgroup 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 */ +#define IS_TIM_IC_PRESCALER(PRESCALER) (((PRESCALER) == TIM_ICPSC_DIV1) || \ + ((PRESCALER) == TIM_ICPSC_DIV2) || \ + ((PRESCALER) == TIM_ICPSC_DIV4) || \ + ((PRESCALER) == TIM_ICPSC_DIV8)) +/** + * @} + */ + +/** @defgroup TIM_Group_Channel5 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 */ +#define IS_TIM_GROUPCH5(OCREF) (((OCREF) == TIM_GroupCH5_None) || \ + ((OCREF) == TIM_CCR5_GC5C1 ) || \ + ((OCREF) == TIM_CCR5_GC5C2 ) || \ + ((OCREF) == TIM_CCR5_GC5C3 )) +/** + * @} + */ + +/** @defgroup TIM_interrupt_sources + * @{ + */ + +#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 IS_TIM_IT(IT) ((((IT) & (uint32_t)0xFFFFFF00) == 0x00000000) && ((IT) != 0x00000000)) +#define IS_TIM_GET_IT(IT) (((IT) == TIM_IT_Update ) || \ + ((IT) == TIM_IT_CC1 ) || \ + ((IT) == TIM_IT_CC2 ) || \ + ((IT) == TIM_IT_CC3 ) || \ + ((IT) == TIM_IT_CC4 ) || \ + ((IT) == TIM_IT_COM ) || \ + ((IT) == TIM_IT_Trigger) || \ + ((IT) == TIM_IT_Break )) + +/** + * @} + */ + +/** @defgroup TIM_DMA_Base_address + * @{ + */ + +#define TIM_DMABase_CR1 ((uint32_t)0x00000000) +#define TIM_DMABase_CR2 ((uint32_t)0x00000001) +#define TIM_DMABase_SMCR ((uint32_t)0x00000002) +#define TIM_DMABase_DIER ((uint32_t)0x00000003) +#define TIM_DMABase_SR ((uint32_t)0x00000004) +#define TIM_DMABase_EGR ((uint32_t)0x00000005) +#define TIM_DMABase_CCMR1 ((uint32_t)0x00000006) +#define TIM_DMABase_CCMR2 ((uint32_t)0x00000007) +#define TIM_DMABase_CCER ((uint32_t)0x00000008) +#define TIM_DMABase_CNT ((uint32_t)0x00000009) +#define TIM_DMABase_PSC ((uint32_t)0x0000000A) +#define TIM_DMABase_ARR ((uint32_t)0x0000000B) +#define TIM_DMABase_RCR ((uint32_t)0x0000000C) +#define TIM_DMABase_CCR1 ((uint32_t)0x0000000D) +#define TIM_DMABase_CCR2 ((uint32_t)0x0000000E) +#define TIM_DMABase_CCR3 ((uint32_t)0x0000000F) +#define TIM_DMABase_CCR4 ((uint32_t)0x00000010) +#define TIM_DMABase_BDTR ((uint32_t)0x00000011) +#define TIM_DMABase_DCR ((uint32_t)0x00000012) +#define TIM_DMABase_OR ((uint32_t)0x00000014) +#define TIM_DMABase_CCMR3 ((uint32_t)0x00000015) +#define TIM_DMABase_CCR5 ((uint32_t)0x00000016) +#define TIM_DMABase_CCR6 ((uint32_t)0x00000017) +#define TIM_DMABase_AF1 ((uint32_t)0x00000018) +#define TIM_DMABase_AF2 ((uint32_t)0x00000019) +#define TIM_DMABase_TISEL ((uint32_t)0x0000001A) +#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_DCR ) || \ + ((BASE) == TIM_DMABase_OR ) || \ + ((BASE) == TIM_DMABase_CCMR3) || \ + ((BASE) == TIM_DMABase_CCR5 ) || \ + ((BASE) == TIM_DMABase_CCR6 ) || \ + ((BASE) == TIM_DMABase_AF1 ) || \ + ((BASE) == TIM_DMABase_AF2 ) || \ + ((BASE) == TIM_DMABase_TISEL)) +/** + * @} + */ + + +/** @defgroup TIM_DMA_Burst_Length TIM DMA Burst Length + * @{ + */ + +#define TIM_DMABurstLength_1Transfer 0x00000000U /*!< The transfer is done to 1 register starting trom TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABurstLength_2Transfers 0x00000100U /*!< The transfer is done to 2 registers starting trom TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABurstLength_3Transfers 0x00000200U /*!< The transfer is done to 3 registers starting trom TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABurstLength_4Transfers 0x00000300U /*!< The transfer is done to 4 registers starting trom TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABurstLength_5Transfers 0x00000400U /*!< The transfer is done to 5 registers starting trom TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABurstLength_6Transfers 0x00000500U /*!< The transfer is done to 6 registers starting trom TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABurstLength_7Transfers 0x00000600U /*!< The transfer is done to 7 registers starting trom TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABurstLength_8Transfers 0x00000700U /*!< The transfer is done to 8 registers starting trom TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABurstLength_9Transfers 0x00000800U /*!< The transfer is done to 9 registers starting trom TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABurstLength_10Transfers 0x00000900U /*!< The transfer is done to 10 registers starting trom TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABurstLength_11Transfers 0x00000A00U /*!< The transfer is done to 11 registers starting trom TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABurstLength_12Transfers 0x00000B00U /*!< The transfer is done to 12 registers starting trom TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABurstLength_13Transfers 0x00000C00U /*!< The transfer is done to 13 registers starting trom TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABurstLength_14Transfers 0x00000D00U /*!< The transfer is done to 14 registers starting trom TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABurstLength_15Transfers 0x00000E00U /*!< The transfer is done to 15 registers starting trom TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABurstLength_16Transfers 0x00000F00U /*!< The transfer is done to 16 registers starting trom TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABurstLength_17Transfers 0x00001000U /*!< The transfer is done to 17 registers starting trom TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABurstLength_18Transfers 0x00001100U /*!< The transfer is done to 18 registers starting trom TIMx_CR1 + TIMx_DCR.DBA */ +#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)) +/** + * @} + */ + +/** @defgroup 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 */ +#define IS_TIM_DMA_SOURCE(SOURCE) ((((SOURCE) & (uint32_t)0xFFFF80FF) == 0x00000000) && ((SOURCE) != 0x00000000)) + +/** + * @} + */ + +/** @defgroup TIM_External_Trigger_Prescaler + * @{ + */ + +#define TIM_ExtTRGPSC_OFF 0x00000000U /*!< No prescaler is used */ +#define TIM_ExtTRGPSC_DIV2 TIM_SMCR_ETPS_0 /*!< ETR input source is divided by 2 */ +#define TIM_ExtTRGPSC_DIV4 TIM_SMCR_ETPS_1 /*!< ETR input source is divided by 4 */ +#define TIM_ExtTRGPSC_DIV8 TIM_SMCR_ETPS /*!< ETR input source is divided by 8 */ +#define IS_TIM_EXT_PRESCALER(PRESCALER) (((PRESCALER) == TIM_ExtTRGPSC_OFF ) || \ + ((PRESCALER) == TIM_ExtTRGPSC_DIV2) || \ + ((PRESCALER) == TIM_ExtTRGPSC_DIV4) || \ + ((PRESCALER) == TIM_ExtTRGPSC_DIV8)) +/** + * @} + */ + +/** @defgroup TIM_Internal_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_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 /*!< Filtered External Trigger input (ETRF) */ +#define IS_TIM_TRIGGER_SELECTION(SELECTION) (((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 )) +#define IS_TIM_INTERNAL_TRIGGER_SELECTION(SELECTION) (((SELECTION) == TIM_TS_ITR0) || \ + ((SELECTION) == TIM_TS_ITR1) || \ + ((SELECTION) == TIM_TS_ITR2) || \ + ((SELECTION) == TIM_TS_ITR3)) +/** + * @} + */ + +/** @defgroup TIM_TIx_External_Clock_Source + * @{ + */ + +#define TIM_TIxExternalCLK1Source_TI1 (TIM_SMCR_TS_0 | TIM_SMCR_TS_2) /*!< Filtered Timer Input 1 (TI1FP1) */ +#define TIM_TIxExternalCLK1Source_TI2 (TIM_SMCR_TS_1 | TIM_SMCR_TS_2) /*!< Filtered Timer Input 2 (TI2FP2) */ +#define TIM_TIxExternalCLK1Source_TI1ED TIM_SMCR_TS_2 /*!< TI1 Edge Detector (TI1F_ED) */ + +/** + * @} + */ + +/** @defgroup TIM_External_Trigger_Polarity + * @{ + */ +#define TIM_ExtTRGPolarity_Inverted TIM_SMCR_ETP /*!< Polarity for ETR source */ +#define TIM_ExtTRGPolarity_NonInverted 0x00000000U /*!< Polarity for ETR source */ +#define IS_TIM_EXT_POLARITY(POLARITY) (((POLARITY) == TIM_ExtTRGPolarity_Inverted ) || \ + ((POLARITY) == TIM_ExtTRGPolarity_NonInverted)) +/** + * @} + */ + +/** @defgroup TIM_Prescaler_Reload_Mode + * @{ + */ + +#define TIM_PSCReloadMode_Update 0x00000000U /*!< Prescaler reload PSC register value at update event */ +#define TIM_PSCReloadMode_Immediate TIM_EGR_UG /*!< Prescaler reload PSC register value at immediate */ +#define IS_TIM_PRESCALER_RELOAD(RELOAD) (((RELOAD) == TIM_PSCReloadMode_Update ) || \ + ((RELOAD) == TIM_PSCReloadMode_Immediate)) +/** + * @} + */ + +/** @defgroup TIM_Forced_Action + * @{ + */ + +#define TIM_ForcedAction_Active (TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_0) /*!< Force active level */ +#define TIM_ForcedAction_InActive TIM_CCMR1_OC1M_2 /*!< Force inactive level */ +#define IS_TIM_FORCED_ACTION(ACTION) (((ACTION) == TIM_ForcedAction_Active ) || \ + ((ACTION) == TIM_ForcedAction_InActive)) +/** + * @} + */ + +/** @defgroup TIM_Encoder_Mode + * @{ + */ + +#define TIM_EncoderMode_TI1 TIM_SMCR_SMS_0 /*!< Quadrature encoder mode 1, counts up/down on TI2FP2 edge depending on TI1FP1 level */ +#define TIM_EncoderMode_TI2 TIM_SMCR_SMS_1 /*!< Quadrature encoder mode 2, counts up/down on TI1FP1 edge depending on TI2FP2 level */ +#define TIM_EncoderMode_TI12 (TIM_SMCR_SMS_1 | TIM_SMCR_SMS_0) /*!< Quadrature encoder mode 3, counts up/down on both TI1FP1 and TI2FP2 edges depending on the level of the other input */ +#define IS_TIM_ENCODER_MODE(MODE) (((MODE) == TIM_EncoderMode_TI1 ) || \ + ((MODE) == TIM_EncoderMode_TI2 ) || \ + ((MODE) == TIM_EncoderMode_TI12)) +/** + * @} + */ + + +/** @defgroup 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 IS_TIM_EVENT_SOURCE(SOURCE) ((((SOURCE) & (uint32_t)0xFFFFFF00) == 0x00000000) && ((SOURCE) != 0x00000000)) + +/** + * @} + */ + +/** @defgroup TIM_Update_Source + * @{ + */ + +#define TIM_UpdateSource_Global 0x00000000U /*!< Source of update is the counter overflow/underflow + or the setting of UG bit, or an update generation + through the slave mode controller. */ +#define TIM_UpdateSource_Regular 0x00000001U /*!< Source of update is counter overflow/underflow. */ +#define IS_TIM_UPDATE_SOURCE(SOURCE) (((SOURCE) == TIM_UpdateSource_Global ) || \ + ((SOURCE) == TIM_UpdateSource_Regular)) +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_Preload_State + * @{ + */ + +#define TIM_OCPreload_Enable TIM_CCMR1_OC1PE /*!< Preload register on TIMx_CCR1 enabled */ +#define TIM_OCPreload_Disable 0x00000000U /*!< Preload register on TIMx_CCR1 disabled */ +#define IS_TIM_OCPRELOAD_STATE(STATE) (((STATE) == TIM_OCPreload_Enable ) || \ + ((STATE) == TIM_OCPreload_Disable)) +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_Fast_State + * @{ + */ + +#define TIM_OCFast_Enable TIM_CCMR1_OC1FE /*!< Output Compare fast enable */ +#define TIM_OCFast_Disable 0x00000000U /*!< Output Compare fast disable */ +#define IS_TIM_OCFAST_STATE(STATE) (((STATE) == TIM_OCFast_Enable ) || \ + ((STATE) == TIM_OCFast_Disable)) + +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_Clear_State + * @{ + */ + +#define TIM_OCClear_Enable TIM_CCMR1_OC1CE /*!< OC1REF is cleared as soon as a high level is dected on OCREF_CLR_INPUT signal */ +#define TIM_OCClear_Disable 0x00000000U /*!< OC1REF is not effected by the OCREF_CLR_INPUT signal */ +#define IS_TIM_OCCLEAR_STATE(STATE) (((STATE) == TIM_OCClear_Enable ) || \ + ((STATE) == TIM_OCClear_Disable)) +/** + * @} + */ + +/** @defgroup TIM_Trigger_Output_Source (TRGO) + * @{ + */ + +#define TIM_TRGOSource_Reset 0x00000000U /*!< TIMx_EGR.UG bit is used as trigger output (TRGO) */ +#define TIM_TRGOSource_Enable TIM_CR2_MMS_0 /*!< TIMx_CR1.CEN bit is used as trigger output (TRGO) */ +#define TIM_TRGOSource_Update TIM_CR2_MMS_1 /*!< Update event is used as trigger output (TRGO) */ +#define TIM_TRGOSource_OC1 (TIM_CR2_MMS_1 | TIM_CR2_MMS_0) /*!< Capture or a compare match 1 is used as trigger output (TRGO) */ +#define TIM_TRGOSource_OC1Ref TIM_CR2_MMS_2 /*!< OC1REF signal is used as trigger output (TRGO) */ +#define TIM_TRGOSource_OC2Ref (TIM_CR2_MMS_2 | TIM_CR2_MMS_0) /*!< OC2REF signal is used as trigger output(TRGO) */ +#define TIM_TRGOSource_OC3Ref (TIM_CR2_MMS_2 | TIM_CR2_MMS_1) /*!< OC3REF signal is used as trigger output(TRGO) */ +#define TIM_TRGOSource_OC4Ref (TIM_CR2_MMS_2 | TIM_CR2_MMS_1 | TIM_CR2_MMS_0) /*!< OC4REF signal is used as trigger output(TRGO) */ +#define IS_TIM_TRGO_SOURCE(SOURCE) (((SOURCE) == TIM_TRGOSource_Reset ) || \ + ((SOURCE) == TIM_TRGOSource_Enable) || \ + ((SOURCE) == TIM_TRGOSource_Update) || \ + ((SOURCE) == TIM_TRGOSource_OC1 ) || \ + ((SOURCE) == TIM_TRGOSource_OC1Ref) || \ + ((SOURCE) == TIM_TRGOSource_OC2Ref) || \ + ((SOURCE) == TIM_TRGOSource_OC3Ref) || \ + ((SOURCE) == TIM_TRGOSource_OC4Ref)) +/** + * @} + */ + +/** @defgroup TIM_Master_Mode_Selection_2 TIM Master Mode Selection 2 (TRGO2) + * @{ + */ + +#define TIM_TRGO2Source_Reset 0x00000000U /*!< TIMx_EGR.UG bit is used as trigger output (TRGO2) */ +#define TIM_TRGO2Source_Enable TIM_CR2_MMS2_0 /*!< TIMx_CR1.CEN bit is used as trigger output (TRGO2) */ +#define TIM_TRGO2Source_Update TIM_CR2_MMS2_1 /*!< Update event is used as trigger output (TRGO2) */ +#define TIM_TRGO2Source_OC1 (TIM_CR2_MMS2_1 | TIM_CR2_MMS2_0) /*!< Capture or a compare match 1 is used as trigger output (TRGO2) */ +#define TIM_TRGO2Source_OC1Ref TIM_CR2_MMS2_2 /*!< OC1REF signal is used as trigger output (TRGO2) */ +#define TIM_TRGO2Source_OC2Ref (TIM_CR2_MMS2_2 | TIM_CR2_MMS2_0) /*!< OC2REF signal is used as trigger output (TRGO2) */ +#define TIM_TRGO2Source_OC3Ref (TIM_CR2_MMS2_2 | TIM_CR2_MMS2_1) /*!< OC3REF signal is used as trigger output (TRGO2) */ +#define TIM_TRGO2Source_OC4Ref (TIM_CR2_MMS2_2 | TIM_CR2_MMS2_1 | TIM_CR2_MMS2_0) /*!< OC4REF signal is used as trigger output (TRGO2) */ +#define TIM_TRGO2Source_OC5Ref TIM_CR2_MMS2_3 /*!< OC5REF signal is used as trigger output (TRGO2) */ +#define TIM_TRGO2Source_OC6Ref (TIM_CR2_MMS2_3 | TIM_CR2_MMS2_0) /*!< OC6REF signal is used as trigger output (TRGO2) */ +#define TIM_TRGO2Source_OC4Ref_RisingFalling (TIM_CR2_MMS2_3 | TIM_CR2_MMS2_1) /*!< OC4REF rising or falling edges generate pulses on TRGO2 */ +#define TIM_TRGO2Source_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_TRGO2Source_OC4Ref_Rising_OC6Ref_Rising (TIM_CR2_MMS2_3 | TIM_CR2_MMS2_2) /*!< OC4REF or OC6REF rising edges generate pulses on TRGO2 */ +#define TIM_TRGO2Source_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_TRGO2Source_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_TRGO2Source_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 */ +#define IS_TIM_TRGO2_SOURCE(SOURCE) (((SOURCE) == TIM_TRGO2Source_Reset ) || \ + ((SOURCE) == TIM_TRGO2Source_Enable ) || \ + ((SOURCE) == TIM_TRGO2Source_Update ) || \ + ((SOURCE) == TIM_TRGO2Source_OC1 ) || \ + ((SOURCE) == TIM_TRGO2Source_OC1Ref ) || \ + ((SOURCE) == TIM_TRGO2Source_OC2Ref ) || \ + ((SOURCE) == TIM_TRGO2Source_OC3Ref ) || \ + ((SOURCE) == TIM_TRGO2Source_OC4Ref ) || \ + ((SOURCE) == TIM_TRGO2Source_OC5Ref ) || \ + ((SOURCE) == TIM_TRGO2Source_OC6Ref ) || \ + ((SOURCE) == TIM_TRGO2Source_OC4Ref_RisingFalling ) || \ + ((SOURCE) == TIM_TRGO2Source_OC6Ref_RisingFalling ) || \ + ((SOURCE) == TIM_TRGO2Source_OC4Ref_Rising_OC6Ref_Rising ) || \ + ((SOURCE) == TIM_TRGO2Source_OC4Ref_Rising_OC6Ref_Falling) || \ + ((SOURCE) == TIM_TRGO2Source_OC5Ref_Rising_OC6Ref_Rising ) || \ + ((SOURCE) == TIM_TRGO2Source_OC5Ref_Rising_OC6Ref_Falling)) + +/** + * @} + */ + +/** @defgroup 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 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)) +/** + * @} + */ + +/** @defgroup TIM_Master_Slave_Mode + * @{ + */ + +#define TIM_MasterSlaveMode_Enable TIM_SMCR_MSM /*!< Master/slave mode is selected */ +#define TIM_MasterSlaveMode_Disable 0x00000000U /*!< No action */ +#define IS_TIM_MSM_STATE(STATE) (((STATE) == TIM_MasterSlaveMode_Enable ) || \ + ((STATE) == TIM_MasterSlaveMode_Disable)) +/** + * @} + */ + +/** @defgroup TIM_Flags + * @{ + */ + +#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_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 IS_TIM_GET_FLAG(FLAG) (((FLAG) == TIM_FLAG_Update ) || \ + ((FLAG) == TIM_FLAG_CC1 ) || \ + ((FLAG) == TIM_FLAG_CC2 ) || \ + ((FLAG) == TIM_FLAG_CC3 ) || \ + ((FLAG) == TIM_FLAG_CC4 ) || \ + ((FLAG) == TIM_FLAG_CC5 ) || \ + ((FLAG) == TIM_FLAG_CC6 ) || \ + ((FLAG) == TIM_FLAG_COM ) || \ + ((FLAG) == TIM_FLAG_Trigger) || \ + ((FLAG) == TIM_FLAG_Break ) || \ + ((FLAG) == TIM_FLAG_CC1OF ) || \ + ((FLAG) == TIM_FLAG_CC2OF ) || \ + ((FLAG) == TIM_FLAG_CC3OF ) || \ + ((FLAG) == TIM_FLAG_CC4OF )) + + +#define IS_TIM_CLEAR_FLAG(TIM_FLAG) ((((TIM_FLAG) & (uint32_t)0xFFFCE100) == 0x00000000) && ((TIM_FLAG) != 0x00000000)) +/** + * @} + */ + + +/** @defgroup TIM_Input_Capture_Filer_Value + * @{ + */ + +#define IS_TIM_IC_FILTER(ICFILTER) ((ICFILTER) <= 0xF) +/** + * @} + */ + +/** @defgroup TIM_External_Trigger_Filter + * @{ + */ + +#define IS_TIM_EXT_FILTER(EXTFILTER) ((EXTFILTER) <= 0xF) +/** + * @} + */ + +/** @defgroup TIM_DeadTime Filter + * @{ + */ + +#define IS_TIM_DEADTIME(DEADTIME) ((DEADTIME) <= 0xFFU) +/** + * @} + */ + +/** @defgroup TIM_BreakFilter + * @{ + */ + +#define IS_TIM_BREAK_FILTER(BRKFILTER) ((BRKFILTER) <= 0xFUL) +/** + * @} + */ + +/** @defgroup TIM_OCReferenceClear + * @{ + */ +#define TIM_OCReferenceClear_ETRF TIM_SMCR_OCCS /*!< OCREF clear select ETRF */ +#define TIM_OCReferenceClear_OCREFCLR 0x00000000U /*!< OCREF clear select OCREF_CLR int input signals */ +#define TIM_OCREFERENCECECLEAR_SOURCE(SOURCE) (((SOURCE) == TIM_OCReferenceClear_ETRF ) || \ + ((SOURCE) == TIM_OCReferenceClear_OCREFCLR)) + +/** + * @} + */ +/** @defgroup TIM_Remap + * @{ + */ +#define TIM2_ITR1ConnectTIM8Trgo ((uint32_t)0x00000000) /*!< TIM8 TRGO is connected to TIM2_ITR1 input */ +#define TIM2_ITR1ConnectPTPTrgo ((uint32_t)0x00000001) /*!< PTP TRGO is connected to TIM2_ITR1 input */ +#define TIM2_ITR1ConnectOTGFSSOF ((uint32_t)0x00000002) /*!< OTG FS SOF is connected to TIM2_ITR1 input */ +#define TIM2_ITR1ConnectOTGHSSOF ((uint32_t)0x00000003) /*!< OTG HS SOF is connected to TIM2_ITR1 input */ + +#define TIM11_IT1ConnectGPIO_0 ((uint32_t)0x00000000) /*!< TIM11 GPIO is connected to TIM11_TI1 input */ +#define TIM11_IT1ConnectGPIO_1 ((uint32_t)0x00000001) /*!< TIM11 GPIO is connected to TIM11_TI1 input */ +#define TIM11_IT1ConnectHSE_RTC ((uint32_t)0x00000002) /*!< HSE RTC clock is connected to TIM11_TI1 input */ +#define TIM11_IT1ConnectGPIO_3 ((uint32_t)0x00000003) /*!< TIM11 GPIO is connected to TIM11_TI1 input */ + +#define IS_TIM2_ITR1REMAP(TIM_REMAP) (((TIM_REMAP) == TIM2_ITR1ConnectTIM8Trgo) || \ + ((TIM_REMAP) == TIM2_ITR1ConnectPTPTrgo ) || \ + ((TIM_REMAP) == TIM2_ITR1ConnectOTGFSSOF) || \ + ((TIM_REMAP) == TIM2_ITR1ConnectOTGHSSOF)) + +#define IS_TIM11_ITR1REMAP(TIM_REMAP) (((TIM_REMAP) == TIM11_IT1ConnectGPIO_0 ) || \ + ((TIM_REMAP) == TIM11_IT1ConnectGPIO_1 ) || \ + ((TIM_REMAP) == TIM11_IT1ConnectHSE_RTC) || \ + ((TIM_REMAP) == TIM11_IT1ConnectGPIO_3 )) +/** + * @} + */ + +/** @defgroup TIM_ETRSel_Remap + * @{ + */ + +#define TIM_ETR_GPIO 0x00000000U /* !< ETR input is connected to GPIO */ +#define TIM_ETR_COMP1 TIM_AF1_ETRSEL_0 /* !< ETR input is connected to COMP1_OUT */ +#define TIM_ETR_COMP2 TIM_AF1_ETRSEL_1 /* !< ETR input is connected to COMP2_OUT */ +#define TIM_ETR_COMP3 (TIM_AF1_ETRSEL_1 | TIM_AF1_ETRSEL_0) /* !< ETR input is connected to COMP3_OUT */ +#define TIM_ETR_COMP4 TIM_AF1_ETRSEL_2 /* !< ETR input is connected to COMP4_OUT */ +#define TIM_ETR_COMP5 (TIM_AF1_ETRSEL_2 | TIM_AF1_ETRSEL_0) /* !< ETR input is connected to COMP5_OUT */ +#define TIM_ETR_COMP6 (TIM_AF1_ETRSEL_2 | TIM_AF1_ETRSEL_1) /* !< ETR input is connected to COMP6_OUT */ +#define TIM_ETR_ADC1_AWD1 (TIM_AF1_ETRSEL_2 | TIM_AF1_ETRSEL_1 | TIM_AF1_ETRSEL_0) /* !< ETR input is connected to ADC1 analog watchdog 1 */ +#define TIM_ETR_ADC1_AWD2 TIM_AF1_ETRSEL_3 /* !< ETR input is connected to ADC1 analog watchdog 2 */ +#define TIM_ETR_ADC1_AWD3 (TIM_AF1_ETRSEL_3 | TIM_AF1_ETRSEL_0) /* !< ETR input is connected to ADC1 analog watchdog 3 */ +#define TIM_ETR_ADC2_AWD1 (TIM_AF1_ETRSEL_3 | TIM_AF1_ETRSEL_1) /* !< ETR input is connected to ADC2 analog watchdog 1 */ +#define TIM_ETR_ADC2_AWD2 (TIM_AF1_ETRSEL_3 | TIM_AF1_ETRSEL_1 | TIM_AF1_ETRSEL_0) /* !< ETR input is connected to ADC2 analog watchdog 2 */ +#define TIM_ETR_ADC2_AWD3 (TIM_AF1_ETRSEL_3 | TIM_AF1_ETRSEL_2) /* !< ETR input is connected to ADC2 analog watchdog 3 */ +#define TIM_ETR_ADC3_AWD1 (TIM_AF1_ETRSEL_3 | TIM_AF1_ETRSEL_2 | TIM_AF1_ETRSEL_0) /* !< ETR input is connected to ADC3 analog watchdog 1 */ +#define TIM_ETR_ADC3_AWD2 (TIM_AF1_ETRSEL_3 | TIM_AF1_ETRSEL_2 | TIM_AF1_ETRSEL_1) /* !< ETR input is connected to ADC3 analog watchdog 2 */ +#define TIM_ETR_ADC3_AWD3 TIM_AF1_ETRSEL /* !< ETR input is connected to ADC3 analog watchdog 3 */ +#define IS_TIM_ETRSEL_LIST1_REMAP(REMAP) (((REMAP) == TIM_ETR_GPIO ) || \ + ((REMAP) == TIM_ETR_COMP1 ) || \ + ((REMAP) == TIM_ETR_COMP2 ) || \ + ((REMAP) == TIM_ETR_COMP3 ) || \ + ((REMAP) == TIM_ETR_COMP4 ) || \ + ((REMAP) == TIM_ETR_COMP5 ) || \ + ((REMAP) == TIM_ETR_COMP6 ) || \ + ((REMAP) == TIM_ETR_ADC1_AWD1) || \ + ((REMAP) == TIM_ETR_ADC1_AWD2) || \ + ((REMAP) == TIM_ETR_ADC1_AWD3) || \ + ((REMAP) == TIM_ETR_ADC2_AWD1) || \ + ((REMAP) == TIM_ETR_ADC2_AWD2) || \ + ((REMAP) == TIM_ETR_ADC2_AWD3) || \ + ((REMAP) == TIM_ETR_ADC3_AWD1) || \ + ((REMAP) == TIM_ETR_ADC3_AWD2) || \ + ((REMAP) == TIM_ETR_ADC3_AWD3)) + +#define TIM_ETR_1 TIM_AF1_ETRSEL_0 /* !< ETR input is connected to ETR[ 1] */ +#define TIM_ETR_2 TIM_AF1_ETRSEL_1 /* !< ETR input is connected to ETR[ 2] */ +#define TIM_ETR_3 (TIM_AF1_ETRSEL_1 | TIM_AF1_ETRSEL_0) /* !< ETR input is connected to ETR[ 3] */ +#define TIM_ETR_4 TIM_AF1_ETRSEL_2 /* !< ETR input is connected to ETR[ 4] */ +#define TIM_ETR_5 (TIM_AF1_ETRSEL_2 | TIM_AF1_ETRSEL_0) /* !< ETR input is connected to ETR[ 5] */ +#define TIM_ETR_6 (TIM_AF1_ETRSEL_2 | TIM_AF1_ETRSEL_1) /* !< ETR input is connected to ETR[ 6] */ +#define TIM_ETR_7 (TIM_AF1_ETRSEL_2 | TIM_AF1_ETRSEL_1 | TIM_AF1_ETRSEL_0) /* !< ETR input is connected to ETR[ 7] */ +#define TIM_ETR_8 TIM_AF1_ETRSEL_3 /* !< ETR input is connected to ETR[ 8] */ +#define TIM_ETR_9 (TIM_AF1_ETRSEL_3 | TIM_AF1_ETRSEL_0) /* !< ETR input is connected to ETR[ 9] */ +#define TIM_ETR_10 (TIM_AF1_ETRSEL_3 | TIM_AF1_ETRSEL_1) /* !< ETR input is connected to ETR[10] */ +#define TIM_ETR_11 (TIM_AF1_ETRSEL_3 | TIM_AF1_ETRSEL_1 | TIM_AF1_ETRSEL_0) /* !< ETR input is connected to ETR[11] */ +#define TIM_ETR_12 (TIM_AF1_ETRSEL_3 | TIM_AF1_ETRSEL_2) /* !< ETR input is connected to ETR[12] */ +#define TIM_ETR_13 (TIM_AF1_ETRSEL_3 | TIM_AF1_ETRSEL_2 | TIM_AF1_ETRSEL_0) /* !< ETR input is connected to ETR[13] */ +#define TIM_ETR_14 (TIM_AF1_ETRSEL_3 | TIM_AF1_ETRSEL_2 | TIM_AF1_ETRSEL_1) /* !< ETR input is connected to ETR[14] */ +#define TIM_ETR_15 TIM_AF1_ETRSEL /* !< ETR input is connected to ETR[15] */ +#define IS_TIM_ETRSEL_LIST2_REMAP(REMAP) (((REMAP) == TIM_ETR_GPIO) || \ + ((REMAP) == TIM_ETR_1 ) || \ + ((REMAP) == TIM_ETR_2 ) || \ + ((REMAP) == TIM_ETR_3 ) || \ + ((REMAP) == TIM_ETR_4 ) || \ + ((REMAP) == TIM_ETR_5 ) || \ + ((REMAP) == TIM_ETR_6 ) || \ + ((REMAP) == TIM_ETR_7 ) || \ + ((REMAP) == TIM_ETR_8 ) || \ + ((REMAP) == TIM_ETR_9 ) || \ + ((REMAP) == TIM_ETR_10 ) || \ + ((REMAP) == TIM_ETR_11 ) || \ + ((REMAP) == TIM_ETR_12 ) || \ + ((REMAP) == TIM_ETR_13 ) || \ + ((REMAP) == TIM_ETR_14 ) || \ + ((REMAP) == TIM_ETR_15 )) + +/** + * @} + */ + +/** @defgroup TIM_OCRSel_Remap + * @{ + */ + +#define TIM_OCR_COMP1 (uint32_t)0x00000000 /* !< OCxref clear source select COMP1_OUT */ +#define TIM_OCR_COMP2 (uint32_t)0x00000001 /* !< OCxref clear source select COMP2_OUT */ +#define TIM_OCR_COMP3 (uint32_t)0x00000002 /* !< OCxref clear source select COMP3_OUT */ +#define TIM_OCR_COMP4 (uint32_t)0x00000003 /* !< OCxref clear source select COMP4_OUT */ +#define TIM_OCR_COMP5 (uint32_t)0x00000004 /* !< OCxref clear source select COMP5_OUT */ +#define TIM_OCR_COMP6 (uint32_t)0x00000005 /* !< OCxref clear source select COMP6_OUT */ +#define IS_TIM_OCRSEL_LIST1_REMAP(REMAP) (((REMAP) == TIM_OCR_COMP1) || \ + ((REMAP) == TIM_OCR_COMP2) || \ + ((REMAP) == TIM_OCR_COMP3) || \ + ((REMAP) == TIM_OCR_COMP4) || \ + ((REMAP) == TIM_OCR_COMP5) || \ + ((REMAP) == TIM_OCR_COMP6)) + +#define TIM_OCR_CLEAR_0 0x00000000U /* !< OCxref clear source select ocrefcr[0] */ +#define TIM_OCR_CLEAR_1 TIM_AF2_OCRSEL_0 /* !< OCxref clear source select ocrefcr[1] */ +#define TIM_OCR_CLEAR_2 TIM_AF2_OCRSEL_1 /* !< OCxref clear source select ocrefcr[2] */ +#define TIM_OCR_CLEAR_3 (TIM_AF2_OCRSEL_1 | TIM_AF2_OCRSEL_0) /* !< OCxref clear source select ocrefcr[3] */ +#define TIM_OCR_CLEAR_4 TIM_AF2_OCRSEL_2 /* !< OCxref clear source select ocrefcr[4] */ +#define TIM_OCR_CLEAR_5 (TIM_AF2_OCRSEL_2 | TIM_AF2_OCRSEL_0) /* !< OCxref clear source select ocrefcr[5] */ +#define TIM_OCR_CLEAR_6 (TIM_AF2_OCRSEL_2 | TIM_AF2_OCRSEL_1) /* !< OCxref clear source select ocrefcr[6] */ +#define TIM_OCR_CLEAR_7 TIM_AF2_OCRSEL /* !< OCxref clear source select ocrefcr[7] */ +#define IS_TIM_OCRSEL_LIST2_REMAP(REMAP) (((REMAP) == TIM_OCR_CLEAR_0) || \ + ((REMAP) == TIM_OCR_CLEAR_1) || \ + ((REMAP) == TIM_OCR_CLEAR_2) || \ + ((REMAP) == TIM_OCR_CLEAR_3) || \ + ((REMAP) == TIM_OCR_CLEAR_4) || \ + ((REMAP) == TIM_OCR_CLEAR_5) || \ + ((REMAP) == TIM_OCR_CLEAR_6) || \ + ((REMAP) == TIM_OCR_CLEAR_7)) + + +/** + * @} + */ + +/** @defgroup TIM_TISel_Remap + * @{ + */ + +#define TIM_TI1_CH1 0x00000000U /* !< TIM_CH1 input select GPIO */ +#define TIM_TI1_COMP1 TIM_TISEL_TI1SEL_0 /* !< TIM_CH1 input select COMP1_OUT */ +#define TIM_TI1_COMP2 TIM_TISEL_TI1SEL_1 /* !< TIM_CH1 input select COMP2_OUT */ +#define TIM_TI1_COMP3 (TIM_TISEL_TI1SEL_1 | TIM_TISEL_TI1SEL_0) /* !< TIM_CH1 input select COMP3_OUT */ +#define TIM_TI1_COMP4 TIM_TISEL_TI1SEL_2 /* !< TIM_CH1 input select COMP4_OUT */ +#define TIM_TI1_COMP5 (TIM_TISEL_TI1SEL_2 | TIM_TISEL_TI1SEL_0) /* !< TIM_CH1 input select COMP5_OUT */ +#define TIM_TI1_COMP6 (TIM_TISEL_TI1SEL_2 | TIM_TISEL_TI1SEL_1) /* !< TIM_CH1 input select COMP6_OUT */ +#define IS_TIM_TISEL_LIST1_REMAP(REMAP) (((REMAP) == TIM_TI1_CH1 ) || \ + ((REMAP) == TIM_TI1_COMP1) || \ + ((REMAP) == TIM_TI1_COMP2) || \ + ((REMAP) == TIM_TI1_COMP3) || \ + ((REMAP) == TIM_TI1_COMP4) || \ + ((REMAP) == TIM_TI1_COMP5) || \ + ((REMAP) == TIM_TI1_COMP6)) + +#define TIM_TI_CH 0x00000000U /* !< TIM_CH input select GPIO */ +#define TIM_TI_I1 TIM_TISEL_TI1SEL_0 /* !< TIM_CH input select ti_i[ 1] */ +#define TIM_TI_I2 TIM_TISEL_TI1SEL_1 /* !< TIM_CH input select ti_i[ 2] */ +#define TIM_TI_I3 (TIM_TISEL_TI1SEL_1 | TIM_TISEL_TI1SEL_0 ) /* !< TIM_CH input select ti_i[ 3] */ +#define TIM_TI_I4 TIM_TISEL_TI1SEL_2 /* !< TIM_CH input select ti_i[ 4] */ +#define TIM_TI_I5 (TIM_TISEL_TI1SEL_2 | TIM_TISEL_TI1SEL_0 ) /* !< TIM_CH input select ti_i[ 5] */ +#define TIM_TI_I6 (TIM_TISEL_TI1SEL_2 | TIM_TISEL_TI1SEL_1 ) /* !< TIM_CH input select ti_i[ 6] */ +#define TIM_TI_I7 (TIM_TISEL_TI1SEL_2 | TIM_TISEL_TI1SEL_1 | TIM_TISEL_TI1SEL_0) /* !< TIM_CH input select ti_i[ 7] */ +#define TIM_TI_I8 TIM_TISEL_TI1SEL_3 /* !< TIM_CH input select ti_i[ 8] */ +#define TIM_TI_I9 (TIM_TISEL_TI1SEL_3 | TIM_TISEL_TI1SEL_0 ) /* !< TIM_CH input select ti_i[ 9] */ +#define TIM_TI_I10 (TIM_TISEL_TI1SEL_3 | TIM_TISEL_TI1SEL_1 ) /* !< TIM_CH input select ti_i[10] */ +#define TIM_TI_I11 (TIM_TISEL_TI1SEL_3 | TIM_TISEL_TI1SEL_1 | TIM_TISEL_TI1SEL_0) /* !< TIM_CH input select ti_i[11] */ +#define TIM_TI_I12 (TIM_TISEL_TI1SEL_3 | TIM_TISEL_TI1SEL_2 ) /* !< TIM_CH input select ti_i[12] */ +#define TIM_TI_I13 (TIM_TISEL_TI1SEL_3 | TIM_TISEL_TI1SEL_2 | TIM_TISEL_TI1SEL_0) /* !< TIM_CH input select ti_i[13] */ +#define TIM_TI_I14 (TIM_TISEL_TI1SEL_3 | TIM_TISEL_TI1SEL_2 | TIM_TISEL_TI1SEL_1) /* !< TIM_CH input select ti_i[14] */ +#define TIM_TI_I15 TIM_TISEL_TI1SEL /* !< TIM_CH input select ti_i[15] */ +#define IS_TIM_TISEL_LIST2_REMAP(REMAP) (((REMAP) == TIM_TI_CH ) || \ + ((REMAP) == TIM_TI_I1 ) || \ + ((REMAP) == TIM_TI_I2 ) || \ + ((REMAP) == TIM_TI_I3 ) || \ + ((REMAP) == TIM_TI_I4 ) || \ + ((REMAP) == TIM_TI_I5 ) || \ + ((REMAP) == TIM_TI_I6 ) || \ + ((REMAP) == TIM_TI_I7 ) || \ + ((REMAP) == TIM_TI_I8 ) || \ + ((REMAP) == TIM_TI_I9 ) || \ + ((REMAP) == TIM_TI_I10) || \ + ((REMAP) == TIM_TI_I11) || \ + ((REMAP) == TIM_TI_I12) || \ + ((REMAP) == TIM_TI_I13) || \ + ((REMAP) == TIM_TI_I14) || \ + ((REMAP) == TIM_TI_I15)) + +/** + * @} + */ + +/** @defgroup TIM_TISel_Channel + * @{ + */ + +#define TIM_TISel_Channel1 (uint32_t)0x00000000 /* !< TIM_CH input select channel1 */ +#define TIM_TISel_Channel2 (uint32_t)0x00000008 /* !< TIM_CH input select channel2 */ +#define TIM_TISel_Channel3 (uint32_t)0x00000010 /* !< TIM_CH input select channel3 */ +#define TIM_TISel_Channel4 (uint32_t)0x00000018 /* !< TIM_CH input select channel4 */ + +/** + * @} + */ + +/** @defgroup TIM_Break_Input_Source TIM Extended Break input source + * @{ + */ + +#define TIM_BREAKINPUTSOURCE_BKIN TIM_AF_BKINE /* !< An external source (GPIO) is connected to the BKIN pin */ +#define TIM_BREAKINPUTSOURCE_COMP1 TIM_AF_BKCMP1E /* !< The COMP1 output is connected to the break input */ +#define TIM_BREAKINPUTSOURCE_COMP2 TIM_AF_BKCMP2E /* !< The COMP2 output is connected to the break input */ +#define TIM_BREAKINPUTSOURCE_COMP3 TIM_AF_BKCMP3E /* !< The COMP3 output is connected to the break input */ +#define TIM_BREAKINPUTSOURCE_COMP4 TIM_AF_BKCMP4E /* !< The COMP4 output is connected to the break input */ +#define TIM_BREAKINPUTSOURCE_COMP5 TIM_AF_BKCMP5E /* !< The COMP5 output is connected to the break input */ +#define TIM_BREAKINPUTSOURCE_COMP6 TIM_AF_BKCMP6E /* !< The COMP6 output is connected to the break input */ +#define IS_TIM_BREAKINPUTSOURCE(SOURCE) (((SOURCE) == TIM_BREAKINPUTSOURCE_BKIN ) || \ + ((SOURCE) == TIM_BREAKINPUTSOURCE_COMP1) || \ + ((SOURCE) == TIM_BREAKINPUTSOURCE_COMP2) || \ + ((SOURCE) == TIM_BREAKINPUTSOURCE_COMP3) || \ + ((SOURCE) == TIM_BREAKINPUTSOURCE_COMP4) || \ + ((SOURCE) == TIM_BREAKINPUTSOURCE_COMP5) || \ + ((SOURCE) == TIM_BREAKINPUTSOURCE_COMP6)) + +/** + * @} + */ + +/** @defgroup TIM_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 */ +#define IS_TIM_BREAKINPUTSOURCE_STATE(STATE) (((STATE) == TIM_BREAKINPUTSOURCE_DISABLE) || \ + ((STATE) == TIM_BREAKINPUTSOURCE_ENABLE )) + +/** + * @} + */ + +/** @defgroup TIM_Break_Input_Source_Polarity TIM Extended Break input polarity + * @{ + */ + +#define TIM_BREAKINPUTSOURCE_POLARITY_INVERTED 0x00000001U /* !< Break input source is inverted + (active high if BKP = 0, active low if BKP = 1) */ +#define TIM_BREAKINPUTSOURCE_POLARITY_NOT_INVERTED 0x00000000U /* !< Break input source is not inverted + (active low if BKP = 0, active high if BKP = 1) */ +#define IS_TIM_BREAKINPUTSOURCE_POLARITY(POLARITY) (((POLARITY) == TIM_BREAKINPUTSOURCE_POLARITY_INVERTED ) || \ + ((POLARITY) == TIM_BREAKINPUTSOURCE_POLARITY_NOT_INVERTED)) + +/** + * @} + */ + +/** @defgroup TIM_AF1 + * @{ + */ +#define TIM_AF_BKINE_Pos (0U) +#define TIM_AF_BKCMP1E_Pos (1U) +#define TIM_AF_BKCMP2E_Pos (2U) +#define TIM_AF_BKCMP3E_Pos (3U) +#define TIM_AF_BKCMP4E_Pos (4U) +#define TIM_AF_BKCMP5E_Pos (5U) +#define TIM_AF_BKCMP6E_Pos (6U) + +#define TIM_AF_BKINP_Pos (9U) +#define TIM_AF_BKCMP1P_Pos (10U) +#define TIM_AF_BKCMP2P_Pos (11U) +#define TIM_AF_BKCMP3P_Pos (12U) +#define TIM_AF_BKCMP4P_Pos (13U) + +/** + * @} + */ + +/** @defgroup TIM_Legacy + * @{ + */ + +#define TIM_DMABurstLength_1Byte TIM_DMABurstLength_1Transfer +#define TIM_DMABurstLength_2Bytes TIM_DMABurstLength_2Transfers +#define TIM_DMABurstLength_3Bytes TIM_DMABurstLength_3Transfers +#define TIM_DMABurstLength_4Bytes TIM_DMABurstLength_4Transfers +#define TIM_DMABurstLength_5Bytes TIM_DMABurstLength_5Transfers +#define TIM_DMABurstLength_6Bytes TIM_DMABurstLength_6Transfers +#define TIM_DMABurstLength_7Bytes TIM_DMABurstLength_7Transfers +#define TIM_DMABurstLength_8Bytes TIM_DMABurstLength_8Transfers +#define TIM_DMABurstLength_9Bytes TIM_DMABurstLength_9Transfers +#define TIM_DMABurstLength_10Bytes TIM_DMABurstLength_10Transfers +#define TIM_DMABurstLength_11Bytes TIM_DMABurstLength_11Transfers +#define TIM_DMABurstLength_12Bytes TIM_DMABurstLength_12Transfers +#define TIM_DMABurstLength_13Bytes TIM_DMABurstLength_13Transfers +#define TIM_DMABurstLength_14Bytes TIM_DMABurstLength_14Transfers +#define TIM_DMABurstLength_15Bytes TIM_DMABurstLength_15Transfers +#define TIM_DMABurstLength_16Bytes TIM_DMABurstLength_16Transfers +#define TIM_DMABurstLength_17Bytes TIM_DMABurstLength_17Transfers +#define TIM_DMABurstLength_18Bytes TIM_DMABurstLength_18Transfers +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +/* TimeBase management ********************************************************/ +void TIM_DeInit(TIM_TypeDef* TIMx); +void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct); +void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct); +void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint32_t Prescaler, uint32_t TIM_PSCReloadMode); +void TIM_CounterModeConfig(TIM_TypeDef* TIMx, uint32_t TIM_CounterMode); +void TIM_SetCounter(TIM_TypeDef* TIMx, uint32_t Counter); +void TIM_SetAutoreload(TIM_TypeDef* TIMx, uint32_t Autoreload); +void TIM_SetRepetitionCounter(TIM_TypeDef* TIMx, uint32_t RepetitionCounter); +uint32_t TIM_GetCounter(TIM_TypeDef* TIMx); +uint32_t TIM_GetPrescaler(TIM_TypeDef* TIMx); +void TIM_UpdateDisableConfig(TIM_TypeDef* TIMx, FunctionalState NewState); +void TIM_UpdateRequestConfig(TIM_TypeDef* TIMx, uint32_t TIM_UpdateSource); +void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState); +void TIM_SelectOnePulseMode(TIM_TypeDef* TIMx, uint32_t TIM_OPMode); +void TIM_SetClockDivision(TIM_TypeDef* TIMx, uint32_t TIM_CKD); +void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState); + +/* Advanced-control timers (TIM1 and TIM8) specific features*******************/ +void TIM_BDTRConfig(TIM_TypeDef* TIMx, TIM_BDTRInitTypeDef* TIM_BDTRInitStruct); +void TIM_BDTRStructInit(TIM_BDTRInitTypeDef* TIM_BDTRInitStruct); +void TIM_ConfigBreakInput(TIM_TypeDef* TIMx, TIM_BreakInputConfigTypeDef* BreakInputConfig); +void TIM_CtrlPWMOutputs(TIM_TypeDef* TIMx, FunctionalState NewState); +void TIM_DisarmBreakInput(TIM_TypeDef* TIMx); +FlagStatus TIM_WaitBkdsrmIsHardwareClear(TIM_TypeDef* TIMx); + +/* Output Compare management **************************************************/ +void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct); +void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct); +void TIM_OC3Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct); +void TIM_OC4Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct); +void TIM_OC5Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct); +void TIM_OC6Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct); +void TIM_GroupChannel5(TIM_TypeDef* TIMx, uint32_t TIM_Group_Channel5); +void TIM_OCStructInit(TIM_OCInitTypeDef* TIM_OCInitStruct); +void TIM_SelectOCxM(TIM_TypeDef* TIMx, uint32_t TIM_Channel, uint32_t TIM_OCMode); +void TIM_SetCompare1(TIM_TypeDef* TIMx, uint32_t Compare1); +void TIM_SetCompare2(TIM_TypeDef* TIMx, uint32_t Compare2); +void TIM_SetCompare3(TIM_TypeDef* TIMx, uint32_t Compare3); +void TIM_SetCompare4(TIM_TypeDef* TIMx, uint32_t Compare4); +void TIM_SetCompare5(TIM_TypeDef* TIMx, uint32_t Compare5); +void TIM_SetCompare6(TIM_TypeDef* TIMx, uint32_t Compare6); +void TIM_ForcedOC1Config(TIM_TypeDef* TIMx, uint32_t TIM_ForcedAction); +void TIM_ForcedOC2Config(TIM_TypeDef* TIMx, uint32_t TIM_ForcedAction); +void TIM_ForcedOC3Config(TIM_TypeDef* TIMx, uint32_t TIM_ForcedAction); +void TIM_ForcedOC4Config(TIM_TypeDef* TIMx, uint32_t TIM_ForcedAction); +void TIM_ForcedOC5Config(TIM_TypeDef* TIMx, uint32_t TIM_ForcedAction); +void TIM_ForcedOC6Config(TIM_TypeDef* TIMx, uint32_t TIM_ForcedAction); +void TIM_CCPreloadControl(TIM_TypeDef* TIMx, FunctionalState NewState); +void TIM_OC1PreloadConfig(TIM_TypeDef* TIMx, uint32_t TIM_OCPreload); +void TIM_OC2PreloadConfig(TIM_TypeDef* TIMx, uint32_t TIM_OCPreload); +void TIM_OC3PreloadConfig(TIM_TypeDef* TIMx, uint32_t TIM_OCPreload); +void TIM_OC4PreloadConfig(TIM_TypeDef* TIMx, uint32_t TIM_OCPreload); +void TIM_OC5PreloadConfig(TIM_TypeDef* TIMx, uint32_t TIM_OCPreload); +void TIM_OC6PreloadConfig(TIM_TypeDef* TIMx, uint32_t TIM_OCPreload); +void TIM_OC1FastConfig(TIM_TypeDef* TIMx, uint32_t TIM_OCFast); +void TIM_OC2FastConfig(TIM_TypeDef* TIMx, uint32_t TIM_OCFast); +void TIM_OC3FastConfig(TIM_TypeDef* TIMx, uint32_t TIM_OCFast); +void TIM_OC4FastConfig(TIM_TypeDef* TIMx, uint32_t TIM_OCFast); +void TIM_OC5FastConfig(TIM_TypeDef* TIMx, uint32_t TIM_OCFast); +void TIM_OC6FastConfig(TIM_TypeDef* TIMx, uint32_t TIM_OCFast); +void TIM_ClearOC1Ref(TIM_TypeDef* TIMx, uint32_t TIM_OCClear); +void TIM_ClearOC2Ref(TIM_TypeDef* TIMx, uint32_t TIM_OCClear); +void TIM_ClearOC3Ref(TIM_TypeDef* TIMx, uint32_t TIM_OCClear); +void TIM_ClearOC4Ref(TIM_TypeDef* TIMx, uint32_t TIM_OCClear); +void TIM_ClearOC5Ref(TIM_TypeDef* TIMx, uint32_t TIM_OCClear); +void TIM_ClearOC6Ref(TIM_TypeDef* TIMx, uint32_t TIM_OCClear); +void TIM_OC1PolarityConfig(TIM_TypeDef* TIMx, uint32_t TIM_OCPolarity); +void TIM_OC1NPolarityConfig(TIM_TypeDef* TIMx, uint32_t TIM_OCNPolarity); +void TIM_OC2PolarityConfig(TIM_TypeDef* TIMx, uint32_t TIM_OCPolarity); +void TIM_OC2NPolarityConfig(TIM_TypeDef* TIMx, uint32_t TIM_OCNPolarity); +void TIM_OC3PolarityConfig(TIM_TypeDef* TIMx, uint32_t TIM_OCPolarity); +void TIM_OC3NPolarityConfig(TIM_TypeDef* TIMx, uint32_t TIM_OCNPolarity); +void TIM_OC4PolarityConfig(TIM_TypeDef* TIMx, uint32_t TIM_OCPolarity); +void TIM_OC5PolarityConfig(TIM_TypeDef* TIMx, uint32_t TIM_OCPolarity); +void TIM_OC6PolarityConfig(TIM_TypeDef* TIMx, uint32_t TIM_OCPolarity); +void TIM_SelectOCREFClear(TIM_TypeDef* TIMx, uint32_t TIM_OCReferenceClear); +void TIM_CCxCmd(TIM_TypeDef* TIMx, uint32_t TIM_Channel, uint32_t TIM_CCx); +void TIM_CCxNCmd(TIM_TypeDef* TIMx, uint32_t TIM_Channel, uint32_t TIM_CCxN); +void TIM_SelectCOM(TIM_TypeDef* TIMx, FunctionalState NewState); + +/* Input Capture management ***************************************************/ +void TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct); +void TIM_ICStructInit(TIM_ICInitTypeDef* TIM_ICInitStruct); +void TIM_PWMIConfig(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct); +uint32_t TIM_GetCapture1(TIM_TypeDef* TIMx); +uint32_t TIM_GetCapture2(TIM_TypeDef* TIMx); +uint32_t TIM_GetCapture3(TIM_TypeDef* TIMx); +uint32_t TIM_GetCapture4(TIM_TypeDef* TIMx); +uint32_t TIM_GetCapture5(TIM_TypeDef* TIMx); +uint32_t TIM_GetCapture6(TIM_TypeDef* TIMx); +void TIM_SetIC1Prescaler(TIM_TypeDef* TIMx, uint32_t TIM_ICPSC); +void TIM_SetIC2Prescaler(TIM_TypeDef* TIMx, uint32_t TIM_ICPSC); +void TIM_SetIC3Prescaler(TIM_TypeDef* TIMx, uint32_t TIM_ICPSC); +void TIM_SetIC4Prescaler(TIM_TypeDef* TIMx, uint32_t TIM_ICPSC); + +/* Interrupts, DMA and flags management ***************************************/ +void TIM_ITConfig(TIM_TypeDef* TIMx, uint32_t TIM_IT, FunctionalState NewState); +void TIM_GenerateEvent(TIM_TypeDef* TIMx, uint32_t TIM_EventSource); +FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint32_t TIM_FLAG); +void TIM_ClearFlag(TIM_TypeDef* TIMx, uint32_t TIM_FLAG); +ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint32_t TIM_IT); +void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint32_t TIM_IT); +void TIM_DMAConfig(TIM_TypeDef* TIMx, uint32_t TIM_DMABase, uint32_t TIM_DMABurstLength); +void TIM_DMACmd(TIM_TypeDef* TIMx, uint32_t TIM_DMASource, FunctionalState NewState); +void TIM_SelectCCDMA(TIM_TypeDef* TIMx, FunctionalState NewState); + +/* Clocks management **********************************************************/ +void TIM_InternalClockConfig(TIM_TypeDef* TIMx); +void TIM_ITRxExternalClockConfig(TIM_TypeDef* TIMx, uint32_t TIM_InputTriggerSource); +void TIM_TIxExternalClockConfig(TIM_TypeDef* TIMx, uint32_t TIM_TIxExternalCLKSource, + uint32_t TIM_ICPolarity, uint32_t ICFilter); +void TIM_ETRClockMode1Config(TIM_TypeDef* TIMx, uint32_t TIM_ExtTRGPrescaler, + uint32_t TIM_ExtTRGPolarity, uint32_t ExtTRGFilter); +void TIM_ETRClockMode2Config(TIM_TypeDef* TIMx, uint32_t TIM_ExtTRGPrescaler, + uint32_t TIM_ExtTRGPolarity, uint32_t ExtTRGFilter); + + +/* Synchronization management *************************************************/ +void TIM_SelectInputTrigger(TIM_TypeDef* TIMx, uint32_t TIM_InputTriggerSource); +void TIM_SelectOutputTrigger(TIM_TypeDef* TIMx, uint32_t TIM_TRGOSource); +void TIM_SelectOutputTrigger2(TIM_TypeDef* TIMx, uint32_t TIM_TRGO2Source); +void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint32_t TIM_SlaveMode); +void TIM_SelectMasterSlaveMode(TIM_TypeDef* TIMx, uint32_t TIM_MasterSlaveMode); +void TIM_ETRConfig(TIM_TypeDef* TIMx, uint32_t TIM_ExtTRGPrescaler, uint32_t TIM_ExtTRGPolarity, + uint32_t ExtTRGFilter); + +/* Specific interface management **********************************************/ +void TIM_EncoderInterfaceConfig(TIM_TypeDef* TIMx, uint32_t TIM_EncoderMode, + uint32_t TIM_IC1Polarity, uint32_t TIM_IC2Polarity); +void TIM_SelectHallSensor(TIM_TypeDef* TIMx, FunctionalState NewState); + +/* Specific remapping management **********************************************/ +/* For TIM2 & TIM11 OR register */ +void TIM_RemapConfig(TIM_TypeDef* TIMx, uint32_t TIM_Remap); +/* For TIM1/TIM8 and TIM2-5 ETRSEL bits of AF1 register */ +void TIM_ETRSelRemapConfig(TIM_TypeDef* TIMx, uint32_t TIM_ETRSel_Remap); +/* For TIM1/TIM8 and TIM2-5 AF2 register */ +void TIM_OCRSelRemapConfig(TIM_TypeDef* TIMx, uint32_t TIM_OCRSel_Remap); +/* For TIM1/TIM8 and TIM2-5 TISEL register */ +void TIM_TISelRemapConfig(TIM_TypeDef* TIMx, uint32_t TIM_TISel_Channel, uint32_t TIM_TISel_Remap); + + +#ifdef __cplusplus +} +#endif + +#endif /*__FT32F4XX_TIM_H */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_uart.h b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_uart.h new file mode 100644 index 00000000000..07348b0281c --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_uart.h @@ -0,0 +1,917 @@ +/** + * @file ft32f4xx_uart.h + * @author FMD AE + * @brief This file contains all the functions prototypes for the UART + * fireware library. + * @version V1.0.0 + * @date 2025-03-28 + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __FT32F4XX_UART_H +#define __FT32F4XX_UART_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx.h" + +/** @addtogroup ft32f4xx_Driver + * @{ + */ + +/** @addtogroup UART + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup UART_Exported_Types SART Exported Types + * @{ + */ + +/** + * @brief UART Init Structure definition + */ +typedef struct +{ + uint32_t UART_BaudRate; /*!< This member configures the UART communication baud rate. + The baud rate is computed using the following formula: + - CD = 0: Disable baud rate clock + + - Asynchronous mode + - X16 : IntegerDivider = ((PCLKx) / (16 * (UART_InitStruct->UART_BaudRate))) + - X8 : IntegerDivider = ((PCLKx) / (8 * (UART_InitStruct->UART_BaudRate))) + */ + + uint32_t UART_FiDiRatio; /*!< Specifies the value of FI over DI ratio value in IrDA mode. + @note This parameter is valid only for UART4, UART5 and UART7, except for LPUART.*/ + + uint32_t UART_IrDAFilter; /*!< Specifies the value of IrDA filter in IrDA mode. + @note This parameter is valid only for UART4, UART5 and UART7, except for LPUART.*/ + + uint32_t UART_WordLength; /*!< Specifies the number of data bits transmitted or received in a frame. + This parameter can be a value of @ref UART_Char_Length & UART_Char_Length9*/ + + uint32_t UART_StopBits; /*!< Specifies the number of stop bits transmitted. + This parameter can be a value of @ref UART_Stop_Bits*/ + + uint32_t UART_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 UART_Mode; /*!< Specifies whether the Receive or Transmit mode is enabled or disabled. + This parameter can be a value of @ref UART_Mode*/ + + uint32_t UART_CLKSelect; /*!< Specifies the selection of clock. + This parameter can be a value of @ref UART_Clock_Select*/ + + uint32_t UART_OperationMode; /*!< Specifies the mode of operation. + This parameter can be a value of @ref UART_Mode_Operation*/ + + uint32_t UART_BitOrder; /*!< Specifies whether the Least or Most Significant Bit is sent/received first. + This parameter can be a value of @ref UART_BIT_ORDER*/ + + uint32_t UART_ChannelMode; /*!< Specifies the channel mode select. + this parameter can be a value of @ref UART_Channel_Mode*/ + + uint32_t UART_OverSampling; /*!< Specifies whether 16x oversampling or 8x oversampling. + This parameter can be a value of @ref UART_OverSampling*/ + + uint32_t UART_INVData; /*!< Specifies whether the data is inverted. + This parameter can be a value of @ref UART_InvertData + @note This parameter is valid only for UART4, UART5 and UART7, except for LPUART.*/ + + uint32_t UART_SYNCDisable; /*!< Specifies whether disable the synchronization in LIN mode. + This parameter can be a value of @ref UART_Sync_Disable + @note This parameter is valid only for UART4, UART5 and UART7, except for LPUART.*/ + + uint32_t UART_PDCMode; /*!< Specifies the DMA mode selection in LIN mode. + This parameter can be a value of @ref UART_PDC_Mode + @note This parameter is valid only for UART4, UART5 and UART7, except for LPUART.*/ + + uint32_t UART_DataLengthControl; /*!< Specifies define the response data length when DataLengthMode = 0 in LIN mode. + 0-255: the response data length is equal to DLC+1 bytes. + @note This parameter is valid only for UART4, UART5 and UART7, except for LPUART.*/ + + uint32_t UART_WkupType; /*!< Specifies whether the wakeup signal type is LIN2.0 wakup signal or LIN1.3 wakup signal. + This parameter can be a value of @ref UART_Wkup_Type + @note This parameter is valid only for UART4, UART5 and UART7, except for LPUART.*/ + + uint32_t UART_FrameSlotDisable; /*!< Specifies whether disable the frame slot mode in LIN mode. + This parameter can be a value of @ref UART_Frame_Slot_Disable + @note This parameter is valid only for UART4, UART5 and UART7, except for LPUART.*/ + + uint32_t UART_DataLengthMode; /*!< Specifies the data length mode in LIN mode. + This parameter can be a value of @ref UART_Data_Length_Mode + @note This parameter is valid only for UART4, UART5 and UART7, except for LPUART.*/ + + uint32_t UART_CheckSumType; /*!< Specifies the checksum type in LIN mode. + This parameter can be a value of @ref UART_Checksum_Type + @note This parameter is valid only for UART4, UART5 and UART7, except for LPUART.*/ + + uint32_t UART_CheckSumDisable; /*!< Specifies whether disable the checksum in LIN mode. + This parameter can be a value of @ref UART_Checksum_Disable + @note This parameter is valid only for UART4, UART5 and UART7, except for LPUART.*/ + + uint32_t UART_ParityDisable; /*!< Specifies whether disable the parity in LIN mode. + This parameter can be a value of @ref UART_Parity_Disable + @note This parameter is valid only for UART4, UART5 and UART7, except for LPUART.*/ + + uint32_t UART_NodeAction; /*!< Specifies the LIN Node Active. + This parameter can be a value of @ref UART_Node_Active + @note This parameter is valid only for UART4, UART5 and UART7, except for LPUART.*/ + +} UART_InitTypeDef; + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup UART_Exported_Constants UART Exported Constants + * @{ + */ + +#define IS_UART_ALL_PERIPH(PERIPH) ( \ + ((PERIPH) == UART4 ) || \ + ((PERIPH) == UART5 ) || \ + ((PERIPH) == UART7 ) || \ + ((PERIPH) == LPUART) \ + ) + +#define IS_UART_45_PERIPH(PERIPH) ( \ + ((PERIPH) == UART4 ) || \ + ((PERIPH) == UART5 ) \ + ) + +#define IS_UART_457_PERIPH(PERIPH) ( \ + ((PERIPH) == UART4 ) || \ + ((PERIPH) == UART5 ) || \ + ((PERIPH) == UART7 ) \ + ) + +#define IS_UART_LP_PERIPH(PERIPH) ( \ + ((PERIPH) == LPUART) \ + ) + +/** @defgroup UART_InvertData UART Invert Data + * @{ + */ +#define UART_INVDATA_DISABLE ((uint32_t)0x00000000U) /*!< UART invert data disbale */ +#define UART_INVDATA_ENABLE USART_MR_INVDATA /*!< UART invert data enable */ + +#define IS_UART_INVDATA(INVDATA) \ + ( \ + ((INVDATA) == UART_INVDATA_DISABLE) || \ + ((INVDATA) == UART_INVDATA_ENABLE ) \ + ) +/** + * @} + */ + +/** @defgroup UART_OverSampling UART Oversampling mode + * @{ + */ +#define UART_OVERSAMPLING_16 ((uint32_t)0x00000000U) /*!< UART 16x sampling */ +#define UART_OVERSAMPLING_8 USART_MR_OVER /*!< UART 8x sampling */ + +#define IS_UART_OVERSAMPLING(OVERSAMPLING) \ + ( \ + ((OVERSAMPLING) == UART_OVERSAMPLING_16) || \ + ((OVERSAMPLING) == UART_OVERSAMPLING_8 ) \ + ) +/** + * @} + */ + +/** @defgroup UART_Char_Length9 UART 9-bit character length + * @{ + */ +#define UART_CHAR_LENGTH9_DISABLE ((uint32_t)0x00000000U) /*!< UART CHRL defined character length */ +#define UART_CHAR_LENGTH9_ENABLE USART_MR_MODE9 /*!< UART 9-bit character length */ + +/** + * @} + */ + +/** @defgroup UART_BIT_ORDER UART bit order + * @{ + */ +#define UART_BIT_ORDER_LSBF ((uint32_t)0x00000000U) /*!< UART Least Significant Bit is sent/received first */ +#define UART_BIT_ORDER_MSBF USART_MR_MSBF /*!< UART Most Significant Bit is sent/received first */ + +#define IS_UART_BIT_ORDER(ORDER) \ + ( \ + ((ORDER) == UART_BIT_ORDER_LSBF) || \ + ((ORDER) == UART_BIT_ORDER_MSBF) \ + ) +/** + * @} + */ + +/** @defgroup UART_Channel_Mode UART channel mode + * @{ + */ +#define UART_CHANNEL_MODE_NORMAL (0x0UL << 14U ) /*!< UART operates in normal mode */ +#define UART_CHANNEL_MODE_AUTOMATIC (0x1UL << 14U ) /*!< UART operates in automatic echo mode */ +#define UART_CHANNEL_MODE_LOCAL_LOOPBACK (0x2UL << 14U ) /*!< UART operates in local loopback mode */ +#define UART_CHANNEL_MODE_REMOTE_LOOPBACK (0x3UL << 14U ) /*!< UART operates in remote loopback mode */ + +#define IS_UART_CHANNEL_MODE(MODE) \ + ( \ + ((MODE) == UART_CHANNEL_MODE_NORMAL ) || \ + ((MODE) == UART_CHANNEL_MODE_AUTOMATIC ) || \ + ((MODE) == UART_CHANNEL_MODE_LOCAL_LOOPBACK ) || \ + ((MODE) == UART_CHANNEL_MODE_REMOTE_LOOPBACK) \ + ) +/** + * @} + */ + +/** @defgroup UART_Stop_Bits UART Number of Stop Bits + * @{ + */ +#define UART_STOPBITS_1 ((uint32_t)0x00000000U) /*!< UART frame with 1 stop bit */ +#define UART_STOPBITS_1_5 (0x1UL << 12U) /*!< UART frame with 1.5 stop bits */ +#define UART_STOPBITS_2 (0x2UL << 12U) /*!< UART frame with 2 stop bits */ + +#define IS_UART_STOPBITS(STOPBITS) \ + ( \ + ((STOPBITS) == UART_STOPBITS_1 ) || \ + ((STOPBITS) == UART_STOPBITS_1_5) || \ + ((STOPBITS) == UART_STOPBITS_2 ) \ + ) +/** + * @} + */ + +/** @defgroup UART_Parity UART Parity + * @{ + */ +#define UART_PARITY_EVEN (0x0 << 9U) /*!< Even parity */ +#define UART_PARITY_ODD (0x1 << 9U) /*!< Odd parity */ +#define UART_PARITY_SPACE (0x2 << 9U) /*!< Space parity */ +#define UART_PARITY_MARK (0x3 << 9U) /*!< Mark parity */ +#define UART_PARITY_NONE (0x4 << 9U) /*!< No parity */ +#define UART_PARITY_MULTIDROP (0x6 << 9U) /*!< Multidrop Mode */ + +#define IS_UART_PARITY(PARITY) \ + ( \ + ((PARITY) == UART_PARITY_EVEN ) || \ + ((PARITY) == UART_PARITY_ODD ) || \ + ((PARITY) == UART_PARITY_SPACE ) || \ + ((PARITY) == UART_PARITY_MARK ) || \ + ((PARITY) == UART_PARITY_NONE ) || \ + ((PARITY) == UART_PARITY_MULTIDROP) \ + ) +/** + * @} + */ + +/** @defgroup UART_Char_Length UART character length + * @{ + */ +#define UART_CHAR_LENGTH_5BIT ((uint32_t)0x00000000U) /*!< UART charcter length is 5bits */ +#define UART_CHAR_LENGTH_6BIT (0x1U << 6U) /*!< UART charcter length is 6bits */ +#define UART_CHAR_LENGTH_7BIT (0x2U << 6U) /*!< UART charcter length is 7bits */ +#define UART_CHAR_LENGTH_8BIT (0x3U << 6U) /*!< UART charcter length is 8bits */ + +#define IS_UART_CHAR_LENGTH(LENGTH) \ + ( \ + ((LENGTH) == UART_CHAR_LENGTH_5BIT) || \ + ((LENGTH) == UART_CHAR_LENGTH_6BIT) || \ + ((LENGTH) == UART_CHAR_LENGTH_7BIT) || \ + ((LENGTH) == UART_CHAR_LENGTH_8BIT) || \ + ((LENGTH) == UART_CHAR_LENGTH9_DISABLE) || \ + ((LENGTH) == UART_CHAR_LENGTH9_ENABLE ) \ + ) +/** + * @} + */ + +/** @defgroup UART_Clock_Select UART clock select + * @{ + */ +#define UART_CLOCK_SELECT_MCK ((uint32_t)0x00000000U) /*!< UART clock source MCK */ +#define UART_CLOCK_SELECT_MCKDIV8 (0x1U << 4U) /*!< UART clock source MCK / 8 */ + +#define IS_UART_CLOCK_SELECT(SELECT) \ + ( \ + ((SELECT) == UART_CLOCK_SELECT_MCK ) || \ + ((SELECT) == UART_CLOCK_SELECT_MCKDIV8) \ + ) +/** + * @} + */ + +/** @defgroup UART_Mode_Operation UART mode of operation + * @{ + */ +#define UART_MODE_OPERATION_NORMAL ((uint32_t)0x00000000U) /*!< UART mode of operation select normal */ +#define UART_MODE_OPERATION_IrDA (0x8U << 0U) /*!< UART mode of operation select irda + @note This define is valid only for UART4, UART5 and UART7, except for LPUART.*/ +#define UART_MODE_OPERATION_LIN_MASTER (0xAU << 0U) /*!< UART mode of operation select lin master + @note This define is valid only for UART4, UART5 and UART7, except for LPUART.*/ +#define UART_MODE_OPERATION_LIN_SLAVE (0xBU << 0U) /*!< UART mode of operation select lin slave + @note This define is valid only for UART4, UART5 and UART7, except for LPUART.*/ + +#define IS_UART_MODE_OPERATION(OPERATION) \ + ( \ + ((OPERATION) == UART_MODE_OPERATION_NORMAL ) || \ + ((OPERATION) == UART_MODE_OPERATION_IrDA ) || \ + ((OPERATION) == UART_MODE_OPERATION_LIN_MASTER ) || \ + ((OPERATION) == UART_MODE_OPERATION_LIN_SLAVE ) \ + ) +/** + * @} + */ + +/** @defgroup UART_Mode UART Mode + * @{ + */ +#define UART_MODE_RX USART_CR_RXEN /*!< RX mode */ +#define UART_MODE_TX USART_CR_TXEN /*!< TX mode */ +#define UART_MODE_TX_RX (USART_CR_TXEN | USART_CR_RXEN) /*!< RX and TX mode */ +#define IS_UART_MODE(MODE) \ + ( \ + ((MODE) == UART_MODE_RX ) || \ + ((MODE) == UART_MODE_TX ) || \ + ((MODE) == UART_MODE_TX_RX) \ + ) +/** + * @} + */ + +/** @defgroup UART_Sync_Disable UART synchronization disable in lin mode + * @{ + */ +#define UART_SYNC_DISABLE_NONE ((uint32_t)0x00000000) /*!< the synchronization procedure is performed in LIN Slave node configuration in LIN mode */ +#define UART_SYNC_DISABLE_ACTIVE USART_LINMR_SYNCDIS /*!< the synchronization procedure is not performed in LIN Slave node configuration in LIN mode */ + +#define IS_UART_SYNC_DISABLE(DISABLE) \ + ( \ + ((DISABLE) == UART_SYNC_DISABLE_NONE ) || \ + ((DISABLE) == UART_SYNC_DISABLE_ACTIVE) \ + ) +/** + * @} + */ + +/** @defgroup UART_PDC_Mode UART DMA mode in LIN mode + * @{ + */ +#define UART_PDC_MODE_LINMR_NOTWRITE ((uint32_t)0x00000000) /*!< The LIN mode register LINMR is not writted by the DMA */ +#define UART_PDC_MODE_LINMR_WRITE USART_LINMR_PDCM /*!< The LIN mode register LINMR(excepting that flag) is writted by the DMA */ + +#define IS_UART_PDC_MODE_LINMR(LINMR) \ + ( \ + ((LINMR) == UART_PDC_MODE_LINMR_NOTWRITE) || \ + ((LINMR) == UART_PDC_MODE_LINMR_WRITE ) \ + ) +/** + * @} + */ + +/** @defgroup UART_Wkup_Type UART wakeup signal type in LIN mode + * @{ + */ +#define UART_WKUP_TYPE_LIN_2_0 ((uint32_t)0x00000000) /*!< Setting the bit LINWKUP in the control register sends a LIN 2.0 wakeup signal */ +#define UART_WKUP_TYPE_LIN_1_3 USART_LINMR_WKUPTYP /*!< Setting the bit LINWKUP in the control register sends a LIN 1.3 wakeup signal */ +#define IS_UART_WKUP_TYPE(TYPE) \ + ( \ + ((TYPE) == UART_WKUP_TYPE_LIN_2_0) || \ + ((TYPE) == UART_WKUP_TYPE_LIN_1_3) \ + ) +/** + * @} + */ + +/** @defgroup UART_Frame_Slot_Disable UART frame slot mode disable in LIN mode + * @{ + */ +#define UART_FRAME_SLOT_DISABLE_NONE ((uint32_t)0x00000000) /*!< The frame slot mode is enabled in LIN mode */ +#define UART_FRAME_SLOT_DISABLE_ACTIVE USART_LINMR_FSDIS /*!< The frame slot mode is disabled in LIN mode */ +#define IS_UART_FRAME_SLOT_DISABLE(DISABLE) \ + ( \ + ((DISABLE) == UART_FRAME_SLOT_DISABLE_NONE ) || \ + ((DISABLE) == UART_FRAME_SLOT_DISABLE_ACTIVE) \ + ) +/** + * @} + */ + +/** @defgroup UART_Data_Length_Mode UART data length mode in LIN mode + * @{ + */ +#define UART_DATA_LENGTH_MODE_DLC ((uint32_t)0x00000000) /*!< The response data length is defined by the field DLC in LIN mode */ +#define UART_DATA_LENGTH_MODE_ID_5_6 USART_LINMR_DLM /*!< The response data length is defined by the bits 5 and 6 of the identifier (IDCHR in LINIR) in LIN mode */ +#define IS_UART_DATA_LENGTH_MODE(MODE) \ + ( \ + ((MODE) == UART_DATA_LENGTH_MODE_DLC ) || \ + ((MODE) == UART_DATA_LENGTH_MODE_ID_5_6) \ + ) +/** + * @} + */ + +/** @defgroup UART_Checksum_Type UART checksum type in LIN mode + * @{ + */ +#define UART_CHECKSUM_TYPE_ENHANCED ((uint32_t)0x00000000) /*!< LIN 2.0 "Enhanced" Checksum */ +#define UART_CHECKSUM_TYPE_CLASSIC USART_LINMR_CHKTYP /*!< LIN 1.3 "Classic " Checksum */ + +#define IS_UART_CHECKSUM_TYPE(TYPE) \ + ( \ + ((TYPE) == UART_CHECKSUM_TYPE_ENHANCED) || \ + ((TYPE) == UART_CHECKSUM_TYPE_CLASSIC ) \ + ) +/** + * @} + */ + +/** @defgroup UART_Checksum_Disable UART checksum disable in LIN mode + * @{ + */ +#define UART_CHECKSUM_DISABLE_NONE ((uint32_t)0x00000000) /*!< LIN Checksum not disable */ +#define UART_CHECKSUM_DISABLE_ACTIVE USART_LINMR_CHKDIS /*!< LIN Checksum disable */ + +#define IS_UART_CHECKSUM_DISABLE(DISABLE) \ + ( \ + ((DISABLE) == UART_CHECKSUM_DISABLE_NONE ) || \ + ((DISABLE) == UART_CHECKSUM_DISABLE_ACTIVE) \ + ) +/** + * @} + */ + +/** @defgroup UART_Parity_Disable UART parity disable in LIN mode + * @{ + */ +#define UART_PARITY_DISABLE_NONE ((uint32_t)0x00000000) /*!< LIN Parity not disable */ +#define UART_PARITY_DISABLE_ACTIVE USART_LINMR_PARDIS /*!< LIN Parity disable */ + +#define IS_UART_PARITY_DISABLE(DISABLE) \ + ( \ + ((DISABLE) == UART_PARITY_DISABLE_NONE ) || \ + ((DISABLE) == UART_PARITY_DISABLE_ACTIVE) \ + ) +/** + * @} + */ + +/** @defgroup UART_Node_Active UART checksum disable in LIN mode + * @{ + */ +#define UART_NODE_ACTIVE_PUBLISH ((uint32_t)0x00000000) /*!< The UART transmits the response */ +#define UART_NODE_ACTIVE_SUBSCRIBE (0x1U << 0U) /*!< The UART receives the response */ +#define UART_NODE_ACTIVE_IGNORE (0x2U << 0U) /*!< The UART does not transmit and does not receive the response */ + +#define IS_UART_NODE_ACTIVE(ACTIVE) \ + ( \ + ((ACTIVE) == UART_NODE_ACTIVE_PUBLISH ) || \ + ((ACTIVE) == UART_NODE_ACTIVE_SUBSCRIBE) || \ + ((ACTIVE) == UART_NODE_ACTIVE_IGNORE ) \ + ) +/** + * @} + */ + +/** @defgroup UART_DMA_TX UART DMA enable transmitter + * @{ + */ +#define UART_DMA_TX_DISABLE ((uint32_t)0x00000000) /*!< DMA mode is disable for transmission */ +#define UART_DMA_TX_ENABLE USART_CR_DMAT_EN /*!< DMA mode is enable for transmission */ + +#define IS_UART_DMA_TX_ENABLE(ENABLE) \ + ( \ + ((ENABLE) == UART_DMA_TX_DISABLE) || \ + ((ENABLE) == UART_DMA_TX_ENABLE ) \ + ) +/** + * @} + */ + +/** @defgroup UART_DMA_RX UART DMA enable receiver + * @{ + */ +#define UART_DMA_RX_DISABLE ((uint32_t)0x00000000) /*!< DMA mode is disable for reception */ +#define UART_DMA_RX_ENABLE USART_CR_DMAR_EN /*!< DMA mode is enable for reception */ + +#define IS_UART_DMA_RX_ENABLE(ENABLE) \ + ( \ + ((ENABLE) == UART_DMA_RX_DISABLE) || \ + ((ENABLE) == UART_DMA_RX_ENABLE ) \ + ) +/** + * @} + */ + +/** @defgroup UART_Flags + * @brief Flag mask in the CSR register + * @{ + */ +#define UART_FLAG_TXEMPTY USART_CSR_TXEMPTY /*!< UART transmitter empty */ +#define UART_FLAG_TIMEOUT USART_CSR_TIMEOUT /*!< UART receiver time-out */ +#define UART_FLAG_PARE USART_CSR_PARE /*!< UART parity error */ +#define UART_FLAG_FRAME USART_CSR_FRAME /*!< UART framing error */ +#define UART_FLAG_OVER USART_CSR_OVRE /*!< UART overrun error */ +#define UART_FLAG_RXBRK USART_CSR_RXBRK /*!< UART break receive/end of break */ +#define UART_FLAG_TXRDY USART_CSR_TXRDY /*!< UART transmitter ready */ +#define UART_FLAG_RXRDY USART_CSR_RXRDY /*!< UART receiver ready */ + +#define UART_FLAG_LINHTE USART_CSR_LINHTE /*!< UART LIN header timeout error */ +#define UART_FLAG_LINSTE USART_CSR_LINSTE /*!< UART LIN synch tolerance eror */ +#define UART_FLAG_LINSNRE USART_CSR_LINSNRE /*!< UART LIN slave not response error */ +#define UART_FLAG_LINCE USART_CSR_LINCE /*!< UART LIN checksum error */ +#define UART_FLAG_LINIPE USART_CSR_LINIPE /*!< UART LIN identifier parity error */ +#define UART_FLAG_LINISFE USART_CSR_LINISFE /*!< UART LIN inconsistent synch field error */ +#define UART_FLAG_LINBE USART_CSR_LINBE /*!< UART LIN bit error */ +#define UART_FLAG_LINBLS USART_CSR_LINBLS /*!< UART LIN bus line status */ +#define UART_FLAG_LINTC USART_CSR_LINTC /*!< UART LIN transfer completed */ +#define UART_FLAG_LINID USART_CSR_LINID /*!< UART LIN identifier sent or LIN identifier received */ +#define UART_FLAG_LINBK USART_CSR_LINBK /*!< UART LIN break sent or LIN break received */ +/** + * @} + */ + +/** @defgroup UART_Clear_Flags + * @brief Flag clear in the CR register + * @{ + */ +#define UART_CLEAR_TXEMPTY USART_CR_RSTTX /*!< UART transmitter empty interrupt clear */ +#define UART_CLEAR_TIMEOUT USART_CR_STTTO /*!< UART receiver time-out interrupt clear */ +#define UART_CLEAR_PARE USART_CR_RSTSTA /*!< UART parity error interrupt clear */ +#define UART_CLEAR_FRAME USART_CR_RSTSTA /*!< UART framing error interrupt clear */ +#define UART_CLEAR_OVER USART_CR_RSTSTA /*!< UART overrun error interrupt clear */ +#define UART_CLEAR_RXBRK USART_CR_RSTSTA /*!< UART break receive/end of break interrupt clear */ +#define UART_CLEAR_TXRDY USART_CR_RSTTX /*!< UART transmitter ready interrupt clear */ +#define UART_CLEAR_RXRDY USART_CR_RSTRX /*!< UART receiver ready interrupt clear */ + +#define UART_CLEAR_LINHTE USART_CR_RSTSTA /*!< UART LIN header timeout error interrupt clear */ +#define UART_CLEAR_LINSTE USART_CR_RSTSTA /*!< UART LIN synch tolerance eror interrupt clear */ +#define UART_CLEAR_LINSNRE USART_CR_RSTSTA /*!< UART LIN slave not response error interrupt clear */ +#define UART_CLEAR_LINCE USART_CR_RSTSTA /*!< UART LIN checksum error interrupt clear */ +#define UART_CLEAR_LINIPE USART_CR_RSTSTA /*!< UART LIN identifier parity error interrupt clear */ +#define UART_CLEAR_LINISFE USART_CR_RSTSTA /*!< UART LIN inconsistent synch field error interrupt clear */ +#define UART_CLEAR_LINBE USART_CR_RSTSTA /*!< UART LIN bit error interrupt clear */ +#define UART_CLEAR_LINTC USART_CR_RSTSTA /*!< UART LIN transfer completed interrupt clear */ +#define UART_CLEAR_LINID USART_CR_RSTSTA /*!< UART LIN identifier sent or LIN identifier received interrupt clear */ +#define UART_CLEAR_LINBK USART_CR_RSTSTA /*!< UART LIN break sent or LIN break received interrupt clear */ +/** + * @} + */ + +/** @defgroup UART_Interrupt_definition + * @brief Interrupt enable register - IER register + * @{ + */ +#define UART_IT_TXEMPTY USART_IER_TXEMPTY /*!< UART transmitter empty interruption */ +#define UART_IT_TIMEOUT USART_IER_TIMEOUT /*!< UART receiver time-out interruption */ +#define UART_IT_PARE USART_IER_PARE /*!< UART parity error interruption */ +#define UART_IT_FRAME USART_IER_FRAME /*!< UART framing error interruption */ +#define UART_IT_OVER USART_IER_OVRE /*!< UART overrun error interruption */ +#define UART_IT_RXBRK USART_IER_RXBRK /*!< UART break receive/end of break interruption */ +#define UART_IT_TXRDY USART_IER_TXRDY /*!< UART transmitter ready interruption */ +#define UART_IT_RXRDY USART_IER_RXRDY /*!< UART receiver ready interruption */ + +#define UART_IT_LINHTE USART_IER_LINHTE /*!< UART LIN header timeout error interruption */ +#define UART_IT_LINSTE USART_IER_LINSTE /*!< UART LIN synch tolerance eror interruption */ +#define UART_IT_LINSNRE USART_IER_LINSNRE /*!< UART LIN slave not response error interruption */ +#define UART_IT_LINCE USART_IER_LINCE /*!< UART LIN checksum error interruption */ +#define UART_IT_LINIPE USART_IER_LINIPE /*!< UART LIN identifier parity error interruption */ +#define UART_IT_LINISFE USART_IER_LINISFE /*!< UART LIN inconsistent synch field error interruption */ +#define UART_IT_LINBE USART_IER_LINBE /*!< UART LIN bit error interruption */ +#define UART_IT_LINTC USART_IER_LINTC /*!< UART LIN transfer completed interruption */ +#define UART_IT_LINID USART_IER_LINID /*!< UART LIN identifier sent or LIN identifier received interruption */ +#define UART_IT_LINBK USART_IER_LINBK /*!< UART LIN break sent or LIN break received interruption */ + +/** + * @} + */ + +/** @defgroup UART_Interrupt_disable + * @brief Interrupt disable register - IDR register + * @{ + */ +#define UART_DIS_TXEMPTY USART_IDR_TXEMPTY /*!< UART transmitter empty interrupt disable */ +#define UART_DIS_TIMEOUT USART_IDR_TIMEOUT /*!< UART receiver time-out interrupt disable */ +#define UART_DIS_PARE USART_IDR_PARE /*!< UART parity error interrupt disable */ +#define UART_DIS_FRAME USART_IDR_FRAME /*!< UART framing error interrupt disable */ +#define UART_DIS_OVER USART_IDR_OVRE /*!< UART overrun error interrupt disable */ +#define UART_DIS_RXBRK USART_IDR_RXBRK /*!< UART break receive/end of break interrupt disable */ +#define UART_DIS_TXRDY USART_IDR_TXRDY /*!< UART transmitter ready interrupt disable */ +#define UART_DIS_RXRDY USART_IDR_RXRDY /*!< UART receiver ready interrupt disable */ + +#define UART_DIS_LINHTE USART_IDR_LINHTE /*!< UART LIN header timeout error interrupt disable */ +#define UART_DIS_LINSTE USART_IDR_LINSTE /*!< UART LIN synch tolerance eror interrupt disable */ +#define UART_DIS_LINSNRE USART_IDR_LINSNRE /*!< UART LIN slave not response error interrupt disable */ +#define UART_DIS_LINCE USART_IDR_LINCE /*!< UART LIN checksum error interrupt disable */ +#define UART_DIS_LINIPE USART_IDR_LINIPE /*!< UART LIN identifier parity error interrupt disable */ +#define UART_DIS_LINISFE USART_IDR_LINISFE /*!< UART LIN inconsistent synch field error interrupt disable */ +#define UART_DIS_LINBE USART_IDR_LINBE /*!< UART LIN bit error interrupt disable */ +#define UART_DIS_LINTC USART_IDR_LINTC /*!< UART LIN transfer completed interrupt disable */ +#define UART_DIS_LINID USART_IDR_LINID /*!< UART LIN identifier sent or LIN identifier received interrupt disable */ +#define UART_DIS_LINBK USART_IDR_LINBK /*!< UART LIN break sent or LIN break received interrupt disable */ +/** + * @} + */ + +/** @defgroup UART_Interruption_Mask + * @brief Interrupt mask register - IMR register + * @{ + */ +#define UART_MASK_TXEMPTY USART_IMR_TXEMPTY /*!< UART transmitter empty interrupt mask */ +#define UART_MASK_TIMEOUT USART_IMR_TIMEOUT /*!< UART receiver time-out interrupt mask */ +#define UART_MASK_PARE USART_IMR_PARE /*!< UART parity error interrupt mask */ +#define UART_MASK_FRAME USART_IMR_FRAME /*!< UART framing error interrupt mask */ +#define UART_MASK_OVER USART_IMR_OVRE /*!< UART overrun error interrupt mask */ +#define UART_MASK_RXBRK USART_IMR_RXBRK /*!< UART break receive/end of break interrupt mask */ +#define UART_MASK_TXRDY USART_IMR_TXRDY /*!< UART transmitter ready interrupt mask */ +#define UART_MASK_RXRDY USART_IMR_RXRDY /*!< UART receiver ready interrupt mask */ + +#define UART_MASK_LINHTE USART_IMR_LINHTE /*!< UART LIN header timeout error interrupt mask */ +#define UART_MASK_LINSTE USART_IMR_LINSTE /*!< UART LIN synch tolerance eror interrupt mask */ +#define UART_MASK_LINSNRE USART_IMR_LINSNRE /*!< UART LIN slave not response error interrupt mask */ +#define UART_MASK_LINCE USART_IMR_LINCE /*!< UART LIN checksum error interrupt mask */ +#define UART_MASK_LINIPE USART_IMR_LINIPE /*!< UART LIN identifier parity error interrupt mask */ +#define UART_MASK_LINISFE USART_IMR_LINISFE /*!< UART LIN inconsistent synch field error interrupt mask */ +#define UART_MASK_LINBE USART_IMR_LINBE /*!< UART LIN bit error interrupt mask */ +#define UART_MASK_LINTC USART_IMR_LINTC /*!< UART LIN transfer completed interrupt mask */ +#define UART_MASK_LINID USART_IMR_LINID /*!< UART LIN identifier sent or LIN identifier received interrupt mask */ +#define UART_MASK_LINBK USART_IMR_LINBK /*!< UART LIN break sent or LIN break received interrupt mask */ + +/** + * @} + */ + +/** + * @} + */ + +/* Exported macros -----------------------------------------------------------*/ +/** @defgroup UART_Exported_Macros UART Exported Macros + * @{ + */ + +/** @brief Check whether the specified UART flag is set or not. + * @param None + * @retval None + */ +#define IS_UART_GET_FLAG(FLAG) \ + ( \ + ((FLAG) == UART_FLAG_TXEMPTY) || \ + ((FLAG) == UART_FLAG_TIMEOUT) || \ + ((FLAG) == UART_FLAG_PARE ) || \ + ((FLAG) == UART_FLAG_FRAME ) || \ + ((FLAG) == UART_FLAG_OVER ) || \ + ((FLAG) == UART_FLAG_RXBRK ) || \ + ((FLAG) == UART_FLAG_TXRDY ) || \ + ((FLAG) == UART_FLAG_RXRDY ) || \ + ((FLAG) == UART_FLAG_LINHTE ) || \ + ((FLAG) == UART_FLAG_LINSTE ) || \ + ((FLAG) == UART_FLAG_LINSNRE) || \ + ((FLAG) == UART_FLAG_LINCE ) || \ + ((FLAG) == UART_FLAG_LINIPE ) || \ + ((FLAG) == UART_FLAG_LINISFE) || \ + ((FLAG) == UART_FLAG_LINBE ) || \ + ((FLAG) == UART_FLAG_LINBLS ) || \ + ((FLAG) == UART_FLAG_LINTC ) || \ + ((FLAG) == UART_FLAG_LINID ) || \ + ((FLAG) == UART_FLAG_LINBK ) \ + ) + +/** @brief Clear the specified UART pending flag enable. + * @param None + * @retval None + */ +#define IS_UART_CLEAR_FLAG(FLAG) \ + ( \ + ((FLAG) == UART_CLEAR_TXEMPTY) || \ + ((FLAG) == UART_CLEAR_TIMEOUT) || \ + ((FLAG) == UART_CLEAR_PARE ) || \ + ((FLAG) == UART_CLEAR_FRAME ) || \ + ((FLAG) == UART_CLEAR_OVER ) || \ + ((FLAG) == UART_CLEAR_RXBRK ) || \ + ((FLAG) == UART_CLEAR_TXRDY ) || \ + ((FLAG) == UART_CLEAR_RXRDY ) || \ + ((FLAG) == UART_CLEAR_LINHTE ) || \ + ((FLAG) == UART_CLEAR_LINSTE ) || \ + ((FLAG) == UART_CLEAR_LINSNRE) || \ + ((FLAG) == UART_CLEAR_LINCE ) || \ + ((FLAG) == UART_CLEAR_LINIPE ) || \ + ((FLAG) == UART_CLEAR_LINISFE) || \ + ((FLAG) == UART_CLEAR_LINBE ) || \ + ((FLAG) == UART_CLEAR_LINTC ) || \ + ((FLAG) == UART_CLEAR_LINID ) || \ + ((FLAG) == UART_CLEAR_LINBK ) \ + ) + +/** @brief Enable the specified UART interrupt. + * @param None + * @retval None + */ +#define IS_UART_ENABLE_IT(IT) \ + ( \ + ((IT) == UART_IT_TXEMPTY) || \ + ((IT) == UART_IT_TIMEOUT) || \ + ((IT) == UART_IT_PARE ) || \ + ((IT) == UART_IT_FRAME ) || \ + ((IT) == UART_IT_OVER ) || \ + ((IT) == UART_IT_RXBRK ) || \ + ((IT) == UART_IT_TXRDY ) || \ + ((IT) == UART_IT_RXRDY ) || \ + ((IT) == UART_IT_LINHTE ) || \ + ((IT) == UART_IT_LINSTE ) || \ + ((IT) == UART_IT_LINSNRE) || \ + ((IT) == UART_IT_LINCE ) || \ + ((IT) == UART_IT_LINIPE ) || \ + ((IT) == UART_IT_LINISFE) || \ + ((IT) == UART_IT_LINBE ) || \ + ((IT) == UART_IT_LINTC ) || \ + ((IT) == UART_IT_LINID ) || \ + ((IT) == UART_IT_LINBK ) \ + ) + +/** @brief Disable the specified UART interrupt. + * @param None + * @retval None + */ +#define IS_UART_CLEAR_IT(IT) \ + ( \ + ((IT) == UART_DIS_TXEMPTY) || \ + ((IT) == UART_DIS_TIMEOUT) || \ + ((IT) == UART_DIS_PARE ) || \ + ((IT) == UART_DIS_FRAME ) || \ + ((IT) == UART_DIS_OVER ) || \ + ((IT) == UART_DIS_RXBRK ) || \ + ((IT) == UART_DIS_TXRDY ) || \ + ((IT) == UART_DIS_RXRDY ) || \ + ((IT) == UART_DIS_LINHTE ) || \ + ((IT) == UART_DIS_LINSTE ) || \ + ((IT) == UART_DIS_LINSNRE) || \ + ((IT) == UART_DIS_LINCE ) || \ + ((IT) == UART_DIS_LINIPE ) || \ + ((IT) == UART_DIS_LINISFE) || \ + ((IT) == UART_DIS_LINBE ) || \ + ((IT) == UART_DIS_LINTC ) || \ + ((IT) == UART_DIS_LINID ) || \ + ((IT) == UART_DIS_LINBK ) \ + ) + + +/** @brief Check whether the specified UART interrupt has occurred or not. + * @param None + * @retval None + */ +#define IS_UART_GET_IT(IT) \ + ( \ + ((IT) == UART_MASK_TXEMPTY) || \ + ((IT) == UART_MASK_TIMEOUT) || \ + ((IT) == UART_MASK_PARE ) || \ + ((IT) == UART_MASK_FRAME ) || \ + ((IT) == UART_MASK_OVER ) || \ + ((IT) == UART_MASK_RXBRK ) || \ + ((IT) == UART_MASK_TXRDY ) || \ + ((IT) == UART_MASK_RXRDY ) || \ + ((IT) == UART_MASK_LINHTE ) || \ + ((IT) == UART_MASK_LINSTE ) || \ + ((IT) == UART_MASK_LINSNRE) || \ + ((IT) == UART_MASK_LINCE ) || \ + ((IT) == UART_MASK_LINIPE ) || \ + ((IT) == UART_MASK_LINISFE) || \ + ((IT) == UART_MASK_LINBE ) || \ + ((IT) == UART_MASK_LINTC ) || \ + ((IT) == UART_MASK_LINID ) || \ + ((IT) == UART_MASK_LINBK ) \ + ) + +/** + * @} + */ + +/** @defgroup UART_Global_definition + * @{ + */ +#define IS_UART_BAUDRATE(BAUDRATE) ((BAUDRATE ) <= 6562500U) +#define IS_UART_FIDIRATIO(FIDIRATE) ((FIDIRATE ) <= 2047U ) +#define IS_UART_IF(IF) ((IF ) <= 0xFFU ) +#define IS_UART_TIMEOUT(TIMEOUT) ((TIMEOUT ) <= 0x1FFFF ) +#define IS_UART_TIMGUARD(TIMEGUARD) ((TIMEGUARD) <= 0xFF ) +#define IS_UART_LINIR_WR(LINIR_WR) ((LINIR_WR ) <= 0xFF ) +#define IS_UART_DATA(DATA) ((DATA ) <= 0x1FF ) +#define IS_UART_DLC(DATA) ((DATA ) <= 0xFF ) + +/** + * @} + */ + + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup UART_Exported_Functions UART Exported Functions + * @{ + */ +/* Initialization and de-initialization functions *****************************/ +void UART_Init(USART_TypeDef* UARTx, UART_InitTypeDef* UART_InitStruct); +void UART_StructInit(UART_InitTypeDef* UART_InitStruct); +void UART_DeInit(USART_TypeDef* UARTx); + +/* Normal command and configuration functions *********************************/ +/* Normal Cmd */ void UART_Cmd(USART_TypeDef* UARTx, FunctionalState NewState); +/* Normal Cmd */ void UART_RSTSTA_Cmd(USART_TypeDef* UARTx, FunctionalState NewState); +/* Normal Cmd */ void UART_TXDIS_Cmd(USART_TypeDef* UARTx, FunctionalState NewState); +/* Normal Cmd */ void UART_TXEN_Cmd(USART_TypeDef* UARTx, FunctionalState NewState); +/* Normal Cmd */ void UART_RXDIS_Cmd(USART_TypeDef* UARTx, FunctionalState NewState); +/* Normal Cmd */ void UART_RXEN_Cmd(USART_TypeDef* UARTx, FunctionalState NewState); +/* Normal Cmd */ void UART_RSTTX_Cmd(USART_TypeDef* UARTx, FunctionalState NewState); +/* Normal Cmd */ void UART_RSTRX_Cmd(USART_TypeDef* UARTx, FunctionalState NewState); +/* Normal Cfg */ void UART_InvData_Cfg(USART_TypeDef* UARTx, FunctionalState NewState); +/* Normal Cfg */ void UART_OverSampling8_Cfg(USART_TypeDef* UARTx, FunctionalState NewState); +/* Normal Cfg */ void UART_DataLength9_Cfg(USART_TypeDef* UARTx, FunctionalState NewState); +/* Normal Cfg */ void UART_MSBFirst_Cfg(USART_TypeDef* UARTx, FunctionalState NewState); +/* Normal Cfg */ void UART_ChannelMode_Cfg(USART_TypeDef* UARTx, uint32_t UART_ChannelMode); +/* Normal Cfg */ void UART_StopBit_Cfg(USART_TypeDef* UARTx, uint32_t UART_StopBits); +/* Normal Cfg */ void UART_Parity_Cfg(USART_TypeDef* UARTx, uint32_t UART_Parity); +/* Normal Cfg */ void UART_DataLength_Cfg(USART_TypeDef* UARTx, uint32_t UART_WordLength); +/* Normal Cfg */ void UART_CLKSelect_Cfg(USART_TypeDef* UARTx, uint32_t UART_CLKSelect); +/* Normal Cfg */ void UART_OperationMode_Cfg(USART_TypeDef* UARTx, uint32_t UART_OperationMode); + +/* Fractional baudrate function ***********************************************/ +/* Normal Cfg */ void UART_FracDivider_Cfg(USART_TypeDef* UARTx, uint32_t UART_BaudRate); + +/* Break command functions ****************************************************/ +/* Normal Cmd */ void UART_STPBRK_Cmd(USART_TypeDef* UARTx, FunctionalState NewState); +/* Normal Cmd */ void UART_STTBRK_Cmd(USART_TypeDef* UARTx, FunctionalState NewState); + +/* Receiver time-out and transmitter timeguard functions **********************/ +/* Normal Cfg */ void UART_Receiver_TimeOut_Cfg(USART_TypeDef* UARTx, uint32_t UART_ReceiverTimeOut); +/* Normal Cmd */ void UART_RETTO_After_Timeout_Cmd(USART_TypeDef* UARTx, FunctionalState NewState); +/* Normal Cmd */ void UART_STTTO_After_Timeout_Cmd(USART_TypeDef* UARTx, FunctionalState NewState); +/* Normal Cfg */ void UART_Transmitter_TimeGuard_Cfg(USART_TypeDef* UARTx, uint32_t UART_TransmitterTimeGuard); + +/* Multidrop mode command function ********************************************/ +/* Normal Cmd */ void UART_SENDAInMultidropMode_Cmd(USART_TypeDef* UARTx, FunctionalState NewState); + +/* IrDA mode function *********************************************************/ +/* IrDA Cfg */ void UART_IrDAFilter_Cfg(USART_TypeDef* UARTx, uint32_t UART_IrDAFilter); + +/* LIN mode functions *********************************************************/ +/* LIN Cmd */ void UART_LINWKUP_Cmd(USART_TypeDef* UARTx, FunctionalState NewState); +/* LIN Cmd */ void UART_LINABT_Cmd(USART_TypeDef* UARTx, FunctionalState NewState); +/* LIN Cfg */ void UART_Write_LINIR_In_LIN_Master(USART_TypeDef* UARTx, uint32_t UART_LINIR_Data); +/* LIN Read */ uint32_t UART_Read_LINIR_In_LIN_Slave(USART_TypeDef* UARTx); +/* LIN Cfg */ void UART_SYNCDisable_Cfg(USART_TypeDef* UARTx, FunctionalState NewState); +/* LIN Cfg */ void UART_PDCMode_Cfg(USART_TypeDef* UARTx, FunctionalState NewState); +/* LIN Cfg */ void UART_DataLengthControl_Cfg(USART_TypeDef* UARTx, uint32_t UART_DataLengthControl); +/* LIN Cfg */ void UART_WkupType_Cfg(USART_TypeDef* UARTx, FunctionalState NewState); +/* LIN Cfg */ void UART_FrameSlotDisable_Cfg(USART_TypeDef* UARTx, FunctionalState NewState); +/* LIN Cfg */ void UART_DataLengthMode_Cfg(USART_TypeDef* UARTx, FunctionalState NewState); +/* LIN Cfg */ void UART_CheckSumType_Cfg(USART_TypeDef* UARTx, FunctionalState NewState); +/* LIN Cfg */ void UART_CheckSumDisable_Cfg(USART_TypeDef* UARTx, FunctionalState NewState); +/* LIN Cfg */ void UART_ParityDisable_Cfg(USART_TypeDef* UARTx, FunctionalState NewState); +/* LIN Cfg */ void UART_NodeAction_Cfg(USART_TypeDef* UARTx, uint32_t UART_NodeAction); +/* LIN Read */ uint32_t UART_LINBaudRate(USART_TypeDef* UARTx); + +/* Data transfers functions ***************************************************/ +void UART_Transmit(USART_TypeDef* UARTx, uint16_t Data); +uint16_t UART_Receive(USART_TypeDef* UARTx); + +/* DMA transfers management functions *****************************************/ +void UART_DMATxEnable_Cmd(USART_TypeDef* UARTx, FunctionalState NewState); +void UART_DMARxEnable_Cmd(USART_TypeDef* UARTx, FunctionalState NewState); + +/* Low-Power SLEEP and STOP wakeup management functions ***********************/ +void UART_LowPowerSleepWkupConfig(USART_TypeDef* UARTx, FunctionalState NewState); +void LPUART_LowPowerStopWkupConfig(USART_TypeDef* UARTx, FunctionalState NewState); + +/* Interrupts and flags management functions **********************************/ +void UART_ITConfig(USART_TypeDef* UARTx, uint32_t UART_IT, FunctionalState NewState); +FlagStatus UART_GetFlagStatus(USART_TypeDef* UARTx, uint32_t UART_FLAG); +void UART_ClearFlag(USART_TypeDef* UARTx, uint32_t UART_FLAG); +ITStatus UART_GetITStatus(USART_TypeDef* UARTx, uint32_t UART_IT); +void UART_ITDisableConfig(USART_TypeDef* UARTx, uint32_t UART_IT, FunctionalState NewState); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __FT32F4XX_UART_H */ + +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_usart.h b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_usart.h new file mode 100644 index 00000000000..e46f3f7bd35 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_usart.h @@ -0,0 +1,1188 @@ +/** + * @file ft32f4xx_usart.h + * @author FMD AE + * @brief This file contains all the functions prototypes for the USART + * fireware library. + * @version V1.0.0 + * @date 2025-03-19 + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __FT32F4XX_USART_H +#define __FT32F4XX_USART_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx.h" + +/** @addtogroup ft32f4xx_Driver + * @{ + */ + +/** @addtogroup USART + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup USART_Exported_Types USART Exported Types + * @{ + */ + +/** + * @brief USART Init Structure definition + */ +typedef struct +{ + uint32_t USART_BaudRate; /*!< This member configures the USART communication baud rate. + The baud rate is computed using the following formula: + - CD = 0: Disable baud rate clock + + - Non ISO7816 mode + - ASYNC X16 : IntegerDivider = ((PCLKx) / (16 * (USRAT_InitStruct->USART_BaudRate))) + - ASYNC X8 : IntegerDivider = ((PCLKx) / (8 * (USRAT_InitStruct->USART_BaudRate))) + - SYNC or SPI: IntegerDivider = ((PCLKx) / ( (USRAT_InitStruct->USART_BaudRate))) + - ISO7816 mode + - ISO7816 : IntegerDivider = ((PCLKx) / (USRAT_InitStruct->USART_FiDiRatio * + (USRAT_InitStruct->USART_BaudRate))) + + - Fractional baud rate in asynchronous mode + - X16 : FractionDivider = (((PCLKx) / (16 * (USRAT_InitStruct->USART_BaudRate))) - IntegerDivider) * 8 + - X8 : FractionDivider = (((PCLKx) / (8 * (USRAT_InitStruct->USART_BaudRate))) - IntegerDivider) * 8 + */ + + uint32_t USART_FiDiRatio; /*!< Specifies the value of FI over DI ratio value in ISO7816 mode and IrDA mode.*/ + + uint32_t USART_IrDAFilter; /*!< Specifies the value of IrDA filter in IrDA mode.*/ + + uint32_t USART_WordLength; /*!< Specifies the number of data bits transmitted or received in a frame. + This parameter can be a value of @ref USART_Char_Length & USART_Char_Length9*/ + + uint32_t USART_ClockOutput; /*!< Specifies whether the USART clock SCK is output or not. + This parameter can be a value of @ref USART_Clock_Output*/ + + uint32_t USART_StopBits; /*!< Specifies the number of stop bits transmitted. + This parameter can be a value of @ref USART_Stop_Bits*/ + + uint32_t USART_Parity; /*!< Specifies the parity mode. + This parameter can be a value of @ref USART_Parity + @note When parity is enabled, the computed parity is inserted + at the MSB position of the transmitted data (9th bit when + the word length is set to 9 data bits; 8th bit when the + word length is set to 8 data bits). */ + + uint32_t USART_Mode; /*!< Specifies whether the Receive or Transmit mode is enabled or disabled. + This parameter can be a value of @ref USART_Mode*/ + + uint32_t USART_CLKSelect; /*!< Specifies the selection of clock. + This parameter can be a value of @ref USART_Clock_Select*/ + + uint32_t USART_OperationMode; /*!< Specifies the mode of operation. + This parameter can be a value of @ref USART_Mode_Operation*/ + + uint32_t USART_HardwareFlowControl; /*!< Specifies whether the hardware flow control mode is enabled + or disabled. + This parameter can be a value of @ref USART_Hardware_Flow_Control*/ + + uint32_t USART_Sync; /*!< Specifies the synchronous mode select. + This parameter can be a value of @ref USART_Sync_Mode*/ + + uint32_t USART_BitOrder; /*!< Specifies whether the Least or Most Significant Bit is sent/received first. + This parameter can be a value of @ref USART_BIT_ORDER*/ + + uint32_t USART_ChannelMode; /*!< Specifies the channel mode select. + this parameter can be a value of @ref USART_Channel_Mode*/ + + uint32_t USART_WRDBT; /*!< Specifies whether wait read data before transfer is enabled or disabled. + This parameter can be a value of @ref USART_WRDBT*/ + + uint32_t USART_OverSampling; /*!< Specifies whether 16x oversampling or 8x oversampling. + This parameter can be a value of @ref USART_OverSampling*/ + + uint32_t USART_CLKPolarity; /*!< Specifies the inactive state value of the serial clock in SPI mode. + This parameter can be a value of @ref USART_Clock_Polarity*/ + + uint32_t USART_CLKPhase; /*!< Specifies the clock transition on which the bit capture and which bit change + is made in SPI mode. + This parameter can be a value of @ref USART_Clock_Phase*/ + + uint32_t USART_INVData; /*!< Specifies whether the data is inverted. + This parameter can be a value of @ref USART_InvertData*/ + + uint32_t USART_InhibitNACK; /*!< Specifies whether the NACK is generated in ISO7816 protocol T = 0. + This parameter can be a value of @ref USART_INACK*/ + + uint32_t USART_DisSuccessiveNACK; /*!< Specifies whether disable the successive NACK in ISO7816 protocol T = 0. + This parameter can be a value of @ref USART_DSNACK*/ + + uint32_t USART_MAXIteration; /*!< Specifies the maximum number of automatic iteration in ISO7816 protocol T = 0. + This parameter can be a value of @ref USART_Max_Iteration*/ + + uint32_t USART_SYNCDisable; /*!< Specifies whether disable the synchronization in LIN mode. + This parameter can be a value of @ref USART_Sync_Disable*/ + + uint32_t USART_PDCMode; /*!< Specifies the DMA mode selection in LIN mode. + This parameter can be a value of @ref USART_PDC_Mode*/ + + uint32_t USART_DataLengthControl; /*!< Specifies define the response data length when DataLengthMode = 0 in LIN mode. + 0-255: the response data length is equal to DLC+1 bytes.*/ + + uint32_t USART_WkupType; /*!< Specifies whether the wakeup signal type is LIN2.0 wakup signal or LIN1.3 wakup signal. + This parameter can be a value of @ref USART_Wkup_Type*/ + + uint32_t USART_FrameSlotDisable; /*!< Specifies whether disable the frame slot mode in LIN mode. + This parameter can be a value of @ref USART_Frame_Slot_Disable*/ + + uint32_t USART_DataLengthMode; /*!< Specifies the data length mode in LIN mode. + This parameter can be a value of @ref USART_Data_Length_Mode*/ + + uint32_t USART_CheckSumType; /*!< Specifies the checksum type in LIN mode. + This parameter can be a value of @ref USART_Checksum_Type*/ + + uint32_t USART_CheckSumDisable; /*!< Specifies whether disable the checksum in LIN mode. + This parameter can be a value of @ref USART_Checksum_Disable*/ + + uint32_t USART_ParityDisable; /*!< Specifies whether disable the parity in LIN mode. + This parameter can be a value of @ref USART_Parity_Disable*/ + + uint32_t USART_NodeAction; /*!< Specifies the LIN Node Active. + This parameter can be a value of @ref USART_Node_Active*/ + +} USART_InitTypeDef; + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup USART_Exported_Constants USART Exported Constants + * @{ + */ + +#define IS_USART_ALL_PERIPH(PERIPH) ( \ + ((PERIPH) == USART1) || \ + ((PERIPH) == USART2) || \ + ((PERIPH) == USART3) || \ + ((PERIPH) == USART6) \ + ) + +#define IS_USART_ALL_PERIPH_WP(PERIPH_WP) ( \ + ((PERIPH_WP) == USART1_WP) || \ + ((PERIPH_WP) == USART2_WP) || \ + ((PERIPH_WP) == USART3_WP) || \ + ((PERIPH_WP) == USART6_WP) \ + ) + +#define IS_USART_12_PERIPH(PERIPH) ( \ + ((PERIPH) == USART1) || \ + ((PERIPH) == USART2) \ + ) + +#define IS_USART_36_PERIPH(PERIPH) ( \ + ((PERIPH) == USART3) || \ + ((PERIPH) == USART6) \ + ) + + +/** @defgroup USART_Max_Iteration USART Number of MAX_ITERATION for ISO7816 T = 0 + * @{ + */ +#define USART_ISO7816_T0_MAX_ITERATION_0 ((uint32_t)0x00000000U << (uint32_t)24U) /*!< USART max_iteration with 0 times */ +#define USART_ISO7816_T0_MAX_ITERATION_1 ((uint32_t)0x00000001U << (uint32_t)24U) /*!< USART max_iteration with 1 times */ +#define USART_ISO7816_T0_MAX_ITERATION_2 ((uint32_t)0x00000002U << (uint32_t)24U) /*!< USART max_iteration with 2 times */ +#define USART_ISO7816_T0_MAX_ITERATION_3 ((uint32_t)0x00000003U << (uint32_t)24U) /*!< USART max_iteration with 3 times */ +#define USART_ISO7816_T0_MAX_ITERATION_4 ((uint32_t)0x00000004U << (uint32_t)24U) /*!< USART max_iteration with 4 times */ +#define USART_ISO7816_T0_MAX_ITERATION_5 ((uint32_t)0x00000005U << (uint32_t)24U) /*!< USART max_iteration with 5 times */ +#define USART_ISO7816_T0_MAX_ITERATION_6 ((uint32_t)0x00000006U << (uint32_t)24U) /*!< USART max_iteration with 6 times */ +#define USART_ISO7816_T0_MAX_ITERATION_7 ((uint32_t)0x00000007U << (uint32_t)24U) /*!< USART max_iteration with 7 times */ + +#define IS_USART_ISO7816_T0_MAX_ITERATION(ITERATION) \ + ( \ + ((ITERATION) == USART_ISO7816_T0_MAX_ITERATION_0) || \ + ((ITERATION) == USART_ISO7816_T0_MAX_ITERATION_1) || \ + ((ITERATION) == USART_ISO7816_T0_MAX_ITERATION_2) || \ + ((ITERATION) == USART_ISO7816_T0_MAX_ITERATION_3) || \ + ((ITERATION) == USART_ISO7816_T0_MAX_ITERATION_4) || \ + ((ITERATION) == USART_ISO7816_T0_MAX_ITERATION_5) || \ + ((ITERATION) == USART_ISO7816_T0_MAX_ITERATION_6) || \ + ((ITERATION) == USART_ISO7816_T0_MAX_ITERATION_7) \ + ) +/** + * @} + */ + +/** @defgroup USART_InvertData USART Invert Data + * @{ + */ +#define USART_INVDATA_DISABLE ((uint32_t)0x00000000U) /*!< USART invert data disbale */ +#define USART_INVDATA_ENABLE USART_MR_INVDATA /*!< USART invert data enable */ + +#define IS_USART_INVDATA(INVDATA) \ + ( \ + ((INVDATA) == USART_INVDATA_DISABLE) || \ + ((INVDATA) == USART_INVDATA_ENABLE ) \ + ) +/** + * @} + */ + +/** @defgroup USART_DSNACK USART disable successive NACK for ISO7816 T = 0 + * @{ + */ +#define USART_ISO7816_T0_DSNACK_DISABLE ((uint32_t)0x00000000U) /*!< USART successive NACK disable*/ +#define USART_ISO7816_T0_DSNACK_ENABLE USART_MR_DSNACK /*!< USART successive NACK enable */ + +#define IS_USART_ISO7816_T0_DSNACK(DSNACK) \ + ( \ + ((DSNACK) == USART_ISO7816_T0_DSNACK_DISABLE) || \ + ((DSNACK) == USART_ISO7816_T0_DSNACK_ENABLE ) \ + ) +/** + * @} + */ + +/** @defgroup USART_INACK USART inhibit Non Acknowledge for ISO7816 T = 0 + * @{ + */ +#define USART_ISO7816_T0_INACK_DISABLE ((uint32_t)0x00000000U) /*!< USART inhibit Non Acknowledge */ +#define USART_ISO7816_T0_INACK_ENABLE USART_MR_INACK /*!< USART Non Acknowledge */ + +#define IS_USART_ISO7816_T0_INACK(INACK) \ + ( \ + ((INACK) == USART_ISO7816_T0_DSNACK_DISABLE) || \ + ((INACK) == USART_ISO7816_T0_DSNACK_ENABLE ) \ + ) +/** + * @} + */ + +/** @defgroup USART_OverSampling USART Oversampling mode + * @{ + */ +#define USART_OVERSAMPLING_16 ((uint32_t)0x00000000U) /*!< USART 16x sampling */ +#define USART_OVERSAMPLING_8 USART_MR_OVER /*!< USART 8x sampling */ + +#define IS_USART_OVERSAMPLING(OVERSAMPLING) \ + ( \ + ((OVERSAMPLING) == USART_OVERSAMPLING_16) || \ + ((OVERSAMPLING) == USART_OVERSAMPLING_8 ) \ + ) +/** + * @} + */ + +/** @defgroup USART_Clock_Output USART clock output select + * @{ + */ +#define USART_CLOCK_OUTPUT_DISABLE ((uint32_t)0x00000000U) /*!< USART don't drive the SCK pin */ +#define USART_CLOCK_OUTPUT_ENABLE USART_MR_CLKO /*!< USART drive the SCK pin if don't select the external clock SCK */ + +#define IS_USART_CLOCK_OUTPUT(OUTPUT) \ + ( \ + ((OUTPUT) == USART_CLOCK_OUTPUT_DISABLE) || \ + ((OUTPUT) == USART_CLOCK_OUTPUT_ENABLE ) \ + ) +/** + * @} + */ + +/** @defgroup USART_Char_Length9 USART 9-bit character length + * @{ + */ +#define USART_CHAR_LENGTH9_DISABLE ((uint32_t)0x00000000U) /*!< USART CHRL defined character length */ +#define USART_CHAR_LENGTH9_ENABLE USART_MR_MODE9 /*!< USART 9-bit character length */ + +/** + * @} + */ + +/** @defgroup USART_BIT_ORDER USART bit order + * @{ + */ +#define USART_BIT_ORDER_LSBF ((uint32_t)0x00000000U) /*!< USART Least Significant Bit is sent/received first */ +#define USART_BIT_ORDER_MSBF USART_MR_MSBF /*!< USART Most Significant Bit is sent/received first */ + +#define IS_USART_BIT_ORDER(ORDER) \ + ( \ + ((ORDER) == USART_BIT_ORDER_LSBF) || \ + ((ORDER) == USART_BIT_ORDER_MSBF) \ + ) +/** + * @} + */ + +/** @defgroup USART_Channel_Mode USART channel mode + * @{ + */ +#define USART_CHANNEL_MODE_NORMAL (0x0UL << 14U ) /*!< USART operates in normal mode */ +#define USART_CHANNEL_MODE_AUTOMATIC (0x1UL << 14U ) /*!< USART operates in automatic echo mode */ +#define USART_CHANNEL_MODE_LOCAL_LOOPBACK (0x2UL << 14U ) /*!< USART operates in local loopback mode */ +#define USART_CHANNEL_MODE_REMOTE_LOOPBACK (0x3UL << 14U ) /*!< USART operates in remote loopback mode */ + +#define IS_USART_CHANNEL_MODE(MODE) \ + ( \ + ((MODE) == USART_CHANNEL_MODE_NORMAL ) || \ + ((MODE) == USART_CHANNEL_MODE_AUTOMATIC ) || \ + ((MODE) == USART_CHANNEL_MODE_LOCAL_LOOPBACK ) || \ + ((MODE) == USART_CHANNEL_MODE_REMOTE_LOOPBACK) \ + ) +/** + * @} + */ + +/** @defgroup USART_Stop_Bits USART Number of Stop Bits + * @{ + */ +#define USART_STOPBITS_1 ((uint32_t)0x00000000U) /*!< USART frame with 1 stop bit */ +#define USART_STOPBITS_1_5 (0x1UL << 12U) /*!< USART frame with 1.5 stop bits */ +#define USART_STOPBITS_2 (0x2UL << 12U) /*!< USART frame with 2 stop bits */ + +#define IS_USART_STOPBITS(STOPBITS) \ + ( \ + ((STOPBITS) == USART_STOPBITS_1 ) || \ + ((STOPBITS) == USART_STOPBITS_1_5) || \ + ((STOPBITS) == USART_STOPBITS_2 ) \ + ) +/** + * @} + */ + +/** @defgroup USART_Parity USART Parity + * @{ + */ +#define USART_PARITY_EVEN (0x0 << 9U) /*!< Even parity */ +#define USART_PARITY_ODD (0x1 << 9U) /*!< Odd parity */ +#define USART_PARITY_SPACE (0x2 << 9U) /*!< Space parity */ +#define USART_PARITY_MARK (0x3 << 9U) /*!< Mark parity */ +#define USART_PARITY_NONE (0x4 << 9U) /*!< No parity */ +#define USART_PARITY_MULTIDROP (0x6 << 9U) /*!< Multidrop Mode */ + +#define IS_USART_PARITY(PARITY) \ + ( \ + ((PARITY) == USART_PARITY_EVEN ) || \ + ((PARITY) == USART_PARITY_ODD ) || \ + ((PARITY) == USART_PARITY_SPACE ) || \ + ((PARITY) == USART_PARITY_MARK ) || \ + ((PARITY) == USART_PARITY_NONE ) || \ + ((PARITY) == USART_PARITY_MULTIDROP) \ + ) +/** + * @} + */ + +/** @defgroup USART_Sync_Mode USART synchronous mode select + * @{ + */ +#define USART_SYNC_MODE_ASYNC ((uint32_t)0x00000000U) /*!< USART operates in asynchronous mode */ +#define USART_SYNC_MODE_SYNC USART_MR_SYNC /*!< USART operates in synchronous mode */ + +#define IS_USART_SYNC_MODE(MODE) \ + ( \ + ((MODE) == USART_SYNC_MODE_ASYNC) || \ + ((MODE) == USART_SYNC_MODE_SYNC ) \ + ) +/** + * @} + */ + +/** @defgroup USART_Char_Length USART character length + * @{ + */ +#define USART_CHAR_LENGTH_5BIT ((uint32_t)0x00000000U) /*!< USART charcter length is 5bits */ +#define USART_CHAR_LENGTH_6BIT (0x1U << 6U) /*!< USART charcter length is 6bits */ +#define USART_CHAR_LENGTH_7BIT (0x2U << 6U) /*!< USART charcter length is 7bits */ +#define USART_CHAR_LENGTH_8BIT (0x3U << 6U) /*!< USART charcter length is 8bits */ + +#define IS_USART_CHAR_LENGTH(LENGTH) \ + ( \ + ((LENGTH) == USART_CHAR_LENGTH_5BIT) || \ + ((LENGTH) == USART_CHAR_LENGTH_6BIT) || \ + ((LENGTH) == USART_CHAR_LENGTH_7BIT) || \ + ((LENGTH) == USART_CHAR_LENGTH_8BIT) || \ + ((LENGTH) == USART_CHAR_LENGTH9_DISABLE) || \ + ((LENGTH) == USART_CHAR_LENGTH9_ENABLE ) \ + ) +/** + * @} + */ + +/** @defgroup USART_Clock_Select USART clock select + * @{ + */ +#define USART_CLOCK_SELECT_MCK ((uint32_t)0x00000000U) /*!< USART clock source MCK */ +#define USART_CLOCK_SELECT_MCKDIV8 (0x1U << 4U) /*!< USART clock source MCK / 8 */ +#define USART_CLOCK_SELECT_SCK (0x3U << 4U) /*!< USART clock source SCK */ + +#define IS_USART_CLOCK_SELECT(SELECT) \ + ( \ + ((SELECT) == USART_CLOCK_SELECT_MCK ) || \ + ((SELECT) == USART_CLOCK_SELECT_MCKDIV8) || \ + ((SELECT) == USART_CLOCK_SELECT_SCK ) \ + ) +/** + * @} + */ + +/** @defgroup USART_Mode_Operation USART mode of operation + * @{ + */ +#define USART_MODE_OPERATION_NORMAL ((uint32_t)0x00000000U) /*!< USART mode of operation select normal */ +#define USART_MODE_OPERATION_RS485 (0x1U << 0U) /*!< USART mode of operation select rs485 */ +#define USART_MODE_OPERATION_MODEM (0x3U << 0U) /*!< USART mode of operation select mode */ +#define USART_MODE_OPERATION_ISO7816_T_0 (0x4U << 0U) /*!< USART mode of operation select iso7816 protocol: t = 0 */ +#define USART_MODE_OPERATION_ISO7816_T_1 (0x6U << 0U) /*!< USART mode of operation select iso7816 protocol: t = 1 */ +#define USART_MODE_OPERATION_IrDA (0x8U << 0U) /*!< USART mode of operation select irda */ +#define USART_MODE_OPERATION_LIN_MASTER (0xAU << 0U) /*!< USART mode of operation select lin master */ +#define USART_MODE_OPERATION_LIN_SLAVE (0xBU << 0U) /*!< USART mode of operation select lin slave */ +#define USART_MODE_OPERATION_SPI_MASTER (0xEU << 0U) /*!< USART mode of operation select spi master */ +#define USART_MODE_OPERATION_SPI_SLAVE (0xFU << 0U) /*!< USART mode of operation select spi slave */ + +#define IS_USART_MODE_OPERATION(OPERATION) \ + ( \ + ((OPERATION) == USART_MODE_OPERATION_NORMAL ) || \ + ((OPERATION) == USART_MODE_OPERATION_RS485 ) || \ + ((OPERATION) == USART_MODE_OPERATION_MODEM ) || \ + ((OPERATION) == USART_MODE_OPERATION_ISO7816_T_0) || \ + ((OPERATION) == USART_MODE_OPERATION_ISO7816_T_1) || \ + ((OPERATION) == USART_MODE_OPERATION_IrDA ) || \ + ((OPERATION) == USART_MODE_OPERATION_LIN_MASTER ) || \ + ((OPERATION) == USART_MODE_OPERATION_LIN_SLAVE ) || \ + ((OPERATION) == USART_MODE_OPERATION_SPI_MASTER ) || \ + ((OPERATION) == USART_MODE_OPERATION_SPI_SLAVE ) \ + ) +/** + * @} + */ + +/** @defgroup USART_WRDBT USART wait read data before transfer in spi mode + * @{ + */ +#define USART_WRDBT_DISABLE ((uint32_t)0x00000000) /*!< the character transmission starts as soon as a character is written into US_THR in SPI mode */ +#define USART_WRDBT_ENABLE USART_MR_WRDBT /*!< the character transmission starts when a character and only if RXRDY flag is cleared in SPI mode */ + +#define IS_USART_WRDBT(TRANSFER) \ + ( \ + ((TRANSFER) == USART_WRDBT_DISABLE) || \ + ((TRANSFER) == USART_WRDBT_ENABLE ) \ + ) +/** + * @} + */ + +/** @defgroup USART_Clock_Polarity USART Clock Polarity in spi mode + * @{ + */ +#define USART_POLARITY_LOW ((uint32_t)0x00000000) /*!< Driver enable signal is active low in SPI mode */ +#define USART_POLARITY_HIGH USART_MR_CPOL /*!< Driver enable signal is active high in SPI mode */ + +#define IS_USART_POLARITY(POLARITY) \ + ( \ + ((POLARITY) == USART_POLARITY_LOW ) || \ + ((POLARITY) == USART_POLARITY_HIGH) \ + ) +/** + * @} + */ + +/** @defgroup USART_Clock_Phase USART Clock Phase in spi mode + * @{ + */ +#define USART_PHASE_2EDGE ((uint32_t)0x00000000) /*!< USART frame phase on second clock capture */ +#define USART_PHASE_1EDGE USART_MR_CPHA /*!< USART frame phase on first clock capture */ + +#define IS_USART_PHASE(PHASE) \ + ( \ + ((PHASE) == USART_PHASE_2EDGE) || \ + ((PHASE) == USART_PHASE_1EDGE) \ + ) +/** + * @} + */ + +/** @defgroup USART_Mode USART Mode + * @{ + */ +#define USART_MODE_RX USART_CR_RXEN /*!< RX mode enable > */ +#define USART_MODE_TX USART_CR_TXEN /*!< TX mode enable > */ +#define USART_MODE_TX_RX (USART_CR_RXEN | USART_CR_TXEN) /*!< TX & RX mode enable > */ +#define IS_USART_MODE(MODE) \ + ( \ + ((MODE) == USART_MODE_RX ) || \ + ((MODE) == USART_MODE_TX ) || \ + ((MODE) == USART_MODE_TX_RX) \ + ) +/** + * @} + */ + +/** @defgroup USART_Sync_Disable USART synchronization disable in LIN mode + * @{ + */ +#define USART_SYNC_DISABLE_NONE ((uint32_t)0x00000000) /*!< the synchronization procedure is performed in LIN Slave node configuration in LIN mode */ +#define USART_SYNC_DISABLE_ACTIVE USART_LINMR_SYNCDIS /*!< the synchronization procedure is not performed in LIN Slave node configuration in LIN mode */ + +#define IS_USART_SYNC_DISABLE(DISABLE) (((DISABLE) == USART_SYNC_DISABLE_NONE ) || \ + ((DISABLE) == USART_SYNC_DISABLE_ACTIVE)) +/** + * @} + */ + +/** @defgroup USART_PDC_Mode USART dma mode in LIN mode + * @{ + */ +#define USART_PDC_MODE_LINMR_NOTWRITE ((uint32_t)0x00000000) /*!< The LIN mode register LINMR is not writted by the DMA */ +#define USART_PDC_MODE_LINMR_WRITE USART_LINMR_PDCM /*!< The LIN mode register LINMR(excepting that flag) is writted by the DMA */ + +#define IS_USART_PDC_MODE_LINMR(LINMR) \ + ( \ + ((LINMR) == USART_PDC_MODE_LINMR_NOTWRITE) || \ + ((LINMR) == USART_PDC_MODE_LINMR_WRITE ) \ + ) +/** + * @} + */ + +/** @defgroup USART_Wkup_Type USART wakeup signal type in LIN mode + * @{ + */ +#define USART_WKUP_TYPE_LIN_2_0 ((uint32_t)0x00000000) /*!< Setting the bit LINWKUP in the control register sends a LIN 2.0 wakeup signal */ +#define USART_WKUP_TYPE_LIN_1_3 USART_LINMR_WKUPTYP /*!< Setting the bit LINWKUP in the control register sends a LIN 1.3 wakeup signal */ +#define IS_USART_WKUP_TYPE(TYPE) \ + ( \ + ((TYPE) == USART_WKUP_TYPE_LIN_2_0) || \ + ((TYPE) == USART_WKUP_TYPE_LIN_1_3) \ + ) +/** + * @} + */ + +/** @defgroup USART_Frame_Slot_Disable USART frame slot mode disable in LIN mode + * @{ + */ +#define USART_FRAME_SLOT_DISABLE_NONE ((uint32_t)0x00000000) /*!< The frame slot mode is enabled in LIN mode */ +#define USART_FRAME_SLOT_DISABLE_ACTIVE USART_LINMR_FSDIS /*!< The frame slot mode is disabled in LIN mode */ +#define IS_USART_FRAME_SLOT_DISABLE(DISABLE) \ + ( \ + ((DISABLE) == USART_FRAME_SLOT_DISABLE_NONE ) || \ + ((DISABLE) == USART_FRAME_SLOT_DISABLE_ACTIVE) ) +/** + * @} + */ + +/** @defgroup USART_Data_Length_Mode USART data length mode in LIN mode + * @{ + */ +#define USART_DATA_LENGTH_MODE_DLC ((uint32_t)0x00000000) /*!< The response data length is defined by the field DLC in LIN mode */ +#define USART_DATA_LENGTH_MODE_ID_5_6 USART_LINMR_DLM /*!< The response data length is defined by the bits 5 and 6 of the identifier (IDCHR in LINIR) in LIN mode */ +#define IS_USART_DATA_LENGTH_MODE(MODE) \ + ( \ + ((MODE) == USART_DATA_LENGTH_MODE_DLC ) || \ + ((MODE) == USART_DATA_LENGTH_MODE_ID_5_6) \ + ) +/** + * @} + */ + +/** @defgroup USART_Checksum_Type USART checksum type in LIN mode + * @{ + */ +#define USART_CHECKSUM_TYPE_ENHANCED ((uint32_t)0x00000000) /*!< LIN 2.0 "Enhanced" Checksum */ +#define USART_CHECKSUM_TYPE_CLASSIC USART_LINMR_CHKTYP /*!< LIN 1.3 "Classic " Checksum */ + +#define IS_USART_CHECKSUM_TYPE(TYPE) \ + ( \ + ((TYPE) == USART_CHECKSUM_TYPE_ENHANCED) || \ + ((TYPE) == USART_CHECKSUM_TYPE_CLASSIC ) \ + ) +/** + * @} + */ + +/** @defgroup USART_Checksum_Disable USART checksum disable in LIN mode + * @{ + */ +#define USART_CHECKSUM_DISABLE_NONE ((uint32_t)0x00000000) /*!< LIN Checksum not disable */ +#define USART_CHECKSUM_DISABLE_ACTIVE USART_LINMR_CHKDIS /*!< LIN Checksum disable */ + +#define IS_USART_CHECKSUM_DISABLE(DISABLE) \ + ( \ + ((DISABLE) == USART_CHECKSUM_DISABLE_NONE ) || \ + ((DISABLE) == USART_CHECKSUM_DISABLE_ACTIVE) \ + ) +/** + * @} + */ + +/** @defgroup USART_Parity_Disable USART parity disable in LIN mode + * @{ + */ +#define USART_PARITY_DISABLE_NONE ((uint32_t)0x00000000) /*!< LIN Parity not disable */ +#define USART_PARITY_DISABLE_ACTIVE USART_LINMR_PARDIS /*!< LIN Parity disable */ + +#define IS_USART_PARITY_DISABLE(DISABLE) \ + ( \ + ((DISABLE) == USART_PARITY_DISABLE_NONE ) || \ + ((DISABLE) == USART_PARITY_DISABLE_ACTIVE) \ + ) +/** + * @} + */ + +/** @defgroup USART_Node_Active USART checksum disable in LIN mode + * @{ + */ +#define USART_NODE_ACTIVE_PUBLISH ((uint32_t)0x00000000) /*!< The USART transmits the response */ +#define USART_NODE_ACTIVE_SUBSCRIBE (0x1U << 0U) /*!< The USART receives the response */ +#define USART_NODE_ACTIVE_IGNORE (0x2U << 0U) /*!< The USART does not transmit and does not receive the response */ + +#define IS_USART_NODE_ACTIVE(ACTIVE) \ + ( \ + ((ACTIVE) == USART_NODE_ACTIVE_PUBLISH ) || \ + ((ACTIVE) == USART_NODE_ACTIVE_SUBSCRIBE) || \ + ((ACTIVE) == USART_NODE_ACTIVE_IGNORE ) \ + ) +/** + * @} + */ + +/** @defgroup USART_DMA_TX USART DMA enable transmitter + * @{ + */ +#define USART_DMA_TX_DISABLE ((uint32_t)0x00000000) /*!< DMA mode is disable for transmission */ +#define USART_DMA_TX_ENABLE USART_CR_DMAT_EN /*!< DMA mode is enable for transmission */ + +#define IS_USART_DMA_TX_ENABLE(ENABLE) \ + ( \ + ((ENABLE) == USART_DMA_TX_DISABLE) || \ + ((ENABLE) == USART_DMA_TX_ENABLE ) \ + ) +/** + * @} + */ + +/** @defgroup USART_DMA_RX USART DMA enable receiver + * @{ + */ +#define USART_DMA_RX_DISABLE ((uint32_t)0x00000000) /*!< DMA mode is disable for reception */ +#define USART_DMA_RX_ENABLE USART_CR_DMAR_EN /*!< DMA mode is enable for reception */ + +#define IS_USART_DMA_RX_ENABLE(ENABLE) \ + ( \ + ((ENABLE) == USART_DMA_RX_DISABLE) || \ + ((ENABLE) == USART_DMA_RX_ENABLE ) \ + ) +/** + * @} + */ + +/** @defgroup USART_Hardware_Flow_Control + * @{ + */ + +#define USART_HardwareFlowControl_None ((uint32_t)0x00000000) +#define USART_HardwareFlowControl_RTS (USART_CR_RTSEN | USART_CR_FCS) +#define USART_HardwareFlowControl_DTR USART_CR_DTREN +#define USART_HardwareFlowControl_RTS_DTR ((USART_CR_RTSEN | USART_CR_FCS) | USART_CR_DTREN) +#define IS_USART_HARDWARE_FLOW_CONTROL(CONTROL) \ + ( \ + ((CONTROL) == USART_HardwareFlowControl_None ) || \ + ((CONTROL) == USART_HardwareFlowControl_RTS ) || \ + ((CONTROL) == USART_HardwareFlowControl_DTR ) || \ + ((CONTROL) == USART_HardwareFlowControl_RTS_DTR) \ + ) + +/** + * @} + */ + +/** @defgroup USART_Flags + * @brief Flag mask in the CSR register + * @{ + */ +#define USART_FLAG_CTS USART_CSR_CTS /*!< USART image of CTS input */ +#define USART_FLAG_DSR USART_CSR_DSR /*!< USART image of DSR input */ +#define USART_FLAG_CTSIC USART_CSR_CTSIC /*!< USART Clear to Send input change flag */ +#define USART_FLAG_DSRIC USART_CSR_DSRIC /*!< USART Data Set Ready input change flag */ +#define USART_FLAG_NACK USART_CSR_NACK /*!< USART non acknowledge interrupt */ +#define USART_FLAG_ITER USART_CSR_ITER /*!< USART max number of repetitions reached */ +#define USART_FLAG_TXEMPTY USART_CSR_TXEMPTY /*!< USART transmitter empty */ +#define USART_FLAG_TIMEOUT USART_CSR_TIMEOUT /*!< USART receiver time-out */ +#define USART_FLAG_PARE USART_CSR_PARE /*!< USART parity error */ +#define USART_FLAG_FRAME USART_CSR_FRAME /*!< USART framing error */ +#define USART_FLAG_OVER USART_CSR_OVRE /*!< USART overrun error */ +#define USART_FLAG_RXBRK USART_CSR_RXBRK /*!< USART break receive/end of break */ +#define USART_FLAG_TXRDY USART_CSR_TXRDY /*!< USART transmitter ready */ +#define USART_FLAG_RXRDY USART_CSR_RXRDY /*!< USART receiver ready */ + +#define USART_FLAG_UNRE USART_CSR_UNRE /*!< USART underrun error */ + +#define USART_FLAG_LINHTE USART_CSR_LINHTE /*!< USART LIN header timeout error */ +#define USART_FLAG_LINSTE USART_CSR_LINSTE /*!< USART LIN synch tolerance eror */ +#define USART_FLAG_LINSNRE USART_CSR_LINSNRE /*!< USART LIN slave not response error */ +#define USART_FLAG_LINCE USART_CSR_LINCE /*!< USART LIN checksum error */ +#define USART_FLAG_LINIPE USART_CSR_LINIPE /*!< USART LIN identifier parity error */ +#define USART_FLAG_LINISFE USART_CSR_LINISFE /*!< USART LIN inconsistent synch field error */ +#define USART_FLAG_LINBE USART_CSR_LINBE /*!< USART LIN bit error */ +#define USART_FLAG_LINBLS USART_CSR_LINBLS /*!< USART LIN bus line status */ +#define USART_FLAG_LINTC USART_CSR_LINTC /*!< USART LIN transfer completed */ +#define USART_FLAG_LINID USART_CSR_LINID /*!< USART LIN identifier sent or LIN identifier received */ +#define USART_FLAG_LINBK USART_CSR_LINBK /*!< USART LIN break sent or LIN break received */ +/** + * @} + */ + +/** @defgroup USART_Clear_Flags + * @brief Flag clear in the CR register + * @{ + */ +#define USART_CLEAR_CTSIC USART_CR_RSTTX /*!< USART Clear to Send input interrupt clear */ +#define USART_CLEAR_DSRIC USART_CR_RSTRX /*!< USART Data Set Ready input change clear */ +#define USART_CLEAR_NACK USART_CR_RSTNACK /*!< USART non acknowledge interrupt clear */ +#define USART_CLEAR_ITER USART_CR_RSTIT /*!< USART max number of repetitions reached interrupt clear */ +#define USART_CLEAR_TXEMPTY USART_CR_RSTTX /*!< USART transmitter empty interrupt clear */ +#define USART_CLEAR_TIMEOUT USART_CR_STTTO /*!< USART receiver time-out interrupt clear */ +#define USART_CLEAR_PARE USART_CR_RSTSTA /*!< USART parity error interrupt clear */ +#define USART_CLEAR_FRAME USART_CR_RSTSTA /*!< USART framing error interrupt clear */ +#define USART_CLEAR_OVER USART_CR_RSTSTA /*!< USART overrun error interrupt clear */ +#define USART_CLEAR_RXBRK USART_CR_RSTSTA /*!< USART break receive/end of break interrupt clear */ +#define USART_CLEAR_TXRDY USART_CR_RSTTX /*!< USART transmitter ready interrupt clear */ +#define USART_CLEAR_RXRDY USART_CR_RSTRX /*!< USART receiver ready interrupt clear */ + +#define USART_CLEAR_UNRE USART_CR_RSTSTA /*!< USART underrun error interrupt clear */ + +#define USART_CLEAR_LINHTE USART_CR_RSTSTA /*!< USART LIN header timeout error interrupt clear */ +#define USART_CLEAR_LINSTE USART_CR_RSTSTA /*!< USART LIN synch tolerance eror interrupt clear */ +#define USART_CLEAR_LINSNRE USART_CR_RSTSTA /*!< USART LIN slave not response error interrupt clear */ +#define USART_CLEAR_LINCE USART_CR_RSTSTA /*!< USART LIN checksum error interrupt clear */ +#define USART_CLEAR_LINIPE USART_CR_RSTSTA /*!< USART LIN identifier parity error interrupt clear */ +#define USART_CLEAR_LINISFE USART_CR_RSTSTA /*!< USART LIN inconsistent synch field error interrupt clear */ +#define USART_CLEAR_LINBE USART_CR_RSTSTA /*!< USART LIN bit error interrupt clear */ +#define USART_CLEAR_LINTC USART_CR_RSTSTA /*!< USART LIN transfer completed interrupt clear */ +#define USART_CLEAR_LINID USART_CR_RSTSTA /*!< USART LIN identifier sent or LIN identifier received interrupt clear */ +#define USART_CLEAR_LINBK USART_CR_RSTSTA /*!< USART LIN break sent or LIN break received interrupt clear */ +/** + * @} + */ + +/** @defgroup USART_Interrupt_definition + * @brief Interrupt enable register - IER register + * @{ + */ +#define USART_IT_CTSIC USART_IER_CTSIC /*!< USART Clear to Send input interruption */ +#define USART_IT_DSRIC USART_IER_DSRIC /*!< USART Data Set Ready input change interruption */ +#define USART_IT_NACK USART_IER_NACK /*!< USART non acknowledge interruption */ +#define USART_IT_ITER USART_IER_ITER /*!< USART max number of repetitions reached interruption */ +#define USART_IT_TXEMPTY USART_IER_TXEMPTY /*!< USART transmitter empty interruption */ +#define USART_IT_TIMEOUT USART_IER_TIMEOUT /*!< USART receiver time-out interruption */ +#define USART_IT_PARE USART_IER_PARE /*!< USART parity error interruption */ +#define USART_IT_FRAME USART_IER_FRAME /*!< USART framing error interruption */ +#define USART_IT_OVER USART_IER_OVRE /*!< USART overrun error interruption */ +#define USART_IT_RXBRK USART_IER_RXBRK /*!< USART break receive/end of break interruption */ +#define USART_IT_TXRDY USART_IER_TXRDY /*!< USART transmitter ready interruption */ +#define USART_IT_RXRDY USART_IER_RXRDY /*!< USART receiver ready interruption */ + +#define USART_IT_UNRE USART_IER_UNRE /*!< USART underrun error interruption */ + +#define USART_IT_LINHTE USART_IER_LINHTE /*!< USART LIN header timeout error interruption */ +#define USART_IT_LINSTE USART_IER_LINSTE /*!< USART LIN synch tolerance eror interruption */ +#define USART_IT_LINSNRE USART_IER_LINSNRE /*!< USART LIN slave not response error interruption */ +#define USART_IT_LINCE USART_IER_LINCE /*!< USART LIN checksum error interruption */ +#define USART_IT_LINIPE USART_IER_LINIPE /*!< USART LIN identifier parity error interruption */ +#define USART_IT_LINISFE USART_IER_LINISFE /*!< USART LIN inconsistent synch field error interruption */ +#define USART_IT_LINBE USART_IER_LINBE /*!< USART LIN bit error interruption */ +#define USART_IT_LINTC USART_IER_LINTC /*!< USART LIN transfer completed interruption */ +#define USART_IT_LINID USART_IER_LINID /*!< USART LIN identifier sent or LIN identifier received interruption */ +#define USART_IT_LINBK USART_IER_LINBK /*!< USART LIN break sent or LIN break received interruption */ +/** + * @} + */ + +/** @defgroup USART_Interrupt_disable + * @brief Interrupt disable register - IDR register + * @{ + */ +#define USART_DIS_CTSIC USART_IDR_CTSIC /*!< USART Clear to Send input interrupt disable */ +#define USART_DIS_DSRIC USART_IDR_DSRIC /*!< USART Data Set Ready input change interrupt disable */ +#define USART_DIS_NACK USART_IDR_NACK /*!< USART non acknowledge interrupt disable */ +#define USART_DIS_ITER USART_IDR_ITER /*!< USART max number of repetitions reached interrupt disable */ +#define USART_DIS_TXEMPTY USART_IDR_TXEMPTY /*!< USART transmitter empty interrupt disable */ +#define USART_DIS_TIMEOUT USART_IDR_TIMEOUT /*!< USART receiver time-out interrupt disable */ +#define USART_DIS_PARE USART_IDR_PARE /*!< USART parity error interrupt disable */ +#define USART_DIS_FRAME USART_IDR_FRAME /*!< USART framing error interrupt disable */ +#define USART_DIS_OVER USART_IDR_OVRE /*!< USART overrun error interrupt disable */ +#define USART_DIS_RXBRK USART_IDR_RXBRK /*!< USART break receive/end of break interrupt disable */ +#define USART_DIS_TXRDY USART_IDR_TXRDY /*!< USART transmitter ready interrupt disable */ +#define USART_DIS_RXRDY USART_IDR_RXRDY /*!< USART receiver ready interrupt disable */ + +#define USART_DIS_UNRE USART_IDR_UNRE /*!< USART underrun error interrupt disable */ + +#define USART_DIS_LINHTE USART_IDR_LINHTE /*!< USART LIN header timeout error interrupt disable */ +#define USART_DIS_LINSTE USART_IDR_LINSTE /*!< USART LIN synch tolerance eror interrupt disable */ +#define USART_DIS_LINSNRE USART_IDR_LINSNRE /*!< USART LIN slave not response error interrupt disable */ +#define USART_DIS_LINCE USART_IDR_LINCE /*!< USART LIN checksum error interrupt disable */ +#define USART_DIS_LINIPE USART_IDR_LINIPE /*!< USART LIN identifier parity error interrupt disable */ +#define USART_DIS_LINISFE USART_IDR_LINISFE /*!< USART LIN inconsistent synch field error interrupt disable */ +#define USART_DIS_LINBE USART_IDR_LINBE /*!< USART LIN bit error interrupt disable */ +#define USART_DIS_LINTC USART_IDR_LINTC /*!< USART LIN transfer completed interrupt disable */ +#define USART_DIS_LINID USART_IDR_LINID /*!< USART LIN identifier sent or LIN identifier received interrupt disable */ +#define USART_DIS_LINBK USART_IDR_LINBK /*!< USART LIN break sent or LIN break received interrupt disable */ +/** + * @} + */ + +/** @defgroup USART_Interruption_Mask + * @brief Interrupt mask register - IMR register + * @{ + */ +#define USART_MASK_CTSIC USART_IMR_CTSIC /*!< USART Clear to Send input interrupt mask */ +#define USART_MASK_DSRIC USART_IMR_DSRIC /*!< USART Data Set Ready input change mask */ +#define USART_MASK_NACK USART_IMR_NACK /*!< USART non acknowledge interrupt mask */ +#define USART_MASK_ITER USART_IMR_ITER /*!< USART max number of repetitions reached interrupt mask */ +#define USART_MASK_TXEMPTY USART_IMR_TXEMPTY /*!< USART transmitter empty interrupt mask */ +#define USART_MASK_TIMEOUT USART_IMR_TIMEOUT /*!< USART receiver time-out interrupt mask */ +#define USART_MASK_PARE USART_IMR_PARE /*!< USART parity error interrupt mask */ +#define USART_MASK_FRAME USART_IMR_FRAME /*!< USART framing error interrupt mask */ +#define USART_MASK_OVER USART_IMR_OVRE /*!< USART overrun error interrupt mask */ +#define USART_MASK_RXBRK USART_IMR_RXBRK /*!< USART break receive/end of break interrupt mask */ +#define USART_MASK_TXRDY USART_IMR_TXRDY /*!< USART transmitter ready interrupt mask */ +#define USART_MASK_RXRDY USART_IMR_RXRDY /*!< USART receiver ready interrupt mask */ + +#define USART_MASK_UNRE USART_IMR_UNRE /*!< USART underrun error interrupt mask */ + +#define USART_MASK_LINHTE USART_IMR_LINHTE /*!< USART LIN header timeout error interrupt mask */ +#define USART_MASK_LINSTE USART_IMR_LINSTE /*!< USART LIN synch tolerance eror interrupt mask */ +#define USART_MASK_LINSNRE USART_IMR_LINSNRE /*!< USART LIN slave not response error interrupt mask */ +#define USART_MASK_LINCE USART_IMR_LINCE /*!< USART LIN checksum error interrupt mask */ +#define USART_MASK_LINIPE USART_IMR_LINIPE /*!< USART LIN identifier parity error interrupt mask */ +#define USART_MASK_LINISFE USART_IMR_LINISFE /*!< USART LIN inconsistent synch field error interrupt mask */ +#define USART_MASK_LINBE USART_IMR_LINBE /*!< USART LIN bit error interrupt mask */ +#define USART_MASK_LINTC USART_IMR_LINTC /*!< USART LIN transfer completed interrupt mask */ +#define USART_MASK_LINID USART_IMR_LINID /*!< USART LIN identifier sent or LIN identifier received interrupt mask */ +#define USART_MASK_LINBK USART_IMR_LINBK /*!< USART LIN break sent or LIN break received interrupt mask */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macros -----------------------------------------------------------*/ +/** @defgroup USART_Exported_Macros USART Exported Macros + * @{ + */ + +/** @brief Check whether the specified USART flag is set or not. + * @param None + * @retval None + */ +#define IS_USART_GET_FLAG(FLAG) \ + ( \ + ((FLAG) == USART_FLAG_CTS ) || \ + ((FLAG) == USART_FLAG_DSR ) || \ + ((FLAG) == USART_FLAG_CTSIC ) || \ + ((FLAG) == USART_FLAG_DSRIC ) || \ + ((FLAG) == USART_FLAG_NACK ) || \ + ((FLAG) == USART_FLAG_ITER ) || \ + ((FLAG) == USART_FLAG_TXEMPTY) || \ + ((FLAG) == USART_FLAG_TIMEOUT) || \ + ((FLAG) == USART_FLAG_PARE ) || \ + ((FLAG) == USART_FLAG_FRAME ) || \ + ((FLAG) == USART_FLAG_OVER ) || \ + ((FLAG) == USART_FLAG_RXBRK ) || \ + ((FLAG) == USART_FLAG_TXRDY ) || \ + ((FLAG) == USART_FLAG_RXRDY ) || \ + ((FLAG) == USART_FLAG_UNRE ) || \ + ((FLAG) == USART_FLAG_LINHTE ) || \ + ((FLAG) == USART_FLAG_LINSTE ) || \ + ((FLAG) == USART_FLAG_LINSNRE) || \ + ((FLAG) == USART_FLAG_LINCE ) || \ + ((FLAG) == USART_FLAG_LINIPE ) || \ + ((FLAG) == USART_FLAG_LINISFE) || \ + ((FLAG) == USART_FLAG_LINBE ) || \ + ((FLAG) == USART_FLAG_LINBLS ) || \ + ((FLAG) == USART_FLAG_LINTC ) || \ + ((FLAG) == USART_FLAG_LINID ) || \ + ((FLAG) == USART_FLAG_LINBK ) \ + ) + +/** @brief Clear the specified USART pending flag enable. + * @param None + * @retval None + */ +#define IS_USART_CLEAR_FLAG(FLAG) \ + ( \ + ((FLAG) == USART_CLEAR_CTSIC ) || \ + ((FLAG) == USART_CLEAR_DSRIC ) || \ + ((FLAG) == USART_CLEAR_NACK ) || \ + ((FLAG) == USART_CLEAR_ITER ) || \ + ((FLAG) == USART_CLEAR_TXEMPTY) || \ + ((FLAG) == USART_CLEAR_TIMEOUT) || \ + ((FLAG) == USART_CLEAR_PARE ) || \ + ((FLAG) == USART_CLEAR_FRAME ) || \ + ((FLAG) == USART_CLEAR_OVER ) || \ + ((FLAG) == USART_CLEAR_RXBRK ) || \ + ((FLAG) == USART_CLEAR_TXRDY ) || \ + ((FLAG) == USART_CLEAR_RXRDY ) || \ + ((FLAG) == USART_CLEAR_UNRE ) || \ + ((FLAG) == USART_CLEAR_LINHTE ) || \ + ((FLAG) == USART_CLEAR_LINSTE ) || \ + ((FLAG) == USART_CLEAR_LINSNRE) || \ + ((FLAG) == USART_CLEAR_LINCE ) || \ + ((FLAG) == USART_CLEAR_LINIPE ) || \ + ((FLAG) == USART_CLEAR_LINISFE) || \ + ((FLAG) == USART_CLEAR_LINBE ) || \ + ((FLAG) == USART_CLEAR_LINTC ) || \ + ((FLAG) == USART_CLEAR_LINID ) || \ + ((FLAG) == USART_CLEAR_LINBK ) \ + ) + +/** @brief Enable the specified USART interrupt. + * @param None + * @retval None + */ +#define IS_USART_ENABLE_IT(IT) \ + ( \ + ((IT) == USART_IT_CTSIC ) || \ + ((IT) == USART_IT_DSRIC ) || \ + ((IT) == USART_IT_NACK ) || \ + ((IT) == USART_IT_ITER ) || \ + ((IT) == USART_IT_TXEMPTY) || \ + ((IT) == USART_IT_TIMEOUT) || \ + ((IT) == USART_IT_PARE ) || \ + ((IT) == USART_IT_FRAME ) || \ + ((IT) == USART_IT_OVER ) || \ + ((IT) == USART_IT_RXBRK ) || \ + ((IT) == USART_IT_TXRDY ) || \ + ((IT) == USART_IT_RXRDY ) || \ + ((IT) == USART_IT_UNRE ) || \ + ((IT) == USART_IT_LINHTE ) || \ + ((IT) == USART_IT_LINSTE ) || \ + ((IT) == USART_IT_LINSNRE) || \ + ((IT) == USART_IT_LINCE ) || \ + ((IT) == USART_IT_LINIPE ) || \ + ((IT) == USART_IT_LINISFE) || \ + ((IT) == USART_IT_LINBE ) || \ + ((IT) == USART_IT_LINTC ) || \ + ((IT) == USART_IT_LINID ) || \ + ((IT) == USART_IT_LINBK ) \ + ) + +/** @brief Disable the specified USART interrupt. + * @param None + * @retval None + */ +#define IS_USART_CLEAR_IT(IT) \ + ( \ + ((IT) == USART_DIS_CTSIC ) || \ + ((IT) == USART_DIS_DSRIC ) || \ + ((IT) == USART_DIS_NACK ) || \ + ((IT) == USART_DIS_ITER ) || \ + ((IT) == USART_DIS_TXEMPTY) || \ + ((IT) == USART_DIS_TIMEOUT) || \ + ((IT) == USART_DIS_PARE ) || \ + ((IT) == USART_DIS_FRAME ) || \ + ((IT) == USART_DIS_OVER ) || \ + ((IT) == USART_DIS_RXBRK ) || \ + ((IT) == USART_DIS_TXRDY ) || \ + ((IT) == USART_DIS_RXRDY ) || \ + ((IT) == USART_DIS_UNRE ) || \ + ((IT) == USART_DIS_LINHTE ) || \ + ((IT) == USART_DIS_LINSTE ) || \ + ((IT) == USART_DIS_LINSNRE) || \ + ((IT) == USART_DIS_LINCE ) || \ + ((IT) == USART_DIS_LINIPE ) || \ + ((IT) == USART_DIS_LINISFE) || \ + ((IT) == USART_DIS_LINBE ) || \ + ((IT) == USART_DIS_LINTC ) || \ + ((IT) == USART_DIS_LINID ) || \ + ((IT) == USART_DIS_LINBK ) \ + ) + + +/** @brief Check whether the specified USART interrupt has occurred or not. + * @param None + * @retval None + */ +#define IS_USART_GET_IT(IT) \ + ( \ + ((IT) == USART_MASK_CTSIC ) || \ + ((IT) == USART_MASK_DSRIC ) || \ + ((IT) == USART_MASK_NACK ) || \ + ((IT) == USART_MASK_ITER ) || \ + ((IT) == USART_MASK_TXEMPTY) || \ + ((IT) == USART_MASK_TIMEOUT) || \ + ((IT) == USART_MASK_PARE ) || \ + ((IT) == USART_MASK_FRAME ) || \ + ((IT) == USART_MASK_OVER ) || \ + ((IT) == USART_MASK_RXBRK ) || \ + ((IT) == USART_MASK_TXRDY ) || \ + ((IT) == USART_MASK_RXRDY ) || \ + ((IT) == USART_MASK_UNRE ) || \ + ((IT) == USART_MASK_LINHTE ) || \ + ((IT) == USART_MASK_LINSTE ) || \ + ((IT) == USART_MASK_LINSNRE) || \ + ((IT) == USART_MASK_LINCE ) || \ + ((IT) == USART_MASK_LINIPE ) || \ + ((IT) == USART_MASK_LINISFE) || \ + ((IT) == USART_MASK_LINBE ) || \ + ((IT) == USART_MASK_LINTC ) || \ + ((IT) == USART_MASK_LINID ) || \ + ((IT) == USART_MASK_LINBK ) \ + ) + +/** + * @} + */ + +/** @defgroup USART_Global_definition + * @{ + */ +#define IS_USART_BAUDRATE(BAUDRATE) ((BAUDRATE ) <= 105000000U) +#define IS_USART_BAUDRATE_APB1(BAUDRATE) ((BAUDRATE ) <= 52500000U ) +#define IS_USART_FIDIRATIO(FIDIRATE) ((FIDIRATE ) <= 2047U ) +#define IS_USART_IF(IF) ((IF ) <= 0xFFU ) +#define IS_USART_TIMEOUT(TIMEOUT) ((TIMEOUT ) <= 0x1FFFF ) +#define IS_USART_TIMGUARD(TIMEGUARD) ((TIMEGUARD) <= 0xFF ) +#define IS_USART_LINIR_WR(LINIR_WR) ((LINIR_WR ) <= 0xFF ) +#define IS_USART_DATA(DATA) ((DATA ) <= 0x1FF ) +#define IS_USART_DLC(DATA) ((DATA ) <= 0xFF ) + +/** + * @} + */ + + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup USART_Exported_Functions USART Exported Functions + * @{ + */ +/* Initialization and de-initialization functions *****************************/ +void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct); +void USART_StructInit(USART_InitTypeDef* USART_InitStruct); +void USART_DeInit(USART_TypeDef* USARTx); + +/* Normal command and configuration functions *********************************/ +/* Normal Cmd */ void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState); +/* Hardware Cmd */ void USART_RTSDIS_Cmd(USART_TypeDef* USARTx, FunctionalState NewState); +/* Hardware Cmd */ void USART_RTSEN_Cmd(USART_TypeDef* USARTx, FunctionalState NewState); +/* Hardware Cmd */ void USART_DTRDIS_Cmd(USART_TypeDef* USARTx, FunctionalState NewState); +/* Hardware Cmd */ void USART_DTREN_Cmd(USART_TypeDef* USARTx, FunctionalState NewState); +/* Normal Cmd */ void USART_RSTSTA_Cmd(USART_TypeDef* USARTx, FunctionalState NewState); +/* Normal Cmd */ void USART_TXDIS_Cmd(USART_TypeDef* USARTx, FunctionalState NewState); +/* Normal Cmd */ void USART_TXEN_Cmd(USART_TypeDef* USARTx, FunctionalState NewState); +/* Normal Cmd */ void USART_RXDIS_Cmd(USART_TypeDef* USARTx, FunctionalState NewState); +/* Normal Cmd */ void USART_RXEN_Cmd(USART_TypeDef* USARTx, FunctionalState NewState); +/* Normal Cmd */ void USART_RSTTX_Cmd(USART_TypeDef* USARTx, FunctionalState NewState); +/* Normal Cmd */ void USART_RSTRX_Cmd(USART_TypeDef* USARTx, FunctionalState NewState); +/* Normal Cfg */ void USART_InvData_Cfg(USART_TypeDef* USARTx, FunctionalState NewState); +/* Normal Cfg */ void USART_OverSampling8_Cfg(USART_TypeDef* USARTx, FunctionalState NewState); +/* Normal Cfg */ void USART_ClkOutput_Cfg(USART_TypeDef* USARTx, FunctionalState NewState); +/* Normal Cfg */ void USART_DataLength9_Cfg(USART_TypeDef* USARTx, FunctionalState NewState); +/* Normal Cfg */ void USART_MSBFirst_Cfg(USART_TypeDef* USARTx, FunctionalState NewState); +/* Normal Cfg */ void USART_ChannelMode_Cfg(USART_TypeDef* USARTx, uint32_t USART_ChannelMode); +/* Normal Cfg */ void USART_StopBit_Cfg(USART_TypeDef* USARTx, uint32_t USART_StopBits); +/* Normal Cfg */ void USART_Parity_Cfg(USART_TypeDef* USARTx, uint32_t USART_Parity); +/* Normal Cfg */ void USART_SYNCMode_Cfg(USART_TypeDef* USARTx, FunctionalState NewState); +/* Normal Cfg */ void USART_DataLength_Cfg(USART_TypeDef* USARTx, uint32_t USART_WordLength); +/* Normal Cfg */ void USART_CLKSelect_Cfg(USART_TypeDef* USARTx, uint32_t USART_CLKSelect); +/* Normal Cfg */ void USART_OperationMode_Cfg(USART_TypeDef* USARTx, uint32_t USART_OperationMode); + +/* Fractional baudrate function ***********************************************/ +/* Normal Cfg */ void USART_FracDivider_Cfg(USART_TypeDef* USARTx, uint32_t USART_BaudRate); + +/* Break command functions ****************************************************/ +/* Normal Cmd */ void USART_STPBRK_Cmd(USART_TypeDef* USARTx, FunctionalState NewState); +/* Normal Cmd */ void USART_STTBRK_Cmd(USART_TypeDef* USARTx, FunctionalState NewState); + +/* Receiver time-out and transmitter timeguard functions **********************/ +/* Normal Cfg */ void USART_Receiver_TimeOut_Cfg(USART_TypeDef* USARTx, uint32_t USART_ReceiverTimeOut); +/* Normal Cmd */ void USART_RETTO_After_Timeout_Cmd(USART_TypeDef* USARTx, FunctionalState NewState); +/* Normal Cmd */ void USART_STTTO_After_Timeout_Cmd(USART_TypeDef* USARTx, FunctionalState NewState); +/* Normal Cfg */ void USART_Transmitter_TimeGuard_Cfg(USART_TypeDef* USARTx, uint32_t USART_TransmitterTimeGuard); + +/* Multidrop mode command function ********************************************/ +/* Normal Cmd */ void USART_SENDAInMultidropMode_Cmd(USART_TypeDef* USARTx, FunctionalState NewState); + +/* SPI mode functions *********************************************************/ +/* SPI Cmd */ void USART_RCS_Cmd(USART_TypeDef* USARTx, FunctionalState NewState); +/* SPI Cmd */ void USART_FCS_Cmd(USART_TypeDef* USARTx, FunctionalState NewState); +/* SPI Cfg */ void USART_WRDBT_Cfg(USART_TypeDef* USARTx, FunctionalState NewState); +/* SPI Cfg */ void USART_CLKPolarity_Cfg(USART_TypeDef* USARTx, FunctionalState NewState); +/* SPI Cfg */ void USART_CLKPhase_Cfg(USART_TypeDef* USARTx, FunctionalState NewState); + +/* ISO7816 mode functions *****************************************************/ +/* ISO7816_T0 Cmd */ void USART_RSTNACK_Cmd(USART_TypeDef* USARTx, FunctionalState NewState); +/* ISO7816_T0 Cmd */ void USART_RSTIT_Cmd(USART_TypeDef* USARTx, FunctionalState NewState); +/* ISO7816_T0 Cfg */ void USART_MaxIteration_Cfg(USART_TypeDef* USARTx, uint32_t USART_MAXIteration); +/* ISO7816_T0 Cfg */ void USART_DsNack_Cfg(USART_TypeDef* USARTx, FunctionalState NewState); +/* ISO7816_T0 Cfg */ void USART_INack_Cfg(USART_TypeDef* USARTx, FunctionalState NewState); +/* ISO7816_T0 Read */ uint32_t USART_GetNumberOfError(USART_TypeDef* USARTx); +/* ISO7816 Cfg */ void USART_FiDiRatio_Cfg(USART_TypeDef* USARTx, uint32_t USART_FiDiRatio, uint32_t USART_BaudRate); + +/* IrDA mode function *********************************************************/ +/* IrDA Cfg */ void USART_IrDAFilter_Cfg(USART_TypeDef* USARTx, uint32_t USART_IrDAFilter); + +/* LIN mode functions *********************************************************/ +/* LIN Cmd */ void USART_LINWKUP_Cmd(USART_TypeDef* USARTx, FunctionalState NewState); +/* LIN Cmd */ void USART_LINABT_Cmd(USART_TypeDef* USARTx, FunctionalState NewState); +/* LIN Cfg */ void USART_Write_LINIR_In_LIN_Master(USART_TypeDef* USARTx, uint32_t USART_LINIR_Data); +/* LIN Read */ uint32_t USART_Read_LINIR_In_LIN_Slave(USART_TypeDef* USARTx); +/* LIN Cfg */ void USART_SYNCDisable_Cfg(USART_TypeDef* USARTx, FunctionalState NewState); +/* LIN Cfg */ void USART_PDCMode_Cfg(USART_TypeDef* USARTx, FunctionalState NewState); +/* LIN Cfg */ void USART_DataLengthControl_Cfg(USART_TypeDef* USARTx, uint32_t USART_DataLengthControl); +/* LIN Cfg */ void USART_WkupType_Cfg(USART_TypeDef* USARTx, FunctionalState NewState); +/* LIN Cfg */ void USART_FrameSlotDisable_Cfg(USART_TypeDef* USARTx, FunctionalState NewState); +/* LIN Cfg */ void USART_DataLengthMode_Cfg(USART_TypeDef* USARTx, FunctionalState NewState); +/* LIN Cfg */ void USART_CheckSumType_Cfg(USART_TypeDef* USARTx, FunctionalState NewState); +/* LIN Cfg */ void USART_CheckSumDisable_Cfg(USART_TypeDef* USARTx, FunctionalState NewState); +/* LIN Cfg */ void USART_ParityDisable_Cfg(USART_TypeDef* USARTx, FunctionalState NewState); +/* LIN Cfg */ void USART_NodeAction_Cfg(USART_TypeDef* USARTx, uint32_t USART_NodeAction); +/* LIN Read */ uint32_t USART_LINBaudRate(USART_TypeDef* USARTx); + +/* Write protection register mode functions ***********************************/ +void USART_WriteProtectionRegisterConfig(USART_WP_TypeDef* USARTx_WP, FunctionalState NewState); +FlagStatus USART_GetWriteProtectionRegisterStatus(USART_WP_TypeDef* USARTx_WP); +uint32_t USART_GetWriteProtectionRegisterSource(USART_WP_TypeDef* USARTx_WP); +uint32_t USART_ClearWPSRField(USART_WP_TypeDef* USARTx_WP); + +/* Data transfers functions ***************************************************/ +void USART_Transmit(USART_TypeDef* USARTx, uint16_t Data); +uint16_t USART_Receive(USART_TypeDef* USARTx); + +/* DMA transfers management functions *****************************************/ +void USART_DMATxEnable_Cmd(USART_TypeDef* USARTx, FunctionalState NewState); +void USART_DMARxEnable_Cmd(USART_TypeDef* USARTx, FunctionalState NewState); + +/* Low-Power SLEEP wakeup management function *********************************/ +void USART_LowPowerSleepWkupConfig(USART_TypeDef* USARTx, FunctionalState NewState); + +/* Interrupts and flags management functions **********************************/ +void USART_ITConfig(USART_TypeDef* USARTx, uint32_t USART_IT, FunctionalState NewState); +FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint32_t USART_FLAG); +void USART_ClearFlag(USART_TypeDef* USARTx, uint32_t USART_FLAG); +ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint32_t USART_IT); +void USART_ITDisableConfig(USART_TypeDef* USARTx, uint32_t USART_IT, FunctionalState NewState); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __FT32F4XX_USART_H */ + +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_usb_fs.h b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_usb_fs.h new file mode 100644 index 00000000000..082bb1656ce --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_usb_fs.h @@ -0,0 +1,472 @@ +/** + ****************************************************************************** + * @file ft32f4xx_usb_fs.h + * @author FMD XA + * @brief This file contains all the functions prototypes for the USB_OTG_FS + * >>->-and USB_OTG_FS firmware library. + * @version V1.0.0 + * @data 2025-05-28 + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __FT32F4XX_USB_FS_H +#define __FT32F4XX_USB_FS_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx.h" + +#if defined (USB_OTG_FS) + + +/* Exported types ------------------------------------------------------------*/ + +#ifndef BYTE + typedef unsigned char BYTE; +#endif +#ifndef WORD + typedef unsigned short WORD; +#endif + +/** + * @brief Register read/write macros + */ + +#define READ_BYTE(addr) *((BYTE *)(addr)) +#define WRITE_BYTE(addr,data) *((BYTE *)(addr)) = data + + +#if !defined(UNUSED) +#define UNUSED(x) (void)x /* to avoid gcc/g++ warnings */ +#endif /* UNUSED */ + + +/** + * @brief USB Mode definition + */ + +typedef enum +{ + USB_FS_DEVICE_MODE = 0, + USB_FS_HOST_MODE = 1, + USB_FS_DRD_MODE = 2 +} USB_FS_ModeTypeDef; + +/** + * @brief URB States definition + * URB : USB Request Block + */ +typedef enum +{ + URB_IDLE = 0, + URB_DONE, + URB_NOTREADY, + URB_ERROR, + URB_STALL +} USB_OTG_FS_URBStateTypeDef; + +/** + * @brief host endpoint state definition + */ +typedef enum +{ + EP_IDLE = 0, + EP_XFRC, + EP_HALTED, + EP_ACK, + EP_NAK, + EP_NYET, + EP_STALL, + EP_XACTERR, + EP_BBLERR, + EP_DATATGLERR +} USB_OTG_FS_HEPStateTypeDef; + +/** + * @brief host endpoint control state definition + */ +typedef enum +{ + CTRL_SETUP_P = 0, + CTRL_DATA, + CTRL_STATUS, +} USB_OTG_FS_CtlStateTypeDef; + +/** + * @brief USB OTG Initialization Structure definition + */ +typedef struct +{ + uint32_t endpoints; /*!< Endpoints number. + This parameter depends on the used USB core. + This parameter must be a number between Min_Data = 1 and Max_Data = 15 */ + + uint32_t Host_eps; /*!< Host Channels number. + This parameter Depends on the used USB core. + This parameter must be a number between Min_Data = 1 and Max_Data = 15 */ + + uint32_t speed; /*!< USB Core speed. + This parameter can be any value of @ref USB_Core_Speed_ */ + + uint32_t ep0_mps; /*!< Set the Endpoint 0 Max Packet size. */ + + uint8_t OTGState; /*!< OTG State. */ + +} USB_OTG_FS_CfgTypeDef; + +typedef struct +{ + uint8_t dev_addr; /*!< USB device address. + This parameter must be a number between Min_Data = 1 and Max_Data = 255 */ + + uint8_t ep_num; /*!< Host channel number. + This parameter must be a number between Min_Data = 1 and Max_Data = 15 */ + + uint8_t epnum; /*!< Endpoint number. index register value + This parameter must be a number between Min_Data = 1 and Max_Data = 15 */ + + uint8_t ep_is_in; /*!< Endpoint direction + This parameter must be a number between Min_Data = 0 and Max_Data = 1 */ + + uint8_t speed; /*!< USB Host Channel speed. + This parameter can be any value of @ref USB_Core_Speed_ */ + + uint8_t ep_type; /*!< Endpoint Type. + This parameter can be any value of @ref USB_EP_Type */ + + uint16_t max_packet; /*!< Endpoint Max packet size. + This parameter must be a number between Min_Data = 0 and Max_Data = 64KB */ + + uint8_t data_pid; /*!< Initial data PID. + This parameter must be a number between Min_Data = 0 and Max_Data = 1 */ + + uint8_t *xfer_buff; /*!< Pointer to transfer buffer. */ + + uint32_t XferSize; /*!< OTG Channel transfer size. */ + + uint32_t xfer_len; /*!< Current transfer length. */ + + uint32_t xfer_count; /*!< Partial transfer length in case of multi packet transfer. */ + + uint8_t toggle_in; /*!< IN transfer current toggle flag. + This parameter must be a number between Min_Data = 0 and Max_Data = 1 */ + + uint8_t toggle_out; /*!< OUT transfer current toggle flag + This parameter must be a number between Min_Data = 0 and Max_Data = 1 */ + + uint32_t ErrCnt; /*!< Host channel error count. */ + + uint8_t interval; /* host tx or rx interval/nakmit*/ + + USB_OTG_FS_URBStateTypeDef urb_state; /*!< URB state. + This parameter can be any value of @ref USB_OTG_URBStateTypeDef */ + + USB_OTG_FS_HEPStateTypeDef state; /*!< Host endpoint state. + This parameter can be any value of @ref USB_OTG_HEPStateTypeDef */ + USB_OTG_FS_CtlStateTypeDef ctrl_state; /*control state + this parameter can be any value of @ref USB_OTG_CtlStateTypeDef */ +} USB_OTG_FS_HEPTypeDef; + +typedef struct +{ + uint8_t dev_addr; /*!< USB device address. + This parameter must be a number between Min_Data = 1 and Max_Data = 255 */ + + uint8_t num; /*!< Endpoint number. + This parameter must be a number between Min_Data = 1 and Max_Data = 15 */ + + uint8_t is_in; /*!< Endpoint direction + This parameter must be a number between Min_Data = 0 and Max_Data = 1 */ + + uint8_t is_stall; /*!< Endpoint stall condition + This parameter must be a number between Min_Data = 0 and Max_Data = 1 */ + + uint8_t speed; /*!< USB Host Channel speed. + This parameter can be any value of @ref USB_Core_Speed_ */ + + uint8_t type; /*!< Endpoint Type. + This parameter can be any value of @ref USB_EP_Type */ + + uint16_t maxpacket; /*!< Endpoint Max packet size. + This parameter must be a number between Min_Data = 0 and Max_Data = 64KB */ + + uint16_t tx_fifo_num; /*!< Transmission FIFO number + This parameter must be a number between Min_Data = 1 and Max_Data = 15 */ + + uint8_t data_pid_start; /*!< Initial data PID. + This parameter must be a number between Min_Data = 0 and Max_Data = 1 */ + + uint8_t *xfer_buff; /*!< Pointer to transfer buffer. */ + + uint32_t xfer_size; /*!< OTG endpoint transfer size. */ + + uint32_t xfer_len; /*!< Current transfer length. */ + + uint32_t xfer_count; /*!< Partial transfer length in case of multi packet transfer. */ +} USB_OTG_FS_DEPTypeDef; + +/** + *@brief USB_FS status structures definition + */ +typedef enum +{ + USB_FS_OK = 0x00U, + USB_FS_ERROR = 0x01U, + USB_FS_BUSY = 0x02U, +} USB_FS_StatusTypeDef; + +/** + *@brief USB_FS lock status structures definition + */ +typedef enum +{ + USB_FS_UNLOCKED = 0x00U, + USB_FS_LOCKED = 0x01U, +} USB_FS_LockTypeDef; + + +/* Exported constants --------------------------------------------------------*/ + +#if defined (USB_OTG_FS) + +#define VBUS_MASK 0x70U + +#define ADDR_FIFO_EP0 OTG_FS_BASE + 0x20U + +#define VBUS_BELOW_SESSION_END 0 +#define VBUS_ABOVE_SESSION_END 1 +#define VBUS_ABOVE_AVALID 2 +#define VBUS_ABOVE_VBUS_VALID 3 +#define VBUS_ERROR 256 + +#define USB_FS_EPNUM 4U /* ep0 + ep1~3 */ +#define EP0_SIZE 64 + + + +#define AB_IDLE 0x00 +#define WAIT_VRISE 0x01 + +#define A_PERIPHERAL 0x21 +#define A_WAIT_BCON 0x22 +#define A_HOST 0x23 +#define A_SUSPEND 0x24 + +#define B_PERIPHERAL 0x11 +#define B_WAIT_ACON 0x12 +#define B_HOST 0x13 +#define B_SRP_INIT 0x14 + +#define S_TRANSITION 0x30 + +/* Using bitstuffing of (7/6) * 8 * bytecount : Sec 5.11.3 */ +#define BitTransferTime(byte_count) (7 * 8 * byte_count / 6) +#define USB_DELAY (1000L) /* Temp : Info from HW Team reqd */ +#define USB_LS_SETUP_TIME (1000L) /* Temp : Info from HW Team reqd */ + +/* Low Speed : 1.5 MBPS -> 1 Frame = 1 msec Hence 1.5 * 1000 * 1000 / 1000 */ +#define USB_LS_FRAME_BITS 1500L + +/* Full Speed : 12 MBPS -> 1 Frame = 1 msec. Hence 12 * 1000 * 1000 / 1000 */ +#define USB_FS_FRAME_BITS 12000L + +/* Frame Time in Micro Sec : Max is 90 % for Low and Full SPeed + * 1 Frame = 1 msec = 1000 micro Sec + * 90 % of it is = 90 * 1000 / 100 = 900 micro sec + */ +#define USB_FRAME_MAX_USECS_ALLOC (900L) + +#define FRAME_OFFSET (1) +#define MAX_POLLING_INTERVAL (255) + + + +/** @defgroup USB Core Mode + * @{ + */ +#define USB_OTG_MODE_DEVICE 0U +#define USB_OTG_MODE_HOST 4U + + + +/** @defgroup USB Device Speed + * @{ + */ +#define USB_FS_SPEED 0U +#define USB_LS_SPEED 1U +/** + * @} + */ + +/** @defgroup USB_Core_Speed USB Low Layer Core Speed + * @{ + */ +#define USB_OTG_SPEED_FULL 0U +#define USB_OTG_SPEED_LOW 1U + +#define FIFO_TX 0U +#define FIFO_RX 1U + +/** + * @} + */ + +/** @defgroup USB_Core_MPS USB Low Layer Core MPS + * @{ + */ +#define USB_OTG_FS_MAX_PACKET_SIZE 64U +#define USB_OTG_FS_MAX_BULK_PACKET_SIZE 64U +#define USB_OTG_FS_MAX_INTR_PACKET_SIZE 64U +#define USB_OTG_LS_MAX_INTR_PACKET_SIZE 8U +#define USB_OTG_FS_MAX_ISOC_PACKET_SIZE 1023U +/** + * @} + */ + + +#endif /* USB_OTG_FS */ + + +/** @defgroup USB_EP_Speed USB Low Layer EP Speed + * @{ + */ +#define EP_SPEED_LOW 0U +#define EP_SPEED_FULL 1U +/** + * @} + */ + +/** @defgroup USB_EP_Type USB Low Layer EP Type + * @{ + */ +#define EP_TYPE_CTRL 0U +#define EP_TYPE_ISOC 1U +#define EP_TYPE_BULK 2U +#define EP_TYPE_INTR 3U +#define EP_TYPE_MSK 3U + + +#define EP_PID_DATA0 0U +#define EP_PID_DATA2 1U +#define EP_PID_DATA1 2U +#define EP_PID_SETUP 3U + +/** + * @} + */ + +#define EP_ADDR_MSK 0xFU + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup USB_Exported_Macros USB Low Layer Exported Macros + * @{ + */ + + +#define __USB_FS_LOCK(__HANDLE__) \ + do{ \ + if((__HANDLE__)->Lock == USB_FS_LOCKED) \ + { \ + return USB_FS_BUSY; \ + } \ + else \ + { \ + (__HANDLE__)->Lock = USB_FS_LOCKED; \ + } \ + }while (0U) + +#define __USB_FS_UNLOCK(__HANDLE__) \ + do{ \ + (__HANDLE__)->Lock = USB_FS_UNLOCKED; \ + }while (0U) + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup USB_FS_Exported_Functions USB Low Layer Exported Functions + * @{ + */ +#if defined (USB_OTG_FS) + +USB_FS_StatusTypeDef USB_FS_CoreInit(void); +USB_FS_StatusTypeDef USB_FS_DevInit(USB_OTG_FS_CfgTypeDef cfg); +USB_FS_StatusTypeDef USB_FS_HostInit(USB_OTG_FS_CfgTypeDef cfg); +USB_FS_StatusTypeDef USB_FS_IndexSel(uint8_t epnum); +USB_FS_StatusTypeDef USB_FS_RstEP0Regs(void); +USB_FS_StatusTypeDef USB_FS_RstEPRegs(uint8_t epnum); +USB_FS_StatusTypeDef USB_FS_FlushEp0Fifo(void); +USB_FS_StatusTypeDef USB_FS_FlushTxFifo(uint8_t epnum); +USB_FS_StatusTypeDef USB_FS_FlushRxFifo(uint8_t epnum); +USB_FS_StatusTypeDef USB_FS_SendStall(USB_OTG_FS_DEPTypeDef *dep); +USB_FS_StatusTypeDef USB_FS_ClrStall(USB_OTG_FS_DEPTypeDef *dep); +USB_FS_StatusTypeDef USB_FS_HEP_Init(uint8_t epnum, uint8_t dev_address, + uint8_t ep_type, uint8_t interval, + uint16_t xfersize); +int32_t usb_log2(int32_t x); +uint32_t USB_FS_Get_VBusStatus(void); +uint16_t USB_FS_Read_RxCount(void); +uint32_t USB_FS_GetCurrentFrame(void); +uint32_t USB_FS_GetSpeed(void); +uint8_t USB_FS_Read_Count0(void); +uint8_t USB_FS_GetMode(void); +uint8_t USB_FS_GetCID(void); +uint8_t USB_FS_GetAddress(void); +uint8_t USB_FS_GetPower(void); +uint8_t USB_FS_GetrDevctl(void); +int8_t USB_FS_Exiting_Host(uint8_t toOTG, USB_OTG_FS_CfgTypeDef *cfg); +uint32_t USB_FS_ReadInterrupts(void); + +void USB_FS_Enable_HEP(USB_OTG_FS_HEPTypeDef *hep); +void USB_FS_Enable_DEP(USB_OTG_FS_DEPTypeDef *dep); +void USB_FS_DEPStartXfer(USB_OTG_FS_DEPTypeDef *dep); +void USB_FS_DEP0StartXfer(USB_OTG_FS_DEPTypeDef *dep); +void USB_FS_HEP_StartXfer(USB_OTG_FS_HEPTypeDef *hep); +void USB_FS_HEP0_StartXfer(USB_OTG_FS_HEPTypeDef *hep, uint8_t ctl_state); +void USB_FS_FIFORead(uint8_t *dstP, uint8_t ep_num, uint16_t len); +void USB_FS_FIFOWrite(uint8_t *srcP, uint8_t ep_num, uint16_t len); +//void USB_FS_IntHandle(void); +void USB_FS_SetEPInt(uint8_t cfg); +void USB_FS_SetUSBInt(uint8_t cfg); +void USB_FS_ClrUSBInt(void); +void USB_FS_ClrEPInt(void); +void USB_FS_SetTxFiFo(uint8_t epnum, uint8_t size, uint8_t address, uint8_t dpb); +void USB_FS_SetRxFiFo(uint8_t epnum, uint8_t size, uint8_t address, uint8_t dpb); +void USB_FS_DrvSess(uint8_t state); +void USB_FS_Set_Polling_Interval(uint8_t epdir, uint8_t interval); +void USB_FS_Set_NAKLMT(uint8_t epnum, uint8_t epdir, uint8_t naklmt); +void USB_FS_SetAddress(uint8_t address); +void USB_FS_SetPower(uint8_t powercfg); +void USB_FS_ClrPower(uint8_t powercfg); +void USB_FS_SetDevctl(uint8_t cfg); +void USB_FS_ClrDevctl(uint8_t cfg); +void USB_FS_Activate_Resume(void); +void USB_FS_DeActivate_Resume(void); +void USB_FS_ResetPort(void); +void USB_FS_Enable_Suspend(void); +void USB_FS_Disable_Suspend(void); +void USB_FS_ActivateSetup(void); + + +#endif /* defined (USB_OTG_FS) */ + + +#endif /* defined (USB_OTG_FS) */ + +#ifdef __cplusplus +} +#endif + + +#endif /* FT32F4xx_USB_FS_H */ + +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_usb_hs.h b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_usb_hs.h new file mode 100644 index 00000000000..9f14c6b3397 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_usb_hs.h @@ -0,0 +1,585 @@ +/** + ****************************************************************************** + * @file ft32f4xx_usb_hs.h + * @author FMD XA + * @brief This file contains all the functions prototypes for the USB_OTG_FS + * >>->-and USB_OTG_HS firmware library. + * @version V1.0.0 + * @data 2025-03-20 + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __FT32F4XX_USB_HS_H +#define __FT32F4XX_USB_HS_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx.h" + +#if defined (USB_OTG_HS) +/** @addtogroup ft32f4xx Drive + * @ + */ + +/** @addtogroup USB_OTG_HS + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +#ifndef USB_TIMEOUT +#define USB_TIMEOUT 0xF000000U +#endif /* define USB_TIMEOUT */ + +#ifndef USB_HS_CURRENT_MODE_MAX_DELAY_MS +#define USB_HS_CURRENT_MODE_MAX_DELAY_MS 200U +#endif /* define USB_HS_CURRENT_MODE_MAX_DELAY_MS */ + + +/* compile define */ +//struct __attribute__((packed)) T_UINT32_READ{ +// uint32_t v; +//}; +//#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + +//struct __attribute__((packed)) T_UINT32_WRITE{ +// uint32_t v; +//}; +//#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + +#if !defined(UNUSED) +#define UNUSED(x) (void)x /* to avoid gcc/g++ warnings */ +#endif /* UNUSED */ + +/** + * @brief USB Mode definition + */ + +typedef enum +{ + USB_DEVICE_MODE = 0, + USB_HOST_MODE = 1, + USB_DRD_MODE = 2 +} USB_ModeTypeDef; + +/** + * @brief URB States definition + * URB : USB Request Block + */ +typedef enum +{ + URB_IDLE = 0, + URB_DONE, + URB_NOTREADY, + URB_NYET, + URB_ERROR, + URB_STALL +} USB_OTG_HS_URBStateTypeDef; + +/** + * @brief Host channel States definition + */ +typedef enum +{ + HC_IDLE = 0, + HC_XFRC, + HC_HALTED, + HC_ACK, + HC_NAK, + HC_NYET, + HC_STALL, + HC_XACTERR, + HC_BBLERR, + HC_DATATGLERR +} USB_OTG_HS_HCStateTypeDef; + +/** + * @brief USB OTG Initialization Structure definition + */ +typedef struct +{ + uint32_t dev_endpoints; /*!< Device Endpoints number. + This parameter depends on the used USB core. + This parameter must be a number between Min_Data = 1 and Max_Data = 15 */ + + uint32_t Host_channels; /*!< Host Channels number. + This parameter Depends on the used USB core. + This parameter must be a number between Min_Data = 1 and Max_Data = 15 */ + + uint32_t speed; /*!< USB Core speed. + This parameter can be any value of @ref USB_Core_Speed_ */ + + uint32_t dma_enable; /*!< Enable or disable of the USB embedded DMA used only for OTG HS. */ + + uint32_t ep0_mps; /*!< Set the Endpoint 0 Max Packet size. */ + + uint32_t low_power_enable; /*!< Enable or disable the low power mode. */ + + uint32_t bvalid_override_enable; /*!< Enable or disable the bvalid value override feature. */ + + uint32_t use_dedicated_ep1; /*!< Enable or disable the use of the dedicated EP1 interrupt. */ + +} USB_OTG_HS_CfgTypeDef; + +typedef struct +{ + uint8_t num; /*!< Endpoint number + This parameter must be a number between Min_Data = 1 and Max_Data = 15 */ + + uint8_t is_in; /*!< Endpoint direction + This parameter must be a number between Min_Data = 0 and Max_Data = 1 */ + + uint8_t is_stall; /*!< Endpoint stall condition + This parameter must be a number between Min_Data = 0 and Max_Data = 1 */ + + uint8_t is_iso_incomplete; /*!< Endpoint isoc condition + This parameter must be a number between Min_Data = 0 and Max_Data = 1 */ + + uint8_t type; /*!< Endpoint type + This parameter can be any value of @ref USB_LL_EP_Type */ + + uint8_t data_pid_start; /*!< Initial data PID + This parameter must be a number between Min_Data = 0 and Max_Data = 1 */ + + uint8_t even_odd_frame; /*!< IFrame parity + This parameter must be a number between Min_Data = 0 and Max_Data = 1 */ + + uint16_t tx_fifo_num; /*!< Transmission FIFO number + This parameter must be a number between Min_Data = 1 and Max_Data = 15 */ + + uint32_t maxpacket; /*!< Endpoint Max packet size + This parameter must be a number between Min_Data = 0 and Max_Data = 64KB */ + + uint8_t *xfer_buff; /*!< Pointer to transfer buffer */ + + uint32_t dma_addr; /*!< 32 bits aligned transfer buffer address */ + + uint32_t xfer_len; /*!< Current transfer length */ + + uint32_t xfer_count; /*!< Partial transfer length in case of multi packet transfer */ + + uint32_t xfer_size; /*!< Requested transfer size */ +} USB_OTG_HS_EPTypeDef; + +typedef struct +{ + uint8_t dev_addr; /*!< USB device address. + This parameter must be a number between Min_Data = 1 and Max_Data = 255 */ + + uint8_t ch_num; /*!< Host channel number. + This parameter must be a number between Min_Data = 1 and Max_Data = 15 */ + + uint8_t ep_num; /*!< Endpoint number. + This parameter must be a number between Min_Data = 1 and Max_Data = 15 */ + + uint8_t ep_is_in; /*!< Endpoint direction + This parameter must be a number between Min_Data = 0 and Max_Data = 1 */ + + uint8_t speed; /*!< USB Host Channel speed. + This parameter can be any value of @ref USB_Core_Speed_ */ + + uint8_t do_ping; /*!< Enable or disable the use of the PING protocol for HS mode. */ + uint8_t do_ssplit; /*!< Enable start split transaction in HS mode. */ + uint8_t do_csplit; /*!< Enable complete split transaction in HS mode. */ + uint8_t ep_ss_schedule; /*!< Enable periodic endpoint start split schedule. */ + uint8_t iso_splt_xactPos; /*!< iso split transfer transaction position. */ + + uint8_t hub_port_nbr; /*!< USB HUB port number */ + uint8_t hub_addr; /*!< USB HUB address */ + + uint8_t ep_type; /*!< Endpoint Type. + This parameter can be any value of @ref USB_EP_Type */ + + uint16_t max_packet; /*!< Endpoint Max packet size. + This parameter must be a number between Min_Data = 0 and Max_Data = 64KB */ + + uint8_t data_pid; /*!< Initial data PID. + This parameter must be a number between Min_Data = 0 and Max_Data = 1 */ + + uint8_t *xfer_buff; /*!< Pointer to transfer buffer. */ + + uint32_t XferSize; /*!< OTG Channel transfer size. */ + + uint32_t xfer_len; /*!< Current transfer length. */ + + uint32_t xfer_count; /*!< Partial transfer length in case of multi packet transfer. */ + + uint8_t toggle_in; /*!< IN transfer current toggle flag. + This parameter must be a number between Min_Data = 0 and Max_Data = 1 */ + + uint8_t toggle_out; /*!< OUT transfer current toggle flag + This parameter must be a number between Min_Data = 0 and Max_Data = 1 */ + + uint32_t dma_addr; /*!< 32 bits aligned transfer buffer address. */ + + uint32_t ErrCnt; /*!< Host channel error count. */ + uint32_t NyetErrCnt; /*!< Complete split NYET Host channel error count. */ + + USB_OTG_HS_URBStateTypeDef urb_state; /*!< URB state. + This parameter can be any value of @ref USB_OTG_URBStateTypeDef */ + + USB_OTG_HS_HCStateTypeDef state; /*!< Host Channel state. + This parameter can be any value of @ref USB_OTG_HCStateTypeDef */ +} USB_OTG_HS_HCTypeDef; + + +/** + *@brief USB_HS status structures definition + */ +typedef enum +{ + USB_HS_OK = 0x00U, + USB_HS_ERROR = 0x01U, + USB_HS_BUSY = 0x02U, + USB_HS_TIMEOUT = 0x03U +} USB_HS_StatusTypeDef; + +/** + *@brief USB_HS lock status structures definition + */ +typedef enum +{ + USB_HS_UNLOCKED = 0x00U, + USB_HS_LOCKED = 0x01U, +} USB_HS_LockTypeDef; + + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup PCD_Exported_Constants PCD Exported Constants + * @{ + */ + +#if defined (USB_OTG_HS) + +/** @defgroup USB Core Mode + * @{ + */ +#define USB_OTG_MODE_DEVICE 0U +#define USB_OTG_MODE_HOST 1U +#define USB_OTG_MODE_DRD 2U +/** + * @} + */ + +/** @defgroup USB Device Speed + * @{ + */ +#define USBD_HS_SPEED 0U +#define USBD_HSINFS_SPEED 1U +#define USBH_HS_SPEED 0U +#define USBD_FS_SPEED 2U +#define USBH_FSLS_SPEED 1U +/** + * @} + */ + +/** @defgroup USB_Core_Speed USB Low Layer Core Speed + * @{ + */ +#define USB_OTG_SPEED_HIGH 0U +#define USB_OTG_SPEED_HIGH_IN_FULL 1U +/** + * @} + */ + +#if !defined (USB_HS_PHYC_TUNE_VALUE) +#define USB_HS_PHYC_TUNE_VALUE 0x00000F13U /* value of USB HS PHY Tune waiting for update */ +#endif /* USB_HS_PHYC_TUNE_VALUE */ + +/** @defgroup USB_Turnaround_Timeout Turnaround Timeout Value + * @{ + */ +#ifndef USBD_HS_TRDT_VALUE +#define USBD_HS_TRDT_VALUE 9U +#endif /* USBD_HS_TRDT_VALUE */ +#ifndef USBD_FS_TRDT_VALUE +#define USBD_FS_TRDT_VALUE 5U +#define USBD_DEFAULT_TRDT_VALUE 9U +#endif /* USBD_HS_TRDT_VALUE */ +/** + * @} + */ + +/** @defgroup USB_Core_MPS USB Low Layer Core MPS + * @{ + */ +#define USB_OTG_HS_MAX_PACKET_SIZE 512U +#define USB_OTG_FS_MAX_PACKET_SIZE 64U +#define USB_OTG_MAX_EP0_SIZE 64U +/** + * @} + */ + +/** @defgroup USB_Core_PHY_Frequency USB Low Layer Core PHY Frequency + * @{ + */ +#define DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ (0U << 1) +#define DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ (1U << 1) +/** + * @} + */ + +/** @defgroup USB_CORE_Frame_Interval USB Low Layer Core Frame Interval + * @{ + */ +#define DCFG_FRAME_INTERVAL_80 0U +#define DCFG_FRAME_INTERVAL_85 1U +#define DCFG_FRAME_INTERVAL_90 2U +#define DCFG_FRAME_INTERVAL_95 3U +/** + * @} + */ +#endif /* USB_OTG_HS */ +/** @defgroup USB_EP0_MPS USB Low Layer EP0 MPS + * @{ + */ +#define EP_MPS_64 0U +#define EP_MPS_32 1U +#define EP_MPS_16 2U +#define EP_MPS_8 3U +/** + * @} + */ + +/** @defgroup USB_EP_Speed USB Low Layer EP Speed + * @{ + */ +#define EP_SPEED_LOW 0U +#define EP_SPEED_FULL 1U +#define EP_SPEED_HIGH 2U +/** + * @} + */ + +/** @defgroup USB_EP_Type USB Low Layer EP Type + * @{ + */ +#define EP_TYPE_CTRL 0U +#define EP_TYPE_ISOC 1U +#define EP_TYPE_BULK 2U +#define EP_TYPE_INTR 3U +#define EP_TYPE_MSK 3U +/** + * @} + */ +#if defined (USB_OTG_HS) +/** @defgroup USB_STS_Defines USB Low Layer STS Defines + * @{ + */ +#define STS_GOUT_NAK 1U +#define STS_DATA_UPDT 2U +#define STS_XFER_COMP 3U +#define STS_SETUP_COMP 4U +#define STS_SETUP_UPDT 6U +/** + * @} + */ + +/** @defgroup USB_HCFG_SPEED_Defines USB Low Layer HCFG Speed Defines + * @{ + */ +#define HCFG_30_60_MHZ 0U +#define HCFG_48_MHZ 1U +#define HCFG_6_MHZ 2U +/** + * @} + */ + +/** @defgroup USB_HFIR_Defines USB Low Layer frame interval Defines + * @{ + */ +#define HFIR_60_MHZ 60000U +#define HFIR_48_MHZ 48000U +#define HFIR_6_MHZ 6000U +/** + * @} + */ + +/** @defgroup USB_HPRT0_PRTSPD_SPEED_Defines USB Low Layer HPRT0 PRTSPD Speed Defines + * @{ + */ +#define HPRT0_PRTSPD_HIGH_SPEED 0U +#define HPRT0_PRTSPD_FULL_SPEED 1U +#define HPRT0_PRTSPD_LOW_SPEED 2U +/** + * @} + */ + +#define HCCHAR_CTRL 0U +#define HCCHAR_ISOC 1U +#define HCCHAR_BULK 2U +#define HCCHAR_INTR 3U + +#define HC_PID_DATA0 0U +#define HC_PID_DATA2 1U +#define HC_PID_DATA1 2U +#define HC_PID_SETUP 3U + +#define GRXSTS_PKTSTS_IN 2U +#define GRXSTS_PKTSTS_IN_XFER_COMP 3U +#define GRXSTS_PKTSTS_DATA_TOGGLE_ERR 5U +#define GRXSTS_PKTSTS_CH_HALTED 7U + +#define CLEAR_INTERRUPT_MASK 0xFFFFFFFFU +#define HC_MAX_PKT_CNT 256U +#define ISO_SPLT_MPS 188U + +#define HCSPLT_BEGIN 1U +#define HCSPLT_MIDDLE 2U +#define HCSPLT_END 3U +#define HCSPLT_FULL 4U + +#define TEST_J 1U +#define TEST_K 2U +#define TEST_SE0_NAK 3U +#define TEST_PACKET 4U +#define TEST_FORCE_EN 5U + +#define USB_HS_PCGCCTL *(__IO uint32_t *)((uint32_t)OTG_HS_BASE + USB_OTG_HS_PCGCCTL_BASE) +#define USB_HS_HPRT0 *(__IO uint32_t *)((uint32_t)OTG_HS_BASE + USB_OTG_HS_HOST_PORT_BASE) + +#define USB_HS_DEVICE ((USB_OTG_HS_DeviceTypeDef *)(OTG_HS_BASE + USB_OTG_HS_DEVICE_BASE)) +#define USB_HS_INEP(i) ((USB_OTG_HS_INEndpointTypeDef *)(OTG_HS_BASE + USB_OTG_HS_IN_ENDPOINT_BASE\ + + ((i) * USB_OTG_HS_EP_REG_SIZE))) +#define USB_HS_OUTEP(i) ((USB_OTG_HS_OUTEndpointTypeDef *)(OTG_HS_BASE + USB_OTG_HS_OUT_ENDPOINT_BASE\ + + ((i) * USB_OTG_HS_EP_REG_SIZE))) +#define USB_HS_DFIFO(i) *(__IO uint32_t *)(OTG_HS_BASE + USB_OTG_HS_FIFO_BASE + ((i) * USB_OTG_HS_FIFO_SIZE)) + +#define USB_HS_HOST ((USB_OTG_HS_HostTypeDef *)(OTG_HS_BASE + USB_OTG_HS_HOST_BASE)) +#define USB_HS_HC(i) ((USB_OTG_HS_HostChannelTypeDef *)(OTG_HS_BASE + USB_OTG_HS_HOST_CHANNEL_BASE \ + + ((i) * USB_OTG_HS_HOST_CHANNEL_SIZE))) + + +#define USB_HS_PKEY *(__IO uint32_t *)((uint32_t)OTG_HS_BASE + USB_OTG_HS_PKEY_BASE) +#define USB_HS_PREG *(__IO uint32_t *)((uint32_t)OTG_HS_BASE + USB_OTG_HS_PREG_BASE) + + +#endif /* defined (USB_OTG_HS) */ + +#define EP_ADDR_MSK 0xFU + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup USB_Exported_Macros USB Low Layer Exported Macros + * @{ + */ +#if defined (USB_OTG_HS) +#define USB_HS_MASK_INTERRUPT(__INTERRUPT__) (USB_HS->GINTMSK &= ~(__INTERRUPT__)) +#define USB_HS_UNMASK_INTERRUPT(__INTERRUPT__) (USB_HS->GINTMSK |= (__INTERRUPT__)) + +#define CLEAR_IN_EP_INTR(__EPNUM__, __INTERRUPT__) (USB_HS_INEP(__EPNUM__)->DIEPINT = (__INTERRUPT__)) +#define CLEAR_OUT_EP_INTR(__EPNUM__, __INTERRUPT__) (USB_HS_OUTEP(__EPNUM__)->DOEPINT = (__INTERRUPT__)) + +#define __USB_HS_LOCK(__HANDLE__) \ + do{ \ + if((__HANDLE__)->Lock == USB_HS_LOCKED) \ + { \ + return USB_HS_BUSY; \ + } \ + else \ + { \ + (__HANDLE__)->Lock = USB_HS_LOCKED; \ + } \ + }while (0U) + +#define __USB_HS_UNLOCK(__HANDLE__) \ + do{ \ + (__HANDLE__)->Lock = USB_HS_UNLOCKED; \ + }while (0U) + +#endif /* defined (USB_OTG_HS) */ +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup USB_HS_Exported_Functions USB Low Layer Exported Functions + * @{ + */ +#if defined (USB_OTG_HS) +void USB_HS_Delayms(uint32_t num); +USB_HS_StatusTypeDef USB_HS_CoreInit(USB_OTG_HS_CfgTypeDef cfg); +USB_HS_StatusTypeDef USB_HS_DevInit(USB_OTG_HS_CfgTypeDef cfg); +void USB_HS_EnableGlobalInt(void); +void USB_HS_DisableGlobalInt(void); +void USB_HS_SetTurnaroundTime(uint32_t hclk, uint8_t speed); +USB_HS_StatusTypeDef USB_HS_SetCurrentMode(USB_ModeTypeDef mode); +void USB_HS_SetDevSpeed(uint8_t speed); +USB_HS_StatusTypeDef USB_HS_FlushRxFifo(void); +USB_HS_StatusTypeDef USB_HS_FlushTxFifo(uint32_t num); +void USB_HS_ActivateEndpoint(USB_OTG_HS_EPTypeDef *ep); +void USB_HS_DeactivateEndpoint(USB_OTG_HS_EPTypeDef *ep); +void USB_HS_ActivateDedicatedEndpoint(USB_OTG_HS_EPTypeDef *ep); +void USB_HS_DeactivateDedicatedEndpoint(USB_OTG_HS_EPTypeDef *ep); +void USB_HS_EPStartXfer(USB_OTG_HS_EPTypeDef *ep, uint8_t dma); +void USB_HS_WritePacket(uint8_t *src, uint8_t ch_ep_num, uint16_t len, uint8_t dma); +void *USB_HS_ReadPacket(uint8_t *dest, uint16_t len); +void USB_HS_EPSetStall(USB_OTG_HS_EPTypeDef *ep); +void USB_HS_EPClearStall(USB_OTG_HS_EPTypeDef *ep); +USB_HS_StatusTypeDef USB_HS_EPStopXfer(USB_OTG_HS_EPTypeDef *ep); +void USB_HS_SetDevAddress(uint8_t address); +void USB_HS_DevConnect(void); +void USB_HS_DevDisconnect(void); +USB_HS_StatusTypeDef USB_HS_StopDevice(void); +void USB_HS_ActivateSetup(void); +USB_HS_StatusTypeDef USB_HS_EP0_OutStart(uint8_t dma, uint8_t *psetup); +uint8_t USB_HS_GetDevSpeed(void); +uint32_t USB_HS_GetMode(void); +uint32_t USB_HS_ReadInterrupts(void); +uint32_t USB_HS_ReadChInterrupts(uint8_t chnum); +uint32_t USB_HS_ReadDevAllOutEpInterrupt(void); +uint32_t USB_HS_ReadDevOutEPInterrupt(uint8_t epnum); +uint32_t USB_HS_ReadDevAllInEpInterrupt(void); +uint32_t USB_HS_ReadDevInEPInterrupt(uint8_t epnum); +void USB_HS_ClearInterrupts(uint32_t interrupt); + +USB_HS_StatusTypeDef USB_HS_HostInit(USB_OTG_HS_CfgTypeDef cfg); +USB_HS_StatusTypeDef USB_HS_InitFSLSPClkSel(uint8_t freq); +void USB_HS_ResetPort(void); +void USB_HS_DriveVbus(uint8_t state); +uint32_t USB_HS_GetHostSpeed(void); +uint32_t USB_HS_GetCurrentFrame(void); +USB_HS_StatusTypeDef USB_HS_HC_Init(uint8_t ch_num, uint8_t epnum, uint8_t dev_address, + uint8_t speed, uint8_t ep_type, uint16_t mps); +void USB_HS_HC_StartXfer(USB_OTG_HS_HCTypeDef *hc, uint8_t dma); +uint32_t USB_HS_HC_ReadInterrupt(void); +void USB_HS_HC_Halt(uint8_t hc_num); +void USB_HS_DoPing(uint8_t ch_num); +USB_HS_StatusTypeDef USB_HS_StopHost(void); +void USB_HS_ActivateRemoteWakeup(void); +void USB_HS_DeActivateRemoteWakeup(void); +void USB_HS_DriveID(uint8_t state); +#endif /* defined (USB_OTG_HS) */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +#endif /* defined (USB_OTG_HS) */ + +#ifdef __cplusplus +} +#endif + + +#endif /* FT32F4xx_USB_HS_H */ + +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_wwdg.h b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_wwdg.h new file mode 100644 index 00000000000..c1d7768c238 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/inc/ft32f4xx_wwdg.h @@ -0,0 +1,91 @@ +/** + ****************************************************************************** + * @file ft32f407xe_wwdg.h + * @author MCD Application Team + * @version V0.0.1 + * @date 2025-03-05 + * @brief This file contains all the functions prototypes for the WWDG + * firmware library. + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __FT32F407XE_WWDG_H +#define __FT32F407XE_WWDG_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx.h" + +/** @addtogroup FT32F407XE_StdPeriph_Driver + * @{ + */ + +/** @addtogroup WWDG + * @{ + */ +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup WWDG_Exported_Constants + * @{ + */ + +/** @defgroup WWDG_Prescaler + * @{ + */ + +#define WWDG_Prescaler_1 ((uint32_t)0x00000000) +#define WWDG_Prescaler_2 ((uint32_t)0x00000080) +#define WWDG_Prescaler_4 ((uint32_t)0x00000100) +#define WWDG_Prescaler_8 ((uint32_t)0x00000180) +#define IS_WWDG_PRESCALER(PRESCALER) (((PRESCALER) == WWDG_Prescaler_1) || \ + ((PRESCALER) == WWDG_Prescaler_2) || \ + ((PRESCALER) == WWDG_Prescaler_4) || \ + ((PRESCALER) == WWDG_Prescaler_8)) +#define IS_WWDG_WINDOW_VALUE(VALUE) ((VALUE) <= 0x7F) +#define IS_WWDG_COUNTER(COUNTER) (((COUNTER) >= 0x40) && ((COUNTER) <= 0x7F)) + +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ +/* Function used to set the WWDG configuration to the default reset state ****/ +void WWDG_DeInit(void); + +/* Prescaler, Refresh window and Counter configuration functions **************/ +void WWDG_SetPrescaler(uint32_t WWDG_Prescaler); +void WWDG_SetWindowValue(uint8_t WindowValue); +void WWDG_EnableIT(void); +void WWDG_SetCounter(uint8_t Counter); + +/* WWDG activation functions **************************************************/ +void WWDG_Enable(uint8_t Counter); + +/* Interrupts and flags management functions **********************************/ +FlagStatus WWDG_GetFlagStatus(void); +void WWDG_ClearFlag(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __FT32F407XE_WWDG_H */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_adc.c b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_adc.c new file mode 100644 index 00000000000..c3b30472651 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_adc.c @@ -0,0 +1,2214 @@ +/** + ****************************************************************************** + * @file ft32f4xx_adc.c + * @author FMD AE + * @brief This file provides firmware functions to manage the following + * functionalities of the Analog to Digital Convertor (ADC) peripheral: + * + Initialization and Configuration + * + Power saving + * + Analog Watchdog configuration + * + Temperature Sensor, Vrefint (Internal Reference Voltage) and + * Vbat (Voltage battery) management + * + ADC Channels Configuration + * + ADC Channels DMA Configuration + * + Interrupts and flags management. + * @version V1.0.0 + * @data 2025-03-06 + ****************************************************************************** + */ + + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx_adc.h" +#include "ft32f4xx_rcc.h" + + +/* ADC CFGR mask */ +#define CFGR1_CLEAR_MASK ((uint32_t)0x80000000) + +/* Calibration time out */ +#define CALIBRATION_TIMEOUT ((uint32_t)0x0000F000) + +/* ADC register bits groups */ +#define ADC_CR_BITS_PROPERTY_RS (ADC_CR_ADCAL | ADC_CR_ADEN | ADC_CR_ADDIS \ + | ADC_CR_JADSTART | ADC_CR_JADSTP \ + | ADC_CR_ADSTART | ADC_CR_ADSTP) +/* ADC register CR bits with HW property "rs": + * Software can read as well as set this bit. + * Writing '0' has no effect on the bit value. */ + +/** + * @brief Deinitializes ADCx peripheral registers to their default reset values. + * @param ADCx: where x can be 1/2/3 to select the ADC peripheral. + * @retval None + */ +void ADC_DeInit(void) +{ + /* Enable ADC1 reset state */ + //RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC, ENABLE); + + /* Release ADC1 from reset state */ + //RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC, DISABLE); +} + +/** + * @brief Initializes the ADCx peripheral according to the specified parameters + * in the ADC_InitStruct. + * @note This function is used to configure the global features of the ADC ( + * Common clock prescaler ,Resolution, Data Alignment, continuous mode activation, External + * trigger source and edge, Data Gain, regular/injected channel, Discontinuous mode, + * Auto injected mode, injected queue contexts, DMA mode, Auto delayed mode, + * Overrun mode, Sampling mode and oversampling mode). + * @param ADCx: where x can be 1/2/3 to select the ADC peripheral. + * @param ADC_InitStruct: pointer to an ADC_InitTypeDef structure that contains + * the configuration information for the specified ADC peripheral. + * @retval None + */ +void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_RESOLUTION(ADC_InitStruct->Resolution)); + assert_param(IS_FUNCTIONAL_STATE(ADC_InitStruct->ContinuousConvMode)); + assert_param(IS_ADC_EXT_TRIG_EDGE(ADC_InitStruct->ExternalTrigConvEdge)); + assert_param(IS_ADC_REGULAR_EXTTRIG_SOURCE(ADCx, ADC_InitStruct->ExternalTrigConv)); + assert_param(IS_ADC_DATA_ALIGN(ADC_InitStruct->DataAlign)); + assert_param(IS_ADC_GAIN_COMPENSATION(ADC_InitStruct->GainCompensation)); + assert_param(IS_FUNCTIONAL_STATE(ADC_InitStruct->DiscontinuousConvMode)); + assert_param(IS_ADC_DMA_MODE(ADC_InitStruct->DMAMode)); + assert_param(IS_FUNCTIONAL_STATE(ADC_InitStruct->AutoDelayedConvMode)); + assert_param(IS_ADC_OVERRUN(ADC_InitStruct->Overrun)); + assert_param(IS_FUNCTIONAL_STATE(ADC_InitStruct->InjectedDiscontinuousConvMode)); + assert_param(IS_FUNCTIONAL_STATE(ADC_InitStruct->AutoInjectedConvMode)); + assert_param(IS_FUNCTIONAL_STATE(ADC_InitStruct->QueueInjectedContext)); + assert_param(IS_FUNCTIONAL_STATE(ADC_InitStruct->QueueMode)); + assert_param(IS_ADC_SAMPLINGMODE(ADC_InitStruct->SamplingMode)); + assert_param(IS_FUNCTIONAL_STATE(ADC_InitStruct->OversamplingMode)); + assert_param(IS_ADC_SAMPLE_PLUS_TIME(ADC_InitStruct->SamplingPlusTime)); + + /* Get the ADCx CFGR value */ + tmpreg = ADCx->CFGR1; + + /* Clear RES[1:0], ALIGN, EXTSEL[2:0], EXTEN[1:0] and CONT bits */ + tmpreg &= CFGR1_CLEAR_MASK; + + /*---------------------------- ADCx CFGR Configuration ---------------------*/ + /* Set DMACFG bit according to ADC_ value */ + /* Set RES[1:0] bits according to ADC_Resolution value */ + /* Set EXTEN[1:0] bits according to ADC_ExternalTrigConvEdge value */ + /* Set EXTSEL[2:0] bits according to ADC_ExternalTrigConv value */ + /* Set OVRMOD bit according to ADC_ value */ + /* Set CONT bit according to ADC_ContinuousConvMode value */ + /* Set ALIGN bit according to ADC_DataAlign value */ + /* Set AUTDLY bit according to ADC_ value */ + /* Set DISCEN bit according to ADC_ value */ + /* Set DISCNUM[2:0] bits according to ADC_ value */ + /* Set JAUTO bit according to ADC_ value */ + /* Set JQM bit according to ADC_ value */ + /* Set JDISCEN bit according to ADC_ value */ + /* Set JQDIS bit according to ADC_ value */ + + if (ADC_InitStruct->DiscontinuousConvMode == ENABLE) + { + assert_param(IS_ADC_REGULAR_DISCONT_NUMBER(ADC_InitStruct->NbrOfDiscConversion)); + tmpreg |= (uint32_t)(ADC_CFGR1_DISCEN | ((ADC_InitStruct->NbrOfDiscConversion - 1) << 17)); + } + + if (ADC_InitStruct->InjectedDiscontinuousConvMode == ENABLE) + { + tmpreg |= (uint32_t)ADC_CFGR1_JDISCEN; + } + + if (ADC_InitStruct->AutoInjectedConvMode == ENABLE) + { + tmpreg |= (uint32_t)ADC_CFGR1_JAUTO; + tmpreg &= (uint32_t)~(ADC_CFGR1_DISCEN | ADC_CFGR1_JDISCEN); + } + + if (ADC_InitStruct->QueueInjectedContext == DISABLE) + { + tmpreg |= (uint32_t)ADC_CFGR1_JQDIS; + } + else + { + tmpreg &= (uint32_t)~ADC_CFGR1_JQDIS; + /* Only when the QueueInjectedContext is enabled, QueueMode can be enabled */ + if (ADC_InitStruct->QueueMode == ENABLE) + { + tmpreg |= (uint32_t)ADC_CFGR1_JQM; + } + } + + /* ADC group regular and injected auto delay conversion mode enable */ + if (ADC_InitStruct->AutoDelayedConvMode == ENABLE) + { + tmpreg |= (uint32_t)ADC_CFGR1_AUTDLY; + } + + /* ADC group regular continuous mode enable */ + if (ADC_InitStruct->ContinuousConvMode == ENABLE) + { + tmpreg |= (uint32_t)ADC_CFGR1_CONT; + } + + /*Set the ADC minimum sampling clock period for all channels */ + if (ADC_InitStruct->SamplingPlusTime == ADC_SAMPLETIMEPLUS_1_5CYCLES) + { + ADCx->SMPR1 &= (uint32_t)(~ADC_SMPR1_SMPLUS); + } + else + { + ADCx->SMPR1 &= (uint32_t)(~ADC_SMPR1_SMPLUS); + ADCx->SMPR1 |= (uint32_t)ADC_InitStruct->SamplingPlusTime; + } + + + if (ADC_InitStruct->ExternalTrigConvEdge == ADC_SOFTWARE_START) + { + tmpreg |= (uint32_t)(ADC_InitStruct->DataAlign | ADC_InitStruct->Resolution | ADC_InitStruct->Overrun | ADC_InitStruct->DMAMode); + } + else + { + tmpreg |= (uint32_t)(ADC_InitStruct->ExternalTrigConvEdge | ADC_InitStruct->ExternalTrigConv | ADC_InitStruct->DataAlign | ADC_InitStruct->Resolution | ADC_InitStruct->Overrun | ADC_InitStruct->DMAMode); + } + + + if (ADC_InitStruct->SamplingMode == ADC_SAMPLING_MODE_TRIGGER_CONTROLED) + { + /* Clear BULB enable bit */ + ADCx->CFGR2 &= (uint32_t)~ADC_CFGR2_BULB; + + /* Set Sampling time control trigger mode enable bit */ + ADCx->CFGR2 |= (uint32_t)ADC_CFGR2_SMPTRIG; + + if (ADC_InitStruct->ExternalTrigConvEdge == ADC_SOFTWARE_START) + { + tmpreg &= (uint32_t)~ADC_CFGR1_EXTEN; + } + else + { + /* If select hardware trigger when sampling time control trigger mode + * external trigger enable and polarity selection for regular channel must set rising edge */ + tmpreg &= (uint32_t)~ADC_CFGR1_EXTEN; + tmpreg |= (uint32_t)ADC_CFGR1_EXTEN_0; + } + } + + + if (ADC_InitStruct->SamplingMode == ADC_SAMPLING_MODE_BULB) + { + ADCx->CFGR2 &= (uint32_t)~ADC_CFGR2_SMPTRIG; + ADCx->CFGR2 |= (uint32_t)ADC_CFGR2_BULB; + } + + /* If the GainCompensation is not 0, Gain mode can be enabled + * Otherwise, disable Gain mode */ + if (ADC_InitStruct->GainCompensation != 0) + { + ADCx->CFGR2 |= (uint32_t)ADC_CFGR2_GCOMP; + ADCx->GCOMP |= (uint32_t)ADC_InitStruct->GainCompensation; + } + else + { + ADCx->CFGR2 &= (uint32_t)~ADC_CFGR2_GCOMP; + ADCx->GCOMP &= (uint32_t)~ADC_GCOMP_GCOMPCOEFF; + } + + + /* Configuration of Oversampler: */ + /* - Oversampling Ratio */ + /* - Right bit shift */ + /* - Triggered mode */ + /* - Oversampling mode (continued/resumed) */ + if (ADC_InitStruct->OversamplingMode == ENABLE) + { + + assert_param(IS_ADC_OVERSAMPLING_RATIO(ADC_InitStruct->Oversampling.Ratio)); + assert_param(IS_ADC_RIGHT_BIT_SHIFT(ADC_InitStruct->Oversampling.RightBitShift)); + assert_param(IS_ADC_TRIGGERED_OVERSAMPLING_MODE(ADC_InitStruct->Oversampling.TriggeredMode)); + assert_param(IS_ADC_REGOVERSAMPLING_MODE(ADC_InitStruct->Oversampling.OversamplingStopReset)); + + + /* Reset the Oversampling config */ + ADCx->CFGR2 &= (uint32_t)~(ADC_CFGR2_ROVSE | ADC_CFGR2_OVSR | ADC_CFGR2_OVSS | ADC_CFGR2_TROVS | ADC_CFGR2_ROVSM); + + /* Configuration of Oversampler: */ + /* - Oversampling Ratio */ + /* - Right bit shift */ + /* - Triggered mode */ + /* - Oversampling mode (continued/resumed) */ + ADCx->CFGR2 |= (uint32_t)(ADC_InitStruct->Oversampling.Ratio | ADC_InitStruct->Oversampling.RightBitShift | ADC_InitStruct->Oversampling.TriggeredMode | ADC_InitStruct->Oversampling.OversamplingStopReset | ADC_CFGR2_ROVSE); + + } + else + { + /* Reset the Oversampling config */ + ADCx->CFGR2 &= (uint32_t)~(ADC_CFGR2_ROVSE | ADC_CFGR2_TROVS | ADC_CFGR2_ROVSM); + } + + + /* Write to ADCx CFGR */ + ADCx->CFGR1 = tmpreg; + + /* Write Regular channel length to ADCx SQR1 and clear all channels config */ + if (ADC_InitStruct->NbrOfConversion == RESET) + { + ADCx->SQR1 = (uint32_t)RESET; + } + else + { + assert_param(IS_ADC_REGULAR_NUMBER(ADC_InitStruct->NbrOfConversion)); + ADCx->SQR1 = (uint32_t)(ADC_InitStruct->NbrOfConversion - 1); + } + +} + +/** + * @brief Fills each ADC_InitStruct member with its default value. + * @note This function is used to initialize the global features of the ADC ( + * Resolution, Data Alignment, continuous mode activation, External + * trigger source and edge, Sequence Scan Direction). + * @param ADC_InitStruct: pointer to an ADC_InitTypeDef structure which will + * be initialized. + * @retval None + */ +void ADC_StructInit(ADC_InitTypeDef *ADC_InitStruct) +{ + /* Reset ADC init structure parameters values */ + /* Initialize the ADC_Resolution member */ + ADC_InitStruct->Resolution = ADC_RESOLUTION_12B; + + /* Initialize the ADC_ContinuousConvMode member */ + ADC_InitStruct->ContinuousConvMode = DISABLE; + + /* Initialize the ADC_ExternalTrigConvEdge member */ + ADC_InitStruct->ExternalTrigConvEdge = ADC_SOFTWARE_START; + + /* Initialize the ADC_DataAlign member */ + ADC_InitStruct->DataAlign = ADC_DATAALIGN_RIGHT; + + /* Initialize the ADC_NbrOfConversion member */ + ADC_InitStruct->NbrOfConversion = 8; + +} + +/** + * @brief Enables or disables the specified ADC peripheral. + * @param ADCx: where x can be 1/2/3 to select the ADCx peripheral. + * @param NewState: new state of the ADCx peripheral. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Set the ADEN bit to Enable the ADC peripheral */ + ADCx->CR |= (uint32_t)ADC_CR_ADEN; + } + else + { + /* Set the ADDIS to Disable the ADC peripheral */ + ADCx->CR |= (uint32_t)ADC_CR_ADDIS; + } +} +/** + * @} + */ + +/** + * @brief Set parameter common to several ADC: Clock source and prescaler. + * This parameter can be a value of @ref ADC_ClockMode. + * @note On this FT32F4xx series, if ADC group injected is used, some + * clock ratio constraints between ADC clock and AHB clock + * must be respected. + * Refer to reference manual. + * @note On this FT32F4xx series, setting of this feature is conditioned to + * ADC state: + * All ADC instances of the ADC common group must be disabled. + * @param ADC_Common ADC common instance + * @param CommonClock This parameter can be one of the following values: + * @arg @ref ADC_CLOCK_SYNC_HCLK_DIV1 + * @arg @ref ADC_CLOCK_SYNC_HCLK_DIV2 + * @arg @ref ADC_CLOCK_SYNC_HCLK_DIV4 + * @arg @ref ADC_CLOCK_ASYNC_DIV1 + * @arg @ref ADC_CLOCK_ASYNC_DIV2 + * @arg @ref ADC_CLOCK_ASYNC_DIV4 + * @arg @ref ADC_CLOCK_ASYNC_DIV6 + * @arg @ref ADC_CLOCK_ASYNC_DIV8 + * @arg @ref ADC_CLOCK_ASYNC_DIV10 + * @arg @ref ADC_CLOCK_ASYNC_DIV12 + * @arg @ref ADC_CLOCK_ASYNC_DIV16 + * @arg @ref ADC_CLOCK_ASYNC_DIV32 + * @arg @ref ADC_CLOCK_ASYNC_DIV64 + * @arg @ref ADC_CLOCK_ASYNC_DIV128 + * @arg @ref ADC_CLOCK_ASYNC_DIV256 + * @retval None + */ +void ADC_ClockModeConfig(uint32_t CommonClock) +{ + assert_param(IS_ADC_CLOCKPRESCALER(CommonClock)); + + /* Clear Clock Mode previous config */ + ADC_Common->CCR &= (uint32_t)~ADC_CCR_CKMODE; + + /* Set ADC Common clock mode and prescaler factor */ + if ((CommonClock != ADC_CLOCK_SYNC_HCLK_DIV1) || (CommonClock != ADC_CLOCK_SYNC_HCLK_DIV2) || (CommonClock != ADC_CLOCK_SYNC_HCLK_DIV4)) + { + /* Set Clock Mode on Async mode */ + ADC_Common->CCR &= (uint32_t)~ADC_CCR_PRESC; + + /* Set prescaler factor to Async mode */ + ADC_Common->CCR |= (uint32_t)CommonClock; + } + else + { + /* Set Clock Mode on Sync and select the HCLK prescaler factor */ + ADC_Common->CCR |= (uint32_t)CommonClock; + } +} +/** + * @} + */ + +/** + * @brief Enable ADC multimode and configure multimode parameters + * @note Possibility to update parameters on the fly: + * This function initializes multimode parameters, following + * calls to this function can be used to reconfigure some parameters + * of structure "ADC_MultiModeTypeDef" on the fly, without resetting + * the ADCs. + * The setting of these parameters is conditioned to ADC state. + * For parameters constraints, see comments of structure + * "ADC_MultiModeTypeDef". + * @note To move back configuration from multimode to single mode, ADC must + * be reset (using function ADC_Init() ). + * @param hadc Master ADC handle + * @param Multimode Structure of ADC multimode configuration + * @retval None + */ +void ADC_MultiModeConfig(ADC_MultiModeTypeDef* MultiMode) +{ + /* Check the parameters */ + assert_param(IS_ADC_MULTIMODE(MultiMode->Mode)); + assert_param(IS_ADC_DMA_ACCESS_MULTIMODE(MultiMode->DMAAccessMode)); + assert_param(IS_ADC_MULTI_DMA_MODE(MultiMode->DMAMode)); + assert_param(IS_ADC_TWOSAMPLING_DELAY(MultiMode->TwoSamplingDelay)); + + /* Config ADCx multi mode */ + if (MultiMode->Mode != ADC_MODE_INDEPENDENT) + { + ADC_Common->CCR &= (uint32_t)(~(ADC_CCR_MDMA | ADC_CCR_DMACFG | ADC_CCR_DELAY | ADC_CCR_MULTI)); + ADC_Common->CCR |= (uint32_t)(MultiMode->Mode | MultiMode->DMAAccessMode | MultiMode->DMAMode | MultiMode->TwoSamplingDelay); + + } + else + { + ADC_Common->CCR &= (uint32_t)(~(ADC_CCR_MDMA | ADC_CCR_DMACFG | ADC_CCR_DELAY | ADC_CCR_MULTI)); + } +} +/** + * @} + */ + +/** + * @brief Start ADC sampling phase for sampling time trigger mode + * @note This function is relevant only when + * - @ref ADC_InitTypeDef->SamplingMode has been set + * using @ref ADC_SAMPLING_MODE_TRIGGER_CONTROLED + * - @ref ADC_SOFTWARE_TRIGCONV is used as trigger source + * @note On this FT32F4xx series, setting of this feature is conditioned to + * ADC state: + * ADC must be enabled without conversion on going on group regular, + * without conversion stop command on going on group regular, + * without ADC disable command on going. + * @rmtoll CFGR2 SWTRIG ADC_StartSamplingPhase + * @param ADCx: where x can be 1/2/3 to select the ADCx peripheral. + * @retval None + */ +void ADC_StartSamplingPhase(ADC_TypeDef* ADCx) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + + /* Start sampling */ + ADCx->CFGR2 |= (uint32_t)ADC_CFGR2_SWTRIG; + SET_BIT(ADCx->CFGR2, ADC_CFGR2_SWTRIG); + +} +/** + * @} + */ + +/** + * @brief Stop ADC sampling phase for sampling time trigger mode + * and start conversion + * @note This function is relevant only when + * - @ref ADC_InitTypeDef->SamplingMode has been set + * using @ref ADC_SAMPLING_MODE_TRIGGER_CONTROLED + * - @ref ADC_SOFTWARE_TRIGCONV is used as trigger source + * - @ref ADC_StartSampling has been called to start + * the sampling phase + * @note On this FT32F4xx series, setting of this feature is conditioned to + * ADC state: + * ADC must be enabled without conversion on going on group regular, + * without conversion stop command on going on group regular, + * without ADC disable command on going. + * @rmtoll CFGR2 SWTRIG ADC_StopSamplingPhase + * @param ADCx: where x can be 1/2/3 to select the ADCx peripheral. + * @retval None + */ +void ADC_StoptSamplingPhase(ADC_TypeDef* ADCx) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + + /* Start sampling */ + ADCx->CFGR2 &= (uint32_t)~ADC_CFGR2_SWTRIG; +} +/** + * @} + */ + +/** + * @brief Enables or disables the Wait conversion mode. + * @note When the CPU clock is not fast enough to manage the data rate, a + * Hardware delay can be introduced between ADC conversions to reduce + * this data rate. + * @note The Hardware delay is inserted after each conversions and until the + * previous data is read from the ADC data register + * @note This is a way to automatically adapt the speed of the ADC to the speed + * of the system which will read the data. + * @note Any hardware triggers wich occur while a conversion is on going or + * while the automatic Delay is applied are ignored + * @param ADCx: where x can be 1/2/3 to select the ADCx peripheral. + * @param NewState: new state of the ADCx Auto-Delay. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void ADC_AutoDelayModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the ADC Automatic Delayed conversion */ + ADCx->CFGR1 |= (uint32_t)ADC_CFGR1_AUTDLY; + } + else + { + /* Disable the ADC Automatic Delayed conversion */ + ADCx->CFGR1 &= (uint32_t)~ADC_CFGR1_AUTDLY; + } +} +/** + * @} + */ + +/** + * @brief Enable the Continuous mode for the selected ADCx channels. + * @param ADCx: where x can be 1/2/3 to select the ADCx peripheral. + * @param NewState: new state of the Continuous mode. + * This parameter can be: ENABLE or DISABLE. + * @note It is not possible to have both discontinuous mode and continuous mode + * enabled. In this case (If DISCEN and CONT are Set), the ADC behaves + * as if continuous mode was disabled + * @retval None + */ +void ADC_ContinuousModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the Continuous mode*/ + ADCx->CFGR1 |= (uint32_t)ADC_CFGR1_CONT; + } + else + { + /* Disable the Continuous mode */ + ADCx->CFGR1 &= (uint32_t)(~ADC_CFGR1_CONT); + } +} +/** + * @} + */ + +/** + * @brief Enable the automatic injected mode for the selected ADCx injected channels. + * @param ADCx: where x can be 1/2/3 to select the ADCx peripheral. + * @param NewState: new state of the automatic injected mode. + * This parameter can be: ENABLE or DISABLE. + * @note It is not possible to enable both ADC group injected + * auto-injected mode and sequencer discontinuous mode. + * @retval None + */ +void ADC_AutoInjectedModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the Continuous mode*/ + ADCx->CFGR1 |= (uint32_t)ADC_CFGR1_JAUTO; + } + else + { + /* Disable the Continuous mode */ + ADCx->CFGR1 &= (uint32_t)(~ADC_CFGR1_JAUTO); + } +} +/** + * @} + */ + +/** + * @brief Enable the discontinuous mode for the selected ADC regular channels. + * @param ADCx: where x can be 1/2/3 to select the ADCx peripheral. + * @param DiscontNum: This parameter can be one of the following values: + * ADC_REG_SEQ_DISCONT_DISABLE + * ADC_REG_SEQ_DISCNUM_1_CHANNEL + * ADC_REG_SEQ_DISCNUM_2_CHANNELS + * ADC_REG_SEQ_DISCNUM_3_CHANNELS + * ADC_REG_SEQ_DISCNUM_4_CHANNELS + * ADC_REG_SEQ_DISCNUM_5_CHANNELS + * ADC_REG_SEQ_DISCNUM_6_CHANNELS + * ADC_REG_SEQ_DISCNUM_7_CHANNELS + * ADC_REG_SEQ_DISCNUM_8_CHANNELS + * @note It is not possible to have both discontinuous mode and continuous mode + * enabled. In this case (If DISCEN and CONT are Set), the ADC behaves + * as if continuous mode was disabled + * @retval None + */ +void ADC_REG_DiscModeCmd(ADC_TypeDef* ADCx, uint32_t DiscontNum) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + + if (DiscontNum != ADC_REG_SEQ_DISCONT_DISABLE) + { + /* Enable the Discontinuous mode and Config the Discontinuous number of channels */ + ADCx->CFGR1 |= (uint32_t)DiscontNum; + } + else + { + /* Disable the Discontinuous mode and clear the Discontinuous number of channels */ + ADCx->CFGR1 &= (uint32_t)~(ADC_CFGR1_DISCNUM | ADC_CFGR1_DISCEN); + } +} +/** + * @} + */ + +/** + * @brief Enable the discontinuous mode for the selected ADC injected channels. + * @param ADCx: where x can be 1/2/3 to select the ADCx peripheral. + * @param NewState: new state of the discontinuous mode. + * This parameter can be: ENABLE or DISABLE. + * @note It is not possible to have both discontinuous mode and continuous mode + * enabled. In this case (If DISCEN and CONT are Set), the ADC behaves + * as if continuous mode was disabled + * @note ADC group injected each conversion only one channel. + * @retval None + */ +void ADC_INJ_DiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the Discontinuous mode */ + ADCx->CFGR1 |= (uint32_t)ADC_CFGR1_JDISCEN; + } + else + { + /* Disable the Discontinuous mode */ + ADCx->CFGR1 &= (uint32_t)(~ADC_CFGR1_JDISCEN); + } +} +/** + * @} + */ + +/** + * @brief Enable the Overrun mode for the selected ADC channels. + * @param ADCx: where x can be 1/2/3 to select the ADCx peripheral. + * @param NewState: new state of the Overrun mode. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void ADC_OverrunModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the Overrun mode */ + ADCx->CFGR1 |= (uint32_t)ADC_CFGR1_OVRMOD; + } + else + { + /* Disable the Overrun mode */ + ADCx->CFGR1 &= (uint32_t)(~ADC_CFGR1_OVRMOD); + } +} +/** + * @} + */ + +/** + * @brief Put ADC instance in deep power down state. + * @note In case of ADC calibration necessary: When ADC is in deep-power-down + * state, the internal analog calibration is lost. After exiting from + * deep power down, calibration must be relaunched or calibration factor + * (preliminarily saved) must be set back into calibration register. + * @note On this FT32F4xx series, setting of this feature is conditioned to + * ADC state: + * ADC must be ADC disabled. + * @param ADCx: where x can be 1/2/3 to select the ADCx peripheral. + * @param NewState: new state of the ADCx DeepPowerDown. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void ADC_DeepPWDModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + /* Note: Write register with some additional bits forced to state reset */ + /* instead of modifying only the selected bit for this function, */ + /* to not interfere with bits. */ + ADCx->CR &= (uint32_t)~ADC_CR_BITS_PROPERTY_RS; + + if (NewState != DISABLE) + { + /* Enable the ADC enter Deep Power Down Mode */ + ADCx->CR |= (uint32_t)ADC_CR_DEEPPWD; + } + else + { + /* Disable the ADC exti Deep Power Down Mode */ + ADCx->CR &= (uint32_t)~ADC_CR_DEEPPWD; + } +} +/** + * @} + */ + +/** + * @brief Enable ADC instance internal voltage regulator. + * @note On this FT32 series, after ADC internal voltage regulator enable, + * a delay for ADC internal voltage regulator stabilization + * is required before performing a ADC calibration or ADC enable. + * Refer to device datasheet, parameter tADCVREG_STUP. + * @note On this FT32F4xx series, setting of this feature is conditioned to + * ADC state: + * ADC must be ADC disabled. + * @param ADCx: where x can be 1/2/3 to select the ADCx peripheral. + * @param NewState: new state of the ADCx DeepPowerDown. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void ADC_InternalRegulatorCmd(ADC_TypeDef* ADCx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + /* Note: Write register with some additional bits forced to state reset */ + /* instead of modifying only the selected bit for this function, */ + /* to not interfere with bits with HW property "rs". */ + ADCx->CR &= (uint32_t)~ADC_CR_BITS_PROPERTY_RS; + + if (NewState != DISABLE) + { + /* Enable the ADC enable ADCx internal voltage regulator */ + ADCx->CR |= (uint32_t)ADC_CR_ADVREGEN; + } + else + { + /* Disable the ADC disable ADCx internal voltage regulator */ + ADCx->CR &= (uint32_t)~ADC_CR_ADVREGEN; + } +} +/** + * @} + */ + +/** + * @brief Enables or disables the temperature sensor channel. + * @param NewState: new state of the temperature sensor input channel. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void ADC_TempSensorCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the temperature sensor channel*/ + ADC_Common->CCR |= (uint32_t)ADC_CCR_VSENSESEL; + } + else + { + /* Disable the temperature sensor channel*/ + ADC_Common->CCR &= (uint32_t)(~ADC_CCR_VSENSESEL); + } +} +/** + * @} + */ + +/** + * @brief Enables or disables the Vrefint channel. + * @param NewState: new state of the Vref input channel. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void ADC_VrefintCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the Vrefint channel*/ + ADC_Common->CCR |= (uint32_t)ADC_CCR_VREFEN; + } + else + { + /* Disable the Vrefint channel*/ + ADC_Common->CCR &= (uint32_t)(~ADC_CCR_VREFEN); + } +} +/** + * @} + */ + +/** + * @brief Enables or disables the Vbat channel. + * @param NewState: new state of the Vbat input channel. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void ADC_VbatCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the Vbat channel */ + ADC_Common->CCR |= (uint32_t)ADC_CCR_VBATSEL; + } + else + { + /* Disable the Vbat channel */ + ADC_Common->CCR &= (uint32_t)(~ADC_CCR_VBATSEL); + } +} +/** + * @} + */ + +/** + * @brief Enables or disables the Analog Watchdog 2 monitor Vbat channel. + * @param NewState: new state of the monitor Vbat input channel. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void ADC_AWD2MonitorVbatCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Sel the AWD2 monitor the Vbat channel */ + ADC_Common->CCR &= (uint32_t)(~ADC_CCR_AWDSEL); + } + else + { + /* Sel the AWD3 monitor the Vbat channel */ + ADC_Common->CCR |= (uint32_t)ADC_CCR_AWDSEL; + } +} +/** + * @} + */ + +/** + * @brief Enables or disables the Analog Watchdog 3 monitor Vbat channel. + * @param NewState: new state of the monitor Vbat input channel. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void ADC_AWD3MonitorVbatCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Sel the AWD3 monitor the Vbat channel */ + ADC_Common->CCR |= (uint32_t)ADC_CCR_AWDSEL; + } + else + { + /* Sel the AWD2 monitor the Vbat channel */ + ADC_Common->CCR &= (uint32_t)(~ADC_CCR_AWDSEL); + } +} +/** + * @} + */ + +/** + * @brief Enables or disables the Battery charging when voltage is lower than threshold. + * @param NewState: This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void ADC_BatteryAutoChargingCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the Vbat channel automatic charging for battery */ + ADC_Common->CCR |= (uint32_t)ADC_CCR_VBEAUTO; + } + else + { + /* Disable the Vbat channel automatic charging for battery */ + ADC_Common->CCR &= (uint32_t)(~ADC_CCR_VBEAUTO); + } +} +/** + * @} + */ + +/** + * @} + */ +/** + * @brief Configures for the selected ADC and its sampling time. + * @param ADCx: where x can be 1/2/3 to select the ADC peripheral. + * @param ADC_Channel: the ADC channel to configure. + * This parameter can be any combination of the following values: + * @arg ADC_Channel_0: ADC Channel0 selected + * @arg ADC_Channel_1: ADC Channel1 selected + * @arg ADC_Channel_2: ADC Channel2 selected + * @arg ADC_Channel_3: ADC Channel3 selected + * @arg ADC_Channel_4: ADC Channel4 selected + * @arg ADC_Channel_5: ADC Channel5 selected + * @arg ADC_Channel_6: ADC Channel6 selected + * @arg ADC_Channel_7: ADC Channel7 selected + * @arg ADC_Channel_8: ADC Channel8 selected + * @arg ADC_Channel_9: ADC Channel9 selected + * @arg ADC_Channel_10: ADC Channel10 selected + * @arg ADC_Channel_11: ADC Channel11 selected + * @arg ADC_Channel_12: ADC Channel12 selected + * @arg ADC_Channel_13: ADC Channel13 selected + * @arg ADC_Channel_14: ADC Channel14 selected + * @arg ADC_Channel_15: ADC Channel15 selected + * @arg ADC_Channel_16: ADC Channel16 selected + * @arg ADC_Channel_17: ADC Channel17 selected + * @arg ADC_Channel_18: ADC Channel18 selected + * @arg ADC_Channel_19: ADC Channel19 selected + * @arg ADC_Channel_20: ADC Channel20 selected + * @arg ADC_Channel_21: ADC Channel21 selected + * @param ADC_SampleTime: The sample time value to be set for the selected channel. + * This parameter can be one of the following values: + * @arg ADC_SAMPLETIME_1_5CYCLES: Sample time equal to 1.5 cycles + * @arg ADC_SAMPLETIME_6_5CYCLES: Sample time equal to 6.5 cycles + * @arg ADC_SAMPLETIME_12_5CYCLES: Sample time equal to 12.5 cycles + * @arg ADC_SAMPLETIME_24_5CYCLES: Sample time equal to 24.5 cycles + * @arg ADC_SAMPLETIME_47_5CYCLES: Sample time equal to 47.5 cycles + * @arg ADC_SAMPLETIME_92_5CYCLES: Sample time equal to 92.5 cycles + * @arg ADC_SAMPLETIME_247_5CYCLES: Sample time equal to 247.5 cycles + * @arg ADC_SAMPLETIME_640_5CYCLES: Sample time equal to 640.5 cycles + * @retval None + */ +void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, ADC_ChannelConfTypeDef* RegularConfig) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_CHANNEL(RegularConfig->Channel)); + assert_param(IS_ADC_REGULAR_RANK(RegularConfig->Rank)); + assert_param(IS_ADC_SAMPLE_TIME(RegularConfig->SamplingTime)); + assert_param(IS_ADC_SINGLE_DIFFERENTIAL(RegularConfig->SingleDiff)); + assert_param(IS_ADC_OFFSET_NUMBER(RegularConfig->OffsetNumber)); + assert_param(IS_ADC_OFFSET_SIGN(RegularConfig->OffsetSign)); + assert_param(IS_FUNCTIONAL_STATE(RegularConfig->OffsetSaturation)); + + + /* Clear th Channel Selection bits, and Configure the ADC Channel */ + if (RegularConfig->Rank <= ADC_REGULAR_RANK_4) + { + ADCx->SQR1 &= (uint32_t)(~(0x1f << ((RegularConfig->Rank + 1) * 6))); + ADCx->SQR1 |= RegularConfig->Channel << ((RegularConfig->Rank + 1) * 6); + } + else if (RegularConfig->Rank <= ADC_REGULAR_RANK_9) + { + ADCx->SQR2 &= (uint32_t)(~(0x1f << ((RegularConfig->Rank - 4) * 6))); + ADCx->SQR2 |= RegularConfig->Channel << ((RegularConfig->Rank - 4) * 6); + } + else if (RegularConfig->Rank <= ADC_REGULAR_RANK_14) + { + ADCx->SQR3 &= (uint32_t)(~(0x1f << ((RegularConfig->Rank - 9) * 6))); + ADCx->SQR3 |= RegularConfig->Channel << ((RegularConfig->Rank - 9) * 6); + } + else if (RegularConfig->Rank <= ADC_REGULAR_RANK_16) + { + ADCx->SQR4 &= (uint32_t)(~(0x1f << ((RegularConfig->Rank - 14) * 6))); + ADCx->SQR4 |= RegularConfig->Channel << ((RegularConfig->Rank - 14) * 6); + } + + + /* Clear the Sampling time Selection bits, and Set the ADC Sampling Time register */ + /* Set sampling time of the selected ADC channel */ + /* Note: ADC channel number masked with value "0x1F" to ensure shift value within 32 bits range */ + if (RegularConfig->Channel <= ADC_CHANNEL_9) + { + ADCx->SMPR1 &= (uint32_t)(~(0x7 << (RegularConfig->Channel * 3))); + ADCx->SMPR1 |= RegularConfig->SamplingTime << (RegularConfig->Channel * 3); + } + else if (RegularConfig->Channel <= ADC_CHANNEL_18) + { + ADCx->SMPR2 &= (uint32_t)(~(0x7 << (RegularConfig->Channel - 10))); + ADCx->SMPR2 |= RegularConfig->SamplingTime << ((RegularConfig->Channel - 10) * 3); + } + else if (RegularConfig->Channel <= ADC_CHANNEL_21) + { + ADCx->SMPR3 &= (uint32_t)(~(0x7 << (RegularConfig->Channel - 19))); + ADCx->SMPR3 |= RegularConfig->SamplingTime << ((RegularConfig->Channel - 19) * 3); + } + + + /* Parameters update conditioned to ADC state: */ + /* Parameters that can be updated only when ADC is disabled: */ + /* - Single or differential mode */ + if (RegularConfig->SingleDiff == ADC_DIFFERENTIAL_ENDED) + { + /* Set mode differential input of the selected ADC channel */ + ADCx->DIFSEL |= (uint32_t)(ADC_DIFFERENTIAL_ENDED << RegularConfig->Channel); + } + else + { + /* Set mode single-ended input of the selected ADC channel */ + ADCx->DIFSEL &= (uint32_t)~(ADC_DIFFERENTIAL_ENDED << RegularConfig->Channel); + } + + + /* Scan each offset register to check if the selected channel is targeted. */ + /* If this is the case, the corresponding offset number is enable or disabled. */ + /* Parameters update conditioned to ADC state: */ + /* Parameters that can be updated when ADC is disabled or enabled without */ + /* conversion on going on regular group or injected group: */ + /* - Channel offset */ + /* Shift the offset with respect to the selected ADC resolution. */ + /* Offset has to be left-aligned on bit 11, the LSB (right bits) are set to 0 */ + /* Set ADC selected offset sign & saturation by @param OffsetSign and OffsetSaturation */ + if (RegularConfig->OffsetNumber != ADC_OFFSET_NONE) + { + /* Config register OFR1 */ + if (RegularConfig->OffsetNumber == ADC_OFFSET_1) + { + ADCx->OFR1 = ADC_OFR1_OFFSET_EN | RegularConfig->OffsetSign | (RegularConfig->Channel << 26) | + (RegularConfig->OffsetSaturation << 25) | RegularConfig->Offset ; + } + + /* Config register OFR2 */ + if (RegularConfig->OffsetNumber == ADC_OFFSET_2) + { + ADCx->OFR2 = ADC_OFR2_OFFSET_EN | RegularConfig->OffsetSign | (RegularConfig->Channel << 26) | + (RegularConfig->OffsetSaturation << 25) | RegularConfig->Offset ; + } + + /* Config register OFR3 */ + if (RegularConfig->OffsetNumber == ADC_OFFSET_3) + { + ADCx->OFR3 = ADC_OFR3_OFFSET_EN | RegularConfig->OffsetSign | (RegularConfig->Channel << 26) | + (RegularConfig->OffsetSaturation << 25) | RegularConfig->Offset ; + } + + /* Config register OFR4 */ + if (RegularConfig->OffsetNumber == ADC_OFFSET_4) + { + ADCx->OFR4 = ADC_OFR4_OFFSET_EN | RegularConfig->OffsetSign | (RegularConfig->Channel << 26) | + (RegularConfig->OffsetSaturation << 25) | RegularConfig->Offset ; + } + } + else + { + /* Reset register OFR1 */ + if (RegularConfig->Channel == ((ADCx->OFR1 >> 26) & 0x1f)) + { + ADCx->OFR1 = (uint32_t)RESET; + } + + /* Reset register OFR2 */ + if (RegularConfig->Channel == ((ADCx->OFR2 >> 26) & 0x1f)) + { + ADCx->OFR2 = (uint32_t)RESET; + } + + /* Reset register OFR3 */ + if (RegularConfig->Channel == ((ADCx->OFR3 >> 26) & 0x1f)) + { + ADCx->OFR3 = (uint32_t)RESET; + } + + /* Reset register OFR4 */ + if (RegularConfig->Channel == ((ADCx->OFR4 >> 26) & 0x1f)) + { + ADCx->OFR4 = (uint32_t)RESET; + } + } +} + + + +/** + * @brief Configures for the selected ADC and its sampling time. + * @param ADCx: where x can be 1 to select the ADC peripheral. + * @param ADC_Channel: the ADC channel to configure. + * This parameter can be any combination of the following values: + * @arg ADC_Channel_0: ADC Channel0 selected + * @arg ADC_Channel_1: ADC Channel1 selected + * @arg ADC_Channel_2: ADC Channel2 selected + * @arg ADC_Channel_3: ADC Channel3 selected + * @arg ADC_Channel_4: ADC Channel4 selected + * @arg ADC_Channel_5: ADC Channel5 selected + * @arg ADC_Channel_6: ADC Channel6 selected + * @arg ADC_Channel_7: ADC Channel7 selected + * @arg ADC_Channel_8: ADC Channel8 selected + * @arg ADC_Channel_9: ADC Channel9 selected + * @arg ADC_Channel_10: ADC Channel10 selected + * @arg ADC_Channel_11: ADC Channel11 selected + * @arg ADC_Channel_12: ADC Channel12 selected + * @arg ADC_Channel_13: ADC Channel13 selected + * @arg ADC_Channel_14: ADC Channel14 selected + * @arg ADC_Channel_15: ADC Channel15 selected + * @arg ADC_Channel_16: ADC Channel16 selected + * @arg ADC_Channel_17: ADC Channel17 selected + * @arg ADC_Channel_18: ADC Channel18 selected + * @arg ADC_Channel_19: ADC Channel19 selected + * @arg ADC_Channel_20: ADC Channel20 selected + * @arg ADC_Channel_21: ADC Channel21 selected + * This parameter can be one of the following values: + * @arg ADC_SampleTime_1_5Cycles: Sample time equal to 1.5 cycles + * @arg ADC_SampleTime_7_5Cycles: Sample time equal to 7.5 cycles + * @arg ADC_SampleTime_13_5Cycles: Sample time equal to 13.5 cycles + * @arg ADC_SampleTime_28_5Cycles: Sample time equal to 28.5 cycles + * @arg ADC_SampleTime_41_5Cycles: Sample time equal to 41.5 cycles + * @arg ADC_SampleTime_55_5Cycles: Sample time equal to 55.5 cycles + * @arg ADC_SampleTime_71_5Cycles: Sample time equal to 71.5 cycles + * @arg ADC_SampleTime_239_5Cycles: Sample time equal to 239.5 cycles + * @retval None + */ +void ADC_InjectedChannelConfig(ADC_TypeDef* ADCx, ADC_InjectedConfTypeDef* InjectedConfig) +{ + static uint32_t tmp_jsqr = 0x0, channel_count = 0x0; + + + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_CHANNEL(InjectedConfig->InjectedChannel)); + assert_param(IS_ADC_REGULAR_RANK(InjectedConfig->InjectedRank)); + assert_param(IS_ADC_SAMPLE_TIME(InjectedConfig->InjectedSamplingTime)); + assert_param(IS_ADC_SINGLE_DIFFERENTIAL(InjectedConfig->InjectedSingleDiff)); + assert_param(IS_ADC_OFFSET_NUMBER(InjectedConfig->InjectedOffsetNumber)); + assert_param(IS_ADC_OFFSET_SIGN(InjectedConfig->InjectedOffsetSign)); + assert_param(IS_FUNCTIONAL_STATE(InjectedConfig->InjectedOffsetSaturation)); + assert_param(IS_FUNCTIONAL_STATE(InjectedConfig->InjectedOversamplingMode)); + assert_param(IS_ADC_INJECTED_NUMBER(InjectedConfig->InjectedNbrOfConversion)); + assert_param(IS_ADC_EXTTRIG_INJEC_EDGE(InjectedConfig->ExternalTrigInjecConvEdge)); + assert_param(IS_ADC_INJECTED_EXTTRIG_SOURCE(ADCx, InjectedConfig->ExternalTrigInjecConv)); + + + if (InjectedConfig->InjectedRank == ADC_INJECTED_RANK_1) + { + if (channel_count != (uint32_t)RESET) + { + channel_count = (uint32_t)RESET; + } + + tmp_jsqr |= (uint32_t)(InjectedConfig->InjectedChannel << 9); + } + else if (InjectedConfig->InjectedRank == ADC_INJECTED_RANK_2) + { + tmp_jsqr |= (uint32_t)(InjectedConfig->InjectedChannel << 15); + } + else if (InjectedConfig->InjectedRank == ADC_INJECTED_RANK_3) + { + tmp_jsqr |= (uint32_t)(InjectedConfig->InjectedChannel << 21); + } + else if (InjectedConfig->InjectedRank == ADC_INJECTED_RANK_4) + { + tmp_jsqr |= (uint32_t)(InjectedConfig->InjectedChannel << 27); + } + + channel_count ++; + + if (channel_count == InjectedConfig->InjectedNbrOfConversion) + { + ADCx->JSQR = tmp_jsqr + (uint32_t)(InjectedConfig->InjectedNbrOfConversion - 1) + (uint32_t)InjectedConfig->ExternalTrigInjecConv + (uint32_t)InjectedConfig->ExternalTrigInjecConvEdge; + + /* ADC group injected config reset when all injected channels set */ + tmp_jsqr = RESET; + + channel_count = RESET; + + /* Configuration of Oversampler: */ + /* - Oversampling Ratio */ + /* - Right bit shift */ + /* - Triggered mode */ + /* - Oversampling mode (continued/resumed) */ + if (InjectedConfig->InjectedOversamplingMode == ENABLE) + { + + assert_param(IS_ADC_OVERSAMPLING_RATIO(InjectedConfig->InjectedOversampling.Ratio)); + assert_param(IS_ADC_RIGHT_BIT_SHIFT(InjectedConfig->InjectedOversampling.RightBitShift)); + + /* Reset the Oversampling config */ + ADCx->CFGR2 &= (uint32_t)~(ADC_CFGR2_JOVSE | ADC_CFGR2_OVSR | ADC_CFGR2_OVSS); + + /* Configuration of Oversampler: */ + /* - Oversampling Ratio */ + /* - Right bit shift */ + ADCx->CFGR2 |= (uint32_t)(InjectedConfig->InjectedOversampling.Ratio | InjectedConfig->InjectedOversampling.RightBitShift | ADC_CFGR2_JOVSE); + + } + else + { + /* Reset the Oversampling config */ + ADCx->CFGR2 &= (uint32_t)~ADC_CFGR2_JOVSE; + } + } + + + /* Clear the Sampling time Selection bits, and Set the ADC Sampling Time register */ + /* Set sampling time of the selected ADC channel */ + /* Note: ADC channel number masked with value "0x1F" to ensure shift value within 32 bits range */ + if (InjectedConfig->InjectedChannel <= ADC_CHANNEL_9) + { + ADCx->SMPR1 &= (uint32_t)(~(0x7 << (InjectedConfig->InjectedChannel * 3))); + ADCx->SMPR1 |= (uint32_t)(InjectedConfig->InjectedSamplingTime << (InjectedConfig->InjectedChannel * 3)); + } + else if (InjectedConfig->InjectedChannel <= ADC_CHANNEL_18) + { + ADCx->SMPR2 &= (uint32_t)(~(0x7 << (InjectedConfig->InjectedChannel - 10))); + ADCx->SMPR2 |= (uint32_t)(InjectedConfig->InjectedSamplingTime << ((InjectedConfig->InjectedChannel - 10) * 3)); + } + else if (InjectedConfig->InjectedChannel <= ADC_CHANNEL_21) + { + ADCx->SMPR3 &= (uint32_t)(~(0x7 << (InjectedConfig->InjectedChannel - 19))); + ADCx->SMPR3 |= (uint32_t)(InjectedConfig->InjectedSamplingTime << ((InjectedConfig->InjectedChannel - 19) * 3)); + } + + /* Parameters update conditioned to ADC state: */ + /* Parameters that can be updated only when ADC is disabled: */ + /* - Single or differential mode */ + if (InjectedConfig->InjectedSingleDiff == ADC_DIFFERENTIAL_ENDED) + { + /* Set mode differential input of the selected ADC channel */ + ADCx->DIFSEL |= (uint32_t)(ADC_DIFFERENTIAL_ENDED << InjectedConfig->InjectedChannel); + } + else + { + /* Set mode single-ended input of the selected ADC channel */ + ADCx->DIFSEL &= (uint32_t)~(ADC_DIFFERENTIAL_ENDED << InjectedConfig->InjectedChannel); + } + + + /* Scan each offset register to check if the selected channel is targeted. */ + /* If this is the case, the corresponding offset number is enable or disabled. */ + /* Parameters update conditioned to ADC state: */ + /* Parameters that can be updated when ADC is disabled or enabled without */ + /* conversion on going on regular group or injected group: */ + /* - Channel offset */ + /* Shift the offset with respect to the selected ADC resolution. */ + /* Offset has to be left-aligned on bit 11, the LSB (right bits) are set to 0 */ + /* Set ADC selected offset sign & saturation by @param OffsetSign and OffsetSaturation */ + if (InjectedConfig->InjectedOffsetNumber != ADC_OFFSET_NONE) + { + /* Config register OFRx */ + if (InjectedConfig->InjectedOffsetNumber == ADC_OFFSET_1) + { + ADCx->OFR1 = ADC_OFR1_OFFSET_EN | (uint32_t)InjectedConfig->InjectedOffsetSign | (uint32_t)(InjectedConfig->InjectedChannel << 26) | + (uint32_t)(InjectedConfig->InjectedOffsetSaturation << 25) | (uint32_t)InjectedConfig->InjectedOffset ; + } + + /* Config register OFRx */ + if (InjectedConfig->InjectedOffsetNumber == ADC_OFFSET_2) + { + ADCx->OFR2 = ADC_OFR2_OFFSET_EN | (uint32_t)InjectedConfig->InjectedOffsetSign | (uint32_t)(InjectedConfig->InjectedChannel << 26) | + (uint32_t)(InjectedConfig->InjectedOffsetSaturation << 25) | (uint32_t)InjectedConfig->InjectedOffset ; + } + + /* Config register OFRx */ + if (InjectedConfig->InjectedOffsetNumber == ADC_OFFSET_3) + { + ADCx->OFR3 = ADC_OFR3_OFFSET_EN | (uint32_t)InjectedConfig->InjectedOffsetSign | (uint32_t)(InjectedConfig->InjectedChannel << 26) | + (uint32_t)(InjectedConfig->InjectedOffsetSaturation << 25) | (uint32_t)InjectedConfig->InjectedOffset ; + } + + /* Config register OFRx */ + if (InjectedConfig->InjectedOffsetNumber == ADC_OFFSET_4) + { + ADCx->OFR4 = ADC_OFR4_OFFSET_EN | (uint32_t)InjectedConfig->InjectedOffsetSign | (uint32_t)(InjectedConfig->InjectedChannel << 26) | + (uint32_t)(InjectedConfig->InjectedOffsetSaturation << 25) | (uint32_t)InjectedConfig->InjectedOffset ; + } + } + else + { + /* Reset register OFR1 */ + if (InjectedConfig->InjectedChannel == ((ADCx->OFR1 >> 26) & 0x1f)) + { + ADCx->OFR1 = (uint32_t)RESET; + } + + /* Reset register OFR2 */ + if (InjectedConfig->InjectedChannel == ((ADCx->OFR2 >> 26) & 0x1f)) + { + ADCx->OFR2 = (uint32_t)RESET; + } + + /* Reset register OFR3 */ + if (InjectedConfig->InjectedChannel == ((ADCx->OFR3 >> 26) & 0x1f)) + { + ADCx->OFR3 = (uint32_t)RESET; + } + + /* Reset register OFR4 */ + if (InjectedConfig->InjectedChannel == ((ADCx->OFR4 >> 26) & 0x1f)) + { + ADCx->OFR4 = (uint32_t)RESET; + } + } +} + + +/** + * @brief Configure the analog watchdog. + * @note Possibility to update parameters on the fly: + * This function initializes the selected analog watchdog, successive + * calls to this function can be used to reconfigure some parameters + * of structure "ADC_AnalogWDGConfTypeDef" on the fly, without resetting + * the ADC. + * The setting of these parameters is conditioned to ADC state. + * For parameters constraints, see comments of structure + * "ADC_AnalogWDGConfTypeDef". + * @note On this FT32 series, analog watchdog thresholds can be modified + * while ADC conversion is on going. + * In this case, some constraints must be taken into account: + * the programmed threshold values are effective from the next + * ADC EOC (end of unitary conversion). + * Considering that registers write delay may happen due to + * bus activity, this might cause an uncertainty on the + * effective timing of the new programmed threshold values. + * @param AnalogWDGConfig Structure of ADC analog watchdog 1 configuration + * AnalogWDG 1 Mode can be any combination of the following values: + * ADC_ANALOGWATCHDOG_SINGLE_REG + * ADC_ANALOGWATCHDOG_SINGLE_INJEC + * ADC_ANALOGWATCHDOG_SINGLE_REGINJEC + * ADC_ANALOGWATCHDOG_ALL_REG + * ADC_ANALOGWATCHDOG_ALL_INJEC + * ADC_ANALOGWATCHDOG_ALL_REGINJEC + * @param ADC_AnalogWatchdog23_Channel: the ADC channel to configure for the analog watchdog. + * This parameter can be one of the following values: + * @arg ADC_AnalogWatchdog_Channel_0: ADC Channel0 selected + * @arg ADC_AnalogWatchdog_Channel_1: ADC Channel1 selected + * @arg ADC_AnalogWatchdog_Channel_2: ADC Channel2 selected + * @arg ADC_AnalogWatchdog_Channel_3: ADC Channel3 selected + * @arg ADC_AnalogWatchdog_Channel_4: ADC Channel4 selected + * @arg ADC_AnalogWatchdog_Channel_5: ADC Channel5 selected + * @arg ADC_AnalogWatchdog_Channel_6: ADC Channel6 selected + * @arg ADC_AnalogWatchdog_Channel_7: ADC Channel7 selected + * @arg ADC_AnalogWatchdog_Channel_8: ADC Channel8 selected + * @arg ADC_AnalogWatchdog_Channel_9: ADC Channel9 selected + * @arg ADC_AnalogWatchdog_Channel_10: ADC Channel10 selected + * @arg ADC_AnalogWatchdog_Channel_11: ADC Channel11 selected + * @arg ADC_AnalogWatchdog_Channel_12: ADC Channel12 selected + * @arg ADC_AnalogWatchdog_Channel_13: ADC Channel13 selected + * @arg ADC_AnalogWatchdog_Channel_14: ADC Channel14 selected + * @arg ADC_AnalogWatchdog_Channel_15: ADC Channel15 selected + * @arg ADC_AnalogWatchdog_Channel_16: ADC Channel16 selected + * @arg ADC_AnalogWatchdog_Channel_17: ADC Channel17 selected + * @arg ADC_AnalogWatchdog_Channel_18: ADC Channel18 selected + * @note The channel selected on the AWDCH must be also set into the AWDxCR + * register + * @retval None + */ + +void ADC_AnalogWDGConfig(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct, ADC_AnalogWDGConfTypeDef* AnalogWDGConfig) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_ANALOG_WATCHDOG_1_MODE(AnalogWDGConfig->WatchdogMode)); + assert_param(IS_FUNCTIONAL_STATE(AnalogWDGConfig->ITMode)); + assert_param(IS_ADC_ANALOG_WATCHDOG_FILTERING_MODE(AnalogWDGConfig->FilteringConfig)); + + if ((AnalogWDGConfig->WatchdogMode == ADC_ANALOGWATCHDOG_SINGLE_REG) || + (AnalogWDGConfig->WatchdogMode == ADC_ANALOGWATCHDOG_SINGLE_INJEC) || + (AnalogWDGConfig->WatchdogMode == ADC_ANALOGWATCHDOG_SINGLE_REGINJEC)) + { + assert_param(IS_ADC_CHANNEL(AnalogWDGConfig->Channel)); + } + + /* Set AnologWatchdog */ + if (((ADCx->CR & ADC_CR_ADSTART) != ADC_CR_ADSTART) || ((ADCx->CR & ADC_CR_JADSTART) != ADC_CR_JADSTART)) + { + /* Analog watchdog configuration */ + if (AnalogWDGConfig->WatchdogNumber == ADC_ANALOGWATCHDOG_1) + { + /* Configuration of analog watchdog: */ + /* - Set the analog watchdog enable mode: one or overall group of */ + /* channels, on groups regular and-or injected. */ + if ((AnalogWDGConfig->WatchdogMode == ADC_ANALOGWATCHDOG_SINGLE_REG) || (AnalogWDGConfig->WatchdogMode == ADC_ANALOGWATCHDOG_SINGLE_INJEC) || (AnalogWDGConfig->WatchdogMode == ADC_ANALOGWATCHDOG_SINGLE_REGINJEC)) + { + ADCx->CFGR1 &= (uint32_t)~(ADC_CFGR1_AWD1EN | ADC_CFGR1_JAWD1EN | ADC_CFGR1_AWD1CH); + ADCx->CFGR1 |= (uint32_t)(AnalogWDGConfig->WatchdogMode | (AnalogWDGConfig->Channel << 26)); + } + else if ((AnalogWDGConfig->WatchdogMode == ADC_ANALOGWATCHDOG_ALL_REG) || (AnalogWDGConfig->WatchdogMode == ADC_ANALOGWATCHDOG_ALL_INJEC) || (AnalogWDGConfig->WatchdogMode == ADC_ANALOGWATCHDOG_ALL_REGINJEC)) + { + ADCx->CFGR1 &= (uint32_t)~(ADC_CFGR1_AWD1EN | ADC_CFGR1_JAWD1EN | ADC_CFGR1_AWD1CH | ADC_CFGR1_AWD1SGL); + ADCx->CFGR1 |= (uint32_t)AnalogWDGConfig->WatchdogMode; + } + else + { + /* Disable Analog watchdog 1 configuration */ + ADCx->CFGR1 &= (uint32_t)~(ADC_CFGR1_AWD1EN | ADC_CFGR1_JAWD1EN | ADC_CFGR1_AWD1CH | ADC_CFGR1_AWD1SGL); + } + + /* Set the filtering configuration */ + ADCx->TR1 &= (uint32_t)~ADC_TR1_AWDFILT; + ADCx->TR1 |= (uint32_t)AnalogWDGConfig->FilteringConfig; + + /* Clear flag ADC analog watchdog */ + /* Note: Flag cleared Clear the ADC Analog watchdog flag to be ready */ + /* to use for ADC_IRQHandler() */ + /* (in case left enabled by previous ADC operations). */ + ADCx->ISR |= (uint32_t)ADC_ISR_AWD1; + + /* Configure ADC analog watchdog interrupt */ + if (AnalogWDGConfig->ITMode == ENABLE) + { + ADC_ITConfig(ADCx, ADC_IT_AWD1, ENABLE); + } + else + { + ADC_ITConfig(ADCx, ADC_IT_AWD1, DISABLE); + } + } + else + { + if (AnalogWDGConfig->WatchdogNumber == ADC_ANALOGWATCHDOG_2) + { + if (AnalogWDGConfig->Channel == (uint32_t)RESET) + { + ADCx->AWD2CR = (uint32_t)AnalogWDGConfig->Channel; + } + else + { + ADCx->AWD2CR = (uint32_t)RESET; + } + + /* Clear flag ADC analog watchdog */ + /* Note: Flag cleared Clear the ADC Analog watchdog flag to be ready */ + /* to use for ADC_IRQHandler() */ + /* (in case left enabled by previous ADC operations). */ + ADCx->ISR |= ADC_ISR_AWD2; + + /* Configure ADC analog watchdog interrupt */ + if (AnalogWDGConfig->ITMode == ENABLE) + { + ADC_ITConfig(ADCx, ADC_IT_AWD2, ENABLE); + } + else + { + ADC_ITConfig(ADCx, ADC_IT_AWD2, DISABLE); + } + } + else if (AnalogWDGConfig->WatchdogNumber == ADC_ANALOGWATCHDOG_3) + { + if (AnalogWDGConfig->Channel == (uint32_t)RESET) + { + ADCx->AWD3CR = (uint32_t)AnalogWDGConfig->Channel; + } + else + { + ADCx->AWD3CR = (uint32_t)RESET; + } + + /* Clear flag ADC analog watchdog */ + /* Note: Flag cleared Clear the ADC Analog watchdog flag to be ready */ + /* to use for ADC_IRQHandler() */ + /* (in case left enabled by previous ADC operations). */ + ADCx->ISR |= ADC_ISR_AWD3; + + /* Configure ADC analog watchdog interrupt */ + if (AnalogWDGConfig->ITMode == ENABLE) + { + ADC_ITConfig(ADCx, ADC_IT_AWD3, ENABLE); + } + else + { + ADC_ITConfig(ADCx, ADC_IT_AWD3, DISABLE); + } + } + } + } + + + /* Analog watchdog thresholds configuration */ + if (AnalogWDGConfig->WatchdogNumber == ADC_ANALOGWATCHDOG_1) + { + /* These value configure the ADC threshold value depending of ADC resolution */ + if (ADC_InitStruct->Resolution == ADC_RESOLUTION_6B) + { + ADCx->TR1 &= (uint32_t)~(ADC_TR1_LT1 | ADC_TR1_HT1); + ADCx->TR1 |= (uint32_t)(((AnalogWDGConfig->HighThreshold & 0xfc0) << 16) | (AnalogWDGConfig->LowThreshold & 0xfc0)); + } + else if (ADC_InitStruct->Resolution == ADC_RESOLUTION_8B) + { + ADCx->TR1 &= (uint32_t)~(ADC_TR1_LT1 | ADC_TR1_HT1); + ADCx->TR1 |= (uint32_t)(((AnalogWDGConfig->HighThreshold & 0xff0) << 16) | (AnalogWDGConfig->LowThreshold & 0xff0)); + } + else if (ADC_InitStruct->Resolution == ADC_RESOLUTION_10B) + { + ADCx->TR1 &= (uint32_t)~(ADC_TR1_LT1 | ADC_TR1_HT1); + ADCx->TR1 |= (uint32_t)(((AnalogWDGConfig->HighThreshold & 0xffc) << 16) | (AnalogWDGConfig->LowThreshold & 0xffc)); + } + else + { + ADCx->TR1 &= (uint32_t)~(ADC_TR1_LT1 | ADC_TR1_HT1); + ADCx->TR1 |= (uint32_t)(((AnalogWDGConfig->HighThreshold & 0xfff) << 16) | (AnalogWDGConfig->LowThreshold & 0xfff)); + } + } + + if (AnalogWDGConfig->WatchdogNumber == ADC_ANALOGWATCHDOG_2) + { + if (ADC_InitStruct->Resolution == ADC_RESOLUTION_6B) + { + ADCx->TR2 &= (uint32_t)~(ADC_TR2_LT2 | ADC_TR2_HT2); + ADCx->TR2 |= (uint32_t)(((AnalogWDGConfig->HighThreshold & 0xfc) << 16) | (AnalogWDGConfig->LowThreshold & 0xfc)); + } + else if (ADC_InitStruct->Resolution == ADC_RESOLUTION_8B) + { + ADCx->TR2 &= (uint32_t)~(ADC_TR2_LT2 | ADC_TR2_HT2); + ADCx->TR2 |= (uint32_t)(((AnalogWDGConfig->HighThreshold & 0xff) << 16) | (AnalogWDGConfig->LowThreshold & 0xff)); + } + else if (ADC_InitStruct->Resolution == ADC_RESOLUTION_10B) + { + ADCx->TR2 &= (uint32_t)~(ADC_TR2_LT2 | ADC_TR2_HT2); + ADCx->TR2 |= (uint32_t)(((AnalogWDGConfig->HighThreshold & 0xff) << 16) | (AnalogWDGConfig->LowThreshold & 0xff)); + } + else + { + ADCx->TR2 &= (uint32_t)~(ADC_TR2_LT2 | ADC_TR2_HT2); + ADCx->TR2 |= (uint32_t)(((AnalogWDGConfig->HighThreshold & 0xff) << 16) | (AnalogWDGConfig->LowThreshold & 0xff)); + } + } + + if (AnalogWDGConfig->WatchdogNumber == ADC_ANALOGWATCHDOG_3) + { + if (ADC_InitStruct->Resolution == ADC_RESOLUTION_6B) + { + ADCx->TR3 &= (uint32_t)~(ADC_TR3_LT3 | ADC_TR3_HT3); + ADCx->TR3 |= (uint32_t)(((AnalogWDGConfig->HighThreshold & 0xfc) << 16) | (AnalogWDGConfig->LowThreshold & 0xfc)); + } + else if (ADC_InitStruct->Resolution == ADC_RESOLUTION_8B) + { + ADCx->TR3 &= (uint32_t)~(ADC_TR3_LT3 | ADC_TR3_HT3); + ADCx->TR3 |= (uint32_t)(((AnalogWDGConfig->HighThreshold & 0xff) << 16) | (AnalogWDGConfig->LowThreshold & 0xff)); + } + else if (ADC_InitStruct->Resolution == ADC_RESOLUTION_10B) + { + ADCx->TR3 &= (uint32_t)~(ADC_TR3_LT3 | ADC_TR3_HT3); + ADCx->TR3 |= (uint32_t)(((AnalogWDGConfig->HighThreshold & 0xff) << 16) | (AnalogWDGConfig->LowThreshold & 0xff)); + } + else + { + ADCx->TR3 &= (uint32_t)~(ADC_TR3_LT3 | ADC_TR3_HT3); + ADCx->TR3 |= (uint32_t)(((AnalogWDGConfig->HighThreshold & 0xff) << 16) | (AnalogWDGConfig->LowThreshold & 0xff)); + } + } +} + + +/** + * @brief Active the Calibration operation in the mode single-ended + * for the selected ADC. + * @note The Calibration can be initiated only when ADC is still in the + * reset configuration (ADEN must be equal to 0). + * @param ADCx: where x can be 1/2/3 to select the ADCx peripheral. + * @retval ADC Calibration factor + */ +uint32_t ADC_StartSingleCalibration(ADC_TypeDef* ADCx) +{ + uint32_t tmpreg = 0x0, calibrationcounter = 0x0, calibrationstatus = 0x0; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + + /* Set the diff calibration mode */ + ADCx->CR &= (uint32_t)~ADC_CR_ADCALDIF; + + /* Set the ADC calibration */ + ADCx->CR |= (uint32_t)ADC_CR_ADCAL; + + /* Wait until no ADC calibration is completed */ + do + { + calibrationstatus = ADCx->CR & ADC_CR_ADCAL; + calibrationcounter++; + } + while ((calibrationcounter != CALIBRATION_TIMEOUT) && (calibrationstatus != 0x00)); + + if ((uint32_t)(ADCx->CR & ADC_CR_ADCAL) == RESET) + { + /*Get the calibration factor from the ADC data register */ + tmpreg = (uint32_t)(ADCx->CALFACT & ADC_CALFACT_S); + } + else + { + /* Error factor */ + tmpreg = (uint32_t)RESET; + } + return tmpreg; +} + + +/** + * @brief Get ADC calibration factor in the mode single-ended. + * @note Calibration factors are set by hardware after performing + * a calibration run using function @ref ADC_SingleCalibrationStart(). + * @param ADCx ADC instance + * @retval Value between Min_Data=0x00 and Max_Data=0x7F + */ +uint32_t ADC_GetSingleCalibrationFactor(ADC_TypeDef* ADCx) +{ + uint32_t tmpreg = 0x0, calibrationcounter = 0x0, calibrationstatus = 0x0; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + + /*Get the calibration factor from the ADC data register */ + tmpreg = (uint32_t)(ADCx->CALFACT & ADC_CALFACT_S); + + return tmpreg; +} + + +/** + * @brief Active the Calibration operation in the mode differential + * for the selected ADC. + * @note The Calibration can be initiated only when ADC is still in the + * reset configuration (ADEN must be equal to 0). + * @param ADCx: where x can be 1/2/3 to select the ADCx peripheral. + * @retval ADC Calibration factor + */ +uint32_t ADC_StartDiffCalibration(ADC_TypeDef* ADCx) +{ + uint32_t tmpreg = 0x0, calibrationcounter = 0x0, calibrationstatus = 0x0; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + + /* Set the diff calibration mode */ + ADCx->CR |= (uint32_t)ADC_CR_ADCALDIF; + + /* Set the ADC calibration */ + ADCx->CR |= (uint32_t)ADC_CR_ADCAL; + + /* Wait until no ADC calibration is completed */ + do + { + calibrationstatus = ADCx->CR & ADC_CR_ADCAL; + calibrationcounter++; + } + while ((calibrationcounter != CALIBRATION_TIMEOUT) && (calibrationstatus != 0x00)); + + if ((uint32_t)(ADCx->CR & ADC_CR_ADCAL) == RESET) + { + /*Get the calibration factor from the ADC data register */ + tmpreg = (uint32_t)((ADCx->CALFACT & ADC_CALFACT_D) >> 16); + } + else + { + /* Error factor */ + tmpreg = (uint32_t)RESET; + } + return tmpreg; +} + + +/** + * @brief Get ADC calibration factor in the mode differential. + * @note Calibration factors are set by hardware after performing + * a calibration run using function @ref ADC_DiffCalibrationStart(). + * @param ADCx ADC instance + * @retval Value between Min_Data=0x00 and Max_Data=0x7F + */ +uint32_t ADC_GetDiffCalibrationFactor(ADC_TypeDef* ADCx) +{ + uint32_t tmpreg = 0x0, calibrationcounter = 0x0, calibrationstatus = 0x0; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + + /*Get the calibration factor from the ADC data register */ + tmpreg = (uint32_t)((ADCx->CALFACT & ADC_CALFACT_D) >> 16); + + return tmpreg; +} + + +/** + * @brief Set ADC calibration factor in the mode single-ended + * for the selected ADC. + * @note This function is intended to set calibration parameters + * without having to perform a new calibration using + * @ref ADC_GetSingleCalibrationFactor(). + * @note Set calibration factor must ensure ADEN=1, ADSTART + * and JADSTART equal to 0. + * @param ADCx: where x can be 1/2/3 to select the ADCx peripheral. + * @param Calfact_S Value between Min_Data=0x00 and Max_Data=0x7F + * @retval None + */ +void ADC_SetSingleCalibrationFactor(ADC_TypeDef* ADCx, uint32_t Calfact_S) +{ + + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + + /* Reset the ADC Single mode calibration factor */ + ADCx->CALFACT &= (uint32_t)~ADC_CALFACT_S; + + /* Set the ADC Single mode calibration factor */ + ADCx->CALFACT |= (uint32_t)Calfact_S; +} + + +/** + * @brief Set ADC calibration factor in the mode differential + * for the selected ADC. + * @note This function is intended to set calibration parameters + * without having to perform a new calibration using + * @ref ADC_GetDiffCalibrationFactor(). + * @note Set calibration factor must ensure ADEN=1, ADSTART + * and JADSTART equal to 0. + * @param ADCx: where x can be 1/2/3 to select the ADCx peripheral. + * @param Calfact_D Value between Min_Data=0x00 and Max_Data=0x7F + * @retval None + */ +void ADC_SetDiffCalibrationFactor(ADC_TypeDef* ADCx, uint32_t Calfact_D) +{ + + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + + /* Reset the ADC Single mode calibration factor */ + ADCx->CALFACT &= (uint32_t)~ADC_CALFACT_D; + + /* Set the ADC Single mode calibration factor */ + ADCx->CALFACT |= (uint32_t)(Calfact_D << 16); +} + + + +/** + * @brief Start Conversion for the selected ADC regular channels. + * @note In continuous mode, ADSTART is not cleared by hardware with the + * assertion of EOSEQ because the sequence is automatic relaunched + * @param ADCx: where x can be 1/2/3 to select the ADCx peripheral. + * @retval None + */ +void ADC_REG_StartOfConversion(ADC_TypeDef* ADCx) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + + ADCx->CR |= (uint32_t)ADC_CR_ADSTART; +} + + +/** + * @brief Stop the on going ADCx group regular conversions for the selected ADC. + * @note When ADSTP is set, any on ADCx group regular going conversion is aborted, + * and the ADC data register is not updated with current conversion. + * @param ADCx: where x can be 1/2/3 to select the ADCx peripheral. + * @retval None + */ +void ADC_REG_StopOfConversion(ADC_TypeDef* ADCx) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + + ADCx->CR |= (uint32_t)ADC_CR_ADSTP; +} + + +/** + * @brief Start Conversion for the selected ADC injected channels. + * @note In continuous mode, JADSTART is not cleared by hardware with the + * assertion of EOSEQ because the sequence is automatic relaunched + * @param ADCx: where x can be 1/2/3 to select the ADCx peripheral. + * @retval None + */ +void ADC_INJ_StartOfConversion(ADC_TypeDef* ADCx) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + + ADCx->CR |= (uint32_t)ADC_CR_JADSTART; +} + + +/** + * @brief Stop the on going ADCx group injected conversions for the selected ADC. + * @note When JADSTP is set, any on ADCx group injected going conversion is aborted, + * and the ADC data register is not updated with current conversion. + * @param ADCx: where x can be 1/2/3 to select the ADCx peripheral. + * @retval None + */ +void ADC_INJ_StopOfConversion(ADC_TypeDef* ADCx) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + + ADCx->CR |= (uint32_t)ADC_CR_JADSTP; +} + + +/** + * @brief Returns the last ADCx conversion result data for ADC regular channel. + * @param ADCx: where x can be 1/2/3 to select the ADCx peripheral. + * @retval The Data conversion value. + */ +uint16_t ADC_REG_GetConversionValue(ADC_TypeDef* ADCx) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + + /* Return the selected ADC conversion value */ + return (uint16_t)ADCx->DR; +} + + +/** + * @brief Returns the last ADCx conversion result data for ADC injected channel. + * @param ADCx: where x can be 1/2/3 to select the ADCx peripheral. + * @param INJ_RANK can be one of the following values: + * @ref ADC_INJECTED_RANK_1 : return to JDR1 data + * @ref ADC_INJECTED_RANK_2 : return to JDR2 data + * @ref ADC_INJECTED_RANK_3 : return to JDR3 data + * @ref ADC_INJECTED_RANK_4 : return to JDR4 data + * @retval The Data conversion value. + */ +uint16_t ADC_INJ_GetConversionValue(ADC_TypeDef* ADCx, uint32_t INJ_RANK) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_INJECTED_RANK(INJ_RANK)); + + /* Return the selected ADC conversion value */ + if (INJ_RANK == ADC_INJECTED_RANK_1) + { + return (uint16_t)ADCx->JDR1; + } + else if (INJ_RANK == ADC_INJECTED_RANK_2) + { + return (uint16_t)ADCx->JDR2; + } + else if (INJ_RANK == ADC_INJECTED_RANK_3) + { + return (uint16_t)ADCx->JDR3; + } + else if (INJ_RANK == ADC_INJECTED_RANK_4) + { + return (uint16_t)ADCx->JDR4; + } + else + { + return 0x00; + } +} + +/** + * @} + */ + + +/** + * @brief Get ADC multimode conversion data of ADC master, ADC slave + * or raw data with ADC master and slave concatenated. + * @retval Value between Min_Data=0x00000000 and Max_Data=0xFFFFFFFF + */ +uint32_t ADC_ReadMultiConversionData32(void) +{ + return (uint32_t)ADC_Common->CDR; +} + + +/** + * @brief Enables or disables the specified ADC DMA request. + * @param ADCx: where x can be 1 to select the ADC1 peripheral. + * @param NewState: new state of the selected ADC DMA transfer. + * This parameter can be: ENABLE or DISABLE. + * @note This function must be configured before group injected + * otherwise, the configuration of the group injected may + * be reset when JQDIS=1. + * @retval None + */ +void ADC_DMACmd(ADC_TypeDef* ADCx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected ADC DMA request */ + ADCx->CFGR1 |= (uint32_t)ADC_CFGR1_DMAEN; + } + else + { + /* Disable the selected ADC DMA request */ + ADCx->CFGR1 &= (uint32_t)(~ADC_CFGR1_DMAEN); + } +} + +/** + * @brief Enables or disables the ADC DMA request after last transfer (Single-ADC mode) + * @param ADCx: where x can be 1 to select the ADC1 peripheral. + * @param ADC_DMARequestMode: the ADC channel to configure. + * This parameter can be one of the following values: + * @arg ADC_DMAMode_OneShot: DMA One Shot Mode + * @arg ADC_DMAMode_Circular: DMA Circular Mode + * @note This function must be configured before group injected + * otherwise, the configuration of the group injected may + * be reset when JQDIS=1. + * @retval None + */ +void ADC_DMARequestModeConfig(ADC_TypeDef* ADCx, uint32_t ADC_DMARequestMode) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + + ADCx->CFGR1 &= (uint32_t)~ADC_CFGR1_DMACFG; + ADCx->CFGR1 |= (uint32_t)ADC_DMARequestMode; +} + +/** + * @} + */ +/** + * @brief Enables or disables the specified ADC interrupts. + * @param ADCx: where x can be 1/2/3 to select the ADC peripheral. + * @param ADC_IT: specifies the ADC interrupt sources to be enabled or disabled. + * This parameter can be one of the following values: + * @arg ADC_IT_ADRDY: ADC Ready interrupt + * @arg ADC_IT_EOSMP: End of sampling interrupt + * @arg ADC_IT_EOC: ADC group regular end of conversion interrupt + * @arg ADC_IT_EOSEQ: ADC group regular end of Sequence interrupt + * @arg ADC_IT_OVR: ADC group regular overrun interrupt + * @arg ADC_IT_JEOC: ADC group injected end of conversion interrupt + * @arg ADC_IT_JEOSEQ: ADC group injected end of Sequence interrupt + * @arg ADC_IT_AWD1: ADC Analog watchdog 1 interrupt + * @arg ADC_IT_AWD2: ADC Analog watchdog 2 interrupt + * @arg ADC_IT_AWD3: ADC Analog watchdog 3 interrupt + * @arg ADC_IT_JQOVF: ADC group injected contexts queue overflow interrupt + * @param NewState: new state of the specified ADC interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void ADC_ITConfig(ADC_TypeDef* ADCx, uint32_t ADC_IT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + assert_param(IS_ADC_CONFIG_IT(ADC_IT)); + + if (NewState != DISABLE) + { + /* Enable the selected ADC interrupts */ + ADCx->IER |= ADC_IT; + } + else + { + /* Disable the selected ADC interrupts */ + ADCx->IER &= (~(uint32_t)ADC_IT); + } +} + +/** + * @brief Checks whether the specified ADC flag is set or not. + * @param ADCx: where x can be 1/2/3 to select the ADC1 peripheral. + * @param ADC_FLAG: specifies the flag to check. + * This parameter can be one of the following values: + * @arg ADC_FLAG_ADRDY: ADC Ready flag + * @arg ADC_FLAG_EOSMP: End of sampling flag + * @arg ADC_FLAG_EOC: ADC group regular end of conversion flag + * @arg ADC_FLAG_EOSEQ: ADC group regular end of Sequence flag + * @arg ADC_FLAG_OVR: ADC group regular overrun flag + * @arg ADC_FLAG_JEOC: ADC group injected end of conversion flag + * @arg ADC_FLAG_JEOSEQ: ADC group injected end of Sequence flag + * @arg ADC_FLAG_AWD1: ADC Analog watchdog 1 flag + * @arg ADC_FLAG_AWD2: ADC Analog watchdog 2 flag + * @arg ADC_FLAG_AWD3: ADC Analog watchdog 3 flag + * @arg ADC_FLAG_JQOVF: ADC group injected contexts queue overflow flag + * @arg ADC_FLAG_ADEN: ADC enable flag + * @arg ADC_FLAG_ADDIS: ADC disable flag + * @arg ADC_FLAG_ADSTART: ADC start flag + * @arg ADC_FLAG_ADSTP: ADC stop flag + * @arg ADC_FLAG_ADCAL: ADC Calibration flag + * @retval The new state of ADC_FLAG (SET or RESET). + */ +FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint32_t ADC_FLAG) +{ + FlagStatus bitstatus = RESET; + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_GET_FLAG(ADC_FLAG)); + + if ((uint32_t)(ADC_FLAG & 0x01000000)) + { + tmpreg = ADCx->CR & 0xFEFFFFFF; + } + else + { + tmpreg = ADCx->ISR; + } + + /* Check the status of the specified ADC flag */ + if ((tmpreg & ADC_FLAG) != (uint32_t)RESET) + { + /* ADC_FLAG is set */ + bitstatus = SET; + } + else + { + /* ADC_FLAG is reset */ + bitstatus = RESET; + } + /* Return the ADC_FLAG status */ + return bitstatus; +} + + +/** + * @brief Checks whether the specified ADC MultiMode flag is set or not. + * @param ADCx: where x can be 1/2/3 to select the ADC1 peripheral. + * @param ADC_FLAG: specifies the flag to check. + * This parameter can be one of the following values: + * @arg ADC_FLAG_ADRDY: ADC Ready flag + * @arg ADC_FLAG_EOSMP: End of sampling flag + * @arg ADC_FLAG_EOC: ADC group regular end of conversion flag + * @arg ADC_FLAG_EOSEQ: ADC group regular end of Sequence flag + * @arg ADC_FLAG_OVR: ADC group regular overrun flag + * @arg ADC_FLAG_JEOC: ADC group injected end of conversion flag + * @arg ADC_FLAG_JEOSEQ: ADC group injected end of Sequence flag + * @arg ADC_FLAG_AWD1: ADC Analog watchdog 1 flag + * @arg ADC_FLAG_AWD2: ADC Analog watchdog 2 flag + * @arg ADC_FLAG_AWD3: ADC Analog watchdog 3 flag + * @arg ADC_FLAG_JQOVF: ADC group injected contexts queue overflow flag + * @retval The new state of ADC_FLAG (SET or RESET). + */ +FlagStatus ADC_GetMultiFlagStatus(ADC_TypeDef* ADCx, uint32_t ADC_FLAG) +{ + FlagStatus bitstatus = RESET; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_GET_FLAG(ADC_FLAG)); + + /* Check the status of the specified ADC flag */ + if (ADCx == ADC1) + { + if ((ADC_Common->CSR1 & ADC_FLAG) != (uint32_t)RESET) + { + /* ADC_FLAG is set */ + bitstatus = SET; + } + else + { + /* ADC_FLAG is reset */ + bitstatus = RESET; + } + } + else if (ADCx == ADC2) + { + if ((ADC_Common->CSR1 & (ADC_FLAG << 16)) != (uint32_t)RESET) + { + /* ADC_FLAG is set */ + bitstatus = SET; + } + else + { + /* ADC_FLAG is reset */ + bitstatus = RESET; + } + } + else if (ADCx == ADC3) + { + if ((ADC_Common->CSR2 & ADC_FLAG) != (uint32_t)RESET) + { + /* ADC_FLAG is set */ + bitstatus = SET; + } + else + { + /* ADC_FLAG is reset */ + bitstatus = RESET; + } + } + + /* Return the ADC_FLAG status */ + return bitstatus; +} + + +/** + * @brief Clears the ADCx's pending flags. + * @param ADCx: where x can be 1/2/3 to select the ADC1 peripheral. + * @param ADC_FLAG: specifies the flag to clear. + * This parameter can be any combination of the following values: + * @arg ADC_FLAG_ADRDY: ADC Ready flag + * @arg ADC_FLAG_EOSMP: End of sampling flag + * @arg ADC_FLAG_EOC: ADC group regular end of conversion flag + * @arg ADC_FLAG_EOSEQ: ADC group regular end of Sequence flag + * @arg ADC_FLAG_OVR: ADC group regular overrun flag + * @arg ADC_FLAG_JEOC: ADC group injected end of conversion flag + * @arg ADC_FLAG_JEOSEQ: ADC group injected end of Sequence flag + * @arg ADC_FLAG_AWD1: ADC Analog watchdog 1 flag + * @arg ADC_FLAG_AWD2: ADC Analog watchdog 2 flag + * @arg ADC_FLAG_AWD3: ADC Analog watchdog 3 flag + * @arg ADC_FLAG_JQOVF: ADC group injected contexts queue overflow flag + * @retval None + */ +void ADC_ClearFlag(ADC_TypeDef* ADCx, uint32_t ADC_FLAG) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_CLEAR_FLAG(ADC_FLAG)); + + /* Clear the selected ADC flags */ + ADCx->ISR = (uint32_t)ADC_FLAG; +} + +/** + * @brief Checks whether the specified ADC interrupt has occurred or not. + * @param ADCx: where x can be 1/2/3 to select the ADC peripheral + * @param ADC_IT: specifies the ADC interrupt source to check. + * This parameter can be one of the following values: + * @arg ADC_IT_ADRDY: ADC Ready interrupt + * @arg ADC_IT_EOSMP: End of sampling interrupt + * @arg ADC_IT_EOC: ADC group regular end of conversion interrupt + * @arg ADC_IT_EOSEQ: ADC group regular end of Sequence interrupt + * @arg ADC_IT_OVR: ADC group regular overrun interrupt + * @arg ADC_IT_JEOC: ADC group injected end of conversion interrupt + * @arg ADC_IT_JEOSEQ: ADC group injected end of Sequence interrupt + * @arg ADC_IT_AWD1: ADC Analog watchdog 1 interrupt + * @arg ADC_IT_AWD2: ADC Analog watchdog 2 interrupt + * @arg ADC_IT_AWD3: ADC Analog watchdog 3 interrupt + * @arg ADC_IT_JQOVF: ADC group injected contexts queue overflow interrupt + * @retval The new state of ADC_IT (SET or RESET). + */ +ITStatus ADC_GetITStatus(ADC_TypeDef* ADCx, uint32_t ADC_IT) +{ + ITStatus bitstatus = RESET; + uint32_t enablestatus = 0; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_GET_IT(ADC_IT)); + + /* Get the ADC_IT enable bit status */ + enablestatus = (uint32_t)(ADCx->IER & ADC_IT); + + /* Check the status of the specified ADC interrupt */ + if (((uint32_t)(ADCx->ISR & ADC_IT) != (uint32_t)RESET) && (enablestatus != (uint32_t)RESET)) + { + /* ADC_IT is set */ + bitstatus = SET; + } + else + { + /* ADC_IT is reset */ + bitstatus = RESET; + } + /* Return the ADC_IT status */ + return bitstatus; +} + + +/** + * @brief Clears the ADCx's interrupt pending bits. + * @param ADCx: where x can be 1/2/3 to select the ADC peripheral. + * @param ADC_IT: specifies the ADC interrupt pending bit to clear. + * This parameter can be one of the following values: + * @arg ADC_IT_ADRDY: ADC Ready interrupt + * @arg ADC_IT_EOSMP: End of sampling interrupt + * @arg ADC_IT_EOC: ADC group regular end of conversion interrupt + * @arg ADC_IT_EOSEQ: ADC group regular end of Sequence interrupt + * @arg ADC_IT_OVR: ADC group regular overrun interrupt + * @arg ADC_IT_JEOC: ADC group injected end of conversion interrupt + * @arg ADC_IT_JEOSEQ: ADC group injected end of Sequence interrupt + * @arg ADC_IT_AWD1: ADC Analog watchdog 1 interrupt + * @arg ADC_IT_AWD2: ADC Analog watchdog 2 interrupt + * @arg ADC_IT_AWD3: ADC Analog watchdog 3 interrupt + * @arg ADC_IT_JQOVF: ADC group injected contexts queue overflow interrupt + * @retval None + */ +void ADC_ClearITPendingBit(ADC_TypeDef* ADCx, uint32_t ADC_IT) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_CLEAR_IT(ADC_IT)); + + /* Clear the selected ADC interrupt pending bits */ + ADCx->ISR = (uint32_t)ADC_IT; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_comp.c b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_comp.c new file mode 100644 index 00000000000..b0046646987 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_comp.c @@ -0,0 +1,689 @@ +/** + ****************************************************************************** + * @file ft32f4xx_comp.c + * @author FMD xzhang + * @brief This file provides firmware functions to manage the following + * functionalities of the comparators (COMP1 COMP2 COMP3 COMP4 COMP5 COMP6) peripheral: + * + Comparators configuration + * + Window mode control + * + RAMP mode control + * + QUALIFICATION mode control + * @version V1.0.0 + * @date 2025-03-20 + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx_comp.h" + +/** + * @brief Initializes the COMP peripheral according to the specified parameters + * in COMP_InitStruct + * @note If the selected comparator is locked, initialization can't be performed. + * To unlock the configuration, perform a system reset. + * + * @param COMP_Selection: the selected comparator. + * This parameter can be one of the following values: + * @arg COMP_Selection_COMP1: COMP1 selected + * @arg COMP_Selection_COMP2: COMP2 selected + * @arg COMP_Selection_COMP3: COMP3 selected + * @arg COMP_Selection_COMP4: COMP4 selected + * @arg COMP_Selection_COMP5: COMP5 selected + * @arg COMP_Selection_COMP6: COMP6 selected + * @param COMP_InitStruct: pointer to an COMP_InitTypeDef structure that contains + * the configuration information for the specified COMP peripheral. + * @retval None + */ +void COMP_Init(uint32_t COMP_Selection, COMP_InitTypeDef *COMP_InitStruct) +{ + uint32_t tmpreg = 0; + /* Check the parameters */ + assert_param(IS_COMP_ALL_PERIPH(COMP_Selection)); + assert_param(IS_COMP_BLANKING(COMP_InitStruct ->COMP_Blanking_Sel)); + assert_param(IS_COMP_HYSTERESIS(COMP_InitStruct ->COMP_Hysteresis_Sel)); + assert_param(IS_COMP_POL(COMP_InitStruct ->COMP_Pol)); + + /*!< Configure COMP: COMP_VipSel, COMP_VinSel,COMP_Blanking_Sel ,COMP_Hysteresis_Sel , COMP_Pol */ + tmpreg = (uint32_t)((COMP_InitStruct ->COMP_VipSel | COMP_InitStruct ->COMP_VinSel | COMP_InitStruct -> COMP_Blanking_Sel | COMP_InitStruct ->COMP_Hysteresis_Sel | COMP_InitStruct ->COMP_Pol)); + + if (COMP_Selection == COMP_Selection_COMP1) + { + /* Check the parameters */ + assert_param(IS_COMP1_VIP_SEL(COMP_InitStruct ->COMP_VipSel)); + assert_param(IS_COMP1_VIN_SEL(COMP_InitStruct ->COMP_VinSel)); + /*!< Write to COMP_CSR register */ + COMP_OPAM_DAC -> COMP1_CSR = tmpreg; + } + else if (COMP_Selection == COMP_Selection_COMP2) + { + /* Check the parameters */ + assert_param(IS_COMP2_VIP_SEL(COMP_InitStruct ->COMP_VipSel)); + assert_param(IS_COMP2_VIN_SEL(COMP_InitStruct ->COMP_VinSel)); + /*!< Write to COMP_CSR register */ + COMP_OPAM_DAC -> COMP2_CSR = tmpreg; + } + else if (COMP_Selection == COMP_Selection_COMP3) + { + /* Check the parameters */ + assert_param(IS_COMP3_VIP_SEL(COMP_InitStruct ->COMP_VipSel)); + assert_param(IS_COMP3_VIN_SEL(COMP_InitStruct ->COMP_VinSel)); + /*!< Write to COMP_CSR register */ + COMP_OPAM_DAC -> COMP3_CSR = tmpreg; + } + else if (COMP_Selection == COMP_Selection_COMP4) + { + /* Check the parameters */ + assert_param(IS_COMP4_VIP_SEL(COMP_InitStruct ->COMP_VipSel)); + assert_param(IS_COMP4_VIN_SEL(COMP_InitStruct ->COMP_VinSel)); + /*!< Write to COMP_CSR register */ + COMP_OPAM_DAC -> COMP4_CSR = tmpreg; + } + else if (COMP_Selection == COMP_Selection_COMP5) + { + /* Check the parameters */ + assert_param(IS_COMP5_VIP_SEL(COMP_InitStruct ->COMP_VipSel)); + assert_param(IS_COMP5_VIN_SEL(COMP_InitStruct ->COMP_VinSel)); + /*!< Write to COMP_CSR register */ + COMP_OPAM_DAC -> COMP5_CSR = tmpreg; + } + else if (COMP_Selection == COMP_Selection_COMP6) + { + /* Check the parameters */ + assert_param(IS_COMP6_VIP_SEL(COMP_InitStruct ->COMP_VipSel)); + assert_param(IS_COMP6_VIN_SEL(COMP_InitStruct ->COMP_VinSel)); + /*!< Write to COMP_CSR register */ + COMP_OPAM_DAC -> COMP6_CSR = tmpreg; + } +} + +/** + * @brief Deinitializes COMP peripheral registers to their default reset values. + * @note Deinitialization can't be performed if the COMP configuration is locked. + * To unlock the configuration, perform a system reset. + * @param None + * @retval None + */ +void COMP_DeInit(uint32_t COMP_Selection) +{ + /* Check the parameters */ + assert_param(IS_COMP_ALL_PERIPH(COMP_Selection)); + + if (COMP_Selection == COMP_Selection_COMP1) + { + COMP_OPAM_DAC -> COMP1_CSR = ((uint32_t)0x00000000); /*!< Set COMP_CSR register to reset value */ + COMP_OPAM_DAC -> COMP1_RAMPMAXREF_SHADOW = ((uint32_t)0x00000000); /*!< Set COMP1_RAMPMAXREF_SHADOW register to reset value */ + COMP_OPAM_DAC -> COMP1_RAMPDECVAL_SHADOW = ((uint32_t)0x00000000); /*!< Set COMP1_RAMPDECVAL_SHADOW register to reset value */ + } + else if (COMP_Selection == COMP_Selection_COMP2) + { + COMP_OPAM_DAC -> COMP2_CSR = ((uint32_t)0x00000000); /*!< Set COMP_CSR register to reset value */ + COMP_OPAM_DAC -> COMP2_RAMPMAXREF_SHADOW = ((uint32_t)0x00000000); /*!< Set COMP2_RAMPMAXREF_SHADOW register to reset value */ + COMP_OPAM_DAC -> COMP2_RAMPDECVAL_SHADOW = ((uint32_t)0x00000000); /*!< Set COMP2_RAMPDECVAL_SHADOW register to reset value */ + } + else if (COMP_Selection == COMP_Selection_COMP3) + { + COMP_OPAM_DAC -> COMP3_CSR = ((uint32_t)0x00000000); /*!< Set COMP_CSR register to reset value */ + } + else if (COMP_Selection == COMP_Selection_COMP4) + { + COMP_OPAM_DAC -> COMP4_CSR = ((uint32_t)0x00000000); /*!< Set COMP_CSR register to reset value */ + } + else if (COMP_Selection == COMP_Selection_COMP5) + { + COMP_OPAM_DAC -> COMP5_CSR = ((uint32_t)0x00000000); /*!< Set COMP_CSR register to reset value */ + } + else if (COMP_Selection == COMP_Selection_COMP6) + { + COMP_OPAM_DAC -> COMP6_CSR = ((uint32_t)0x00000000); /*!< Set COMP_CSR register to reset value */ + } + +} + + +/** + * @brief Enable or disable the COMP peripheral. + * @note If the selected comparator is locked, enable/disable can't be performed. + * To unlock the configuration, perform a system reset. + * @param COMP_Selection: the selected comparator. + * This parameter can be one of the following values: + * @arg COMP_Selection_COMP1: COMP1 selected + * @arg COMP_Selection_COMP2: COMP2 selected + * @arg COMP_Selection_COMP3: COMP3 selected + * @arg COMP_Selection_COMP4: COMP4 selected + * @arg COMP_Selection_COMP5: COMP5 selected + * @arg COMP_Selection_COMP6: COMP6 selected + * @param NewState: new state of the COMP peripheral. + * This parameter can be: ENABLE or DISABLE. + * @note When enabled, the comparator compares the non inverting input with + * the inverting input and the comparison result is available on comparator output. + * @note When disabled, the comparator doesn't perform comparison and the + * output level is low. + * @retval None + */ +void COMP_Cmd(uint32_t COMP_Selection, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_COMP_ALL_PERIPH(COMP_Selection)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + if (COMP_Selection == COMP_Selection_COMP1) + { + COMP_OPAM_DAC -> COMP1_CSR |= COMP_EN; //enable comp1 + } + else if (COMP_Selection == COMP_Selection_COMP2) + { + COMP_OPAM_DAC -> COMP2_CSR |= COMP_EN; //enable comp2 + } + else if (COMP_Selection == COMP_Selection_COMP3) + { + COMP_OPAM_DAC -> COMP3_CSR |= COMP_EN; //enable comp3 + } + else if (COMP_Selection == COMP_Selection_COMP4) + { + COMP_OPAM_DAC -> COMP4_CSR |= COMP_EN; //enable comp4 + } + else if (COMP_Selection == COMP_Selection_COMP5) + { + COMP_OPAM_DAC -> COMP5_CSR |= COMP_EN; //enable comp5 + } + else if (COMP_Selection == COMP_Selection_COMP6) + { + COMP_OPAM_DAC -> COMP6_CSR |= COMP_EN; //enable comp6 + } + } + else + { + if (COMP_Selection == COMP_Selection_COMP1) + { + COMP_OPAM_DAC -> COMP1_CSR &= ~COMP_EN; //disable comp1 + } + else if (COMP_Selection == COMP_Selection_COMP2) + { + COMP_OPAM_DAC -> COMP2_CSR &= ~COMP_EN; //disable comp2 + } + else if (COMP_Selection == COMP_Selection_COMP3) + { + COMP_OPAM_DAC -> COMP3_CSR &= ~COMP_EN; //disable comp3 + } + else if (COMP_Selection == COMP_Selection_COMP4) + { + COMP_OPAM_DAC -> COMP4_CSR &= ~COMP_EN; //disable comp4 + } + else if (COMP_Selection == COMP_Selection_COMP5) + { + COMP_OPAM_DAC -> COMP5_CSR &= ~COMP_EN; //disable comp5 + } + else if (COMP_Selection == COMP_Selection_COMP6) + { + COMP_OPAM_DAC -> COMP6_CSR &= ~COMP_EN; //disable comp6 + } + } +} +/** + * @} + */ +/** + * @brief Enables or disables the window mode. + * @note In window mode, COMP3 COMP4 are connected together,COMP5 COMP6 are connected together + * if select COMP3 's window mode as output ,COMP4 will not enable COMPx_OUTSEL; + * if select COMP4 's window mode as output ,COMP3 will not enable COMPx_OUTSEL; + * if select COMP5 's window mode as output ,COMP6 will not enable COMPx_OUTSEL; + * if select COMP6 's window mode as output ,COMP5 will not enable COMPx_OUTSEL; + * @param NewState: new state of the window mode. + * This parameter can be : + * @arg ENABLE: COMP3 and COMP4 or COMP5 and COMP6 are connected together. + * @arg DISABLE: COMP3 and COMP4 or COMP5 and COMP6 are disconnected. + * @param COMP_WIN_Selection: the selected comparator of Window mode. + * This parameter can be one of the following values: + * COMP_WIN_Selection_COMP3 : Connect INP of COMP3 to INP of COMP4 + * COMP_WIN_Selection_COMP4 : Connect INP of COMP4 to INP of COMP3 + * COMP_WIN_Selection_COMP5 : Connect INP of COMP5 to INP of COMP6 + * COMP_WIN_Selection_COMP6 : Connect INP of COMP6 to INP of COMP5 + * @retval None + */ +void COMP_WindowCmd(FunctionalState NewState, uint32_t COMP_WIN_Selection) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + assert_param(IS_COMP_WIN_PERIPH(COMP_WIN_Selection)); + + if (NewState != DISABLE) + { + if (COMP_WIN_Selection == COMP_WIN_Selection_COMP3) //comp3 inp to comp4 inp + { + /* Enable the window mode of COMP3*/ + COMP_OPAM_DAC -> COMP3_CSR |= WINMODE | OUTSEL; //enable Comp3_outsel + COMP_OPAM_DAC -> COMP4_CSR &= ~WINMODE & ~OUTSEL; //disable Comp4_outsel + } + else if (COMP_WIN_Selection == COMP_WIN_Selection_COMP4) //comp4 inp to comp3 inp + { + /* Enable the window mode of COMP4*/ + COMP_OPAM_DAC -> COMP4_CSR |= WINMODE | OUTSEL ; //enable Comp4_outsel; + COMP_OPAM_DAC -> COMP3_CSR &= ~WINMODE & ~OUTSEL ; //disable Comp3_outsel; + } + else if (COMP_WIN_Selection == COMP_WIN_Selection_COMP5)//comp5 inp to comp6 inp + { + /* Enable the window mode of COMP5*/ + COMP_OPAM_DAC -> COMP5_CSR |= WINMODE | OUTSEL ; //enable Comp5_outsel; + COMP_OPAM_DAC -> COMP6_CSR &= ~WINMODE & ~OUTSEL ; //disable Comp6_outsel; + } + else if (COMP_WIN_Selection == COMP_WIN_Selection_COMP6) //comp6 inp to comp5 inp + { + /* Enable the window mode of COMP6*/ + COMP_OPAM_DAC -> COMP6_CSR |= WINMODE | OUTSEL; //enable Comp6_outsel; + COMP_OPAM_DAC -> COMP5_CSR &= ~WINMODE & ~OUTSEL ; //disable Comp5_outsel; + } + } + else + { + if (COMP_WIN_Selection == COMP_WIN_Selection_COMP3 || COMP_WIN_Selection == COMP_WIN_Selection_COMP4) + { + /* Disable the window mode of comp3 comp4 */ + COMP_OPAM_DAC -> COMP3_CSR &= ~WINMODE & ~OUTSEL; + COMP_OPAM_DAC -> COMP4_CSR &= ~WINMODE & ~OUTSEL; + } + else if (COMP_WIN_Selection == COMP_WIN_Selection_COMP5 || COMP_WIN_Selection == COMP_WIN_Selection_COMP6) + { + /* Disable the window mode of comp5 comp6 */ + COMP_OPAM_DAC -> COMP5_CSR &= ~WINMODE & ~OUTSEL; + COMP_OPAM_DAC -> COMP6_CSR &= ~WINMODE & ~OUTSEL; + } + } +} + +/** + * @brief Select epwm from HRTIME as trigger of RAMP mode in comp1 and comp 2. + * @note If want to use RAMP function need to enable DAC_Input_sel.DAC_INPUT_SEL_RAMP firstly. + * @param COMP_1_2_Selection: select COMP1 or COMP2. + * This parameter can be : + * @arg COMP_1_2_Selection_COMP1:select COMP1 . + * @arg COMP_1_2_Selection_COMP2:select COMP2. + * @param COMP_RAMP_SEL: Select EPWM as trigger of RAMP source . + * This parameter can be one of the following values: + * COMPx_RAMPSRC_PWM1 : select EPWM1 as RAMP function trigger source + * COMPx_RAMPSRC_PWM2 : select EPWM2 as RAMP function trigger source + * COMPx_RAMPSRC_PWM3 : select EPWM3 as RAMP function trigger source + * COMPx_RAMPSRC_PWM4 : select EPWM4 as RAMP function trigger source + * @retval None + */ +void COMPx_RAMP_EPWM_SEL(uint32_t COMP_1_2_Selection, uint32_t COMP_RAMP_SEL) +{ + assert_param(IS_COMP_1_2_PERIPH(COMP_1_2_Selection)); + assert_param(IS_COMP_RAMPSRC(COMP_RAMP_SEL)); + + if (COMP_1_2_Selection == COMP_1_2_Selection_COMP1) //select COMP1 's RAMP mode + { + if (COMP_RAMP_SEL == COMPx_RAMPSRC_PWM1) //select epwm1 as trigger + { + COMP_OPAM_DAC -> COMP1_CSR |= COMPx_RAMPSRC_PWM1; + } + else if (COMP_RAMP_SEL == COMPx_RAMPSRC_PWM2) //select epwm2 as trigger + { + COMP_OPAM_DAC -> COMP1_CSR |= COMPx_RAMPSRC_PWM2; + } + else if (COMP_RAMP_SEL == COMPx_RAMPSRC_PWM3) //select epwm3 as trigger + { + COMP_OPAM_DAC -> COMP1_CSR |= COMPx_RAMPSRC_PWM3; + } + else if (COMP_RAMP_SEL == COMPx_RAMPSRC_PWM4) //select epwm4 as trigger + { + COMP_OPAM_DAC -> COMP1_CSR |= COMPx_RAMPSRC_PWM4; + } + } + else if (COMP_1_2_Selection == COMP_1_2_Selection_COMP2) //select COMP2 's RAMP mode + { + if (COMP_RAMP_SEL == COMPx_RAMPSRC_PWM1) //select epwm1 as trigger + { + COMP_OPAM_DAC -> COMP2_CSR |= COMPx_RAMPSRC_PWM1; + } + else if (COMP_RAMP_SEL == COMPx_RAMPSRC_PWM2) //select epwm2 as trigger + { + COMP_OPAM_DAC -> COMP2_CSR |= COMPx_RAMPSRC_PWM2; + } + else if (COMP_RAMP_SEL == COMPx_RAMPSRC_PWM3) //select epwm3 as trigger + { + COMP_OPAM_DAC -> COMP2_CSR |= COMPx_RAMPSRC_PWM3; + } + else if (COMP_RAMP_SEL == COMPx_RAMPSRC_PWM4) //select epwm4 as trigger + { + COMP_OPAM_DAC -> COMP2_CSR |= COMPx_RAMPSRC_PWM4; + } + } +} + +/** + * @brief Select RAMPLDIS bit to forbid COMP RAMP reset in comp1 and comp 2. + * @note If want to use RAMP function need to enable DAC_Input_sel.DAC_INPUT_SEL_RAMP firstly. + * @param COMP_1_2_Selection: select COMP1 or COMP2. + * This parameter can be : + * @arg COMP_1_2_Selection_COMP1:select COMP1 . + * @arg COMP_1_2_Selection_COMP2:select COMP2. + * @param NewState: new state of the COMP peripheral. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void COMPx_RAMP_RMPRLDIS(FunctionalState NewState, uint32_t COMP_1_2_Selection) +{ + assert_param(IS_COMP_1_2_PERIPH(COMP_1_2_Selection)); + + if (COMP_1_2_Selection == COMP_1_2_Selection_COMP1) //select COMP1 + { + if (NewState != DISABLE) + COMP_OPAM_DAC -> COMP1_CSR |= RAMPLDIS; + else + COMP_OPAM_DAC -> COMP1_CSR &= ~RAMPLDIS; + } + else if (COMP_1_2_Selection == COMP_1_2_Selection_COMP2) //select COMP2 + { + if (NewState != DISABLE) + COMP_OPAM_DAC -> COMP2_CSR |= RAMPLDIS; + else + COMP_OPAM_DAC -> COMP2_CSR &= ~RAMPLDIS; + } +} + +/** + * @brief Load RAMPDECVAL_SHADOW and RAMPMAXREF_SHADOW of COMP1 and COMP2. + * @param COMPx_RAMPDECVAL_SHADOW is 16 bit ,x=comp1 or comp2 + * @param COMPx_RAMPMAXREF_SHADOW is 16 bit ,x=comp1 or comp2 + * @param COMP_1_2_Selection: the selected comparator. + * This parameter can be one of the following values: + * @arg COMP_1_2_Selection_COMP1: COMP1 be selected + * @arg COMP_1_2_Selection_COMP2: COMP2 be selected + * @retval + */ +void COMP_RAMPVAL_SHADOW_LOAD(uint32_t COMP_1_2_Selection, uint16_t COMPx_RAMPDECVAL_SHADOW, uint16_t COMPx_RAMPMAXREF_SHADOW) +{ + /* Check the parameters */ + assert_param(IS_COMP_1_2_PERIPH(COMP_1_2_Selection)); + + if (COMP_1_2_Selection == COMP_1_2_Selection_COMP1) //select comp1 + { + /* load ramp max value*/ + COMP_OPAM_DAC -> COMP1_RAMPMAXREF_SHADOW = COMPx_RAMPMAXREF_SHADOW; + /* load ramp dec value */ + COMP_OPAM_DAC -> COMP1_RAMPDECVAL_SHADOW = COMPx_RAMPDECVAL_SHADOW; + } + else if (COMP_1_2_Selection == COMP_1_2_Selection_COMP2) //select comp2 + { + /* load ramp max value*/ + COMP_OPAM_DAC -> COMP2_RAMPMAXREF_SHADOW = COMPx_RAMPMAXREF_SHADOW; + /* load ramp dec value */ + COMP_OPAM_DAC -> COMP2_RAMPDECVAL_SHADOW = COMPx_RAMPDECVAL_SHADOW; + } + +} + + +/** + * @brief Select qualification number and enable qualification mode in comp1 and comp2. + * @note + * @param NewState: new state of the qualification mode. + * This parameter can be : + * @arg ENABLE: COMP1 or COMP2 enable qualification mode. + * @arg DISABLE: COMP1 or COMP2 disable qualification mode. + * @param COMP_1_2_Selection: select COMP1 or COMP2. + * This parameter can be : + * @arg COMP_1_2_Selection_COMP1:select COMP1. + * @arg COMP_1_2_Selection_COMP2:select COMP2. + * @param COMP_qualsel: Select qualification clk number. + * This parameter can be one of the following values: + * COMPx_QUALSEL_NONE :None select qualification clk number + * COMPx_QUALSEL_1C : select 1 clk as qualification clk number + * COMPx_QUALSEL_2C : select 2 clk as qualification clk number + * COMPx_QUALSEL_3C : select 3 clk as qualification clk number + * COMPx_QUALSEL_4C : select 4 clk as qualification clk number + * COMPx_QUALSEL_5C : select 5 clk as qualification clk number + * COMPx_QUALSEL_6C : select 6 clk as qualification clk number + * COMPx_QUALSEL_7C : select 7 clk as qualification clk number + * COMPx_QUALSEL_8C : select 8 clk as qualification clk number + * COMPx_QUALSEL_9C : select 9 clk as qualification clk number + * COMPx_QUALSEL_10C: select 10 clk as qualification clk number + * COMPx_QUALSEL_11C: select 11 clk as qualification clk number + * COMPx_QUALSEL_12C: select 12 clk as qualification clk number + * COMPx_QUALSEL_13C: select 13 clk as qualification clk number + * COMPx_QUALSEL_14C: select 14 clk as qualification clk number + * COMPx_QUALSEL_15C: select 15 clk as qualification clk number + * COMPx_QUALSEL_16C: select 16 clk as qualification clk number + * COMPx_QUALSEL_17C: select 17 clk as qualification clk number + * COMPx_QUALSEL_18C: select 18 clk as qualification clk number + * COMPx_QUALSEL_18C: select 19 clk as qualification clk number + * COMPx_QUALSEL_20C: select 20 clk as qualification clk number + * COMPx_QUALSEL_21C: select 21 clk as qualification clk number + * COMPx_QUALSEL_22C: select 22 clk as qualification clk number + * COMPx_QUALSEL_23C: select 23 clk as qualification clk number + * COMPx_QUALSEL_24C: select 24 clk as qualification clk number + * COMPx_QUALSEL_25C: select 25 clk as qualification clk number + * COMPx_QUALSEL_26C: select 26 clk as qualification clk number + * COMPx_QUALSEL_27C: select 27 clk as qualification clk number + * COMPx_QUALSEL_28C: select 28 clk as qualification clk number + * COMPx_QUALSEL_29C: select 29 clk as qualification clk number + * COMPx_QUALSEL_30C: select 30 clk as qualification clk number + * COMPx_QUALSEL_31C: select 31 clk as qualification clk number + * @retval None + */ +void COMPx_QUALIFICATION(FunctionalState NewState, uint32_t COMP_1_2_Selection, uint32_t COMP_qualsel) +{ + assert_param(IS_COMP_1_2_PERIPH(COMP_1_2_Selection)); + assert_param(IS_COMP_QUALSER_PERIPH(COMP_qualsel)); + + if (NewState != DISABLE) + { + if (COMP_1_2_Selection == COMP_1_2_Selection_COMP1) //select COMP1 + { + /* enable qualification mode in Comp1 */ + COMP_OPAM_DAC -> COMP1_CSR |= QUALEN ; + /* select qualification number and enable sync bit*/ + COMP_OPAM_DAC -> COMP1_CSR |= COMP_qualsel | SYNCSEL; + } + else if (COMP_1_2_Selection == COMP_1_2_Selection_COMP2) //select COMP2 + { + /* enable qualification mode in Comp1 */ + COMP_OPAM_DAC -> COMP2_CSR |= QUALEN ; + /* select qualification number and enable sync bit */ + COMP_OPAM_DAC -> COMP2_CSR |= COMP_qualsel | SYNCSEL; + } + } + else + { + if (COMP_1_2_Selection == COMP_1_2_Selection_COMP1) //select COMP1 + { + COMP_OPAM_DAC -> COMP1_CSR &= ~COMP_qualsel & ~SYNCSEL & ~QUALEN; + } + else if (COMP_1_2_Selection == COMP_1_2_Selection_COMP2) //select COMP2 + { + COMP_OPAM_DAC -> COMP2_CSR &= ~COMP_qualsel & ~SYNCSEL & ~QUALEN; + } + } +} + +/** + * @brief enable or disable feedback 100K resistor. + * @param NewState: new state of the RAMP mode. + * This parameter can be : + * @arg ENABLE: COMP1 or COMP2 enable feedback resistor . + * @arg DISABLE: COMP1 or COMP2 disable feedback resistor . + * @param COMP_1_2_Selection: select COMP1 or COMP2. + * This parameter can be : + * @arg COMP_1_2_Selection_COMP1:select COMP1. + * @arg COMP_1_2_Selection_COMP2:select COMP2. + * @retval None + */ +void COMPx_Resistor(FunctionalState NewState, uint32_t COMP_1_2_Selection) +{ + assert_param(IS_COMP_1_2_PERIPH(COMP_1_2_Selection)); + + if (NewState != DISABLE) + { + if (COMP_1_2_Selection == COMP_1_2_Selection_COMP1) + { + COMP_OPAM_DAC -> COMP1_CSR |= RSWITCH; //enable resistor of comp1 + } + else if (COMP_1_2_Selection == COMP_1_2_Selection_COMP2) + { + COMP_OPAM_DAC -> COMP2_CSR |= RSWITCH; //enable resistor of comp1 + } + } + else + { + if (COMP_1_2_Selection == COMP_1_2_Selection_COMP1) + { + COMP_OPAM_DAC -> COMP1_CSR &= ~RSWITCH; //disable resistor of comp1 + } + else if (COMP_1_2_Selection == COMP_1_2_Selection_COMP2) + { + COMP_OPAM_DAC -> COMP2_CSR &= ~RSWITCH; //disable resistor of comp1 + } + } +} + + +/** + * @brief Lock the selected comparator (COMP1/COMP2/COMP3/COMP4/COMP5/COMP6) configuration. + * @note Locking the configuration means that all control bits are read-only. + * To unlock the comparator configuration, perform a system reset. + * @param COMP_Selection: selects the comparator to be locked + * This parameter can be a value of the following values: + * @arg COMP_Selection_COMP1: COMP1 configuration is locked. + * @arg COMP_Selection_COMP2: COMP2 configuration is locked. + * @arg COMP_Selection_COMP3: COMP3 configuration is locked. + * @arg COMP_Selection_COMP4: COMP4 configuration is locked. + * @arg COMP_Selection_COMP5: COMP5 configuration is locked. + * @arg COMP_Selection_COMP6: COMP6 configuration is locked. + * @retval None + */ +void COMP_LockConfig(uint32_t COMP_Selection) +{ + /* Check the parameter */ + assert_param(IS_COMP_ALL_PERIPH(COMP_Selection)); + + if (COMP_Selection == COMP_Selection_COMP1) + COMP_OPAM_DAC -> COMP1_CSR |= COMP_LOCK; //lock COMP1_CSR's bit + + else if (COMP_Selection == COMP_Selection_COMP2) + COMP_OPAM_DAC -> COMP2_CSR |= COMP_LOCK; //lock COMP2_CSR's bit + + else if (COMP_Selection == COMP_Selection_COMP3) + COMP_OPAM_DAC -> COMP3_CSR |= COMP_LOCK; //lock COMP3_CSR's bit + + else if (COMP_Selection == COMP_Selection_COMP4) + COMP_OPAM_DAC -> COMP4_CSR |= COMP_LOCK; //lock COMP4_CSR's bit + + else if (COMP_Selection == COMP_Selection_COMP5) + COMP_OPAM_DAC -> COMP5_CSR |= COMP_LOCK; //lock COMP5_CSR's bit + + else if (COMP_Selection == COMP_Selection_COMP6) + COMP_OPAM_DAC -> COMP6_CSR |= COMP_LOCK; //lock COMP6_CSR's bit +} + + +/** + * @brief Return the output level (high or low) of the selected comparator ,which is behind the comp analog out and ahead of qualification . + * @note The output level NOT depends on the selected polarity. + * @note The polarity is not influence output value: + * - Comparator output is low when the non-inverting input is at a lower + * voltage than the inverting input + * - Comparator output is high when the non-inverting input is at a higher + * voltage than the inverting input + * @param COMP_Selection: the selected comparator. + * This parameter can be one of the following values: + * @arg COMP_Selection_COMP1: COMP1 selected + * @arg COMP_Selection_COMP2: COMP2 selected + * @arg COMP_Selection_COMP3: COMP3 selected + * @arg COMP_Selection_COMP4: COMP4 selected + * @arg COMP_Selection_COMP5: COMP5 selected + * @arg COMP_Selection_COMP6: COMP6 selected + * @retval Returns the selected comparator output level: low or high. + * + */ +uint32_t COMP_GetOutputLevel(uint32_t COMP_Selection) +{ + uint32_t compout = 0x0; + + /* Check the parameters */ + assert_param(IS_COMP_ALL_PERIPH(COMP_Selection)); + + if (COMP_Selection == COMP_Selection_COMP1) + { + /* Check if selected comparator output is high */ + if (((COMP_OPAM_DAC -> COMP1_CSR) & COMPx_CSR_VALUE_Msk) == (uint32_t)VALUE) + { + compout = (uint32_t) COMP_OutputLevel_High >> 30; + } + else + { + compout = (uint32_t) COMP_OutputLevel_Low >> 30; + } + } + else if (COMP_Selection == COMP_Selection_COMP2) + { + /* Check if selected comparator output is high */ + if (((COMP_OPAM_DAC -> COMP2_CSR) & COMPx_CSR_VALUE_Msk) == (uint32_t)VALUE) + { + compout = (uint32_t) COMP_OutputLevel_High >> 30; + } + else + { + compout = (uint32_t) COMP_OutputLevel_Low >> 30; + } + } + else if (COMP_Selection == COMP_Selection_COMP3) + { + /* Check if selected comparator output is high */ + if (((COMP_OPAM_DAC -> COMP3_CSR) & (uint32_t)VALUE) == (uint32_t)VALUE) + { + compout = (uint32_t) COMP_OutputLevel_High >> 30; + } + else + { + compout = (uint32_t) COMP_OutputLevel_Low >> 30; + } + } + else if (COMP_Selection == COMP_Selection_COMP4) + { + /* Check if selected comparator output is high */ + if (((COMP_OPAM_DAC -> COMP4_CSR) & (uint32_t)VALUE) == (uint32_t)VALUE) + { + compout = (uint32_t) COMP_OutputLevel_High >> 30; + } + else + { + compout = (uint32_t) COMP_OutputLevel_Low >> 30; + } + } + else if (COMP_Selection == COMP_Selection_COMP5) + { + /* Check if selected comparator output is high */ + if (((COMP_OPAM_DAC -> COMP5_CSR) & (uint32_t)VALUE) == (uint32_t)VALUE) + { + compout = (uint32_t) COMP_OutputLevel_High >> 30; + } + else + { + compout = (uint32_t) COMP_OutputLevel_Low >> 30; + } + } + else if (COMP_Selection == COMP_Selection_COMP6) + { + /* Check if selected comparator output is high */ + if (((COMP_OPAM_DAC -> COMP6_CSR) & (uint32_t)VALUE) == (uint32_t)VALUE) + { + compout = (uint32_t) COMP_OutputLevel_High >> 30; + } + else + { + compout = (uint32_t) COMP_OutputLevel_Low >> 30; + } + } + /* Return the comparator output level */ + return (uint32_t)(compout); +} + + +/** + * @} + */ + +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_crc.c b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_crc.c new file mode 100644 index 00000000000..0f488ebc905 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_crc.c @@ -0,0 +1,239 @@ +/** + ****************************************************************************** + * @file ft32f4xx_crc.c + * @author FMD AE + * @brief This file provides firmware functions to manage the following + * functionalities of CRC computation unit peripheral: + * + Configuration of the CRC computation unit + * + CRC computation of one/many 32-bit data + * + CRC Independent register (IDR) access + * @version V1.0.0 + * @date 2025-03-26 + ****************************************************************************** + */ + + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx_crc.h" +#include "ft32f4xx_rcc.h" + +/** @defgroup CRC CRC + * @brief CRC module driver + * @{ + */ + +/** @defgroup CRC_Exported_Functions CRC Exported Functions + * @{ + */ + +/** + * @brief Deinitializes CRC peripheral registers to their default reset values. + * @param None + * @retval None + */ +void CRC_DeInit(void) +{ + /* Enable CRC reset state */ + RCC_AHB1PeriphResetCmd(RCC_AHB1PeriphRst_CRC, ENABLE); + /* Release CRC from reset state */ + RCC_AHB1PeriphResetCmd(RCC_AHB1PeriphRst_CRC, DISABLE); +} + +/** + * @brief Resets the CRC calculation unit and sets INIT register content in DR register. + * @param None + * @retval None + */ +void CRC_ResetDR(void) +{ + /* Reset CRC generator */ + CRC->CR |= CRC_CR_RESET; +} + +/** + * @brief Selects the reverse operation to be performed on input data. + * @param CRC_ReverseInputData: Specifies the reverse operation on input data. + * This parameter can be: + * @arg CRC_ReverseInputData_No: No reverse operation is performed + * @arg CRC_ReverseInputData_8bits: reverse operation performed on 8 bits + * @arg CRC_ReverseInputData_16bits: reverse operation performed on 16 bits + * @arg CRC_ReverseInputData_32bits: reverse operation performed on 32 bits + * @retval None + */ +void CRC_ReverseInputDataSelect(uint32_t CRC_ReverseInputData) +{ + uint32_t tmpcr = 0; + + /* Check the parameter */ + assert_param(IS_CRC_REVERSE_INPUT_DATA(CRC_ReverseInputData)); + + /* Get CR register value */ + tmpcr = CRC->CR; + + /* Reset REV_IN bits */ + tmpcr &= (uint32_t)~((uint32_t)CRC_CR_REV_IN); + /* Set the reverse operation */ + tmpcr |= (uint32_t)CRC_ReverseInputData; + + /* Write to CR register */ + CRC->CR = (uint32_t)tmpcr; +} + +/** + * @brief Enables or disable the reverse operation on output data. + * The reverse operation on output data is performed on 32-bit. + * @param NewState: new state of the reverse operation on output data. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void CRC_ReverseOutputDataCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable reverse operation on output data */ + CRC->CR |= CRC_CR_REV_OUT; + } + else + { + /* Disable reverse operation on output data */ + CRC->CR &= (uint32_t)~((uint32_t)CRC_CR_REV_OUT); + } +} + +/** + * @brief Set control register. + * @param CRC_CRValue: Programmable control register value + * @retval None + */ +void CRC_SetCRegister(uint32_t CRC_CRValue) +{ + CRC->CR = CRC_CRValue; +} + +/** + * @brief Initializes the INIT register. + * @note After resetting CRC calculation unit, CRC_InitValue is stored in DR register + * @param CRC_InitValue: Programmable initial CRC value + * @retval None + */ +void CRC_SetINITRegister(uint32_t CRC_InitValue) +{ + CRC->INIT = CRC_InitValue; +} + +/** + * @brief Computes the 32-bit CRC of a given data word(32-bit). + * @param CRC_Data: data word(32-bit) to compute its CRC + * @retval 32-bit CRC + */ +uint32_t CRC_CalcCRC(uint32_t CRC_Data) +{ + CRC->DR = CRC_Data; + + return (CRC->DR); +} + +/** + * @brief Computes the 16-bit CRC of a given 16-bit data. + * @param CRC_Data: data half-word(16-bit) to compute its CRC + * @retval 16-bit CRC + */ +uint32_t CRC_CalcCRC16bits(uint16_t CRC_Data) +{ + *(uint16_t*)(CRC_BASE) = (uint16_t) CRC_Data; + + return (CRC->DR); +} + +/** + * @brief Computes the 8-bit CRC of a given 8-bit data. + * @param CRC_Data: 8-bit data to compute its CRC + * @retval 8-bit CRC + */ +uint32_t CRC_CalcCRC8bits(uint8_t CRC_Data) +{ + *(uint8_t*)(CRC_BASE) = (uint8_t) CRC_Data; + + return (CRC->DR); +} + +/** + * @brief Computes the 32-bit CRC of a given buffer of data word(32-bit). + * @param pBuffer: pointer to the buffer containing the data to be computed + * @param BufferLength: length of the buffer to be computed + * @retval 32-bit CRC + */ +uint32_t CRC_CalcBlockCRC(uint32_t pBuffer[], uint32_t BufferLength) +{ + uint32_t index = 0; + + for (index = 0; index < BufferLength; index++) + { + CRC->DR = pBuffer[index]; + } + return (CRC->DR); +} + +/** + * @brief Returns the current CRC value. + * @param None + * @retval 32-bit CRC + */ +uint32_t CRC_GetCRC(void) +{ + return (CRC->DR); +} + +/** + * @brief Stores an 8-bit data in the Independent Data(ID) register. + * @param CRC_IDValue: 8-bit value to be stored in the ID register + * @retval None + */ +void CRC_SetIDRegister(uint8_t CRC_IDValue) +{ + CRC->IDR = CRC_IDValue; +} + +/** + * @brief Returns the 8-bit data stored in the Independent Data(ID) register + * @param None + * @retval 8-bit value of the ID register + */ +uint8_t CRC_GetIDRegister(void) +{ + return (uint8_t)(CRC->IDR); +} + +/** + * @brief Returns the 32-bit data in the CRC control register + * @param None + * @retval 32-bit value of the CR register + */ +uint32_t CRC_GetCRegister(void) +{ + return (CRC->CR); +} + +/** + * @brief Returns the 32-bit data in the CRC INIT register + * @param None + * @retval 32-bit value of the INIT register + */ +uint32_t CRC_GetINITRegister(void) +{ + return (CRC->INIT); +} + +/** + * @} + */ + +/** + * @} + */ + + +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_crs.c b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_crs.c new file mode 100644 index 00000000000..06f25711666 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_crs.c @@ -0,0 +1,381 @@ +/** + ****************************************************************************** + * @file ft32f4xx_crs.c + ****************************************************************************** + */ + + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx_crs.h" +#include "system_ft32f4xx.h" +#include "ft32f4xx_rcc.h" + + +/** @defgroup CRS + * @brief CRS driver modules + * @{ + */ + +/* CRS Flag Mask */ +#define FLAG_MASK ((uint32_t)0x700) + + +/** + * @brief Deinitializes CRS peripheral registers to their default reset values. + * @param None + * @retval None + */ +void CRS_DeInit(void) +{ + RCC_APB1PeriphResetCmd(RCC_APB1Periph_CRS, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_CRS, DISABLE); +} + +/** + * @brief Adjusts the Internal High Speed 48 oscillator (HSI 48) calibration value. + * @note The calibration is used to compensate for the variations in voltage + * and temperature that influence the frequency of the internal HSI48 RC. + * @note This function can be called only when the AUTOTRIMEN bit is reset. + * @param CRS_HSI48CalibrationValue: + * @retval None + */ +void CRS_AdjustHSI48CalibrationValue(uint8_t CRS_HSI48CalibrationValue) +{ + /* Clear TRIM[5:0] bits */ + CRS->CR &= ~CRS_CR_TRIM; + + /* Set the TRIM[5:0] bits according to CRS_HSI48CalibrationValue value */ + CRS->CR |= (uint32_t)((uint32_t)CRS_HSI48CalibrationValue << 8); + +} + + +/** + * @brief Enables or disables the oscillator clock for frequency error counter. + * @note when the CEN bit is set the CRS_CFGR register becomes write-protected. + * @param NewState: new state of the frequency error counter. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void CRS_FrequencyErrorCounterCmd(FunctionalState NewState) +{ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + CRS->CR |= CRS_CR_CEN; + } + else + { + CRS->CR &= ~CRS_CR_CEN; + } +} + +/** + * @brief Enables or disables the automatic hardware adjustement of TRIM bits. + * @note When the AUTOTRIMEN bit is set the CRS_CFGR register becomes write-protected. + * @param NewState: new state of the automatic trimming. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void CRS_AutomaticCalibrationCmd(FunctionalState NewState) +{ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + CRS->CR |= CRS_CR_AUTOTRIMEN; + } + else + { + CRS->CR &= ~CRS_CR_AUTOTRIMEN; + } +} + +/** + * @brief Generate the software synchronization event + * @param None + * @retval None + */ +void CRS_SoftwareSynchronizationGenerate(void) +{ + CRS->CR |= CRS_CR_SWSYNC; +} + +/** + * @brief Adjusts the Internal High Speed 48 oscillator (HSI 48) calibration value. + * @note The calibration is used to compensate for the variations in voltage + * and temperature that influence the frequency of the internal HSI48 RC. + * @note This function can be called only when the CEN bit is reset. + * @param CRS_ReloadValue: specifies the HSI calibration trimming value. + * This parameter must be a number between 0 and . + * @retval None + */ +void CRS_FrequencyErrorCounterReload(uint32_t CRS_ReloadValue) +{ + + /* Clear RELOAD[15:0] bits */ + CRS->CFGR &= ~CRS_CFGR_RELOAD; + + /* Set the RELOAD[15:0] bits according to CRS_ReloadValue value */ + CRS->CFGR |= (uint32_t)CRS_ReloadValue; + +} + +/** + * @brief + * @note This function can be called only when the CEN bit is reset. + * @param CRS_ErrorLimitValue: specifies the HSI calibration trimming value. + * This parameter must be a number between 0 and . + * @retval None + */ +void CRS_FrequencyErrorLimitConfig(uint8_t CRS_ErrorLimitValue) +{ + /* Clear FELIM[7:0] bits */ + CRS->CFGR &= ~CRS_CFGR_FELIM; + + /* Set the FELIM[7:0] bits according to CRS_ErrorLimitValue value */ + CRS->CFGR |= (uint32_t)(CRS_ErrorLimitValue << 16); +} + +/** + * @brief + * @note This function can be called only when the CEN bit is reset. + * @param CRS_Prescaler: specifies the HSI calibration trimming value. + * This parameter can be one of the following values: + * @arg CRS_SYNC_Div1: + * @arg CRS_SYNC_Div2: + * @arg CRS_SYNC_Div4: + * @arg CRS_SYNC_Div8: + * @arg CRS_SYNC_Div16: + * @arg CRS_SYNC_Div32: + * @arg CRS_SYNC_Div64: + * @arg CRS_SYNC_Div128: + * @retval None + */ +void CRS_SynchronizationPrescalerConfig(uint32_t CRS_Prescaler) +{ + /* Check the parameters */ + assert_param(IS_CRS_SYNC_DIV(CRS_Prescaler)); + + /* Clear SYNCDIV[2:0] bits */ + CRS->CFGR &= ~CRS_CFGR_SYNCDIV; + + /* Set the CRS_CFGR_SYNCDIV[2:0] bits according to CRS_Prescaler value */ + CRS->CFGR |= CRS_Prescaler; +} + +/** + * @brief + * @note This function can be called only when the CEN bit is reset. + * @param CRS_Source: . + * This parameter can be one of the following values: + * @arg CRS_SYNCSource_GPIO: + * @arg CRS_SYNCSource_LSE: + * @arg CRS_SYNCSource_USB: + * @retval None + */ +void CRS_SynchronizationSourceConfig(uint32_t CRS_Source) +{ + /* Check the parameters */ + assert_param(IS_CRS_SYNC_SOURCE(CRS_Source)); + + /* Clear SYNCSRC[1:0] bits */ + CRS->CFGR &= ~CRS_CFGR_SYNCSRC; + + /* Set the SYNCSRC[1:0] bits according to CRS_Source value */ + CRS->CFGR |= CRS_Source; +} + +/** + * @brief + * @note This function can be called only when the CEN bit is reset. + * @param CRS_Polarity: . + * This parameter can be one of the following values: + * @arg CRS_SYNCPolarity_Rising: + * @arg CRS_SYNCPolarity_Falling: + * @retval None + */ +void CRS_SynchronizationPolarityConfig(uint32_t CRS_Polarity) +{ + /* Check the parameters */ + assert_param(IS_CRS_SYNC_POLARITY(CRS_Polarity)); + + /* Clear SYNCSPOL bit */ + CRS->CFGR &= ~CRS_CFGR_SYNCPOL; + + /* Set the SYNCSPOL bits according to CRS_Polarity value */ + CRS->CFGR |= CRS_Polarity; +} + +/** + * @brief Returns the Relaod value. + * @param None + * @retval The reload value + */ +uint32_t CRS_GetReloadValue(void) +{ + return ((uint32_t)(CRS->CFGR & CRS_CFGR_RELOAD)); +} + +/** + * @brief Returns the HSI48 Calibration value. + * @param None + * @retval The reload value + */ +uint32_t CRS_GetHSI48CalibrationValue(void) +{ + return (((uint32_t)(CRS->CR & CRS_CR_TRIM)) >> 8); +} + +/** + * @brief Returns the frequency error capture. + * @param None + * @retval The frequency error capture value + */ +uint32_t CRS_GetFrequencyErrorValue(void) +{ + return ((uint32_t)(CRS->ISR & CRS_ISR_FECAP)); +} + +/** + * @brief Returns the frequency error direction. + * @param None + * @retval The frequency error direction. The returned value can be one + * of the following values: + * - 0x00: Up counting + * - 0x8000: Down counting + */ +uint32_t CRS_GetFrequencyErrorDirection(void) +{ + return ((uint32_t)(CRS->ISR & CRS_ISR_FEDIR)); +} + +/** + * @brief Enables or disables the specified CRS interrupts. + * @param CRS_IT: specifies the RCC interrupt sources to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg CRS_IT_SYNCOK: + * @arg CRS_IT_SYNCWARN: + * @arg CRS_IT_ERR: + * @arg CRS_IT_ESYNC: + * @param NewState: new state of the specified CRS interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void CRS_ITConfig(uint32_t CRS_IT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_CRS_IT(CRS_IT)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + CRS->CR |= CRS_IT; + } + else + { + CRS->CR &= ~CRS_IT; + } +} + +/** + * @brief Checks whether the specified CRS flag is set or not. + * @param CRS_FLAG: specifies the flag to check. + * This parameter can be one of the following values: + * @arg CRS_FLAG_SYNCOK: + * @arg CRS_FLAG_SYNCWARN: + * @arg CRS_FLAG_ERR: + * @arg CRS_FLAG_ESYNC: + * @arg CRS_FLAG_TRIMOVF: + * @arg CRS_FLAG_SYNCERR: + * @arg CRS_FLAG_SYNCMISS: + * @retval The new state of CRS_FLAG (SET or RESET). + */ +FlagStatus CRS_GetFlagStatus(uint32_t CRS_FLAG) +{ + /* Check the parameters */ + assert_param(IS_CRS_FLAG(CRS_FLAG)); + + return ((FlagStatus)(CRS->ISR & CRS_FLAG)); +} + +/** + * @brief Clears the CRS specified FLAG. + * @param CRS_FLAG: specifies the flag to check. + * This parameter can be one of the following values: + * @arg CRS_FLAG_SYNCOK: + * @arg CRS_FLAG_SYNCWARN: + * @arg CRS_FLAG_ERR: + * @arg CRS_FLAG_ESYNC: + * @arg CRS_FLAG_TRIMOVF: + * @arg CRS_FLAG_SYNCERR: + * @arg CRS_FLAG_SYNCMISS: + * @retval None + */ +void CRS_ClearFlag(uint32_t CRS_FLAG) +{ + /* Check the parameters */ + assert_param(IS_CRS_FLAG(CRS_FLAG)); + + if ((CRS_FLAG & FLAG_MASK) != 0) + { + CRS->ICR |= CRS_ICR_ERRC; + } + else + { + CRS->ICR |= CRS_FLAG; + } +} + +/** + * @brief Checks whether the specified CRS IT pending bit is set or not. + * @param CRS_IT: specifies the IT pending bit to check. + * This parameter can be one of the following values: + * @arg CRS_IT_SYNCOK: + * @arg CRS_IT_SYNCWARN: + * @arg CRS_IT_ERR: + * @arg CRS_IT_ESYNC: + * @arg CRS_IT_TRIMOVF: + * @arg CRS_IT_SYNCERR: + * @arg CRS_IT_SYNCMISS: + * @retval The new state of CRS_IT (SET or RESET). + */ +ITStatus CRS_GetITStatus(uint32_t CRS_IT) +{ + /* Check the parameters */ + assert_param(IS_CRS_GET_IT(CRS_IT)); + + return ((ITStatus)(CRS->ISR & CRS_IT)); +} + +/** + * @brief Clears the CRS specified IT pending bi. + * @param CRS_FLAG: specifies the IT pending bi to clear. + * This parameter can be one of the following values: + * @arg CRS_IT_SYNCOK: + * @arg CRS_IT_SYNCWARN: + * @arg CRS_IT_ERR: + * @arg CRS_IT_ESYNC: + * @arg CRS_IT_TRIMOVF: + * @arg CRS_IT_SYNCERR: + * @arg CRS_IT_SYNCMISS: + * @retval None + */ +void CRS_ClearITPendingBit(uint32_t CRS_IT) +{ + /* Check the parameters */ + assert_param(IS_CRS_CLEAR_IT(CRS_IT)); + + if ((CRS_IT & FLAG_MASK) != 0) + { + CRS->ICR |= CRS_ICR_ERRC; + } + else + { + CRS->ICR |= CRS_IT; + } +} + + +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_dac.c b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_dac.c new file mode 100644 index 00000000000..e052744637f --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_dac.c @@ -0,0 +1,514 @@ +/** + ****************************************************************************** + * @file ft32f4xx_dac.c + * @author FMD xzhang + * @brief This file provides firmware functions to manage the following + * functionalities of the comparators (DAC1 DAC2 ) peripheral: + * + DAC triangle + * + DAC Noise wave + * @version V1.0.0 + * @data 2025-03-20 + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx_dac.h" +/* Exported types ------------------------------------------------------------*/ +/** @defgroup DAC_Exported_Types DAC Exported Types + * @{ + + ============================================================================== + ##### Initialization and de-initialization functions ##### + ============================================================================== + [..] This section provides functions allowing to: + (+) Initialize and configure the DAC. + (+) De-initialize the DAC. +*/ +/* + * @brief Initialize the DAC peripheral according to the specified parameters + * in the DAC_InitStruct and initialize the associated handle. + * @param DAC_1_2_Selection: the selected DAC + * This parameter can be one of the following values: + * @arg DAC_CHANNEL_1 : DAC1 selected + * @arg DAC_CHANNEL_2 : DAC2 selected + * @arg DAC_CHANNEL_D12:DAC1 and DAC2 selected + * @param DAC_InitStruct: pointer to a DAC_InitTypeDef structure that contains + * the configuration information for the specified DAC. + * @retval +*/ +void DAC_Init(uint32_t DAC_1_2_Selection, DAC_InitTypeDef* DAC_InitStruct) +{ + uint16_t tmpreg = 0; + /* Check the parameters */ + assert_param(IS_DAC_1_2_PERIPH(DAC_1_2_Selection)); + assert_param(IS_DAC_BUFFER(DAC_InitStruct -> DAC_OutputBuffer)); + assert_param(IS_DAC_TRIGGER(DAC_InitStruct -> DAC_trigger)); + + /*!< Configure : DAC_Trigger / DAC_OutputBuffer/DAC_Input_sel/DAC_Output_sel*/ + tmpreg = (uint16_t)((DAC_InitStruct ->DAC_Trigger | DAC_InitStruct -> DAC_OutputBuffer | DAC_InitStruct ->DAC_Input_sel | DAC_InitStruct -> DAC_Output_sel)); + + if (DAC_1_2_Selection == DAC_CHANNEL_1) //config DAC1 + { + /*!< Write to DAC_CSR register */ + COMP_OPAM_DAC -> DAC_CR |= (uint32_t) tmpreg; + } + else if (DAC_1_2_Selection == DAC_CHANNEL_2) //config DAC2 + { + /*!< Write to DAC_CSR register */ + COMP_OPAM_DAC -> DAC_CR |= (uint32_t)(tmpreg << 16); + } + else if (DAC_1_2_Selection == DAC_CHANNEL_D12) //config DAC1 and DAC2 sametime + { + /*!< Write to DAC_CSR register */ + COMP_OPAM_DAC -> DAC_CR |= (uint32_t)((tmpreg << 16) | tmpreg); + } +} + + +/** + * @brief Deinitializes DAC peripheral registers to their default reset values. + * @note Deinitializes DAC_CR DAC_SR + * @param DAC_1_2_Selection: the selected DAC + * This parameter can be one of the following values: + * @arg DAC_CHANNEL_1 : DAC1 selected + * @arg DAC_CHANNEL_2 : DAC2 selected + * @arg DAC_CHANNEL_D12:DAC1 and DAC2 selected + * @retval None + */ +void DAC_DeInit(uint32_t DAC_1_2_Selection) +{ + /* Check the parameters */ + assert_param(IS_DAC_1_2_PERIPH(DAC_1_2_Selection)); + + if (DAC_1_2_Selection == DAC_CHANNEL_1) + { + /*!< Write to DAC_CSR register */ + COMP_OPAM_DAC -> DAC_CR &= 0xffff0000; + /*DAC_SR:RC_W1*/ + COMP_OPAM_DAC -> DAC_SR |= DMAUDR1; + } + else if (DAC_1_2_Selection == DAC_CHANNEL_2) + { + /*!< Write to DAC_CSR register */ + COMP_OPAM_DAC -> DAC_CR &= 0x0000ffff; + /*DAC_SR:RC_W1*/ + COMP_OPAM_DAC -> DAC_SR |= DMAUDR2; + } + else if (DAC_1_2_Selection == DAC_CHANNEL_D12) + { + /*!< Write to DAC_CSR register */ + COMP_OPAM_DAC -> DAC_CR &= 0x00000000; + COMP_OPAM_DAC -> DAC_SR |= DMAUDR1 | DMAUDR2; + } +} +/** + * @brief Enables DAC and starts conversion of channel by soft trriger once. + * the configuration information for the specified DAC. + * @param DAC_1_2_Selection The selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_CHANNEL_1: DAC Channel1 selected + * @arg DAC_CHANNEL_2: DAC Channel2 selected + * @arg DAC_CHANNEL_D12:DAC1 and DAC2 selected + * @retval + */ +void DAC_Start(uint32_t DAC_1_2_Selection) +{ + /* Check the parameters */ + assert_param(IS_DAC_1_2_PERIPH(DAC_1_2_Selection)); + + /* Enable the Peripheral */ + if (DAC_1_2_Selection == DAC_CHANNEL_D12) + { + COMP_OPAM_DAC -> DAC_CR |= EN1 | EN2; + } + else + { + /*Enable DAC1 or DAC2*/ + COMP_OPAM_DAC -> DAC_CR |= (EN1 << (DAC_1_2_Selection & 0x10UL)) ; + } + //software trriger mode + if (DAC_1_2_Selection == DAC_CHANNEL_1) + { + /* Check if software trigger enabled */ + if (((COMP_OPAM_DAC -> DAC_CR) & (TEN1 | DAC_CR_TSEL1_Msk)) == DAC_TRIGGER_SOFTWARE) + { + /* Enable the selected DAC1 software conversion */ + COMP_OPAM_DAC -> DAC_SWTRIGR |= SWTRIGR1; + } + } + else if (DAC_1_2_Selection == DAC_CHANNEL_2) + { + /* Check if software trigger enabled */ + if (((COMP_OPAM_DAC -> DAC_CR) & (TEN2 | DAC_CR_TSEL2_Msk)) == (DAC_TRIGGER_SOFTWARE << (DAC_1_2_Selection & 0x10UL))) + { + /* Enable the selected DAC2 software conversion */ + COMP_OPAM_DAC -> DAC_SWTRIGR |= SWTRIGR2; + } + } + else if (DAC_1_2_Selection == DAC_CHANNEL_D12) + { + /* Check if software trigger enabled */ + if (((COMP_OPAM_DAC -> DAC_CR) & (TEN1 | DAC_CR_TSEL1_Msk | TEN2 | DAC_CR_TSEL2_Msk)) == (DAC_TRIGGER_SOFTWARE | (DAC_TRIGGER_SOFTWARE << 0x10UL))) + { + /* Enable the selected DAC1 DAC2 software conversion */ + COMP_OPAM_DAC -> DAC_SWTRIGR |= SWTRIGR1; + COMP_OPAM_DAC -> DAC_SWTRIGR |= SWTRIGR2; + } + } +} +/** + * @brief Disables DAC and stop conversion of channel. + * the configuration information for the specified DAC. + * @param Channel The selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_CHANNEL_1: DAC Channel1 selected + * @arg DAC_CHANNEL_2: DAC Channel2 selected + * @arg DAC_CHANNEL_D12:DAC1 and DAC2 selected + * @retval + */ +void DAC_STOP(uint32_t DAC_1_2_Selection) +{ + /* Check the parameters */ + assert_param(IS_DAC_1_2_PERIPH(DAC_1_2_Selection)); + + if (DAC_1_2_Selection == DAC_CHANNEL_1) + { + /* disable the Peripheral */ + COMP_OPAM_DAC -> DAC_CR &= ~EN1; + } + else if (DAC_1_2_Selection == DAC_CHANNEL_2) + { + /* disable the Peripheral */ + COMP_OPAM_DAC -> DAC_CR &= ~EN2; + } + else if (DAC_1_2_Selection == DAC_CHANNEL_D12) + { + /* disable the Peripheral */ + COMP_OPAM_DAC -> DAC_CR &= (~EN1 & ~EN2); + } +} + +/** + * @brief Set the specified data holding register value for DAC channel. + * @param DAC_1_2_Selection: The selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_CHANNEL_1: DAC Channel1 selected + * @arg DAC_CHANNEL_2: DAC Channel2 selected + * @arg DAC_CHANNEL_D12: DAC Channel2 selected + * @param Alignment: Specifies the data alignment. + * This parameter can be one of the following values: + * @arg DAC_ALIGN_8B_R: 8bit right data alignment selected + * @arg DAC_ALIGN_12B_L: 12bit left data alignment selected + * @arg DAC_ALIGN_12B_R: 12bit right data alignment selected + * @param Data :Data to be loaded in the selected data holding register. + * @retval + */ +void DAC_SetValue(uint32_t DAC_1_2_Selection, uint32_t Alignment, uint32_t Data) +{ + + /* Check the parameters */ + assert_param(IS_DAC_1_2_PERIPH(DAC_1_2_Selection)); + assert_param(IS_DAC_ALIGN(Alignment)); + + if (DAC_1_2_Selection == DAC_CHANNEL_1) //Data to DAC1 + { + if (Alignment == DAC_ALIGN_12B_R) //Data to DHR12R1 + { + COMP_OPAM_DAC -> DAC_DHR12R1 = Data; + } + else if (Alignment == DAC_ALIGN_12B_L) //Data to DHR12L1 + { + COMP_OPAM_DAC -> DAC_DHR12L1 = Data; + } + else if (Alignment == DAC_ALIGN_8B_R) //Data to DHR8R1 + { + COMP_OPAM_DAC -> DAC_DHR8R1 = Data; + } + } + else if (DAC_1_2_Selection == DAC_CHANNEL_2) //Data to DAC2 + { + if (Alignment == DAC_ALIGN_12B_R) //Data to DHR12R2 + { + COMP_OPAM_DAC -> DAC_DHR12R2 = Data; + } + else if (Alignment == DAC_ALIGN_12B_L) //Data to DHR12L2 + { + COMP_OPAM_DAC -> DAC_DHR12L2 = Data; + } + else if (Alignment == DAC_ALIGN_8B_R) //Data to DHR8R2 + { + COMP_OPAM_DAC -> DAC_DHR8R2 = Data; + } + } + else if (DAC_1_2_Selection == DAC_CHANNEL_D12) //Data to DAC double + { + if (Alignment == DAC_ALIGN_12B_R) //Data to DHR12RD + { + COMP_OPAM_DAC -> DAC_DHR12RD = Data; + } + else if (Alignment == DAC_ALIGN_12B_L) //Data to DHR12LD + { + COMP_OPAM_DAC -> DAC_DHR12LD = Data; + } + else if (Alignment == DAC_ALIGN_8B_R) //Data to DHR8RD + { + COMP_OPAM_DAC -> DAC_DHR8RD = Data; + } + } +} + + +/** + * @brief Return the last data output value of the selected DAC channel. + * @param DAC_1_2_Selection The selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_CHANNEL_1: DAC Channel1 selected + * @arg DAC_CHANNEL_2: DAC Channel2 selected + * @retval The selected DAC channel data output value. + */ +uint32_t DAC_GetValue(uint32_t DAC_1_2_Selection) +{ + uint32_t result ; + + /* Check the parameters */ + assert_param(IS_DAC_1_2_PERIPH(DAC_1_2_Selection)); + /*delay to read for wait DAC */ + Delay_read(); + + if (DAC_1_2_Selection == DAC_CHANNEL_1) + { + result = COMP_OPAM_DAC -> DAC_DOR1 ; + } + else if (DAC_1_2_Selection == DAC_CHANNEL_2) + { + result = COMP_OPAM_DAC -> DAC_DOR2 ; + } + /* Returns the DAC channel data output register value */ + return result; +} + + + + +/** + * @brief Enables DAC DMA mode and enable DMA under interrupt. + * @param DAC_1_2_Selection The selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_CHANNEL_1: DAC Channel1 selected + * @arg DAC_CHANNEL_2: DAC Channel2 selected + * @arg DAC_CHANNEL_D12:DAC1 and DAC2 selected + * @param NewState: new state of the DAC 's DMA interrupt. + * This parameter can be: ENABLE or DISABLE . + * @retval + */ +void DAC_Start_DMA(uint32_t DAC_1_2_Selection, FunctionalState NewState) +{ + assert_param(IS_DAC_1_2_PERIPH(DAC_1_2_Selection)); + + if (DAC_1_2_Selection == DAC_CHANNEL_1) + { + /* Enable the selected DAC channel1 DMA request */ + COMP_OPAM_DAC -> DAC_CR |= DMAEN1; + + if (NewState != DISABLE) + { + /* Enable the DAC DMA underrun interrupt */ + COMP_OPAM_DAC -> DAC_CR |= DMAUDRIE1; + } + else if (NewState == DISABLE) + { + /* Disable the DAC DMA underrun interrupt */ + COMP_OPAM_DAC -> DAC_CR &= ~DMAUDRIE1; + } + } + else if (DAC_1_2_Selection == DAC_CHANNEL_2) + { + /* Enable the selected DAC channel1 DMA request */ + COMP_OPAM_DAC -> DAC_CR |= DMAEN2; + /* Enable the DAC DMA underrun interrupt */ + if (NewState != DISABLE) + { + COMP_OPAM_DAC -> DAC_CR |= DMAUDRIE2; + } + else if (NewState == DISABLE) + { + /* Disable the DAC DMA underrun interrupt */ + COMP_OPAM_DAC -> DAC_CR &= ~DMAUDRIE2; + } + } + else if (DAC_1_2_Selection == DAC_CHANNEL_D12) + { + COMP_OPAM_DAC -> DAC_CR |= DMAEN1 | DMAEN2; + + if (NewState != DISABLE) + { + COMP_OPAM_DAC -> DAC_CR |= DMAUDRIE1 | DMAUDRIE2; + } + else if (NewState == DISABLE) + { + /* Disable the DAC DMA underrun interrupt */ + COMP_OPAM_DAC -> DAC_CR &= (~DMAUDRIE1) & (~DMAUDRIE2); + } + } +} + + +/** + * @brief Disable DAC DMA mode and disable DMA under interrupt. + * @param DAC_1_2_Selection The selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_CHANNEL_1: DAC Channel1 selected + * @arg DAC_CHANNEL_2: DAC Channel2 selected + * @arg DAC_CHANNEL_D12:DAC1 and DAC2 selected + * @retval + */ +void DAC_Stop_DMA(uint32_t DAC_1_2_Selection) +{ + assert_param(IS_DAC_1_2_PERIPH(DAC_1_2_Selection)); + + if (DAC_1_2_Selection == DAC_CHANNEL_1) + { + /* Disable the selected DAC channel1 DMA request */ + COMP_OPAM_DAC -> DAC_CR &= ~DMAEN1; + /* Disable the DAC DMA underrun interrupt */ + COMP_OPAM_DAC -> DAC_CR &= ~DMAUDRIE1; + } + else if (DAC_1_2_Selection == DAC_CHANNEL_2) + { + /* Disable the selected DAC channel1 DMA request */ + COMP_OPAM_DAC -> DAC_CR &= ~DMAEN2; + /* Disable the DAC DMA underrun interrupt */ + COMP_OPAM_DAC -> DAC_CR &= ~DMAUDRIE2; + } + else if (DAC_1_2_Selection == DAC_CHANNEL_D12) + { + /* Disable the selected DAC channel1 DMA request */ + COMP_OPAM_DAC -> DAC_CR &= ~DMAEN1 & ~DMAEN2; + /* Disable the DAC DMA underrun interrupt */ + COMP_OPAM_DAC -> DAC_CR &= (~DMAUDRIE1) & (~DMAUDRIE2); + } +} + + +/** + * @brief Enable or disable the selected DAC channel wave generation ,DAC_Init and DAC_Start used firstly. + * @param DAC_1_2_Selection The selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_CHANNEL_1: DAC Channel1 selected + * @arg DAC_CHANNEL_2: DAC Channel2 selected + * @arg DAC_CHANNEL_D12:DAC1 and DAC2 selected + * @param Amplitude Select max triangle amplitude. + * This parameter can be one of the following values: + * @arg DAC_TRIANGLEAMPLITUDE_1: Select max triangle amplitude of 1 + * @arg DAC_TRIANGLEAMPLITUDE_3: Select max triangle amplitude of 3 + * @arg DAC_TRIANGLEAMPLITUDE_7: Select max triangle amplitude of 7 + * @arg DAC_TRIANGLEAMPLITUDE_15: Select max triangle amplitude of 15 + * @arg DAC_TRIANGLEAMPLITUDE_31: Select max triangle amplitude of 31 + * @arg DAC_TRIANGLEAMPLITUDE_63: Select max triangle amplitude of 63 + * @arg DAC_TRIANGLEAMPLITUDE_127: Select max triangle amplitude of 127 + * @arg DAC_TRIANGLEAMPLITUDE_255: Select max triangle amplitude of 255 + * @arg DAC_TRIANGLEAMPLITUDE_511: Select max triangle amplitude of 511 + * @arg DAC_TRIANGLEAMPLITUDE_1023: Select max triangle amplitude of 1023 + * @arg DAC_TRIANGLEAMPLITUDE_2047: Select max triangle amplitude of 2047 + * @arg DAC_TRIANGLEAMPLITUDE_4095: Select max triangle amplitude of 4095 + * @retval + */ +void DAC_TriangleWaveGenerate(uint32_t DAC_1_2_Selection, uint32_t Amplitude) +{ + /* Check the parameters */ + assert_param(IS_DAC_1_2_PERIPH(DAC_1_2_Selection)); + assert_param(IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(Amplitude)); + + if (DAC_1_2_Selection == DAC_CHANNEL_1) + { + /* enable DAC1 triangle */ + COMP_OPAM_DAC -> DAC_CR |= WAVE1_1; + COMP_OPAM_DAC -> DAC_CR |= Amplitude; + } + else if (DAC_1_2_Selection == DAC_CHANNEL_2) + { + /* enable DAC2 triangle */ + COMP_OPAM_DAC -> DAC_CR |= WAVE2_1; + COMP_OPAM_DAC -> DAC_CR |= Amplitude << (DAC_1_2_Selection & 0x10UL); + } + else if (DAC_1_2_Selection == DAC_CHANNEL_D12) + { + /* enable DAC1 2 triangle */ + COMP_OPAM_DAC -> DAC_CR |= WAVE1_1 | WAVE2_1; + COMP_OPAM_DAC -> DAC_CR |= ((Amplitude << (DAC_CHANNEL_2 & 0x10UL)) | Amplitude); + } +} + + +/** + * @brief Enable or disable the selected DAC channel wave generation. + * @param DAC_1_2_Selection The selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_CHANNEL_1: DAC Channel1 selected + * @arg DAC_CHANNEL_2: DAC Channel2 selected + * @param Amplitude Unmask DAC channel LFSR for noise wave generation. + * This parameter can be one of the following values: + * @arg DAC_LFSRUNMASK_BIT0: Unmask DAC channel LFSR bit0 for noise wave generation + * @arg DAC_LFSRUNMASK_BITS1_0: Unmask DAC channel LFSR bit[1:0] for noise wave generation + * @arg DAC_LFSRUNMASK_BITS2_0: Unmask DAC channel LFSR bit[2:0] for noise wave generation + * @arg DAC_LFSRUNMASK_BITS3_0: Unmask DAC channel LFSR bit[3:0] for noise wave generation + * @arg DAC_LFSRUNMASK_BITS4_0: Unmask DAC channel LFSR bit[4:0] for noise wave generation + * @arg DAC_LFSRUNMASK_BITS5_0: Unmask DAC channel LFSR bit[5:0] for noise wave generation + * @arg DAC_LFSRUNMASK_BITS6_0: Unmask DAC channel LFSR bit[6:0] for noise wave generation + * @arg DAC_LFSRUNMASK_BITS7_0: Unmask DAC channel LFSR bit[7:0] for noise wave generation + * @arg DAC_LFSRUNMASK_BITS8_0: Unmask DAC channel LFSR bit[8:0] for noise wave generation + * @arg DAC_LFSRUNMASK_BITS9_0: Unmask DAC channel LFSR bit[9:0] for noise wave generation + * @arg DAC_LFSRUNMASK_BITS10_0: Unmask DAC channel LFSR bit[10:0] for noise wave generation + * @arg DAC_LFSRUNMASK_BITS11_0: Unmask DAC channel LFSR bit[11:0] for noise wave generation + * @retval + */ +void DAC_NoiseWaveGenerate(uint32_t DAC_1_2_Selection, uint32_t Amplitude) +{ + /* Check the parameters */ + assert_param(IS_DAC_1_2_PERIPH(DAC_1_2_Selection)); + assert_param(IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(Amplitude)); + + if (DAC_1_2_Selection == DAC_CHANNEL_1) + { + /* enable DAC1 noise wave */ + COMP_OPAM_DAC -> DAC_CR |= WAVE1_0; + COMP_OPAM_DAC -> DAC_CR |= Amplitude; + } + else if (DAC_1_2_Selection == DAC_CHANNEL_2) + { + /* enable DAC2 noise wave */ + COMP_OPAM_DAC -> DAC_CR |= WAVE2_0; + COMP_OPAM_DAC -> DAC_CR |= Amplitude << (DAC_1_2_Selection & 0x10UL); + } + else if (DAC_1_2_Selection == DAC_CHANNEL_D12) + { + /* enable DAC1 2 noise wave */ + COMP_OPAM_DAC -> DAC_CR |= WAVE1_0 | WAVE2_0; + COMP_OPAM_DAC -> DAC_CR |= ((Amplitude << (DAC_CHANNEL_2 & 0x10UL)) | Amplitude); + } +} + +/** + * @} + */ +void Delay_read(void) +{ + int m; + for (m = 0; m < 15; m++) + { + __ASM("nop"); + } +} +/** + * @} + */ + +/** +* @} +*/ + +/** + * @} + */ + +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_debug.c b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_debug.c new file mode 100644 index 00000000000..11ce7dc7fc4 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_debug.c @@ -0,0 +1,166 @@ +/** + ****************************************************************************** + * @file ft32f4xx_debug.c + * @author FMD AE + * @brief This file provides firmware functions to manage the following + * functionalities of the Debug MCU (DBGMCU) peripheral: + * + Device and Revision ID management + * + Peripherals Configuration + * @version V1.0.0 + * @data 2025-03-06 + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx_debug.h" + + +#define IDCODE_DEVID_MASK ((uint32_t)0x00000FFF) + + + +/** + * @brief Returns the device revision identifier. + * @param None + * @retval Device revision identifier + */ +uint32_t DBGMCU_GetREVID(void) +{ + return (DBGMCU->IDCODE >> 16); +} + +/** + * @brief Returns the device identifier. + * @param None + * @retval Device identifier + */ +uint32_t DBGMCU_GetDEVID(void) +{ + return (DBGMCU->IDCODE & IDCODE_DEVID_MASK); +} +/** + * @} + */ + +/** + * @brief Configures low power mode behavior when the MCU is in Debug mode. + * @param DBGMCU_Periph: specifies the low power mode. + * This parameter can be any combination of the following values: + * @arg DBGMCU_SLEEP: Keep debugger connection during SLEEP mode + * @arg DBGMCU_STOP: Keep debugger connection during STOP mode + * @arg DBGMCU_STANDBY: Keep debugger connection during STANDBY mode + * @param NewState: new state of the specified low power mode in Debug mode. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void DBGMCU_Config(uint32_t DBGMCU_Periph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_DBGMCU_PERIPH(DBGMCU_Periph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + DBGMCU->CR |= DBGMCU_Periph; + } + else + { + DBGMCU->CR &= ~DBGMCU_Periph; + } +} +/** + * @} + */ + +/** + * @brief Configures APB1 peripheral behavior when the MCU is in Debug mode. + * @param DBGMCU_Periph: specifies the APB1 peripheral. + * This parameter can be any combination of the following values: + * @arg DBGMCU_TIM2_STOP: TIM2 counter stopped when Core is halted + * @arg DBGMCU_TIM3_STOP: TIM3 counter stopped when Core is halted + * @arg DBGMCU_TIM4_STOP: TIM4 counter stopped when Core is halted + * @arg DBGMCU_TIM5_STOP: TIM5 counter stopped when Core is halted + * @arg DBGMCU_TIM6_STOP: TIM6 counter stopped when Core is halted + * @arg DBGMCU_TIM7_STOP: TIM7 counter stopped when Core is halted + * @arg DBGMCU_TIM12_STOP: TIM12 counter stopped when Core is halted + * @arg DBGMCU_TIM13_STOP: TIM13 counter stopped when Core is halted + * @arg DBGMCU_TIM14_STOP: TIM14 counter stopped when Core is halted + * @arg DBGMCU_RTC_STOP: RTC Calendar and Wakeup counter stopped + * when Core is halted. + * @arg DBGMCU_WWDG_STOP: Debug WWDG stopped when Core is halted + * @arg DBGMCU_IWDG_STOP: Debug IWDG stopped when Core is halted + * @arg DBGMCU_I2C1_SMBUS_TIMEOUT_STOP: I2C1 SMBUS timeout mode stopped + * when Core is halted + * @arg DBGMCU_I2C2_SMBUS_TIMEOUT_STOP: I2C2 SMBUS timeout mode stopped + * when Core is halted + * @arg DBGMCU_I2C3_SMBUS_TIMEOUT_STOP: I2C3 SMBUS timeout mode stopped + * when Core is halted + * @arg DBGMCU_CAN1_STOP: Debug CAN1 stopped when Core is halted + * @arg DBGMCU_CAN2_STOP: Debug CAN2 stopped when Core is halted + * @arg DBGMCU_CAN3_STOP: Debug CAN3 stopped when Core is halted + * @arg DBGMCU_CAN4_STOP: Debug CAN4 stopped when Core is halted + * @param NewState: new state of the specified APB1 peripheral in Debug mode. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void DBGMCU_APB1PeriphConfig(uint32_t DBGMCU_Periph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_DBGMCU_APB1PERIPH(DBGMCU_Periph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + DBGMCU->APB1FZ |= DBGMCU_Periph; + } + else + { + DBGMCU->APB1FZ &= ~DBGMCU_Periph; + } +} +/** + * @} + */ + +/** + * @brief Configures APB2 peripheral behavior when the MCU is in Debug mode. + * @param DBGMCU_Periph: specifies the APB2 peripheral. + * This parameter can be any combination of the following values: + * @arg DBGMCU_TIM1_STOP: TIM1 counter stopped when Core is halted + * @arg DBGMCU_TIM8_STOP: TIM8 counter stopped when Core is halted + * @arg DBGMCU_LPTIM_STOP: LPTIM counter stopped when Core is halted + * @arg DBGMCU_TIM9_STOP: TIM9 counter stopped when Core is halted + * @arg DBGMCU_TIM10_STOP: TIM10 counter stopped when Core is halted + * @arg DBGMCU_EPWM1_STOP: EPWM1 counter stopped when Core is halted + * @arg DBGMCU_EPWM2_STOP: EPWM2 counter stopped when Core is halted + * @arg DBGMCU_EPWM3_STOP: EPWM3 counter stopped when Core is halted + * @arg DBGMCU_EPWM4_STOP: EPWM4 counter stopped when Core is halted + * @param NewState: new state of the specified APB2 peripheral in Debug mode. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void DBGMCU_APB2PeriphConfig(uint32_t DBGMCU_Periph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_DBGMCU_APB2PERIPH(DBGMCU_Periph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + DBGMCU->APB2FZ |= DBGMCU_Periph; + } + else + { + DBGMCU->APB2FZ &= ~DBGMCU_Periph; + } +} + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_dma.c b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_dma.c new file mode 100644 index 00000000000..8e2904534c2 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_dma.c @@ -0,0 +1,732 @@ +/** + ****************************************************************************** + * @file ft32f4xx_dma.c + * @author FMD AE + * @brief This file provides firmware functions to manage the following + * functionalities of the Direct Memory Access controller (DMA): + * + Initialization and Configuration + * + Data Counter + * + Interrupts and flags management + * + Software Request + * @version V1.0.0 + * @data 2025-04-15 + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx_dma.h" +#include "ft32f4xx_rcc.h" +/** @defgroup DMA + * @brief DMA driver modules + * @{ + */ + + +/** + * @brief Initialize the DMA according to the specified + * parameters in the DMA_InitTypeDef and initialize the associated handle. + * @param DMAy_Channelx Where y can be 1 or 2 to select the DMA and x can be 0 to 7 + * for DMAy to select the DMA Channel. + * @retval None + */ +void DMA_Init(DMA_Channel_TypeDef* DMAy_Channelx, DMA_InitTypeDef* Init) +{ + uint32_t tmp_high = 0; + uint32_t tmp_low = 0; + + /* Check the parameters */ + assert_param(IS_DMA_ALL_INSTANCE(DMAy_Channelx)); + assert_param(IS_DMA_SRC_DST_MASTER_SEL(Init->SrcDstMasterSel)); + assert_param(IS_DMA_TRANS_TYPE_FLOW_CTL(Init->TransferTypeFlowCtl)); + assert_param(IS_DMA_SRC_BURST_TRANS_LENGTH(Init->SrcBurstTransferLength)); + assert_param(IS_DMA_DST_BURST_TRANS_LENGTH(Init->DstBurstTransferLength)); + assert_param(IS_DMA_SRC_ADDR_MODE(Init->SrcAddrMode)); + assert_param(IS_DMA_DST_ADDR_MODE(Init->DstAddrMode)); + assert_param(IS_DMA_SRC_TRANS_WIDTH(Init->SrcTransferWidth)); + assert_param(IS_DMA_DST_TRANS_WIDTH(Init->DstTransferWidth)); + assert_param(IS_DMA_DST_HW_IF(Init->DstHardwareInterface)); + assert_param(IS_DMA_SRC_HW_IF(Init->SrcHardwareInterface)); + assert_param(IS_FUNCTIONAL_STATE(Init->FIFOMode)); + assert_param(IS_FUNCTIONAL_STATE(Init->FlowCtlMode)); + assert_param(IS_FUNCTIONAL_STATE(Init->ReloadDst)); + assert_param(IS_FUNCTIONAL_STATE(Init->ReloadSrc)); + assert_param(IS_DMA_SRC_HS_IF_POL(Init->SrcHsIfPol)); + assert_param(IS_DMA_DST_HS_IF_POL(Init->DstHsIfPol)); + assert_param(IS_DMA_SRC_HS_SEL(Init->SrcHsSel)); + assert_param(IS_DMA_DST_HS_SEL(Init->DstHsSel)); + assert_param(IS_DMA_CHANNEL_POLARITY(Init->Polarity)); + assert_param(IS_DMA_DST_HANDSHAKE_INTERFACE_SEL(Init->DstHsIfPeriphSel)); + assert_param(IS_DMA_SRC_HANDSHAKE_INTERFACE_SEL(Init->SrcHsIfPeriphSel)); + + + /* Calculate the base address and channel index of the DMA */ + DMA_BaseAddressAndChannelIndex DMA = CalBaseAddressAndChannelIndex(DMAy_Channelx); + + /* Config DMA source address */ + DMAy_Channelx->SAR = (uint64_t)Init->SrcAddress; + + /* Config DMA destination address */ + DMAy_Channelx->DAR = (uint64_t)Init->DstAddress; + + + //tmp_high = (uint32_t)(DMAy_Channelx->CTL >> 32U); + //tmp_low = (uint32_t)(DMAy_Channelx->CTL); + + /* Prepare the DMA Channel configuration */ + tmp_high = (uint32_t)Init->BlockTransSize << 13U; + + tmp_low = ((uint32_t)Init->SrcDstMasterSel | Init->TransferTypeFlowCtl | + Init->SrcBurstTransferLength | Init->DstBurstTransferLength | + Init->SrcAddrMode | Init->DstAddrMode | + Init->SrcTransferWidth | Init->DstTransferWidth) ; + + /* Write to DMA Channel CTL register */ + DMAy_Channelx->CTL = (((uint64_t)tmp_high << 32UL) | (uint64_t)tmp_low); + + + //tmp_high = (uint32_t)(DMAy_Channelx->CFG >> 32U); + //tmp_low = (uint32_t)(DMAy_Channelx->CFG); + tmp_high = 0; + tmp_low = 0; + + /* Prepare the DMA Channel configuration */ + tmp_high |= ((uint32_t)(Init->DstHardwareInterface << 11U) | + (Init->SrcHardwareInterface << 7U)); + + if (Init->FIFOMode == ENABLE) + { + tmp_high |= (uint32_t)(DMA_CFG_FIFO_MODE >> 32U); + } + + if (Init->FlowCtlMode == ENABLE) + { + tmp_high |= (uint32_t)(DMA_CFG_FCMODE >> 32U); + } + + tmp_low |= ((uint32_t)(Init->MaxBurstLength << 20U) | + (Init->SrcHsIfPol << 19U) | + (Init->DstHsIfPol << 18U) | + (Init->SrcHsSel << 11U) | + (Init->DstHsSel << 10U) | + (Init->Polarity << 5U)); + + if (Init->ReloadDst == ENABLE) + { + tmp_low |= (uint32_t)DMA_CFG_RELOAD_DST; + } + + if (Init->ReloadSrc == ENABLE) + { + tmp_low |= (uint32_t)DMA_CFG_RELOAD_SRC; + } + + /* Write to DMA Channel CFG register */ + DMAy_Channelx->CFG = (((uint64_t)tmp_high << 32UL) | (uint64_t)tmp_low); + + + /* Select peripheral request for the handshake interface */ + DMA.BaseAddress->CHSEL |= (uint64_t)((Init->DstHsIfPeriphSel << (Init->DstHardwareInterface * 3UL)) | + (Init->SrcHsIfPeriphSel << (Init->SrcHardwareInterface * 3UL))); +} + + +/** + * @brief Fills each DMA_StructInit member with its default value. + * @param DMA_StructInit: pointer to a DMA_InitTypeDef structure + * which will be initialized. + * @retval None + */ +void DMA_StructInit(DMA_InitTypeDef* DMA_InitStruct) +{ + /*-------------- Reset DMA init structure parameters values ------------------*/ + /* Initialize the DMA source address */ + DMA_InitStruct->SrcAddress = 0U; + + /* Initialize the DMA destination address */ + DMA_InitStruct->DstAddress = 0U; + + /* Initialize the DMA block transfer size */ + DMA_InitStruct->BlockTransSize = 0U; + + /* Initialize the DMA source/destination master select */ + DMA_InitStruct->SrcDstMasterSel = DMA_SRCMASTER1_DSTMASTER1; + + /* Initialize the DMA transfer type and flow control */ + DMA_InitStruct->TransferTypeFlowCtl = DMA_TRANSFERTYPE_FLOWCTL_M2M_DMA; + + /* Initialize the DMA source burst transaction length */ + DMA_InitStruct->SrcBurstTransferLength = DMA_SRC_BURSTTRANSFERLENGTH_1; + + /* Initialize the DMA destination burst transaction length */ + DMA_InitStruct->DstBurstTransferLength = DMA_DST_BURSTTRANSFERLENGTH_1; + + /* Initialize the DMA source address increment */ + DMA_InitStruct->SrcAddrMode = DMA_SRC_ADDRMODE_INC; + + /* Initialize the DMA destination address increment */ + DMA_InitStruct->DstAddrMode = DMA_DST_ADDRMODE_INC; + + /* Initialize the DMA srouce transfer width */ + DMA_InitStruct->SrcTransferWidth = DMA_SRC_TRANSFERWIDTH_8BITS; + + /* Initialize the DMA destination transfer width */ + DMA_InitStruct->DstTransferWidth = DMA_DST_TRANSFERWIDTH_8BITS; + + + /* Initialize the DMA destination hardware interface */ + DMA_InitStruct->DstHardwareInterface = DMA_DST_HARDWARE_INTERFACE_0; + + /* Initialize the DMA source hardware interface */ + DMA_InitStruct->SrcHardwareInterface = DMA_SRC_HARDWARE_INTERFACE_0; + + /* Initialize the DMA FIFO mode */ + DMA_InitStruct->FIFOMode = DISABLE; + + /* Initialize the DMA flow control mode */ + DMA_InitStruct->FlowCtlMode = DISABLE; + + /* Initialize the DMA automatic destination reload */ + DMA_InitStruct->ReloadDst = DISABLE; + + /* Initialize the DMA automatic source reload */ + DMA_InitStruct->ReloadSrc = DISABLE; + + /* Initialize the DMA maximum AMBA burst length */ + DMA_InitStruct->MaxBurstLength = 0U; + + /* Initialize the DMA source handshaking interface polarity */ + DMA_InitStruct->SrcHsIfPol = DMA_SRCHSIFPOL_HIGH; + + /* Initialize the DMA destination handshaking interface polarity */ + DMA_InitStruct->DstHsIfPol = DMA_DSTHSIFPOL_HIGH; + + /* Initialize the DMA source software or handware handshaking */ + DMA_InitStruct->SrcHsSel = DMA_SRCHSSEL_HARDWARE; + + /* Initialize the DMA destination software or handware handshaking */ + DMA_InitStruct->DstHsSel = DMA_DSTHSSEL_HARDWARE; + + /* Initialize the DMA channel polarity */ + DMA_InitStruct->Polarity = DMA_CH_POLARITY_0; + + /* Initialize the destination peripheral request */ + DMA_InitStruct->DstHsIfPeriphSel = DMA_DST_HANDSHAKE_INTERFACE_SEL_0; + + /* Initialize the source peripheral request */ + DMA_InitStruct->SrcHsIfPeriphSel = DMA_SRC_HANDSHAKE_INTERFACE_SEL_0; + +} + + +/** + * @brief DeInitialize the DMA peripheral. + * @param DMAy_Channelx Where y can be 1 or 2 to select the DMA and x can be 0 to 7 + * for DMAy to select the DMA Channel. + * @retval None + */ +void DMA_DeInit(DMA_Channel_TypeDef* DMAy_Channelx) +{ + /* Check the parameters */ + assert_param(IS_DMA_ALL_INSTANCE(DMAy_Channelx)); + + + /* Calculate the base address and channel index of the DMA */ + DMA_BaseAddressAndChannelIndex DMA = CalBaseAddressAndChannelIndex(DMAy_Channelx); + + + if (DMA.BaseAddress == DMA1) + { + /* Enable DMA1 reset state */ + RCC_AHB1PeriphResetCmd(RCC_AHB1PeriphRst_DMA1, ENABLE); + + /* Release DMA1 from reset state */ + RCC_AHB1PeriphResetCmd(RCC_AHB1PeriphRst_DMA1, DISABLE); + } + else if (DMA.BaseAddress == DMA2) + { + /* Enable DMA2 reset state */ + RCC_AHB1PeriphResetCmd(RCC_AHB1PeriphRst_DMA2, ENABLE); + + /* Release DMA2 from reset state */ + RCC_AHB1PeriphResetCmd(RCC_AHB1PeriphRst_DMA2, DISABLE); + } + +} + + +/** + * @brief Return the DMA base address and channel index depending on DMAy_Channelx. + * @param DMAy_Channelx Where y can be 1 or 2 to select the DMA and x can be 0 to 7 + * for DMAy to select the DMA Channel. + * @retval DMA base address and channel index. + */ +DMA_BaseAddressAndChannelIndex CalBaseAddressAndChannelIndex(DMA_Channel_TypeDef* DMAy_Channelx) +{ + DMA_BaseAddressAndChannelIndex DMA; + + /* Compute the channel index */ + if ((uint32_t)(DMAy_Channelx) < (uint32_t)(DMA2_Channel0)) + { + /* DMA1 */ + DMA.ChannelIndex = (((uint32_t)DMAy_Channelx - (uint32_t)DMA1_Channel0) / ((uint32_t)DMA1_Channel2 - (uint32_t)DMA1_Channel1)); + DMA.BaseAddress = DMA1; + } + else + { + /* DMA2 */ + DMA.ChannelIndex = (((uint32_t)DMAy_Channelx - (uint32_t)DMA2_Channel0) / ((uint32_t)DMA2_Channel2 - (uint32_t)DMA2_Channel1)); + DMA.BaseAddress = DMA2; + } + + return DMA; +} + + +/** + * @brief Enables or disables the specified DMAy Channelx. + * @param DMAy_Channelx Where y can be 1 or 2 to select the DMA and x can be 0 to 7 + * for DMAy to select the DMA Channel. + * @param NewState New state of the DMAy Channelx. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void DMA_Cmd(DMA_Channel_TypeDef* DMAy_Channelx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_DMA_ALL_INSTANCE(DMAy_Channelx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + /* Calculate the base address and channel index of the DMA */ + DMA_BaseAddressAndChannelIndex DMA = CalBaseAddressAndChannelIndex(DMAy_Channelx); + + if (NewState != DISABLE) + { + /* Enable the Peripheral */ + DMA_ENABLE(DMA.BaseAddress); + /* Enable the DMA Channel */ + DMA_Channel_Cmd(DMAy_Channelx, ENABLE); + } + else + { + /* Disable the DMA Channel */ + DMA_Channel_Cmd(DMAy_Channelx, DISABLE); + /* Disable the Peripheral */ + DMA_DISABLE(DMA.BaseAddress); + } + +} + + +/** + * @brief Returns the number of data units transferred by the current DMAy Channelx. + * @param DMAy_Channelx Where y can be 1 or 2 to select the DMA and x can be 0 to 7 + * for DMAy to select the DMA Channel. + * @retval The number of data units transferred by the current DMAy Channelx. + */ +uint16_t DMA_GetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx) +{ + /* Check the parameters */ + assert_param(IS_DMA_ALL_INSTANCE(DMAy_Channelx)); + + /* Return the number of remaining data units for DMAy Channelx */ + return ((uint16_t)((DMAy_Channelx->CTL) >> 45U)); +} + + +/** + * @brief Enable the specified DMA Channel interrupts. + * @param DMAy_Channelx Where y can be 1 or 2 to select the DMA and x can be 0 to 7 + * for DMAy to select the DMA Channel. + * @param DMA_IT specifies the DMA interrupt sources to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg DMA_IT_TFR Transfer complete interrupt mask + * @arg DMA_IT_BLOCK Block transfer complete interrupt mask + * @arg DMA_IT_SRC Source transfer complete interrupt mask + * @arg DMA_IT_DST Destination transfer complete interrupt mask + * @arg DMA_IT_ERR Transfer error interrupt mask + * @retval None + */ +void DMA_ITConfig(DMA_Channel_TypeDef* DMAy_Channelx, uint8_t DMA_IT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_DMA_ALL_INSTANCE(DMAy_Channelx)); + assert_param(IS_DMA_IT(DMA_IT)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + + /* Calculate the base address and channel index of the DMA */ + DMA_BaseAddressAndChannelIndex DMA = CalBaseAddressAndChannelIndex(DMAy_Channelx); + + /* Config channel interrupt mask */ + const uint32_t ch_mask = (1U << (DMA.ChannelIndex)); + const uint32_t ch_en_mask = (0x100U << (DMA.ChannelIndex)); + + /* Config channelx transfer complete interrupt */ + if ((DMA_IT & DMA_IT_TFR) != 0U) + { + (NewState) ? (DMA.BaseAddress->MASKTFR |= (ch_en_mask | ch_mask)) + : (DMA.BaseAddress->MASKTFR &= (ch_en_mask | (~ch_mask))); + } + + /* Config channelx block transfer complete interrupt */ + if ((DMA_IT & DMA_IT_BLOCK) != 0U) + { + (NewState) ? (DMA.BaseAddress->MASKBLOCK |= (ch_en_mask | ch_mask)) + : (DMA.BaseAddress->MASKBLOCK &= (ch_en_mask | (~ch_mask))); + } + + /* Config channelx source transfer complete interrupt */ + if ((DMA_IT & DMA_IT_SRC) != 0U) + { + (NewState) ? (DMA.BaseAddress->MASKSRCTRAN |= (ch_en_mask | ch_mask)) + : (DMA.BaseAddress->MASKSRCTRAN &= (ch_en_mask | (~ch_mask))); + } + + /* Config channelx destination transfer complete interrupt */ + if ((DMA_IT & DMA_IT_DST) != 0U) + { + (NewState) ? (DMA.BaseAddress->MASKDSTTRAN |= (ch_en_mask | ch_mask)) + : (DMA.BaseAddress->MASKDSTTRAN &= (ch_en_mask | (~ch_mask))); + } + + /* Config channelx transfer error interrupt */ + if ((DMA_IT & DMA_IT_ERR) != 0U) + { + (NewState) ? (DMA.BaseAddress->MASKERR |= (ch_en_mask | ch_mask)) + : (DMA.BaseAddress->MASKERR &= (ch_en_mask | (~ch_mask))); + } + + /* Config global interrupt */ + const uint8_t int_en_bit = 0x01; //CTL[0] + if (NewState == ENABLE) + { + /* Enable global interrupt */ + DMAy_Channelx->CTL |= (uint64_t)int_en_bit; + } + else + { + // Check all interrupts are disabled. + if (!(DMA.BaseAddress->MASKTFR & ch_mask) && + !(DMA.BaseAddress->MASKBLOCK & ch_mask) && + !(DMA.BaseAddress->MASKSRCTRAN & ch_mask) && + !(DMA.BaseAddress->MASKDSTTRAN & ch_mask) && + !(DMA.BaseAddress->MASKERR & ch_mask)) + { + /* Disable global interrupt */ + DMAy_Channelx->CTL &= ~(uint64_t)int_en_bit; + } + } +} + + +/** + * @brief Clears the DMA interrupt flags. + * @param DMAy_Channelx Where y can be 1 or 2 to select the DMA and x can be 0 to 7 + * for DMAy to select the DMA Channel. + * @param DMA_IT specifies DMA interrupt flag to clear. + * This parameter can be one of the following values: + * @arg DMA_IT_TFR Transfer complete flag. + * @arg DMA_IT_BLOCK Block transfer complete flag. + * @arg DMA_IT_SRC Source transfer complete flag. + * @arg DMA_IT_DST Destination transfer complete flag. + * @arg DMA_IT_ERR Transfer error flag. + * @retval None + */ +void DMA_ClearFlagStatus(DMA_Channel_TypeDef* DMAy_Channelx, uint8_t DMA_IT) +{ + /* Check the parameters */ + assert_param(IS_DMA_ALL_INSTANCE(DMAy_Channelx)); + assert_param(IS_DMA_IT(DMA_IT)); + + + /* Calculate the base address and channel index of the DMA */ + DMA_BaseAddressAndChannelIndex DMA = CalBaseAddressAndChannelIndex(DMAy_Channelx); + + /* Config channel mask */ + const uint32_t ch_mask = (1U << (DMA.ChannelIndex)); + + /* Clear channelx transfer complete interrupt */ + if ((DMA_IT & DMA_IT_TFR) != 0U) + { + DMA.BaseAddress->CLEARTFR = ch_mask; + } + /* Clear channelx block transfer complete interrupt */ + if ((DMA_IT & DMA_IT_BLOCK) != 0U) + { + DMA.BaseAddress->CLEARBLOCK = ch_mask; + } + /* Clear channelx source transfer complete interrupt */ + if ((DMA_IT & DMA_IT_SRC) != 0U) + { + DMA.BaseAddress->CLEARSRCTRAN = ch_mask; + } + /* Clear channelx destination transfer complete interrupt */ + if ((DMA_IT & DMA_IT_DST) != 0U) + { + DMA.BaseAddress->CLEARDSTTRAN = ch_mask; + } + /* Clear channelx transfer error interrupt */ + if ((DMA_IT & DMA_IT_ERR) != 0U) + { + DMA.BaseAddress->CLEARERR = ch_mask; + } +} + + +/** + * @brief Checks whether the specified DMAy Channelx interrupt has occurred or not. + * @param DMAy_Channelx Where y can be 1 or 2 to select the DMA and x can be 0 to 7 + * for DMAy to select the DMA Channel. + * @param DMA_IT specifies the DMA interrupt source to check + * This parameter can be one of the following values: + * @arg DMA_IT_TFR Transfer complete interrupt. + * @arg DMA_IT_BLOCK Block transfer complete interrupt. + * @arg DMA_IT_SRC Source transfer complete interrupt. + * @arg DMA_IT_DST Destination transfer complete interrupt. + * @arg DMA_IT_ERR Transfer error interrupt. + * @retval The new state of DMA_IT (SET or RESET). + */ +ITStatus DMA_GetITStatus(DMA_Channel_TypeDef* DMAy_Channelx, uint8_t DMA_IT) +{ + /* Check the parameters */ + assert_param(IS_DMA_ALL_INSTANCE(DMAy_Channelx)); + assert_param(IS_DMA_IT(DMA_IT)); + + ITStatus bitstatus = RESET; + uint32_t tmpreg = 0; + + /* Calculate the base address and channel index of the DMA */ + DMA_BaseAddressAndChannelIndex DMA = CalBaseAddressAndChannelIndex(DMAy_Channelx); + + /* Config channel mask */ + const uint32_t ch_mask = (1U << (DMA.ChannelIndex)); + + /* Get DMA IT Status register value */ + /* Get channelx transfer complete interrupt status */ + if ((DMA_IT & DMA_IT_TFR) != 0U) + { + tmpreg = DMA.BaseAddress->STATUSTFR; + } + + /* Get channelx block transfer complete interrupt status */ + if ((DMA_IT & DMA_IT_BLOCK) != 0U) + { + tmpreg = DMA.BaseAddress->STATUSBLOCK; + } + + /* Get channelx source transfer complete interrupt status */ + if ((DMA_IT & DMA_IT_SRC) != 0U) + { + tmpreg = DMA.BaseAddress->STATUSSRCTRAN; + } + + /* Get channelx destination transfer complete interrupt status */ + if ((DMA_IT & DMA_IT_DST) != 0U) + { + tmpreg = DMA.BaseAddress->STATUSDSTTRAN; + } + + /* Get channelx transfer error interrupt status */ + if ((DMA_IT & DMA_IT_ERR) != 0U) + { + tmpreg = DMA.BaseAddress->STATUSERR; + } + + /* Check the status of the specified DMAy interrupt */ + if ((tmpreg & ch_mask) != (uint32_t)RESET) + { + /* DMA_IT is set */ + bitstatus = SET; + } + else + { + /* DMA_IT is reset */ + bitstatus = RESET; + } + /* Return the DMA_IT status */ + return bitstatus; +} + + +/** + * @brief Checks whether the specified DMAy Channelx flag has occurred or not. + * @param DMAy_Channelx Where y can be 1 or 2 to select the DMA and x can be 0 to 7 + * for DMAy to select the DMA Channel. + * @param DMA_FLAG specifies the DMA flag to check + * This parameter can be one of the following values: + * @arg DMA_IT_TFR Transfer complete flag. + * @arg DMA_IT_BLOCK Block transfer complete flag. + * @arg DMA_IT_SRC Source transfer complete flag. + * @arg DMA_IT_DST Destination transfer complete flag. + * @arg DMA_IT_ERR Transfer error flag. + * @retval The new state of DMA_FLAG (SET or RESET). + */ +FlagStatus DMA_GetFlagStatus(DMA_Channel_TypeDef* DMAy_Channelx, uint8_t DMA_FLAG) +{ + /* Check the parameters */ + assert_param(IS_DMA_ALL_INSTANCE(DMAy_Channelx)); + assert_param(IS_DMA_FLAG(DMA_FLAG)); + + FlagStatus bitstatus = RESET; + uint32_t tmpreg = 0; + + /* Calculate the base address and channel index of the DMA */ + DMA_BaseAddressAndChannelIndex DMA = CalBaseAddressAndChannelIndex(DMAy_Channelx); + + /* Config channel mask */ + const uint32_t ch_mask = (1U << (DMA.ChannelIndex)); + + /* Get DMA IT Status register value */ + /* Get channelx transfer complete interrupt status */ + if ((DMA_FLAG & DMA_FLAG_TFR) != 0U) + { + tmpreg = DMA.BaseAddress->RAWTFR; + } + + /* Get channelx block transfer complete interrupt status */ + if ((DMA_FLAG & DMA_FLAG_BLOCK) != 0U) + { + tmpreg = DMA.BaseAddress->RAWBLOCK; + } + + /* Get channelx source transfer complete interrupt status */ + if ((DMA_FLAG & DMA_FLAG_SRC) != 0U) + { + tmpreg = DMA.BaseAddress->RAWSRCTRAN; + } + + /* Get channelx destination transfer complete interrupt status */ + if ((DMA_FLAG & DMA_FLAG_DST) != 0U) + { + tmpreg = DMA.BaseAddress->RAWDSTTRAN; + } + + /* Get channelx transfer error interrupt status */ + if ((DMA_FLAG & DMA_FLAG_ERR) != 0U) + { + tmpreg = DMA.BaseAddress->RAWERR; + } + + /* Check the status of the specified DMAy interrupt */ + if ((tmpreg & ch_mask) != (uint32_t)RESET) + { + /* DMA_FLAG is set */ + bitstatus = SET; + } + else + { + /* DMA_FLAG is reset */ + bitstatus = RESET; + } + /* Return the DMA_FLAG status */ + return bitstatus; +} + + +/** + * @brief Enable or disable the specified DMA Channel. + * @param DMAy_Channelx Where y can be 1 or 2 to select the DMA and x can be 0 to 7 + * for DMAy to select the DMA Channel. + * @param NewState new state of the specified DMA Channel. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void DMA_Channel_Cmd(DMA_Channel_TypeDef* DMAy_Channelx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_DMA_ALL_INSTANCE(DMAy_Channelx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + + /* Calculate the base address and channel index of the DMA */ + DMA_BaseAddressAndChannelIndex DMA = CalBaseAddressAndChannelIndex(DMAy_Channelx); + + /* Config channel mask */ + const uint32_t ch_mask = (1U << (DMA.ChannelIndex)); + const uint32_t ch_en_mask = (0x100U << (DMA.ChannelIndex)); + + if (NewState != DISABLE) + { + DMA.BaseAddress->CHEN |= (ch_en_mask | ch_mask); + DMA.BaseAddress->CHEN &= ~ch_en_mask; + } + else + { + DMA.BaseAddress->CHEN |= ch_en_mask; + DMA.BaseAddress->CHEN &= ~ch_mask; + DMA.BaseAddress->CHEN &= ~ch_en_mask; + } +} + + +/** + * @brief Sets software request. + * @param DMAy_Channelx Where y can be 1 or 2 to select the DMA and x can be 0 to 7 + * for DMAy to select the DMA Channel. + * @param SoftwareRequest The specified software request. + * This parameter can be one of the following values: + * DMA_SW_REQUEST_SRC DMA source software transaction request + * DMA_SW_REQUEST_DST DMA destination software transaction request + * DMA_SW_REQUEST_SRC_SGL DMA source single transaction request + * DMA_SW_REQUEST_DST_SGL DMA destination single transaction request + * DMA_SW_REQUEST_SRC_LST DMA source last transaction request + * DMA_SW_REQUEST_DST_LST DMA destination last transaction request + * @retval None + */ +void DMA_SoftWare_Request(DMA_Channel_TypeDef* DMAy_Channelx, DMA_SoftwareRequestTypeDef SoftwareRequest) +{ + /* Check the parameters */ + assert_param(IS_DMA_ALL_INSTANCE(DMAy_Channelx)); + assert_param(IS_DMA_SOFTWARE_REQUEST(SoftwareRequest)); + + + /* Calculate the base address and channel index of the DMA */ + DMA_BaseAddressAndChannelIndex DMA = CalBaseAddressAndChannelIndex(DMAy_Channelx); + + /* Config channel mask */ + const uint32_t ch_mask = (1U << (DMA.ChannelIndex)); + const uint32_t ch_en_mask = (0x100U << (DMA.ChannelIndex)); + + /* Config the source software transaction request */ + if (SoftwareRequest == DMA_SW_REQUEST_SRC) + { + DMA.BaseAddress->REQSRC |= (ch_en_mask | ch_mask); + } + + /* Config the destination software transaction request */ + if (SoftwareRequest == DMA_SW_REQUEST_DST) + { + DMA.BaseAddress->REQDST |= (ch_en_mask | ch_mask); + } + + /* Config the source single transaction request */ + if (SoftwareRequest == DMA_SW_REQUEST_SRC_SGL) + { + DMA.BaseAddress->SGLRQSRC |= (ch_en_mask | ch_mask); + } + + /* Config the destination single transaction request */ + if (SoftwareRequest == DMA_SW_REQUEST_DST_SGL) + { + DMA.BaseAddress->SGLRQDST |= (ch_en_mask | ch_mask); + } + + /* Config the source last transaction request */ + if (SoftwareRequest == DMA_SW_REQUEST_SRC_LST) + { + DMA.BaseAddress->LSTSRC |= (ch_en_mask | ch_mask); + } + + /* Config the destination last transaction request */ + if (SoftwareRequest == DMA_SW_REQUEST_DST_LST) + { + DMA.BaseAddress->LSTDST |= (ch_en_mask | ch_mask); + } +} + + +/** + * @} + */ + +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_ecap.c b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_ecap.c new file mode 100644 index 00000000000..84474a81b30 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_ecap.c @@ -0,0 +1,549 @@ +/** + ****************************************************************************** + * @file ft32f4xx_ecap.c + * @author FMD AE + * @brief This file provides firmware functions to manage the following + * functionalities of the Enhanced Capture (ECAP): + * + Initialization and Configuration + * + ECAP control + * + Data register access + * + Interrupts and flags management + * @version V1.0.0 + * @data 2025-04-22 + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx_ecap.h" +#include "ft32f4xx_rcc.h" + + +/** @defgroup ECAP + * @brief ECAP driver modules + * @{ + */ + + +/** + * @brief Initialize the ECAP according to the specified parameters in the + * ECAP_InitTypeDef and initialize the associated handle. + * @param ECAP_InitStruct pointer to a ECAP_InitTypeDef structure that contains the + * configuration information for the specified ECAP peripheral. + * @retval None + */ +void ECAP_Init(ECAP_InitTypeDef* ECAP_InitStruct) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_ECAP_MODE(ECAP_InitStruct->ECAPMode)); + assert_param(IS_ECAP_EVENT_PRESCALER(ECAP_InitStruct->EventPrescaler)); + assert_param(IS_FUNCTIONAL_STATE(ECAP_InitStruct->CaptureLoad)); + assert_param(IS_FUNCTIONAL_STATE(ECAP_InitStruct->CaptureEvent4Reset)); + assert_param(IS_FUNCTIONAL_STATE(ECAP_InitStruct->CaptureEvent3Reset)); + assert_param(IS_FUNCTIONAL_STATE(ECAP_InitStruct->CaptureEvent2Reset)); + assert_param(IS_FUNCTIONAL_STATE(ECAP_InitStruct->CaptureEvent1Reset)); + assert_param(IS_ECAP_EVENT_POLARITY(ECAP_InitStruct->CaptureEvent4Polarity)); + assert_param(IS_ECAP_EVENT_POLARITY(ECAP_InitStruct->CaptureEvent3Polarity)); + assert_param(IS_ECAP_EVENT_POLARITY(ECAP_InitStruct->CaptureEvent2Polarity)); + assert_param(IS_ECAP_EVENT_POLARITY(ECAP_InitStruct->CaptureEvent1Polarity)); + assert_param(IS_ECAP_APWM_POLARITY(ECAP_InitStruct->APWMPolarity)); + assert_param(IS_FUNCTIONAL_STATE(ECAP_InitStruct->CounterSyncIn)); + assert_param(IS_ECAP_MOD_COUNTER_STOP_WRAP(ECAP_InitStruct->ModCounterStopWrap)); + assert_param(IS_ECAP_MOD_COUNTER_MODE(ECAP_InitStruct->ModCounterMode)); + assert_param(IS_ECAP_COUNTER_VALUE(ECAP_InitStruct->CounterValue)); + assert_param(IS_ECAP_COUNTER_PHASE_VALUE(ECAP_InitStruct->CounterPhaseValue)); + assert_param(IS_ECAP_CAPTURE1_REGISTER_VALUE(ECAP_InitStruct->Capture1RegisterValue)); + assert_param(IS_ECAP_CAPTURE2_REGISTER_VALUE(ECAP_InitStruct->Capture2RegisterValue)); + + /* Config ECAP capture control1 */ + tmpreg = ((uint32_t)(ECAP_InitStruct->EventPrescaler << 9U) | + (ECAP_InitStruct->CaptureEvent4Polarity << 6U) | + (ECAP_InitStruct->CaptureEvent3Polarity << 4U) | + (ECAP_InitStruct->CaptureEvent2Polarity << 2U) | + (ECAP_InitStruct->CaptureEvent1Polarity << 0U)); + + if (ECAP_InitStruct->CaptureLoad == ENABLE) + { + tmpreg |= (uint32_t)ECAP_ECCTL1_CAPLDEN; + } + + if (ECAP_InitStruct->CaptureEvent4Reset == ENABLE) + { + tmpreg |= (uint32_t)ECAP_ECCTL1_CTRRST4; + } + + if (ECAP_InitStruct->CaptureEvent3Reset == ENABLE) + { + tmpreg |= (uint32_t)ECAP_ECCTL1_CTRRST3; + } + + if (ECAP_InitStruct->CaptureEvent2Reset == ENABLE) + { + tmpreg |= (uint32_t)ECAP_ECCTL1_CTRRST2; + } + + if (ECAP_InitStruct->CaptureEvent1Reset == ENABLE) + { + tmpreg |= (uint32_t)ECAP_ECCTL1_CTRRST1; + } + + /* Write to ECAP ECCTL1 */ + ECAP->ECCTL1 = tmpreg; + + + tmpreg = 0; + + /* Config ECAP capture control2 */ + tmpreg = ((uint32_t)(ECAP_InitStruct->ECAPMode) | + (ECAP_InitStruct->ModCounterStopWrap) | + (ECAP_InitStruct->ModCounterMode)); + + //tmpreg &= (uint32_t)~ECAP_ECCTL2_STOP_WRAP; + //tmpreg |= (uint32_t)(ECAP_InitStruct->ModCounterStopWrap); + + if (ECAP_InitStruct->CounterSyncIn == ENABLE) + { + tmpreg |= (uint32_t)ECAP_ECCTL2_SYNCI_EN; + } + + /* Config ECAP APWM mode */ + if (ECAP_InitStruct->ECAPMode == ECAP_MODE_APWM) + { + /* Config APWM output polarity */ + tmpreg |= ((uint32_t)(ECAP_InitStruct->APWMPolarity)); + + /* Config ECAP counter value */ + ECAP->TSCTR = ECAP_InitStruct->CounterValue; + + /* Config ECAP counter phase value */ + ECAP->CTRPHS = ECAP_InitStruct->CounterPhaseValue; + + /* Config ECAP capture 1 register value */ + ECAP->CAP1 = ECAP_InitStruct->Capture1RegisterValue; + + /* Config ECAP capture 2 register value */ + ECAP->CAP2 = ECAP_InitStruct->Capture2RegisterValue; + } + + /* Write to ECAP ECCTL2 */ + ECAP->ECCTL2 = tmpreg; + +} + + +/** + * @brief Fills each ECAP_StructInit member with its default value. + * @param ECAP_StructInit pointer to a ECAP_InitTypeDef structure + * which will be initialized. + * @retval None + */ +void ECAP_StructInit(ECAP_InitTypeDef* ECAP_InitStruct) +{ + /*-------------- Reset ECAP init structure parameters values ------------------*/ + /* Initialize the ECAP mode */ + ECAP_InitStruct->ECAPMode = 0U; + + /* Initialize the prescaler of event filter */ + ECAP_InitStruct->EventPrescaler = 0U; + + /* Initialize the enable loading of CAP1-4 registers on a capture event */ + ECAP_InitStruct->CaptureLoad = DISABLE; + + /* Initialize the counter reset on capture event 4 */ + ECAP_InitStruct->CaptureEvent4Reset = DISABLE; + + /* Initialize the counter reset on capture event 3 */ + ECAP_InitStruct->CaptureEvent3Reset = DISABLE; + + /* Initialize the counter reset on capture event 2 */ + ECAP_InitStruct->CaptureEvent2Reset = DISABLE; + + /* Initialize the counter reset on capture event 1 */ + ECAP_InitStruct->CaptureEvent1Reset = DISABLE; + + /* Initialize the polarity of capture event 4 */ + ECAP_InitStruct->CaptureEvent4Polarity = ECAP_EVENT_POLARITY_RE; + + /* Initialize the polarity of capture event 3 */ + ECAP_InitStruct->CaptureEvent3Polarity = ECAP_EVENT_POLARITY_RE; + + /* Initialize the polarity of capture event 2 */ + ECAP_InitStruct->CaptureEvent2Polarity = ECAP_EVENT_POLARITY_RE; + + /* Initialize the polarity of capture event 1 */ + ECAP_InitStruct->CaptureEvent1Polarity = ECAP_EVENT_POLARITY_RE; + + /* Initialize the polarity of the APWM output */ + ECAP_InitStruct->APWMPolarity = 0U; + + /* Initialize the counter Sync-In */ + ECAP_InitStruct->CounterSyncIn = DISABLE; + + /* Initialize the stop/wrap value of Mod counter */ + ECAP_InitStruct->ModCounterStopWrap = ECAP_STOP_WRAP_EVENT1; + + /* Initialize the mode of Mod counter to continuous mode */ + ECAP_InitStruct->ModCounterMode = ECAP_MOD_COUNTER_CONT; + + /* Initialize the phase value of counter */ + ECAP_InitStruct->CounterPhaseValue = 0U; +} + + +/** + * @brief DeInitialize the ECAP peripheral. + * @retval None + */ +void ECAP_DeInit() +{ + + /* Enable ECAP reset state */ + RCC_APB2PeriphResetCmd(RCC_APB2PeriphRst_ECAP, ENABLE); + + /* Release ECAP from reset state */ + RCC_APB2PeriphResetCmd(RCC_APB2PeriphRst_ECAP, DISABLE); + +} + + +/** + * @brief Enables or disables the ECAP counter(TSCTR). + * @param NewState New state of the ECAP counter. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void ECAP_Cmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the ECAP, TSCTR free-running */ + ECAP->ECCTL2 |= (uint32_t)ECAP_ECCTL2_TSCTRSTOP; + } + else + { + /* Disable the ECAP, TSCRT stopped */ + ECAP->ECCTL2 &= (uint32_t)(~ECAP_ECCTL2_TSCTRSTOP); + } +} + + +/** + * @brief Re-Ariming control. + * @Note The re-arm function is valid in one-shot or continuous mode. + * Write 0 : Has no effect; + * Write 1 : Arms the one-shot sequence as follows: + * +Resets the Mod4 counter to zero + * +Unfreezes the Mod4 counter + * +Enables capture register loads + * @retval None + */ +void ECAP_ReArm() +{ + uint32_t tmpreg = 0; + + /* Get the ECCTL2 value */ + tmpreg = ECAP->ECCTL2; + + /* Config the REARM bit of ECCTL2 */ + tmpreg |= (uint32_t)ECAP_ECCTL2_REARM; + + /* Write to ECCTL2 */ + ECAP->ECCTL2 = tmpreg; +} + + +/** + * @brief Software-forced counter(TSCTR) synchronizer. + * This provides the user a method to generate a synchronization pulse + * through software. + * Write 0 : Has no effect; + * Write 1 : Forces a TSCTR shadow load of current ECAP module. + * @retval None + */ +void ECAP_SoftwareForceSync() +{ + uint32_t tmpreg = 0; + + /* Get the ECCTL2 value */ + tmpreg = ECAP->ECCTL2; + + /* Force a TSCTR shadow load */ + tmpreg |= (uint32_t)ECAP_ECCTL2_SWSYNC; + + /* Write to ECCTL2 */ + ECAP->ECCTL2 = tmpreg; +} + + +/** + * @brief Write a value to the specified data register. + * @param ECAP_DATA_REG ECAP data registers. + * @arg ECAP_DATA_REG_TSCTR Counter register + * @arg ECAP_DATA_REG_CTRPHS Counter phase offset register + * @arg ECAP_DATA_REG_CAP1 Capture 1 register + * @arg ECAP_DATA_REG_CAP2 Capture 2 register + * @arg ECAP_DATA_REG_CAP3 Capture 3 register + * @arg ECAP_DATA_REG_CAP4 Capture 4 register + * @param Value The value of data register. + * @retval None + */ +void ECAP_WriteDataRegister(uint8_t ECAP_DATA_REG, uint32_t Value) +{ + /* Check the parameters */ + assert_param(IS_ECAP_DATA_REG(ECAP_DATA_REG)); + + if (ECAP_DATA_REG == ECAP_DATA_REG_TSCTR) + { + /* Write the value to TSCTR */ + ECAP->TSCTR = ((uint32_t)Value); + } + if (ECAP_DATA_REG == ECAP_DATA_REG_CTRPHS) + { + /* Write the value to CTRPHS */ + ECAP->CTRPHS = ((uint32_t)Value); + } + if (ECAP_DATA_REG == ECAP_DATA_REG_CAP1) + { + /* Write the value to CAP1 */ + ECAP->CAP1 = ((uint32_t)Value); + } + if (ECAP_DATA_REG == ECAP_DATA_REG_CAP2) + { + /* Write the value to CAP2 */ + ECAP->CAP2 = ((uint32_t)Value); + } + if (ECAP_DATA_REG == ECAP_DATA_REG_CAP3) + { + /* Write the value to CAP3 */ + ECAP->CAP3 = ((uint32_t)Value); + } + if (ECAP_DATA_REG == ECAP_DATA_REG_CAP4) + { + /* Write the value to CAP4 */ + ECAP->CAP4 = ((uint32_t)Value); + } +} + + +/** + * @brief Returns the value of data registers. + * @param ECAP_DATA_REG ECAP data registers. + * @arg ECAP_DATA_REG_TSCTR Counter register + * @arg ECAP_DATA_REG_CTRPHS Counter phase offset register + * @arg ECAP_DATA_REG_CAP1 Capture 1 register + * @arg ECAP_DATA_REG_CAP2 Capture 2 register + * @arg ECAP_DATA_REG_CAP3 Capture 3 register + * @arg ECAP_DATA_REG_CAP4 Capture 4 register + * @retval The value of data registers. + */ +uint32_t ECAP_GetDataRegister(uint8_t ECAP_DATA_REG) +{ + uint32_t tmpreg = 0; + /* Check the parameters */ + assert_param(IS_ECAP_DATA_REG(ECAP_DATA_REG)); + + if (ECAP_DATA_REG == ECAP_DATA_REG_TSCTR) + { + /* Get the value of TSCTR */ + tmpreg = ((uint32_t)(ECAP->TSCTR)); + } + if (ECAP_DATA_REG == ECAP_DATA_REG_CTRPHS) + { + /* Get the value of CTRPHS */ + tmpreg = ((uint32_t)(ECAP->CTRPHS)); + } + if (ECAP_DATA_REG == ECAP_DATA_REG_CAP1) + { + /* Get the value of CAP1 */ + tmpreg = ((uint32_t)(ECAP->CAP1)); + } + if (ECAP_DATA_REG == ECAP_DATA_REG_CAP2) + { + /* Get the value of CAP2 */ + tmpreg = ((uint32_t)(ECAP->CAP2)); + } + if (ECAP_DATA_REG == ECAP_DATA_REG_CAP3) + { + /* Get the value of CAP3 */ + tmpreg = ((uint32_t)(ECAP->CAP3)); + } + if (ECAP_DATA_REG == ECAP_DATA_REG_CAP4) + { + /* Get the value of CAP4 */ + tmpreg = ((uint32_t)(ECAP->CAP4)); + } + + /* Return the value of data register */ + return tmpreg; +} + + +/** + * @brief Enable the specified ECAP interrupts. + * @param ECAP_IT specifies the ECAP interrupt sources to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg ECAP_IT_CEVT1 Capture event 1 interrupt + * @arg ECAP_IT_CEVT2 Capture event 2 interrupt + * @arg ECAP_IT_CEVT3 Capture event 3 interrupt + * @arg ECAP_IT_CEVT4 Capture event 4 interrupt + * @arg ECAP_IT_CTROVF Counter overflow interrupt + * @arg ECAP_IT_CTRPRD Counter equal period interrupt + * @arg ECAP_IT_CTRCMP Counter equal compare interrupt + * @param NewState new state of the specified ECAP interrupt. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void ECAP_ITConfig(uint8_t ECAP_IT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_ECAP_IT(ECAP_IT)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + + if (NewState != DISABLE) + { + /* Enable the selected ECAP interrupts */ + ECAP->ECEINT |= ECAP_IT; + } + else + { + /* Disable the selected ECAP interrupts */ + ECAP->ECEINT &= ~ECAP_IT; + } +} + + +/** + * @brief Clears the ECAP interrupt flags. + * @param ECAP_FLAG specifies the ECAP interrupt flag to clear. + * This parameter can be one of the following values: + * @arg ECAP_FLAG_INT ECAP global interrupt flag + * @arg ECAP_FLAG_CEVT1 Capture event 1 interrupt flag + * @arg ECAP_FLAG_CEVT2 Capture event 2 interrupt flag + * @arg ECAP_FLAG_CEVT3 Capture event 3 interrupt flag + * @arg ECAP_FLAG_CEVT4 Capture event 3 interrupt flag + * @arg ECAP_FLAG_CTROVF Counter overflow interrupt flag + * @arg ECAP_FLAG_CTRPRD Counter equal period interrupt flag + * @arg ECAP_FLAG_CTRCMP Counter equal compare interrupt flag + * @retval None + */ +void ECAP_ClearFlag(uint8_t ECAP_FLAG) +{ + /* Check the parameters */ + assert_param(IS_ECAP_FLAG(ECAP_FLAG)); + + /* Clear the selected ECAP flags */ + ECAP->ECCLR = ECAP_FLAG; +} + + +/** + * @brief Force the specified ECAP interrupt. + * @param ECAP_IT specifies the ECAP interrupt sources to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg ECAP_IT_CEVT1 Capture event 1 interrupt + * @arg ECAP_IT_CEVT2 Capture event 2 interrupt + * @arg ECAP_IT_CEVT3 Capture event 3 interrupt + * @arg ECAP_IT_CEVT4 Capture event 4 interrupt + * @arg ECAP_IT_CTROVF Counter overflow interrupt + * @arg ECAP_IT_CTRPRD Counter equal period interrupt + * @arg ECAP_IT_CTRCMP Counter equal compare interrupt + * @retval None + */ +void ECAP_ITForce(uint8_t ECAP_IT) +{ + /* Check the parameters */ + assert_param(IS_ECAP_IT(ECAP_IT)); + + /* Force the selected ECAP interrupt */ + ECAP->ECFRC = ECAP_IT; +} + +/** + * @brief Checks whether the specified ECAP interrupt has occurred or not. + * @param ECAP_IT specifies the ECAP interrupt sources to check. + * This parameter can be any combination of the following values: + * @arg ECAP_IT_CEVT1 Capture event 1 interrupt + * @arg ECAP_IT_CEVT2 Capture event 2 interrupt + * @arg ECAP_IT_CEVT3 Capture event 3 interrupt + * @arg ECAP_IT_CEVT4 Capture event 4 interrupt + * @arg ECAP_IT_CTROVF Counter overflow interrupt + * @arg ECAP_IT_CTRPRD Counter equal period interrupt + * @arg ECAP_IT_CTRCMP Counter equal compare interrupt + * @retval The new state of ECAP_IT (SET or RESET). + */ +ITStatus ECAP_GetITStatus(uint8_t ECAP_IT) +{ + /* Check the parameters */ + assert_param(IS_ECAP_IT(ECAP_IT)); + + + ITStatus bitstatus = RESET; + + /* Check the status of the specified ECAP interrupt */ + if ((uint32_t)(ECAP->ECEINT & ECAP_IT) != (uint32_t)RESET) + { + /* ECAP_IT is set */ + bitstatus = SET; + } + else + { + /* ECAP_IT is reset */ + bitstatus = RESET; + } + /* Return the ECAP_IT status */ + return bitstatus; +} + + + +/** + * @brief Checks whether the specified ECAP flag has occurred or not. + * @param ECAP_FLAG specifies the ECAP flag to check. + * This parameter can be any combination of the following values: + * @arg ECAP_FLAG_INT ECAP global interrupt flag + * @arg ECAP_FLAG_CEVT1 Capture event 1 interrupt flag + * @arg ECAP_FLAG_CEVT2 Capture event 2 interrupt flag + * @arg ECAP_FLAG_CEVT3 Capture event 3 interrupt flag + * @arg ECAP_FLAG_CEVT4 Capture event 4 interrupt flag + * @arg ECAP_FLAG_CTROVF Counter overflow interrupt flag + * @arg ECAP_FLAG_CTRPRD Counter equal period interrupt flag + * @arg ECAP_FLAG_CTRCMP Counter equal compare interrupt flag + * @retval The new state of ECAP_FLAG (SET or RESET). + */ +FlagStatus ECAP_GetFlagStatus(uint8_t ECAP_FLAG) +{ + /* Check the parameters */ + assert_param(IS_ECAP_FLAG(ECAP_FLAG)); + + + FlagStatus bitstatus = RESET; + + /* Check the status of the specified ECAP interrupt */ + if ((uint32_t)(ECAP->ECFLG & ECAP_FLAG) != (uint32_t)RESET) + { + /* ECAP_FLAG is set */ + bitstatus = SET; + } + else + { + /* ECAP_FLAG is reset */ + bitstatus = RESET; + } + /* Return the ECAP_FLAG status */ + return bitstatus; +} + + + + + +/** + * @} + */ + +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_epwm.c b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_epwm.c new file mode 100644 index 00000000000..5f840579e71 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_epwm.c @@ -0,0 +1,2027 @@ +/** + ****************************************************************************** + * @file ft32f4xx_epwm.c + * @author FMD AE + * @brief This file provides firmware functions to manage the following + * functionalities of the Enhanced Pulse Width Modulator (EPWM): + * + Initialization and Configuration + * + Interrupts and flags management + * @version V1.0.0 + * @data 2025-03-26 + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx_epwm.h" +#include "ft32f4xx_rcc.h" + +/** @defgroup EPWM + * @brief EPWM driver modules + * @{ + */ + + + +/** + * @brief When the EALLOW bit is set to 1, write protection function will be disable and + * write operations can be performed on the related registers. + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral. + * @retval None + */ +void EALLOW(EPWM_TypeDef* EPWMx) +{ + EPWMx->TBCTL |= EPWM_TBCTL_EALLOW_BITS; +} + +/** + * @brief When the EALLOW bit is set to 0, write protection function will be enabled and + * write operations on the related registers will not be allowed. + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral. + * @retval None + */ +void EDIS(EPWM_TypeDef* EPWMx) +{ + EPWMx->TBCTL &= ~EPWM_TBCTL_EALLOW_BITS; +} + + +/** + * @brief Checks whether the specified EPWM TripZone flag is set or not. + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral. + * @param TZ_FLAG: specifies the TripZone flag to check. + * This parameter can be one of the following values: + * @arg EPWM_TZ_FLAG_INT : Transmit buffer empty flag. + * @arg EPWM_TZ_FLAG_CBC : Receive buffer not empty flag. + * @arg EPWM_TZ_FLAG_OST : Busy flag. + * @arg EPWM_TZ_FLAG_DCAEVT1 : Overrun flag. + * @arg EPWM_TZ_FLAG_DCAEVT2 : Mode Fault flag. + * @arg EPWM_TZ_FLAG_DCBEVT1 : CRC Error flag. + * @arg EPWM_TZ_FLAG_DCBEVT2 : TI frame format error flag. + * @retval The new state of TZ_FLAG (SET or RESET). + */ +FlagStatus EPWM_TripZone_GetFlagStatus(EPWM_TypeDef* EPWMx, uint16_t TZ_FLAG) +{ + FlagStatus bitstatus = RESET; + /* Check the parameters */ + assert_param(IS_EPWM_TZ_GET_FLAG(TZ_FLAG)); + + /* Check the status of the specified EPWM flag */ + if ((EPWMx->TZFLG & TZ_FLAG) != (uint16_t)RESET) + { + /* TZ_FLAG is set */ + bitstatus = SET; + } + else + { + /* TZ_FLAG is reset */ + bitstatus = RESET; + } + /* Return the TZ_FLAG status */ + return bitstatus; +} + +/** + * @brief Checks whether the specified EPWM Event Trigger flag is set or not. + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral. + * @param ET_FLAG: specifies the Event Trigger flag to check. + * This parameter can be one of the following values: + * @arg EPWM_ET_FLAG_INT : Transmit buffer empty flag. + * @arg EPWM_ET_FLAG_SOCA : Receive buffer not empty flag. + * @arg EPWM_ET_FLAG_SOCB : Busy flag. + * @retval The new state of ET_FLAG (SET or RESET). + */ +FlagStatus EPWM_EventTrigger_GetFlagStatus(EPWM_TypeDef* EPWMx, uint16_t ET_FLAG) +{ + FlagStatus bitstatus = RESET; + /* Check the parameters */ + assert_param(IS_EPWM_ET_GET_FLAG(ET_FLAG)); + + /* Check the status of the specified EPWM flag */ + if ((EPWMx->ETFLG & ET_FLAG) != (uint16_t)RESET) + { + /* ET_FLAG is set */ + bitstatus = SET; + } + else + { + /* ET_FLAG is reset */ + bitstatus = RESET; + } + /* Return the ET_FLAG status */ + return bitstatus; +} + +/** + * @brief Checks whether the specified EPWM Mep Calibration flag is set or not. + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral. + * @param MEP_FLAG: specifies the Mep Calibration flag to check. + * This parameter can be one of the following values: + * @arg EPWM_MEP_FLAG_INT : Mep Calibration done flag. + * @retval The new state of MEP_FLAG (SET or RESET). + */ +FlagStatus EPWM_MepCalibration_GetFlagStatus(EPWM_TypeDef* EPWMx, uint16_t MEP_FLAG) +{ + FlagStatus bitstatus = RESET; + /* Check the parameters */ + assert_param(IS_EPWM_MEP_GET_FLAG(MEP_FLAG)); + + /* Check the status of the specified EPWM flag */ + if ((EPWMx->MEPFLG & MEP_FLAG) != (uint16_t)RESET) + { + /* MEP_FLAG is set */ + bitstatus = SET; + } + else + { + /* MEP_FLAG is reset */ + bitstatus = RESET; + } + /* Return the MEP_FLAG status */ + return bitstatus; +} + +/** + * @brief Enable MEP SFO when AUTOCONV = 1. + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @retval HRMSTEP value when MEPFLG_MEPFLG = 1. + */ +uint8_t EPWM_enableMEPSFO(EPWM_TypeDef* EPWMx) +{ + EALLOW(EPWMx); + + if (((EPWMx->HRCNFG)&EPWM_HRCNFG_AUTOCONV_BITS) == EPWM_HRCNFG_AUTOCONV_BITS) + { + EPWMx->HRPWR |= EPWM_HRPPWR_MEPSFO_BITS; + + while ((EPWM_MepCalibration_GetFlagStatus(EPWM1, EPWM_MEP_FLAG_INT)) != 1) {}; + + return (EPWMx->HRMSTEP); + } + + EDIS(EPWMx); + return 0; +} + +/** + * @brief Disable MEP SFO. + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + */ +void EPWM_disableMEPSFO(EPWM_TypeDef* EPWMx) +{ + EALLOW(EPWMx); + + EPWMx->HRPWR &= ~EPWM_HRPPWR_MEPSFO_BITS; + + EDIS(EPWMx); +} + + +/** + * @brief Sets the filter value of the TZ1-3 for the trip zone (TZ). + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param FILTER The filter value(0~255). + */ +void EPWM_setTripZoneFilter(EPWM_TypeDef* EPWMx, uint8_t FILTER) +{ + EALLOW(EPWMx); + + EPWMx->TZSEL |= (FILTER << 16); + + EDIS(EPWMx); +} + + + + +/** + * @brief Clears the trip zone (TZ) flag specified + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param tripZoneFlag The trip zone flag to clear + */ +void EPWM_clearTripZone(EPWM_TypeDef* EPWMx, const EPWM_TripZoneFlag_e tripZoneFlag) +{ + EALLOW(EPWMx); + + EPWMx->TZCLR |= tripZoneFlag; + + EDIS(EPWMx); + +} + +/** + * @brief Decrement the dead band falling edge delay + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + */ +void EPWM_decrementDeadBandFallingEdgeDelay(EPWM_TypeDef* EPWMx) +{ + + EPWMx->DBFED--; + +} + +/** + * @brief Decrement the dead band rising edge delay + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + */ +void EPWM_decrementDeadBandRisingEdgeDelay(EPWM_TypeDef* EPWMx) +{ + + EPWMx->DBRED--; + +} + +/** + * @brief Disables auto conversion of delay line value + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + */ +void EPWM_disableAutoConvert(EPWM_TypeDef* EPWMx) +{ + + EALLOW(EPWMx); + + EPWMx->HRCNFG &= ~EPWM_HRCNFG_AUTOCONV_BITS; + + EDIS(EPWMx); + +} + +/** + * @brief Enables the pulse width modulation (PWM) chopping + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + */ +void EPWM_enableChopping(EPWM_TypeDef* EPWMx) +{ + + EPWMx->PCCTL = (uint16_t)1; + +} + +/** + * @brief Disables the pulse width modulation (PWM) chopping + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + */ +void EPWM_disableChopping(EPWM_TypeDef* EPWMx) +{ + + EPWMx->PCCTL &= (~EPWM_PCCTL_CHPEN_BITS); + +} + +/** + * @brief Disables the pulse width modulation (PWM) counter loading from + the phase register + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + */ +void EPWM_disableCounterLoad(EPWM_TypeDef* EPWMx) +{ + + EPWMx->TBCTL &= (~EPWM_TBCTL_PHSEN_BITS); + +} + +/** + * @brief Disables the pulse width modulation (PWM) deadband + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + */ +void EPWM_disableDeadBand(EPWM_TypeDef* EPWMx) +{ + + EPWMx->DBCTL = 0; + +} + +/** + * @brief Disables the pulse width modulation (PWM) deadband half cycle + clocking + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + */ +void EPWM_disableDeadBandHalfCycle(EPWM_TypeDef* EPWMx) +{ + + EPWMx->DBCTL &= (~EPWM_DBCTL_HALFCYCLE_BITS); + +} + +/** + * @brief Disables the pulse width modulation (PWM) digital compare + blanking window + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + */ +void EPWM_disableDigitalCompareBlankingWindow(EPWM_TypeDef* EPWMx) +{ + + EALLOW(EPWMx); + + EPWMx->DCFCTL &= ~EPWM_DCFCTL_BLANKE_BITS; + + EDIS(EPWMx); + +} + +/** + * @brief Disables the pulse width modulation (PWM) digital compare + blanking window inversion + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + */ +void EPWM_disableDigitalCompareBlankingWindowInversion(EPWM_TypeDef* EPWMx) +{ + + EALLOW(EPWMx); + + EPWMx->DCFCTL &= ~EPWM_DCFCTL_BLANKINV_BITS; + + EDIS(EPWMx); + +} + +/** + * @brief Disables high resolution period control + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + */ +void EPWM_disableHrPeriod(EPWM_TypeDef* EPWMx) +{ + + EALLOW(EPWMx); + + EPWMx->HRPCTL &= ~EPWM_HRPCTL_HRPE_BITS; + + EDIS(EPWMx); + +} + +/** + * @brief Disables high resolution phase synchronization + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + */ +void EPWM_disableHrPhaseSync(EPWM_TypeDef* EPWMx) +{ + + EALLOW(EPWMx); + + EPWMx->HRPCTL &= ~EPWM_HRPCTL_TBPHSHRLOADE_BITS; + + EDIS(EPWMx); + +} + +/** + * @brief Disables MEP Calibration Off bit + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + */ +void EPWM_disableMEPCalibrationOff(EPWM_TypeDef* EPWMx) +{ + EALLOW(EPWMx); + + EPWMx->HRPWR &= ~EPWM_HRPPWR_MEPOFF_BITS; + + EDIS(EPWMx); + +} + +/** + * @brief Disables the pulse width modulation (PWM) interrupt + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + */ +void EPWM_disableInt(EPWM_TypeDef* EPWMx) +{ + + EPWMx->ETSEL &= (~EPWM_ETSEL_INTEN_BITS); + +} + +/** + * @brief Disables the pulse width modulation (PWM) start of conversion + (SOC) B pulse generation + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + */ +void EPWM_disableSocAPulse(EPWM_TypeDef* EPWMx) +{ + + EPWMx->ETSEL &= (~EPWM_ETSEL_SOCAEN_BITS); + +} + +/** + * @brief Disables the pulse width modulation (PWM) start of conversion + (SOC) B pulse generation + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + */ +void EPWM_disableSocBPulse(EPWM_TypeDef* EPWMx) +{ + + EPWMx->ETSEL &= (~EPWM_ETSEL_SOCBEN_BITS); + +} + +/** + * @brief Disables the pulse width modulation (PWM) trip zones + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + */ +void EPWM_disableTripZones(EPWM_TypeDef* EPWMx) +{ + + EALLOW(EPWMx); + + EPWMx->TZSEL = 0; + + EDIS(EPWMx); + +} + +/** + * @brief Disables the pulse width modulation (PWM) trip zones interrupts + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param interruptSource The interrupt source to disable + */ +void EPWM_disableTripZoneInt(EPWM_TypeDef* EPWMx, const EPWM_TripZoneFlag_e interruptSource) +{ + + EALLOW(EPWMx); + + EPWMx->TZEINT &= ~interruptSource; + + EDIS(EPWMx); + +} + +/** + * @brief Disable the pulse width modulation (PWM) trip zone source + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param src The pulse width modulation (PWM) trip zone source + */ +void EPWM_disableTripZoneSrc(EPWM_TypeDef* EPWMx, const EPWM_TripZoneSrc_e src) +{ + + EALLOW(EPWMx); + + EPWMx->TZSEL &= (~src); + + EDIS(EPWMx); + +} + +/** + * @brief Enables auto conversion of delay line value + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + */ +void EPWM_enableAutoConvert(EPWM_TypeDef* EPWMx) +{ + + EALLOW(EPWMx); + + EPWMx->HRCNFG |= EPWM_HRCNFG_AUTOCONV_BITS; + + EDIS(EPWMx); + +} + +/** + * @brief Enables the pulse width modulation (PWM) counter loading from + the phase register + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + */ +void EPWM_enableCounterLoad(EPWM_TypeDef* EPWMx) +{ + + EPWMx->TBCTL |= EPWM_TBCTL_PHSEN_BITS; + +} + +/** + * @brief Enables the pulse width modulation (PWM) deadband half cycle + clocking + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + */ +void EPWM_enableDeadBandHalfCycle(EPWM_TypeDef* EPWMx) +{ + + EPWMx->DBCTL |= (uint16_t)EPWM_DBCTL_HALFCYCLE_BITS; + +} + +/** + * @brief Enables the pulse width modulation (PWM) digital compare + blanking window + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + */ +void EPWM_enableDigitalCompareBlankingWindow(EPWM_TypeDef* EPWMx) +{ + + EALLOW(EPWMx); + + EPWMx->DCFCTL |= EPWM_DCFCTL_BLANKE_BITS; + + EDIS(EPWMx); + +} + +/** + * @brief Enables the pulse width modulation (PWM) digital compare + blanking window inversion + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + */ +void EPWM_enableDigitalCompareBlankingWindowInversion(EPWM_TypeDef* EPWMx) +{ + + EALLOW(EPWMx); + + EPWMx->DCFCTL |= EPWM_DCFCTL_BLANKINV_BITS; + + EDIS(EPWMx); + +} + +/** + * @brief Enables high resolution period control + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + */ +void EPWM_enableHrPeriod(EPWM_TypeDef* EPWMx) +{ + EALLOW(EPWMx); + + EPWMx->HRPCTL |= EPWM_HRPCTL_HRPE_BITS; + + EDIS(EPWMx); + +} + +/** + * @brief Enables the pulse width modulation (PWM) interrupt + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + */ +void EPWM_enableInt(EPWM_TypeDef* EPWMx) +{ + + EPWMx->ETSEL |= EPWM_ETSEL_INTEN_BITS; + +} + +/** + * @brief Enables high resolution phase synchronization + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + */ +void EPWM_enableHrPhaseSync(EPWM_TypeDef* EPWMx) +{ + EALLOW(EPWMx); + + EPWMx->HRPCTL |= EPWM_HRPCTL_TBPHSHRLOADE_BITS; + + EDIS(EPWMx); + +} + +/** + * @brief Enables MEP Calibration Off bit + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + */ +void EPWM_enableMEPCalibrationOff(EPWM_TypeDef* EPWMx) +{ + EALLOW(EPWMx); + + EPWMx->HRPWR |= EPWM_HRPPWR_MEPOFF_BITS; + + EDIS(EPWMx); + +} + +/** + * @brief Enables the pulse width modulation (PWM) start of conversion + (SOC) A pulse generation + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + */ +void EPWM_enableSocAPulse(EPWM_TypeDef* EPWMx) +{ + + EPWMx->ETSEL |= EPWM_ETSEL_SOCAEN_BITS; + +} + +/** + * @brief Enables the pulse width modulation (PWM) start of conversion + (SOC) B pulse generation + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + */ +void EPWM_enableSocBPulse(EPWM_TypeDef* EPWMx) +{ + + EPWMx->ETSEL |= (uint16_t)EPWM_ETSEL_SOCBEN_BITS; + +} + +/** + * @brief Enables the pulse width modulation (PWM) trip zones interrupts + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param interruptSource The interrupt source to enable + */ +void EPWM_enableTripZoneInt(EPWM_TypeDef* EPWMx, const EPWM_TripZoneFlag_e interruptSource) +{ + + EALLOW(EPWMx); + + EPWMx->TZEINT |= interruptSource; + + EDIS(EPWMx); + +} + +/** + * @brief Enable the pulse width modulation (PWM) trip zone source + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param src The pulse width modulation (PWM) trip zone source + */ +void EPWM_enableTripZoneSrc(EPWM_TypeDef* EPWMx, const EPWM_TripZoneSrc_e src) +{ + + EALLOW(EPWMx); + + EPWMx->TZSEL |= src; + + EDIS(EPWMx); + +} + +/** + * @brief Gets the pulse width modulation (PWM) deadband falling edge + delay + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @retval The delay + */ +uint16_t EPWM_getDeadBandFallingEdgeDelay(EPWM_TypeDef* EPWMx) +{ + + return (EPWMx->DBFED); +} + +/** + * @brief Gets the pulse width modulation (PWM) deadband rising edge delay + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @retval The delay + */ +uint16_t EPWM_getDeadBandRisingEdgeDelay(EPWM_TypeDef* EPWMx) +{ + + return (EPWMx->DBRED); +} + +/** + * @brief Gets the pulse width modulation (PWM) interrupt event count + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @retval The interrupt event count + */ +uint16_t EPWM_getIntCount(EPWM_TypeDef* EPWMx) +{ + uint16_t intCount; + + intCount = EPWMx->ETPS & EPWM_ETPS_INTCNT_BITS; + + return (intCount); +} + +/** + * @brief Gets the pulse width modulation (PWM) start of conversion (SOC) + A count + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @retval The SOC A count + */ +uint16_t EPWM_getSocACount(EPWM_TypeDef* EPWMx) +{ + uint16_t intCount; + + intCount = EPWMx->ETPS & EPWM_ETPS_SOCACNT_BITS; + + intCount >>= 10; + + return (intCount); +} + +/** + * @brief Gets the pulse width modulation (PWM) start of conversion (SOC) + B count + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @retval The SOC B count + */ +uint16_t EPWM_getSocBCount(EPWM_TypeDef* EPWMx) +{ + uint16_t intCount; + + intCount = EPWMx->ETPS & (uint16_t)EPWM_ETPS_SOCBCNT_BITS; + + intCount >>= 14; + + return (intCount); +} + + +EPWM_ShadowStatus_e EPWM_getShadowStatus_CmpA(EPWM_TypeDef* EPWMx) +{ + EPWM_ShadowStatus_e status; + + status = (EPWM_ShadowStatus_e)(EPWMx->CMPCTL & (EPWM_CMPCTL_SHDWAFULL_BITS)); + + status >>= 5; + + return (status); +} + + +EPWM_ShadowStatus_e EPWM_getShadowStatus_CmpB(EPWM_TypeDef* EPWMx) +{ + EPWM_ShadowStatus_e status; + + status = (EPWM_ShadowStatus_e)(EPWMx->CMPCTL & (EPWM_CMPCTL_SHDWBFULL_BITS)); + + status >>= 7; + + return (status); +} + +/** + * @brief Set the High Resolution Control Mode + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param controlMode The control mode HREPWM should use + */ +void EPWM_setHrControlMode(EPWM_TypeDef* EPWMx, const EPWM_HrControlMode_e controlMode) +{ + EALLOW(EPWMx); + + EPWMx->HRCNFG &= ~EPWM_HRCNFG_CTLMODE_BITS; + + EPWMx->HRCNFG |= controlMode; + + EDIS(EPWMx); + +} + +/** + * @brief Set the High Resolution Edge Mode + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param edgeMode The edge mode HREPWM should use + */ +void EPWM_setHrEdgeMode(EPWM_TypeDef* EPWMx, const EPWM_HrEdgeMode_e edgeMode) +{ + EALLOW(EPWMx); + + EPWMx->HRCNFG &= ~EPWM_HRCNFG_EDGMODE_BITS; + + EPWMx->HRCNFG |= edgeMode; + + EDIS(EPWMx); + +} + +/** + * @brief Set the High Resolution Shadow Load Mode + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param shadowMode The shadow load mode HREPWM should use + */ +void EPWM_setHrShadowMode(EPWM_TypeDef* EPWMx, const EPWM_HrShadowMode_e shadowMode) +{ + EALLOW(EPWMx); + + EPWMx->HRCNFG &= ~EPWM_HRCNFG_HRLOAD_BITS; + + EPWMx->HRCNFG |= shadowMode; + + EDIS(EPWMx); + +} + +/** + * @brief Increment the dead band falling edge delay + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + */ +void EPWM_incrementDeadBandFallingEdgeDelay(EPWM_TypeDef* EPWMx) +{ + EPWMx->DBFED++; + +} + +/** + * @brief Increment the dead band rising edge delay + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + */ +void EPWM_incrementDeadBandRisingEdgeDelay(EPWM_TypeDef* EPWMx) +{ + EPWMx->DBRED++; + +} + +/** + * @brief Initializes the pulse width modulation (PWM) object handle + * @param pMemory A pointer to the base address of the EPWM registers + * @param numBytes The number of bytes allocated for the EPWM object, bytes + * @retval The pulse width modulation (PWM) object handle + */ +//EPWM_Handle EPWM_init(void *pMemory, const size_t numBytes) +//{ +// EPWM_TypeDef* EPWMx; +// +// if(numBytes < sizeof(EPWM_TypeDef)) +// { +// return((EPWM_Handle)NULL); +// } +// +// // +// // assign the handle +// // +// +//} + + +/** + * @brief Sets the pulse width modulation (PWM) object action for EPWM A + when the counter equals CMPA and the counter is decrementing + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param actionQual The action qualifier + */ +void EPWM_setActionQual_CntDown_CmpA_PwmA(EPWM_TypeDef* EPWMx, const EPWM_ActionQual_e actionQual) +{ + + EPWMx->AQCTLA &= (~EPWM_AQCTL_CAD_BITS); + + EPWMx->AQCTLA |= (actionQual << 6); + +} + +/** + * @brief Sets the pulse width modulation (PWM) object action for EPWM B + when the counter equals CMPA and the counter is decrementing + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param actionQual The action qualifier + */ +void EPWM_setActionQual_CntDown_CmpA_PwmB(EPWM_TypeDef* EPWMx, const EPWM_ActionQual_e actionQual) +{ + + EPWMx->AQCTLB &= (~EPWM_AQCTL_CAD_BITS); + + EPWMx->AQCTLB |= (actionQual << 6); + +} + +/** + * @brief Sets the pulse width modulation (PWM) object action for EPWM A + when the counter equals CMPB and the counter is decrementing + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param actionQual The action qualifier + */ +void EPWM_setActionQual_CntDown_CmpB_PwmA(EPWM_TypeDef* EPWMx, const EPWM_ActionQual_e actionQual) +{ + + EPWMx->AQCTLA &= (~EPWM_AQCTL_CBD_BITS); + + EPWMx->AQCTLA |= (actionQual << 10); + +} + +/** + * @brief Sets the pulse width modulation (PWM) object action for EPWM B + when the counter equals CMPB and the counter is decrementing + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param actionQual The action qualifier + */ +void EPWM_setActionQual_CntDown_CmpB_PwmB(EPWM_TypeDef* EPWMx, const EPWM_ActionQual_e actionQual) +{ + + EPWMx->AQCTLB &= (~EPWM_AQCTL_CBD_BITS); + + EPWMx->AQCTLB |= (actionQual << 10); + +} + +/** + * @brief Sets the pulse width modulation (PWM) object action for EPWM A + when the counter equals CMPA and the counter is incrementing + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param actionQual The action qualifier + */ +void EPWM_setActionQual_CntUp_CmpA_PwmA(EPWM_TypeDef* EPWMx, const EPWM_ActionQual_e actionQual) +{ + + EPWMx->AQCTLA &= (~EPWM_AQCTL_CAU_BITS); + + EPWMx->AQCTLA |= (actionQual << 4); + +} + +/** + * @brief Sets the pulse width modulation (PWM) object action for EPWM B + when the counter equals CMPA and the counter is incrementing + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param actionQual The action qualifier + */ +void EPWM_setActionQual_CntUp_CmpA_PwmB(EPWM_TypeDef* EPWMx, const EPWM_ActionQual_e actionQual) +{ + + EPWMx->AQCTLB &= (~EPWM_AQCTL_CAU_BITS); + + EPWMx->AQCTLB |= (actionQual << 4); + +} + +/** + * @brief Sets the pulse width modulation (PWM) object action for EPWM A + when the counter equals CMPB and the counter is incrementing + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param actionQual The action qualifier + */ +void EPWM_setActionQual_CntUp_CmpB_PwmA(EPWM_TypeDef* EPWMx, const EPWM_ActionQual_e actionQual) +{ + + EPWMx->AQCTLA &= (~EPWM_AQCTL_CBU_BITS); + + EPWMx->AQCTLA |= (actionQual << 8); + +} + +/** + * @brief Sets the pulse width modulation (PWM) object action for EPWM B + when the counter equals CMPB and the counter is incrementing + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param actionQual The action qualifier + */ +void EPWM_setActionQual_CntUp_CmpB_PwmB(EPWM_TypeDef* EPWMx, const EPWM_ActionQual_e actionQual) +{ + + EPWMx->AQCTLB &= (~EPWM_AQCTL_CBU_BITS); + + EPWMx->AQCTLB |= (actionQual << 8); + +} + +/** + * @brief Sets the pulse width modulation (PWM) object action for EPWM A + when the counter equals the period + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param actionQual The action qualifier + */ +void EPWM_setActionQual_Period_PwmA(EPWM_TypeDef* EPWMx, const EPWM_ActionQual_e actionQual) +{ + + EPWMx->AQCTLA &= (~EPWM_AQCTL_PRD_BITS); + + EPWMx->AQCTLA |= (actionQual << 2); + +} + +/** + * @brief Sets the pulse width modulation (PWM) object action for EPWM B + when the counter equals the period + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param actionQual The action qualifier + */ +void EPWM_setActionQual_Period_PwmB(EPWM_TypeDef* EPWMx, const EPWM_ActionQual_e actionQual) +{ + + EPWMx->AQCTLB &= (~EPWM_AQCTL_PRD_BITS); + + EPWMx->AQCTLB |= (actionQual << 2); + +} + +/** + * @brief Sets the pulse width modulation (PWM) object action for EPWM A + when the counter equals the zero + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param actionQual The action qualifier + */ +void EPWM_setActionQual_Zero_PwmA(EPWM_TypeDef* EPWMx, const EPWM_ActionQual_e actionQual) +{ + + EPWMx->AQCTLA &= (~EPWM_AQCTL_ZRO_BITS); + + EPWMx->AQCTLA |= actionQual; + +} + +/** + * @brief Sets the pulse width modulation (PWM) object action for EPWM B + when the counter equals the zero + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param actionQual The action qualifier + */ +void EPWM_setActionQual_Zero_PwmB(EPWM_TypeDef* EPWMx, const EPWM_ActionQual_e actionQual) +{ + + EPWMx->AQCTLB &= (~EPWM_AQCTL_ZRO_BITS); + + EPWMx->AQCTLB |= actionQual; + +} + +/** + * @brief Sets the pulse width modulation (PWM) chopping clock frequency + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param clkFreq The clock frequency + */ +void EPWM_setChoppingClkFreq(EPWM_TypeDef* EPWMx, const EPWM_ChoppingClkFreq_e clkFreq) +{ + + EPWMx->PCCTL &= (~EPWM_PCCTL_CHPFREQ_BITS); + + EPWMx->PCCTL |= clkFreq; + +} + +/** + * @brief Sets the pulse width modulation (PWM) chopping clock duty cycle + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param dutyCycle The duty cycle + */ +void EPWM_setChoppingDutyCycle(EPWM_TypeDef* EPWMx, const EPWM_ChoppingDutyCycle_e dutyCycle) +{ + + EPWMx->PCCTL &= (~EPWM_PCCTL_CHPDUTY_BITS); + + EPWMx->PCCTL |= dutyCycle; + +} + +/** + * @brief Sets the pulse width modulation (PWM) chopping clock pulse width + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param pulseWidth The pulse width + */ +void EPWM_setChoppingPulseWidth(EPWM_TypeDef* EPWMx, const EPWM_ChoppingPulseWidth_e pulseWidth) +{ + + EPWMx->PCCTL &= (~EPWM_PCCTL_OSHTWTH_BITS); + + EPWMx->PCCTL |= pulseWidth; + +} + +/** + * @brief Sets the pulse width modulation (PWM) high speed clock divisor + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param clkDiv The clock divisor + */ +void EPWM_setHighSpeedClkDiv(EPWM_TypeDef* EPWMx, const EPWM_HspClkDiv_e clkDiv) +{ + + EPWMx->TBCTL &= (~EPWM_TBCTL_HSPCLKDIV_BITS); + + EPWMx->TBCTL |= clkDiv; + +} + +/** + * @brief Sets the pulse width modulation (PWM) clock divisor + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param clkDiv The clock divisor + */ +void EPWM_setClkDiv(EPWM_TypeDef* EPWMx, const EPWM_ClkDiv_e clkDiv) +{ + + EPWMx->TBCTL &= (~EPWM_TBCTL_CLKDIV_BITS); + + EPWMx->TBCTL |= clkDiv; + +} + +/** + * @brief Sets the pulse width modulation (PWM) count + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param count The count + */ +void EPWM_setCount(EPWM_TypeDef* EPWMx, const uint16_t count) +{ + + EPWMx->TBCTR = count; + +} + +/** + * @brief Sets the pulse width modulation (PWM) counter mode + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param counterMode The count mode + */ +void EPWM_setCounterMode(EPWM_TypeDef* EPWMx, const EPWM_CounterMode_e counterMode) +{ + + EPWMx->TBCTL &= (~EPWM_TBCTL_CTRMODE_BITS); + + EPWMx->TBCTL |= counterMode; + +} + +/** + * @brief Sets the pulse width modulation (PWM) deadband falling edge delay + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param delay The delay + */ +void EPWM_setDeadBandFallingEdgeDelay(EPWM_TypeDef* EPWMx, const uint16_t delay) +{ + + EPWMx->DBFED |= delay; + +} + +/** + * @brief Sets the pulse width modulation (PWM) deadband input mode + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param inputMode The input mode + */ +void EPWM_setDeadBandInputMode(EPWM_TypeDef* EPWMx, const EPWM_DeadBandInputMode_e inputMode) +{ + + EPWMx->DBCTL &= (~EPWM_DBCTL_INMODE_BITS); + + EPWMx->DBCTL |= inputMode; + +} + +/** + * @brief Sets the pulse width modulation (PWM) deadband output mode + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param outputMode The output mode + */ +void EPWM_setDeadBandOutputMode(EPWM_TypeDef* EPWMx, const EPWM_DeadBandOutputMode_e outputMode) +{ + + EPWMx->DBCTL &= (~EPWM_DBCTL_OUTMODE_BITS); + + EPWMx->DBCTL |= outputMode; + +} + +/** + * @brief Sets the pulse width modulation (PWM) deadband polarity + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param polarity The polarity + */ +void EPWM_setDeadBandPolarity(EPWM_TypeDef* EPWMx, const EPWM_DeadBandPolarity_e polarity) +{ + + EPWMx->DBCTL &= (~EPWM_DBCTL_POLSEL_BITS); + + EPWMx->DBCTL |= polarity; + +} + +/** + * @brief Sets the pulse width modulation (PWM) deadband rising edge delay + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param delay The delay + */ +void EPWM_setDeadBandRisingEdgeDelay(EPWM_TypeDef* EPWMx, const uint16_t delay) +{ + + EPWMx->DBRED |= delay; + +} + +/** + * @brief Sets the pulse width modulation (PWM) digital compare filter + source + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param input The filter's source + */ +void EPWM_setDigitalCompareFilterSource(EPWM_TypeDef* EPWMx, const EPWM_DigitalCompare_FilterSrc_e input) +{ + EALLOW(EPWMx); + + EPWMx->DCFCTL &= ~EPWM_DCFCTL_SRCSEL_BITS; + + EPWMx->DCFCTL |= input; + + EDIS(EPWMx); + +} + +/** + * @brief Sets the pulse width modulation (PWM) digital compare blanking + pulse + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param pulseSelect The pulse selection + */ +void EPWM_setDigitalCompareBlankingPulse(EPWM_TypeDef* EPWMx, const EPWM_DigitalCompare_PulseSel_e pulseSelect) +{ + EALLOW(EPWMx); + + EPWMx->DCFCTL &= ~EPWM_DCFCTL_PULSESEL_BITS; + + EPWMx->DCFCTL |= pulseSelect << 4; + + EDIS(EPWMx); + +} + +/** + * @brief Sets the pulse width modulation (PWM) digital compare filter + offset + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param offset The offset + */ +void EPWM_setDigitalCompareFilterOffset(EPWM_TypeDef* EPWMx, const uint16_t offset) +{ + EPWMx->DCFOFFSET = offset; + +} + +/** + * @brief Sets the pulse width modulation (PWM) digital compare filter + offset + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param window The window + */ +void EPWM_setDigitalCompareFilterWindow(EPWM_TypeDef* EPWMx, const uint16_t window) +{ + EPWMx->DCFWINDOW = window; + +} + +/** + * @brief Sets the pulse width modulation (PWM) digital compare input + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param input Comparator input to change + * @param inputSel Input selection for designated input + */ +void EPWM_setDigitalCompareInput(EPWM_TypeDef* EPWMx, const EPWM_DigitalCompare_Input_e input, const EPWM_DigitalCompare_InputSel_e inputSel) +{ + EALLOW(EPWMx); + + EPWMx->DCTRIPSEL &= ~(0x000F << input); + + EPWMx->DCTRIPSEL |= (inputSel << input); + + EDIS(EPWMx); + +} + +/** + * @brief Sets the pulse width modulation (PWM) digital compare A event 1 + source parameters + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param selectFilter Select filter output if true + * @param disableSync Asynchronous if true + * @param enableSoc Enable SOC generation if true + * @param generateSync Generate SYNC if true + */ +void EPWM_setDigitalCompareAEvent1(EPWM_TypeDef* EPWMx, const uint16_t selectFilter, const uint16_t disableSync, const uint16_t enableSoc, const uint16_t generateSync) +{ + EALLOW(EPWMx); + + EPWMx->DCACTL &= ~0x000F; + + EPWMx->DCACTL |= selectFilter | (disableSync << 1) | (enableSoc << 2) | + (generateSync << 3); + + EDIS(EPWMx); + +} + + +/** + * @brief Sets the pulse width modulation (PWM) digital compare A event 2 + source parameters + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param selectFilter Select filter output if true + * @param disableSync Asynchronous if true + */ +void EPWM_setDigitalCompareAEvent2(EPWM_TypeDef* EPWMx, const uint16_t selectFilter, const uint16_t disableSync) +{ + + EALLOW(EPWMx); + + EPWMx->DCACTL &= ~0x0300; + + EPWMx->DCACTL |= (selectFilter << 8) | (disableSync << 9) ; + + EDIS(EPWMx); + +} + +/** + * @brief Sets the pulse width modulation (PWM) digital compare B event 1 + source parameters + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param selectFilter Select filter output if true + * @param disableSync Asynchronous if true + * @param enableSoc Enable SOC generation if true + * @param generateSync Generate SYNC if true + */ +void EPWM_setDigitalCompareBEvent1(EPWM_TypeDef* EPWMx, const uint16_t selectFilter, const uint16_t disableSync, const uint16_t enableSoc, const uint16_t generateSync) +{ + + EALLOW(EPWMx); + + EPWMx->DCBCTL &= ~0x000F; + + EPWMx->DCBCTL |= selectFilter | (disableSync << 1) | (enableSoc << 2) | + (generateSync << 3); + + EDIS(EPWMx); + +} + +/** + * @brief Sets the pulse width modulation (PWM) digital compare B event 2 + source parameters + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param selectFilter Select filter output if true + * @param disableSync Asynchronous if true + */ +void EPWM_setDigitalCompareBEvent2(EPWM_TypeDef* EPWMx, const uint16_t selectFilter, const uint16_t disableSync) +{ + EALLOW(EPWMx); + + EPWMx->DCBCTL &= ~0x0300; + + EPWMx->DCBCTL |= (selectFilter << 8) | (disableSync << 9) ; + + EDIS(EPWMx); + +} + +/** + * @brief Sets the pulse width modulation (PWM) interrupt mode + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param intMode The interrupt mode + */ +void EPWM_setIntMode(EPWM_TypeDef* EPWMx, const EPWM_IntMode_e intMode) +{ + + EPWMx->ETSEL &= (~EPWM_ETSEL_INTSEL_BITS); + + EPWMx->ETSEL |= intMode; + +} + +/** + * @brief Sets the pulse width modulation (PWM) interrupt period + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param intPeriod The interrupt period + */ +void EPWM_setIntPeriod(EPWM_TypeDef* EPWMx, const EPWM_IntPeriod_e intPeriod) +{ + + EPWMx->ETPS &= (~EPWM_ETPS_INTPRD_BITS); + + EPWMx->ETPS |= intPeriod; + +} + +/** + * @brief Sets the pulse width modulation (PWM) load mode for CMPA + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param loadMode The load mode + */ +void EPWM_setLoadMode_CmpA(EPWM_TypeDef* EPWMx, const EPWM_LoadMode_e loadMode) +{ + + EPWMx->CMPCTL &= (~EPWM_CMPCTL_LOADAMODE_BITS); + + EPWMx->CMPCTL |= loadMode; + +} + +/** + * @brief Sets the pulse width modulation (PWM) load mode for CMPB + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param loadMode The load mode + */ +void EPWM_setLoadMode_CmpB(EPWM_TypeDef* EPWMx, const EPWM_LoadMode_e loadMode) +{ + + EPWMx->CMPCTL &= (~EPWM_CMPCTL_LOADBMODE_BITS); + + EPWMx->CMPCTL |= (loadMode << 2); + +} + +/** + * @brief Sets the pulse width modulation (PWM) period + * Initialize the Time-Base Period Register (TBPRD). These bits determine + * the period of the time-base counter. + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param period The period + */ +void EPWM_setPeriod(EPWM_TypeDef* EPWMx, const uint16_t period) +{ + + EPWMx->TBPRD = period; + +} + +/** + * @brief Sets the pulse width modulation (PWM) high resolution period + * Initialize the Time-Base Period Register (TBPRD). These bits determine + * the period of the time-base counter. + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param period The period + */ +void EPWM_setPeriodHr(EPWM_TypeDef* EPWMx, const uint16_t period) +{ + + EALLOW(EPWMx); + + EPWMx->TBPRDHR = period; + + EDIS(EPWMx); + +} + +/** + * @brief Sets the pulse width modulation (PWM) phase + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param phase The phase + */ +void EPWM_setPhase(EPWM_TypeDef* EPWMx, const uint16_t phase) +{ + + EPWMx->TBPHS = phase; + +} + +/** + * @brief Sets the pulse width modulation (PWM) phase direction + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param phaseDir The phase direction + */ +void EPWM_setPhaseDir(EPWM_TypeDef* EPWMx, const EPWM_PhaseDir_e phaseDir) +{ + + EPWMx->TBCTL &= (~EPWM_TBCTL_PHSDIR_BITS); + + EPWMx->TBCTL |= phaseDir; + +} + +/** + * @brief Sets the pulse width modulation (PWM) period load mode + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param periodLoad The period load mode + */ +void EPWM_setPeriodLoad(EPWM_TypeDef* EPWMx, const EPWM_PeriodLoad_e periodLoad) +{ + + EPWMx->TBCTL &= (~EPWM_TBCTL_PRDLD_BITS); + + EPWMx->TBCTL |= periodLoad; + +} + +/** + * @brief Sets the pulse width modulation (PWM) run mode + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param runMode The run mode + */ +//void EPWM_setRunMode(EPWM_TypeDef* EPWMx, const EPWM_RunMode_e runMode) +//{ +// +// EPWMx->TBCTL &= (~EPWM_TBCTL_FREESOFT_BITS); +// +// EPWMx->TBCTL |= runMode; +// +//} + +/** + * @brief Sets the pulse width modulation (PWM) start of conversion (SOC) + A interrupt period + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param intPeriod The interrupt period + */ +void EPWM_setSocAPeriod(EPWM_TypeDef* EPWMx, const EPWM_SocPeriod_e intPeriod) +{ + + EPWMx->ETPS &= (~EPWM_ETPS_SOCAPRD_BITS); + + EPWMx->ETPS |= (intPeriod << 8); + +} + +/** + * @brief Sets the pulse width modulation (PWM) start of conversion (SOC) + A interrupt pulse source + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param pulseSrc The interrupt pulse source + */ +void EPWM_setSocAPulseSrc(EPWM_TypeDef* EPWMx, const EPWM_SocPulseSrc_e pulseSrc) +{ + + EPWMx->ETSEL &= (~EPWM_ETSEL_SOCASEL_BITS); + + EPWMx->ETSEL |= (pulseSrc << 8); + +} + +/** + * @brief Sets the pulse width modulation (PWM) start of conversion (SOC) + B interrupt period + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param intPeriod The interrupt period + */ +void EPWM_setSocBPeriod(EPWM_TypeDef* EPWMx, const EPWM_SocPeriod_e intPeriod) +{ + + EPWMx->ETPS &= (~EPWM_ETPS_SOCBPRD_BITS); + + EPWMx->ETPS |= (intPeriod << 12); + +} + +/** + * @brief Sets the pulse width modulation (PWM) start of conversion (SOC) + B interrupt pulse source + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param pulseSrc The interrupt pulse source + */ +void EPWM_setSocBPulseSrc(EPWM_TypeDef* EPWMx, const EPWM_SocPulseSrc_e pulseSrc) +{ + + EPWMx->ETSEL &= (~EPWM_ETSEL_SOCBSEL_BITS); + + EPWMx->ETSEL |= (pulseSrc << 12); + +} + +/** + * @brief Sets the pulse width modulation (PWM) shadow mode for CMPA + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param shadowMode The shadow mode + */ +void EPWM_setShadowMode_CmpA(EPWM_TypeDef* EPWMx, const EPWM_ShadowMode_e shadowMode) +{ + + EPWMx->CMPCTL &= (~EPWM_CMPCTL_SHDWAMODE_BITS); + + EPWMx->CMPCTL |= (shadowMode << 4); + +} + +/** + * @brief Sets the pulse width modulation (PWM) shadow mode for CMPB + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param shadowMode The shadow mode + */ +void EPWM_setShadowMode_CmpB(EPWM_TypeDef* EPWMx, const EPWM_ShadowMode_e shadowMode) +{ + + EPWMx->CMPCTL &= (~EPWM_CMPCTL_SHDWBMODE_BITS); + + EPWMx->CMPCTL |= (shadowMode << 6); + +} + +/** + * @brief Sets the pulse width modulation (PWM) software sync + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + */ +void EPWM_setSwSync(EPWM_TypeDef* EPWMx) +{ + + EPWMx->TBCTL |= 1 << 6; + +} + +/** + * @brief Force Synchronization + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + */ +inline void EPWM_forceSync(EPWM_TypeDef* EPWMx) +{ + + EPWMx->TBCTL |= EPWM_TBCTL_SWFSYNC_BITS; + +} + + +/** + * @brief Sets the pulse width modulation (PWM) sync mode + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param syncMode The sync mode + */ +void EPWM_setSyncMode(EPWM_TypeDef* EPWMx, const EPWM_SyncMode_e syncMode) +{ + + EPWMx->TBCTL &= (~EPWM_TBCTL_SYNCOSEL_BITS); + + EPWMx->TBCTL |= syncMode; + +} + +/** + * @brief Sets the pulse width modulation (PWM) trip zone digital compare + event select for Digital Compare Output A Event 1 (DCAEVT1) + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param tripZoneEvent The trip zone digital compare event + */ +void EPWM_setTripZoneDCEventSelect_DCAEVT1(EPWM_TypeDef* EPWMx, const EPWM_TripZoneDCEventSel_e tripZoneEvent) +{ + + EALLOW(EPWMx); + + EPWMx->TZDCSEL &= (~EPWM_TZDCSEL_DCAEVT1_BITS); + + EPWMx->TZDCSEL |= tripZoneEvent << 0; + + EDIS(EPWMx); + +} + +/** + * @brief Sets the pulse width modulation (PWM) trip zone digital compare + event select for Digital Compare Output A Event 2 (DCAEVT2) + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param tripZoneEvent The trip zone digital compare event + */ +void EPWM_setTripZoneDCEventSelect_DCAEVT2(EPWM_TypeDef* EPWMx, const EPWM_TripZoneDCEventSel_e tripZoneEvent) +{ + + EALLOW(EPWMx); + + EPWMx->TZDCSEL &= (~EPWM_TZDCSEL_DCAEVT2_BITS); + + EPWMx->TZDCSEL |= tripZoneEvent << 3; + + EDIS(EPWMx); + +} + +/** + * @brief Sets the pulse width modulation (PWM) trip zone digital compare + event select for Digital Compare Output B Event 1 (DCBEVT1) + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param tripZoneEvent The trip zone digital compare event + */ +void EPWM_setTripZoneDCEventSelect_DCBEVT1(EPWM_TypeDef* EPWMx, const EPWM_TripZoneDCEventSel_e tripZoneEvent) +{ + + EALLOW(EPWMx); + + EPWMx->TZDCSEL &= (~EPWM_TZDCSEL_DCBEVT1_BITS); + + EPWMx->TZDCSEL |= tripZoneEvent << 6; + + EDIS(EPWMx); + +} + +/** + * @brief Sets the pulse width modulation (PWM) trip zone digital compare + event select for Digital Compare Output B Event 2 (DCBEVT2) + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param tripZoneEvent The trip zone digital compare event + */ +void EPWM_setTripZoneDCEventSelect_DCBEVT2(EPWM_TypeDef* EPWMx, const EPWM_TripZoneDCEventSel_e tripZoneEvent) +{ + + EALLOW(EPWMx); + + EPWMx->TZDCSEL &= (~EPWM_TZDCSEL_DCBEVT2_BITS); + + EPWMx->TZDCSEL |= tripZoneEvent << 9; + + EDIS(EPWMx); + +} + +/** + * @brief Sets the pulse width modulation (PWM) trip zone state for + Digital Compare Output A Event 1 (DCAEVT1) + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param tripZoneState The trip zone state + */ +void EPWM_setTripZoneState_DCAEVT1(EPWM_TypeDef* EPWMx, const EPWM_TripZoneState_e tripZoneState) +{ + + EALLOW(EPWMx); + + EPWMx->TZCTL &= (~EPWM_TZCTL_DCAEVT1_BITS); + + EPWMx->TZCTL |= tripZoneState << 4; + + EDIS(EPWMx); + +} + +/** + * @brief Sets the pulse width modulation (PWM) trip zone state for + Digital Compare Output A Event 2 (DCAEVT1) + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param tripZoneState The trip zone state + */ +void EPWM_setTripZoneState_DCAEVT2(EPWM_TypeDef* EPWMx, const EPWM_TripZoneState_e tripZoneState) +{ + + EALLOW(EPWMx); + + EPWMx->TZCTL &= (~EPWM_TZCTL_DCAEVT2_BITS); + + EPWMx->TZCTL |= tripZoneState << 6; + + EDIS(EPWMx); + +} + +/** + * @brief Sets the pulse width modulation (PWM) trip zone state for + Digital Compare Output B Event 1 (DCBEVT1) + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param tripZoneState The trip zone state + */ +void EPWM_setTripZoneState_DCBEVT1(EPWM_TypeDef* EPWMx, const EPWM_TripZoneState_e tripZoneState) +{ + + EALLOW(EPWMx); + + EPWMx->TZCTL &= (~EPWM_TZCTL_DCBEVT1_BITS); + + EPWMx->TZCTL |= tripZoneState << 8; + + EDIS(EPWMx); + +} + +/** + * @brief Sets the pulse width modulation (PWM) trip zone state for + Digital Compare Output B Event 2 (DCBEVT1) + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param tripZoneState The trip zone state + */ +void EPWM_setTripZoneState_DCBEVT2(EPWM_TypeDef* EPWMx, const EPWM_TripZoneState_e tripZoneState) +{ + + EALLOW(EPWMx); + + EPWMx->TZCTL &= (~EPWM_TZCTL_DCBEVT2_BITS); + + EPWMx->TZCTL |= tripZoneState << 10; + + EDIS(EPWMx); + +} + +/** + * @brief Sets the pulse width modulation (PWM) trip zone state for Output + A (TZA) + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param tripZoneState The trip zone state + */ +void EPWM_setTripZoneState_TZA(EPWM_TypeDef* EPWMx, const EPWM_TripZoneState_e tripZoneState) +{ + + EALLOW(EPWMx); + + EPWMx->TZCTL &= (~EPWM_TZCTL_TZA_BITS); + + EPWMx->TZCTL |= tripZoneState << 0; + + EDIS(EPWMx); + +} + +/** + * @brief Sets the pulse width modulation (PWM) trip zone state for Output + B (TZB) + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param tripZoneState The trip zone state + */ +void EPWM_setTripZoneState_TZB(EPWM_TypeDef* EPWMx, const EPWM_TripZoneState_e tripZoneState) +{ + + EALLOW(EPWMx); + + EPWMx->TZCTL &= (~EPWM_TZCTL_TZB_BITS); + + EPWMx->TZCTL |= tripZoneState << 2; + + EDIS(EPWMx); + +} + + + + + + + +/** + * @brief Clears the Mep Calibration interrupt flag + * @param EPWMx The pulse width modulation (PWM) object handle + */ +inline void EPWM_clearMepFlag(EPWM_TypeDef* EPWMx) +{ + EPWMx->MEPCLR = EPWM_MEP_INT_BITS; +} + + +/** + * @brief Clears the pulse width modulation (PWM) interrupt flag + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + */ +inline void EPWM_clearIntFlag(EPWM_TypeDef* EPWMx) +{ + + EPWMx->ETCLR = EPWM_ETCLR_INT_BITS; + +} + + +/** + * @brief Clears the pulse width modulation (PWM) one shot trip + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + */ +inline void EPWM_clearOneShotTrip(EPWM_TypeDef* EPWMx) +{ + + EALLOW(EPWMx); + + EPWMx->TZCLR = EPWM_TZCLR_OST_BITS; + + EDIS(EPWMx); + +} + + +/** + * @brief Clears the pulse width modulation (PWM) start of conversion + (SOC) A flag + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + */ +inline void EPWM_clearSocAFlag(EPWM_TypeDef* EPWMx) +{ + + EPWMx->ETCLR = EPWM_ETCLR_SOCA_BITS; + +} + + +/** + * @brief Clears the pulse width modulation (PWM) start of conversion + (SOC) B flag + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + */ +inline void EPWM_clearSocBFlag(EPWM_TypeDef* EPWMx) +{ + + EPWMx->ETCLR = EPWM_ETCLR_SOCB_BITS; + +} + + +/** + * @brief Gets the pulse width modulation (PWM) period value + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @retval The pwm period value + */ +inline uint16_t EPWM_getPeriod(EPWM_TypeDef* EPWMx) +{ + + return (EPWMx->TBPRD); +} + + +/** + * @brief Gets the pulse width modulation (PWM) data value from the + Counter Compare A hardware + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @retval The EPWM compare data value + */ +inline uint16_t EPWM_getCmpA(EPWM_TypeDef* EPWMx) +{ + + return (EPWMx->CMPA); +} + + +/** + * @brief Gets the pulse width modulation (PWM) data value from the + Counter Compare A Hr hardware + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @retval The EPWM compare high resolution data value + */ +inline uint16_t EPWM_getCmpAHr(EPWM_TypeDef* EPWMx) +{ + + return (EPWMx->CMPAHR); +} + + +/** + * @brief Gets the pulse width modulation (PWM) data value from the + Counter Compare B hardware + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @retval The EPWM compare data value + */ +inline uint16_t EPWM_getCmpB(EPWM_TypeDef* EPWMx) +{ + + return (EPWMx->CMPB); +} + + +/** + * @brief Sets the pulse width modulation (PWM) one shot trip + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + */ +inline void EPWM_setOneShotTrip(EPWM_TypeDef* EPWMx) +{ + + EALLOW(EPWMx); + + EPWMx->TZFRC |= EPWM_TZFRC_OST_BITS; + + EDIS(EPWMx); + +} + + +/** + * @brief Writes the pulse width modulation (PWM) data value to the + Counter Compare A hardware + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param pwmData The EPWM data value + */ +inline void EPWM_write_CmpA(EPWM_TypeDef* EPWMx, const int16_t pwmData) +{ + + int16_t value; + uint16_t period = EPWMx->TBPRD; + int32_t tmp; + + /* Compute the compare A (Q0) from the related duty cycle ratio (Q15) */ + tmp = (int32_t)period * (int32_t)(pwmData); // Q15 = Q0*Q15 + + /* Q0 = (Q15->Q0)/2 + (Q0/2) */ + value = (int16_t)(tmp >> 16) + (int16_t)(period >> 1); + + EPWMx->CMPA = value; + +} + + +/** + * @brief Writes the pulse width modulation (PWM) data value to the + Counter Compare A hardware + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param pwmData The EPWM data value + */ +inline void EPWM_setCmpA(EPWM_TypeDef* EPWMx, const uint16_t pwmData) +{ + + EPWMx->CMPA = pwmData; + +} + + +/** + * @brief Writes the pulse width modulation (PWM) data value to the + Counter Compare A Hr hardware + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param pwmData The EPWM high resolution data value + */ +inline void EPWM_setCmpAHr(EPWM_TypeDef* EPWMx, const uint16_t pwmData) +{ + + EPWMx->CMPAHR = (pwmData << 8); + +} + + +/** + * @brief Writes the pulse width modulation (PWM) data value to the + Counter Compare B hardware + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param pwmData The EPWM data value + */ +inline void EPWM_write_CmpB(EPWM_TypeDef* EPWMx, const int16_t pwmData) +{ + + int16_t value; + uint16_t period = EPWMx->TBPRD; + int32_t tmp; + + /* Compute the compare A (Q0) from the related duty cycle ratio (Q15) */ + tmp = (int32_t)period * (int32_t)(pwmData); // Q15 = Q0*Q15 + + /* Q0 = (Q15->Q0)/2 + (Q0/2) */ + value = (int16_t)(tmp >> 16) + (int16_t)(period >> 1); + + EPWMx->CMPB = value; + +} + + +/** + * @brief Writes the pulse width modulation (PWM) data value to the + Counter Compare B hardware + * @param EPWMx where x can be 1 to 4 to select the EPWM peripheral + * @param pwmData The EPWM data value + */ +inline void EPWM_setCmpB(EPWM_TypeDef* EPWMx, const uint16_t pwmData) +{ + + EPWMx->CMPB = pwmData; + +} + + + + + +/** + * @} + */ + +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_eqep.c b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_eqep.c new file mode 100644 index 00000000000..a289b669a8a --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_eqep.c @@ -0,0 +1,956 @@ +/** + ****************************************************************************** + * @file ft32f4xx_eqep.c + * @author FMD AE + * @brief This file provides firmware functions to manage the following + * functionalities of the Enhanced Quadrature Encoder Pulse (eQEP): + * + Initialization and Configuration + * + EQEP control + * + Data register access + * + Interrupts and flags management + * @version V1.0.0 + * @date 2025-04-22 + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx_eqep.h" +#include "ft32f4xx_rcc.h" + + +/** @defgroup EQEP + * @brief EQEP driver modules + * @{ + */ + + +/** + * @brief Initialize the EQEP control according to the specified parameters in the + * EQEP_InitTypeDef and initialize the associated handle. + * @param EQEP_InitStruct pointer to a EQEP_InitTypeDef structure that contains the + * configuration information for the specified EQEP peripheral. + * @retval None + */ +void EQEP_Init(EQEP_InitTypeDef* EQEP_InitStruct) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_EQEP_RESET_SOURCE(EQEP_InitStruct->PosCounterResetSrc)); + assert_param(IS_EQEP_SE_INIT(EQEP_InitStruct->SEInitPosCounter)); + assert_param(IS_EQEP_IE_INIT(EQEP_InitStruct->IEInitPosCounter)); + assert_param(IS_EQEP_SE_LATCH(EQEP_InitStruct->SELatchPosCounter)); + assert_param(IS_EQEP_IE_LATCH(EQEP_InitStruct->IELatchPosCounter)); + assert_param(IS_EQEP_CAPTURELATCH_MODE(EQEP_InitStruct->CaptureLatchMode)); + assert_param(IS_EQEP_POS_COUNTER_VALUE(EQEP_InitStruct->PosCounterValue)); + assert_param(IS_EQEP_POS_COUNTER_INIT_VALUE(EQEP_InitStruct->PosCounterInitValue)); + assert_param(IS_EQEP_POS_COUNTER_MAX_VALUE(EQEP_InitStruct->PosCounterMaxValue)); + assert_param(IS_EQEP_POS_COUNTER_CMP_VALUE(EQEP_InitStruct->PosCounterCmpValue)); + assert_param(IS_EQEP_UNIT_TIMER_PERIOD_VALUE(EQEP_InitStruct->UnitTimerPeriodValue)); + assert_param(IS_EQEP_WDG_TIMER_PERIOD_VALUE(EQEP_InitStruct->WdgTimerPeriodValue)); + + + /* Config EQEP control register */ + tmpreg = (uint32_t)((EQEP_InitStruct->PosCounterResetSrc) | + (EQEP_InitStruct->SEInitPosCounter) | + (EQEP_InitStruct->IEInitPosCounter) | + (EQEP_InitStruct->SELatchPosCounter) | + (EQEP_InitStruct->IELatchPosCounter) | + (EQEP_InitStruct->CaptureLatchMode)); + + /* Write to EQEP QEPCTL register */ + EQEP->QEPCTL = tmpreg; + + /* Write the EQEP position counter register */ + EQEP->QPOSCNT = EQEP_InitStruct->PosCounterValue; + + /* Config the initialization value of the EQEP position counter register */ + EQEP->QPOSINIT = EQEP_InitStruct->PosCounterInitValue; + + /* Config the maximum value of the EQEP position counter register */ + EQEP->QPOSMAX = EQEP_InitStruct->PosCounterMaxValue; + + /* Config the compare value of the EQEP position counter register */ + EQEP->QPOSCMP = EQEP_InitStruct->PosCounterCmpValue; + + /* Config the period value of the EQEP unit timer register */ + EQEP->QUPRD = EQEP_InitStruct->UnitTimerPeriodValue; + + /* Config the period value of the EQEP watch dog timer register */ + EQEP->QWDPRD = EQEP_InitStruct->WdgTimerPeriodValue; + + +} + + +/** + * @brief Initialize the EQEP quadrature decoder unit according to the specified parameters in the + * EQEP_QDUInitStruct. + * @param EQEP_QDUInitStruct pointer to a EQEP_QDUInitTypeDef structure that contains the + * configuration information for the specified EQEP quadrature decoder unit. + * @retval None + */ +void EQEP_QDUInit(EQEP_QDUInitTypeDef* EQEP_QDUInitStruct) +{ + uint32_t tmpreg; + + /* Check the parameters */ + assert_param(IS_EQEP_POSCNTSRC_MODE(EQEP_QDUInitStruct->PosCounterSource)); + assert_param(IS_FUNCTIONAL_STATE(EQEP_QDUInitStruct->SyncOutput)); + assert_param(IS_EQEP_SYNC_OUTPUT_PIN(EQEP_QDUInitStruct->SyncOutputPin)); + assert_param(IS_EQEP_EXTERNAL_CLOCK_RATE(EQEP_QDUInitStruct->ExternalClockRate)); + assert_param(IS_FUNCTIONAL_STATE(EQEP_QDUInitStruct->ClockDirSwap)); + assert_param(IS_FUNCTIONAL_STATE(EQEP_QDUInitStruct->IndexGate)); + assert_param(IS_EQEP_QEPA_POLARITY(EQEP_QDUInitStruct->QEPAPolarity)); + assert_param(IS_EQEP_QEPB_POLARITY(EQEP_QDUInitStruct->QEPBPolarity)); + assert_param(IS_EQEP_QEPI_POLARITY(EQEP_QDUInitStruct->QEPIPolarity)); + assert_param(IS_EQEP_QEPS_POLARITY(EQEP_QDUInitStruct->QEPSPolarity)); + + + /* Get the EQEP QEPCTL value */ + tmpreg = EQEP->QDECCTL; + + /* Config EQEP quadrature decoder control register */ + tmpreg &= (uint32_t)~EQEP_QDECCTL_QSRC; + tmpreg |= (uint32_t)(EQEP_QDUInitStruct->PosCounterSource); + + tmpreg |= (uint32_t)((EQEP_QDUInitStruct->ExternalClockRate) | + (EQEP_QDUInitStruct->IndexGate << 9U) | + (EQEP_QDUInitStruct->QEPAPolarity) | + (EQEP_QDUInitStruct->QEPBPolarity) | + (EQEP_QDUInitStruct->QEPIPolarity) | + (EQEP_QDUInitStruct->QEPSPolarity)); + + if (EQEP_QDUInitStruct->SyncOutput == ENABLE) + { + tmpreg |= (uint32_t)(EQEP_QDECCTL_SOEN | + (EQEP_QDUInitStruct->SyncOutputPin)); + } + + if (EQEP_QDUInitStruct->ClockDirSwap == ENABLE) + { + tmpreg |= (uint32_t)EQEP_QDECCTL_SWAP; + } + + if (EQEP_QDUInitStruct->IndexGate == ENABLE) + { + tmpreg |= (uint32_t)EQEP_QDECCTL_IGATE; + } + + /* Write to EQEP QEPCTL register */ + EQEP->QDECCTL = tmpreg; + +} + + +/** + * @brief Initialize the EQEP capture control according to the specified parameters in the + * EQEP_CAPInitStruct. + * @param EQEP_CAPInitStruct pointer to a EQEP_CAPInitTypeDef structure that contains the + * configuration information for the specified EQEP capture unit. + * @retval None + */ +void EQEP_CAPInit(EQEP_CAPInitTypeDef* EQEP_CAPInitStruct) +{ + uint32_t tmpreg; + + /* Check the parameters */ + assert_param(IS_EQEP_CLOCKPRESCALER(EQEP_CAPInitStruct->CaptureClockPrescaler)); + assert_param(IS_EQEP_EVENTPRESCALER(EQEP_CAPInitStruct->UnitPosEventPrescaler)); + assert_param(IS_EQEP_CAPTURE_PERIOD_VALUE(EQEP_CAPInitStruct->CapturePeriodValue)); + + + /* Get the EQEP QCAPCTL value */ + tmpreg = EQEP->QCAPCTL; + + /* Config EQEP capture control register */ + tmpreg &= (uint32_t)~EQEP_QCAPCTL_CEN; + tmpreg |= (uint32_t)(EQEP_CAPInitStruct->CaptureClockPrescaler); + tmpreg |= (uint32_t)(EQEP_CAPInitStruct->UnitPosEventPrescaler); + + /* Write to EQEP QCAPCTL register */ + EQEP->QCAPCTL = tmpreg; + + /* Config the period value of the EQEP capture counter register */ + EQEP->QCPRD = EQEP_CAPInitStruct->CapturePeriodValue; + +} + + + +/** + * @brief Initialize the EQEP position compare control according to the specified + * parameters in the EQEP_PosCmpInitStruct. + * @param EQEP_PosCmpInitStruct pointer to a EQEP_PosCmpInitTypeDef structure + * that contains the configuration information for the specified + * EQEP position compare unit. + * @retval None + */ +void EQEP_POSCMPInit(EQEP_PosCmpInitTypeDef* EQEP_PosCmpInitStruct) +{ + uint32_t tmpreg; + + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(EQEP_PosCmpInitStruct->PosCompareShadow)); + assert_param(IS_EQEP_POSCMP_LOAD(EQEP_PosCmpInitStruct->PosCompareShadowLoad)); + assert_param(IS_EQEP_SYNCOUT_POLARITY(EQEP_PosCmpInitStruct->SyncOutPolarity)); + assert_param(IS_FUNCTIONAL_STATE(EQEP_PosCmpInitStruct->PosCompare)); + assert_param(IS_EQEP_SYNCOUT_PULSE_WIDTH(EQEP_PosCmpInitStruct->SyncOutPulseWidth)); + + + /* Get the EQEP QPOSCTL value */ + tmpreg = EQEP->QPOSCTL; + + /* Config EQEP position compare control register */ + if (EQEP_PosCmpInitStruct->PosCompareShadow == ENABLE) + { + tmpreg |= (uint32_t)EQEP_QPOSCTL_PCSHDW; + } + + tmpreg |= (uint32_t)((EQEP_PosCmpInitStruct->PosCompareShadowLoad) | + (EQEP_PosCmpInitStruct->SyncOutPolarity)); + + if (EQEP_PosCmpInitStruct->PosCompare == ENABLE) + { + tmpreg |= (uint32_t)EQEP_QPOSCTL_PCMPE; + } + + tmpreg |= (uint32_t)(EQEP_PosCmpInitStruct->SyncOutPulseWidth); + + /* Write to EQEP QCAPCTL register */ + EQEP->QPOSCTL = tmpreg; + +} + + +/** + * @brief Fills each EQEP_StructInit member with its default value. + * @param EQEP_InitStruct pointer to a EQEP_InitTypeDef structure + * which will be initialized. + * @retval None + */ +void EQEP_StructInit(EQEP_InitTypeDef* EQEP_InitStruct) +{ + /*---- Reset the parameter values of the EQEP structure ----*/ + /* Initialize the EQEP_PosCounterResetSrc member */ + EQEP_InitStruct->PosCounterResetSrc = 0U; + + /* Initialize the EQEP_SEInitPosCounter member */ + EQEP_InitStruct->SEInitPosCounter = 0U; + + /* Initialize the EQEP_IEInitPosCounter member */ + EQEP_InitStruct->IEInitPosCounter = 0U; + + /* Initialize the EQEP_SELatchPosCounter member */ + EQEP_InitStruct->SELatchPosCounter = 0U; + + /* Initialize the EQEP_IELatchPosCounter member */ + EQEP_InitStruct->IELatchPosCounter = 0U; + + /* Initialize the EQEP_CaptureLatchMode member */ + EQEP_InitStruct->CaptureLatchMode = 0U; + + /* Initialize the EQEP_PosCounterValue member */ + EQEP_InitStruct->PosCounterValue = 0U; + + /* Initialize the EQEP_PosCounterInitValue member */ + EQEP_InitStruct->PosCounterInitValue = 0U; + + /* Initialize the EQEP_PosCounterMaxValue member */ + EQEP_InitStruct->PosCounterMaxValue = 0U; + + /* Initialize the EQEP_PosCounterCmpValue member */ + EQEP_InitStruct->PosCounterCmpValue = 0U; + + /* Initialize the EQEP_UnitTimerPeriodValue member */ + EQEP_InitStruct->UnitTimerPeriodValue = 0U; + + /* Initialize the EQEP_WdgTimerPeriodValue member */ + EQEP_InitStruct->WdgTimerPeriodValue = 0U; + +} + + +/** + * @brief Fills each EQEP_QDUStructInit member with its default value. + * @param EQEP_QDUInitStruct pointer to a EQEP_QDUInitTypeDef structure + * which will be initialized. + * @retval None + */ +void EQEP_QDUStructInit(EQEP_QDUInitTypeDef* EQEP_QDUInitStruct) +{ + /*---- Reset the parameter values of the EQEP quadrature decoder structure ----*/ + /* Initialize the EQEP_PosCounterSource member */ + EQEP_QDUInitStruct->PosCounterSource = 0U; + + /* Initialize the EQEP_SyncOutput member */ + EQEP_QDUInitStruct->SyncOutput = DISABLE; + + /* Initialize the EQEP_SyncOutputPin member */ + EQEP_QDUInitStruct->SyncOutputPin = 0U; + + /* Initialize the EQEP_ExternalClockRate member */ + EQEP_QDUInitStruct->ExternalClockRate = 0U; + + /* Initialize the EQEP_ClockDirSwap member */ + EQEP_QDUInitStruct->ClockDirSwap = DISABLE; + + /* Initialize the EQEP_IndexGate member */ + EQEP_QDUInitStruct->IndexGate = DISABLE; + + /* Initialize the EQEP_QEPAPolarity member */ + EQEP_QDUInitStruct->QEPAPolarity = 0U; + + /* Initialize the EQEP_QEPBPolarity member */ + EQEP_QDUInitStruct->QEPBPolarity = 0U; + + /* Initialize the EQEP_QEPIPolarity member */ + EQEP_QDUInitStruct->QEPIPolarity = 0U; + + /* Initialize the EQEP_QEPSPolarity member */ + EQEP_QDUInitStruct->QEPSPolarity = 0U; + +} + + +/** + * @brief Fills each EQEP_CAPStructInit member with its default value. + * @param EQEP_CAPInitStruct pointer to a EQEP_CAPInitTypeDef structure + * which will be initialized. + * @retval None + */ +void EQEP_CAPStructInit(EQEP_CAPInitTypeDef* EQEP_CAPInitStruct) +{ + /*---- Reset the parameter values of the EQEP capture structure ----*/ + /* Initialize the EQEP_CaptureClockPrescaler member */ + EQEP_CAPInitStruct->CaptureClockPrescaler = 0U; + + /* Initialize the EQEP_UnitPosEventPrescaler member */ + EQEP_CAPInitStruct->UnitPosEventPrescaler = 0U; + + /* Initialize the EQEP_CapturePeriodValue member */ + EQEP_CAPInitStruct->CapturePeriodValue = 0U; + +} + + +/** + * @brief Fills each EQEP_POSCMPStructInit member with its default value. + * @param EQEP_PosCmpInitStruct pointer to a EQEP_PosCmpInitTypeDef structure + * which will be initialized. + * @retval None + */ +void EQEP_POSCMPStructInit(EQEP_PosCmpInitTypeDef* EQEP_PosCmpInitStruct) +{ + /*---- Reset the parameter values of the EQEP position compare structure ----*/ + /* Initialize the EQEP_PosCompareShadow member */ + EQEP_PosCmpInitStruct->PosCompareShadow = DISABLE; + + /* Initialize the EQEP_PosCompareShadowLoad member */ + EQEP_PosCmpInitStruct->PosCompareShadowLoad = 0U; + + /* Initialize the EQEP_SyncOutPolarity member */ + EQEP_PosCmpInitStruct->SyncOutPolarity = 0U; + + /* Initialize the EQEP_PosCompare member */ + EQEP_PosCmpInitStruct->PosCompare = DISABLE; + + /* Initialize the EQEP_SyncOutPulseWidth member */ + EQEP_PosCmpInitStruct->SyncOutPulseWidth = 0U; + +} + + + + + +/** + * @brief DeInitialize the EQEP peripheral. + * @retval None + */ +void EQEP_DeInit() +{ + /* Enable EQEP reset state */ + RCC_APB2PeriphResetCmd(RCC_APB2PeriphRst_EQEP, ENABLE); + + /* Release EQEP from reset state */ + RCC_APB2PeriphResetCmd(RCC_APB2PeriphRst_EQEP, DISABLE); + +} + + +/** + * @brief Enables or disables the following EQEP counters. + * @arg Position counter(QPOSCNT) + * @arg Unit timer(QUTMR) + * @arg Watch dog timer(QWDTMR) + * @arg Capture timer(QCTMR) + * @note While resetting the position counter, the internal operating + * flags and read-only registers will also be reset. However, + * the control and configuration registers are not disturbed + * by the software reset. + * @note When QEPCTL.OPEN is disabled, some flags in the QFLG register + * do not get reset or cleared and show the actual state of that flag. + * @param EQEP_SUBMDU_TYPE The data registers of the EQEP. + * This parameter can be one of the following values: + * @arg EQEP_POS_CNT : EQEP position counter. + * @arg EQEP_UNIT_TMR: EQEP unit timer. + * @arg EQEP_WTD_TMR : EQEP watch dog timer. + * @arg EQEP_CAP_TMR : EQEP capture timer. + * @param NewState New state of the EQEP position counter. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void EQEP_Cmd(uint16_t EQEP_SUBMDU_TYPE, FunctionalState NewState) +{ + uint32_t tmpreg = 0; + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + assert_param(IS_EQEP_SUBMDU_TYPE(EQEP_SUBMDU_TYPE)); + + if ((EQEP_SUBMDU_TYPE & EQEP_POS_CNT) != 0U) + { + /* Enable the EQEP position counter, QPOSCNT free-running */ + tmpreg |= (uint32_t)EQEP_QEPCTL_QPEN; + } + if ((EQEP_SUBMDU_TYPE & EQEP_UNIT_TMR) != 0U) + { + /* Enable the EQEP unit timer, QUTMR free-running */ + tmpreg |= (uint32_t)EQEP_QEPCTL_UTE; + } + if ((EQEP_SUBMDU_TYPE & EQEP_WTD_TMR) != 0U) + { + /* Enable the EQEP watch dog timer, QWDTMR free-running */ + tmpreg |= (uint32_t)EQEP_QEPCTL_WDE; + } + if ((EQEP_SUBMDU_TYPE & EQEP_CAP_TMR) != 0U) + { + if (NewState != DISABLE) + { + /* Enable the EQEP capture timer, QCTMR free-running */ + EQEP->QCAPCTL |= (uint32_t)EQEP_QCAPCTL_CEN; + } + else + { + /* Disable the EQEP capture timer, QCTMR reset */ + EQEP->QCAPCTL &= (uint32_t)~EQEP_QCAPCTL_CEN; + } + } + + if (NewState != DISABLE) + { + /* Write to QEPCTL */ + EQEP->QEPCTL |= tmpreg; + } + else + { + /* Write to QEPCTL */ + EQEP->QEPCTL &= ~tmpreg; + } +} + +//void EQEP_Cmd(uint8_t EQEP_SUBMDU_TYPE, FunctionalState NewState) +//{ +// uint32_t tmpreg = 0; +// /* Check the parameters */ +// assert_param(IS_FUNCTIONAL_STATE(NewState)); +// assert_param(IS_EQEP_SUBMDU_TYPE(EQEP_SUBMDU_TYPE)); +// +// if(NewState != DISABLE) +// { +// if((EQEP_SUBMDU_TYPE & EQEP_QPOSCNT) != 0U) +// { +// /* Enable the EQEP position counter, QPOSCNT free-running */ +// tmpreg |= (uint32_t)EQEP_QEPCTL_QPEN; +// } +// if((EQEP_SUBMDU_TYPE & EQEP_QUTMR) != 0U) +// { +// /* Enable the EQEP unit timer, QUTMR free-running */ +// tmpreg |= (uint32_t)EQEP_QEPCTL_UTE; +// } +// if((EQEP_SUBMDU_TYPE & EQEP_QWDTMR) != 0U) +// { +// /* Enable the EQEP watch dog timer, QWDTMR free-running */ +// tmpreg |= (uint32_t)EQEP_QEPCTL_WDE; +// } +// if((EQEP_SUBMDU_TYPE & EQEP_QCTMR) != 0U) +// { +// /* Enable the EQEP capture timer, QCTMR free-running */ +// EQEP->QCAPCTL |= (uint32_t)EQEP_QCAPCTL_CEN; +// } +// +// /* Write to QEPCTL */ +// EQEP->QEPCTL |= tmpreg; +// } +// else +// { +// tmpreg = EQEP->QEPCTL; +// +// if((EQEP_SUBMDU_TYPE & EQEP_QPOSCNT) != 0U) +// { +// /* Disable the EQEP position counter, QPOSCNT reset */ +// tmpreg &= (uint32_t)~EQEP_QEPCTL_QPEN; +// } +// if((EQEP_SUBMDU_TYPE & EQEP_QUTMR) != 0U) +// { +// /* Disable the EQEP unit timer, QUTMR reset */ +// tmpreg &= (uint32_t)~EQEP_QEPCTL_UTE; +// } +// if((EQEP_SUBMDU_TYPE & EQEP_QWDTMR) != 0U) +// { +// /* Disable the EQEP watch dog timer, QWDTMR reset */ +// tmpreg &= (uint32_t)~EQEP_QEPCTL_WDE; +// } +// if((EQEP_SUBMDU_TYPE & EQEP_QCTMR) != 0U) +// { +// /* Disable the EQEP capture timer, QCTMR reset */ +// EQEP->QCAPCTL &= (uint32_t)~EQEP_QCAPCTL_CEN; +// } +// +// /* Write to QEPCTL */ +// EQEP->QEPCTL = tmpreg; +// } +//} + + +/** + * @brief Software initialization position counter. + * @note The SWI bit will not be automatically cleared. It is + * necessary to use this function again and pass the DISABLE + * parameter to clear this bit. + * @param NewState New state of the QEPCTL.SWI. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void EQEP_SoftwareInitPositionCounter(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the QEPCTL.SWI, initialize the position counter */ + EQEP->QEPCTL |= (uint32_t)EQEP_QEPCTL_SWI; + } + else + { + /* Disable the EQEP unit timer, QUTMR reset */ + EQEP->QEPCTL &= (uint32_t)~EQEP_QEPCTL_SWI; + } +} + + + + + +/** + * @brief Write a value to the specified EQEP register. + * @param EQEP_REG_TYPE The data registers of the EQEP. + * This parameter can be one of the following values: + * @arg EQEP_QPOSCNT : EQEP position counter register. + * @arg EQEP_QPOSINIT : EQEP position counter initialization register. + * @arg EQEP_QPOSMAX : EQEP position counter maximum register. + * @arg EQEP_QPOSCMP : EQEP position counter compare register. + * @arg EQEP_QUTMR : EQEP unit timer. + * @arg EQEP_QUPRD : EQEP unit timer period register. + * @arg EQEP_QWDTMR : EQEP watch dog timer. + * @arg EQEP_QWDPRD : EQEP watch dog timer period register. + * @arg EQEP_QCTMR : EQEP capture timer. + * @arg EQEP_QCPRD : EQEP capture timer period register. + * @param Value The values of the specified EQEP registers. + * @retval None + */ +void EQEP_WriteDataRegister(uint16_t EQEP_REG_TYPE, uint32_t Value) +{ + /* Check the parameters */ + assert_param(IS_EQEP_REG_TYPE(EQEP_REG_TYPE)); + + if (EQEP_REG_TYPE == EQEP_QPOSCNT) + { + /* Write the value to QPOSCNT */ + EQEP->QPOSCNT = ((uint32_t)Value); + } + if (EQEP_REG_TYPE == EQEP_QPOSINIT) + { + /* Write the value to QPOSINIT */ + EQEP->QPOSINIT = ((uint32_t)Value); + } + if (EQEP_REG_TYPE == EQEP_QPOSMAX) + { + /* Write the value to QPOSMAX */ + EQEP->QPOSMAX = ((uint32_t)Value); + } + if (EQEP_REG_TYPE == EQEP_QPOSCMP) + { + /* Write the value to QPOSCMP */ + EQEP->QPOSCMP = ((uint32_t)Value); + } + if (EQEP_REG_TYPE == EQEP_QUTMR) + { + /* Write the value to QUTMR */ + EQEP->QUTMR = ((uint32_t)Value); + } + if (EQEP_REG_TYPE == EQEP_QUPRD) + { + /* Write the value to QUPRD */ + EQEP->QUPRD = ((uint32_t)Value); + } + if (EQEP_REG_TYPE == EQEP_QWDTMR) + { + /* Write the value to QWDTMR */ + EQEP->QWDTMR = ((uint32_t)Value); + } + if (EQEP_REG_TYPE == EQEP_QWDPRD) + { + /* Write the value to QWDPRD */ + EQEP->QWDPRD = ((uint32_t)Value); + } + if (EQEP_REG_TYPE == EQEP_QCTMR) + { + /* Write the value to QCTMR */ + EQEP->QCTMR = ((uint32_t)Value); + } + if (EQEP_REG_TYPE == EQEP_QCPRD) + { + /* Write the value to QCPRD */ + EQEP->QCPRD = ((uint32_t)Value); + } +} + + +/** + * @brief Returns the value of the specified EQEP registers. + * @param EQEP_REG_TYPE The data registers of the EQEP. + * This parameter can be one of the following values: + * @arg EQEP_QPOSCNT : EQEP position counter register. + * @arg EQEP_QPOSINIT : EQEP position counter initialization register. + * @arg EQEP_QPOSMAX : EQEP position counter maximum register. + * @arg EQEP_QPOSCMP : EQEP position counter compare register. + * @arg EQEP_QPOSILAT : EQEP index position latch register. + * @arg EQEP_QPOSSLAT : EQEP strobe position latch register. + * @arg EQEP_QPOSLAT : EQEP position latch register. + * @arg EQEP_QUTMR : EQEP unit timer. + * @arg EQEP_QUPRD : EQEP unit timer period register. + * @arg EQEP_QWDTMR : EQEP watch dog timer. + * @arg EQEP_QWDPRD : EQEP watch dog timer period register. + * @arg EQEP_QCTMR : EQEP capture timer. + * @arg EQEP_QCPRD : EQEP capture timer period register. + * @arg EQEP_QCTMRLAT : EQEP capture timer latch register. + * @arg EQEP_QCPRDLAT : EQEP capture timer period latch register. + * @retval The value of the specified EQEP registers. + */ +uint32_t EQEP_GetDataRegister(uint16_t EQEP_REG_TYPE) +{ + uint32_t tmpreg = 0; + /* Check the parameters */ + assert_param(IS_EQEP_REG_TYPE(EQEP_REG_TYPE)); + + + if (EQEP_REG_TYPE == EQEP_QPOSCNT) + { + /* Get the value of QPOSCNT */ + tmpreg = ((uint32_t)(EQEP->QPOSCNT)); + } + if (EQEP_REG_TYPE == EQEP_QPOSINIT) + { + /* Get the value of QPOSINIT */ + tmpreg = ((uint32_t)(EQEP->QPOSINIT)); + } + if (EQEP_REG_TYPE == EQEP_QPOSMAX) + { + /* Get the value of QPOSMAX */ + tmpreg = ((uint32_t)(EQEP->QPOSMAX)); + } + if (EQEP_REG_TYPE == EQEP_QPOSCMP) + { + /* Get the value of QPOSCMP */ + tmpreg = ((uint32_t)(EQEP->QPOSCMP)); + } + if (EQEP_REG_TYPE == EQEP_QPOSILAT) + { + /* Get the value of */ + tmpreg = ((uint32_t)(EQEP->QPOSILAT)); + } + if (EQEP_REG_TYPE == EQEP_QPOSSLAT) + { + /* Get the value of */ + tmpreg = ((uint32_t)(EQEP->QPOSSLAT)); + } + if (EQEP_REG_TYPE == EQEP_QPOSLAT) + { + /* Get the value of */ + tmpreg = ((uint32_t)(EQEP->QPOSLAT)); + } + if (EQEP_REG_TYPE == EQEP_QUTMR) + { + /* Get the value of QUTMR */ + tmpreg = ((uint32_t)(EQEP->QUTMR)); + } + if (EQEP_REG_TYPE == EQEP_QUPRD) + { + /* Get the value of QUPRD */ + tmpreg = ((uint32_t)(EQEP->QUPRD)); + } + if (EQEP_REG_TYPE == EQEP_QWDTMR) + { + /* Get the value of QWDTMR */ + tmpreg = ((uint32_t)(EQEP->QWDTMR)); + } + if (EQEP_REG_TYPE == EQEP_QWDPRD) + { + /* Get the value of QWDPRD */ + tmpreg = ((uint32_t)(EQEP->QWDPRD)); + } + if (EQEP_REG_TYPE == EQEP_QCTMR) + { + /* Get the value of QCTMR */ + tmpreg = ((uint32_t)(EQEP->QCTMR)); + } + if (EQEP_REG_TYPE == EQEP_QCPRD) + { + /* Get the value of QCPRD */ + tmpreg = ((uint32_t)(EQEP->QCPRD)); + } + if (EQEP_REG_TYPE == EQEP_QCTMRLAT) + { + /* Get the value of QCTMRLAT */ + tmpreg = ((uint32_t)(EQEP->QCTMRLAT)); + } + if (EQEP_REG_TYPE == EQEP_QCPRDLAT) + { + /* Get the value of QCPRDLAT */ + tmpreg = ((uint32_t)(EQEP->QCPRDLAT)); + } + + /* Return the value of data register */ + return tmpreg; +} + + +/** + * @brief Enable the specified EQEP interrupts. + * @param EQEP_IT specifies the EQEP interrupt sources to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg EQEP_IT_PCE Position counter error interrupt + * @arg EQEP_IT_PHE Quadrature phase error interrupt + * @arg EQEP_IT_QDC Quadrature direction change interrupt + * @arg EQEP_IT_WTO Watchdog time out interrupt + * @arg EQEP_IT_PCU Position counter underflow interrupt + * @arg EQEP_IT_PCO Position counter overflow interrupt + * @arg EQEP_IT_PCR Position compare ready interrupt + * @arg EQEP_IT_PCM Position compare match interrupt + * @arg EQEP_IT_SEL Strobe event latch interrupt + * @arg EQEP_IT_IEL Index event latch interrupt + * @arg EQEP_IT_UTO Unit time out interrupt + * @param NewState new state of the specified EQEP interrupt. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void EQEP_ITConfig(uint16_t EQEP_IT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_EQEP_IT(EQEP_IT)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + + if (NewState != DISABLE) + { + /* Enable the selected EQEP interrupts */ + EQEP->QEINT |= EQEP_IT; + } + else + { + /* Disable the selected EQEP interrupts */ + EQEP->QEINT &= ~EQEP_IT; + } +} + + +/** + * @brief Clears the EQEP interrupt flags. + * @param EQEP_FLAG specifies the EQEP interrupt flag to clear. + * This parameter can be one of the following values: + * @arg EQEP_FLAG_INT EQEP global interrupt flag + * @arg EQEP_FLAG_PCE Position counter error interrupt flag + * @arg EQEP_FLAG_PHE Quadrature phase error interrupt flag + * @arg EQEP_FLAG_QDC Quadrature direction change interrupt flag + * @arg EQEP_FLAG_WTO Watchdog time out interrupt flag + * @arg EQEP_FLAG_PCU Position counter underflow interrupt flag + * @arg EQEP_FLAG_PCO Position counter overflow interrupt flag + * @arg EQEP_FLAG_PCR Position compare ready interrupt flag + * @arg EQEP_FLAG_PCM Position compare match interrupt flag + * @arg EQEP_FLAG_SEL Strobe event latch interrupt flag + * @arg EQEP_FLAG_IEL Index event latch interrupt flag + * @arg EQEP_FLAG_UTO Unit time out interrupt flag + * @retval None + */ +void EQEP_ClearFlag(uint16_t EQEP_FLAG) +{ + /* Check the parameters */ + assert_param(IS_EQEP_FLAG(EQEP_FLAG)); + + /* Clear the selected EQEP flags */ + EQEP->QCLR = EQEP_FLAG; +} + + +/** + * @brief Force the specified EQEP interrupt. + * @param EQEP_IT specifies the EQEP interrupt sources to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg EQEP_IT_PCE Position counter error interrupt + * @arg EQEP_IT_PHE Quadrature phase error interrupt + * @arg EQEP_IT_QDC Quadrature direction change interrupt + * @arg EQEP_IT_WTO Watchdog time out interrupt + * @arg EQEP_IT_PCU Position counter underflow interrupt + * @arg EQEP_IT_PCO Position counter overflow interrupt + * @arg EQEP_IT_PCR Position compare ready interrupt + * @arg EQEP_IT_PCM Position compare match interrupt + * @arg EQEP_IT_SEL Strobe event latch interrupt + * @arg EQEP_IT_IEL Index event latch interrupt + * @arg EQEP_IT_UTO Unit time out interrupt + * @retval None + */ +void EQEP_ITForce(uint16_t EQEP_IT) +{ + /* Check the parameters */ + assert_param(IS_EQEP_IT(EQEP_IT)); + + /* Force the selected EQEP interrupt */ + EQEP->QFRC = EQEP_IT; +} + + +/** + * @brief Checks whether the specified EQEP interrupt has occurred or not. + * @param EQEP_IT specifies the EQEP interrupt sources to check. + * This parameter can be any combination of the following values: + * @arg EQEP_IT_PCE Position counter error interrupt + * @arg EQEP_IT_PHE Quadrature phase error interrupt + * @arg EQEP_IT_QDC Quadrature direction change interrupt + * @arg EQEP_IT_WTO Watchdog time out interrupt + * @arg EQEP_IT_PCU Position counter underflow interrupt + * @arg EQEP_IT_PCO Position counter overflow interrupt + * @arg EQEP_IT_PCR Position compare ready interrupt + * @arg EQEP_IT_PCM Position compare match interrupt + * @arg EQEP_IT_SEL Strobe event latch interrupt + * @arg EQEP_IT_IEL Index event latch interrupt + * @arg EQEP_IT_UTO Unit time out interrupt + * @retval The new state of EQEP_IT (SET or RESET). + */ +ITStatus EQEP_GetITStatus(uint16_t EQEP_IT) +{ + /* Check the parameters */ + assert_param(IS_EQEP_IT(EQEP_IT)); + + + ITStatus bitstatus = RESET; + + /* Check the status of the specified EQEP interrupt */ + if ((uint32_t)(EQEP->QEINT & EQEP_IT) != (uint32_t)RESET) + { + /* EQEP_IT is set */ + bitstatus = SET; + } + else + { + /* EQEP_IT is reset */ + bitstatus = RESET; + } + /* Return the EQEP_IT status */ + return bitstatus; + +} + + +/** + * @brief Checks whether the specified EQEP flag has occurred or not. + * @param EQEP_FLAG specifies the EQEP flag to check. + * This parameter can be any combination of the following values: + * @arg EQEP_FLAG_INT EQEP global interrupt flag + * @arg EQEP_FLAG_PCE Position counter error interrupt flag + * @arg EQEP_FLAG_PHE Quadrature phase error interrupt flag + * @arg EQEP_FLAG_QDC Quadrature direction change interrupt flag + * @arg EQEP_FLAG_WTO Watchdog time out interrupt flag + * @arg EQEP_FLAG_PCU Position counter underflow interrupt flag + * @arg EQEP_FLAG_PCO Position counter overflow interrupt flag + * @arg EQEP_FLAG_PCR Position compare ready interrupt flag + * @arg EQEP_FLAG_PCM Position compare match interrupt flag + * @arg EQEP_FLAG_SEL Strobe event latch interrupt flag + * @arg EQEP_FLAG_IEL Index event latch interrupt flag + * @arg EQEP_FLAG_UTO Unit time out interrupt flag + * @retval The new state of EQEP_FLAG (SET or RESET). + */ +FlagStatus EQEP_GetFlagStatus(uint16_t EQEP_FLAG) +{ + /* Check the parameters */ + assert_param(IS_EQEP_FLAG(EQEP_FLAG)); + + + FlagStatus bitstatus = RESET; + + /* Check the status of the specified EQEP flag */ + if ((uint32_t)(EQEP->QFLG & EQEP_FLAG) != (uint32_t)RESET) + { + /* EQEP_FLAG is set */ + bitstatus = SET; + } + else + { + /* EQEP_FLAG is reset */ + bitstatus = RESET; + } + /* Return the EQEP_FLAG status */ + return bitstatus; + +} + + +/** + * @brief Checks whether the specified EQEP status has occurred or not. + * @param EQEP_STATUS specifies the EQEP status sources to check. + * This parameter can be any combination of the following values: + * @arg EQEP_STATUS_UPEVNT Unit position event flag + * @arg EQEP_STATUS_FIDF Direction on the first index marker + * @arg EQEP_STATUS_QDF Quadrature direction flag + * @arg EQEP_STATUS_QDLF EQEP direction latch flag + * @arg EQEP_STATUS_COEF Capture overflow error flag + * @arg EQEP_STATUS_CDEF Capture direction error flag + * @arg EQEP_STATUS_FIMF First index marker flag + * @arg EQEP_STATUS_PCEF Position counter error flag + * @retval The new state of EQEP_STATUS (SET or RESET). + */ +FlagStatus EQEP_GetStatus(uint8_t EQEP_STATUS) +{ + /* Check the parameters */ + assert_param(IS_EQEP_STATUS(EQEP_STATUS)); + + + FlagStatus bitstatus = RESET; + + /* Check the status of the specified EQEP status */ + if ((uint32_t)(EQEP->QEPSTS & EQEP_STATUS) != (uint32_t)RESET) + { + /* EQEP_STATUS is set */ + bitstatus = SET; + } + else + { + /* EQEP_STATUS is reset */ + bitstatus = RESET; + } + /* Return the EQEP_STATUS status */ + return bitstatus; + +} + + + + + + +/** + * @} + */ + +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_eth.c b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_eth.c new file mode 100644 index 00000000000..0bd060e638e --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_eth.c @@ -0,0 +1,2841 @@ +/** + ************************************************************************** + * @file ft32f4xx_eth.c + * @author xcao + * @brief heth module driver + * This file provides firmware functions to manage the following + * functionalities of the Ethernet (heth) peripheral: + * + Initialization and deinitialization functions + * + IO operation :functions + * + Peripheral Control funtions + * + Peripheral State and Errors functions + * + ************************************************************************** + * @attention + * + ************************************************************************** + @verbatim + ========================================================================== + #### How to use this driver + ========================================================================== + [..] + The heth driver can be used as follows: + + (#)Declare a ETH_HandleTypeDef handle structure, for example: + ETH_HandleTypeDef heth; + + (#)Fill parameter of Init structure in heth handle + + (#)Call ETH_Init() API to initialize the Ethernet peripheral (MAC,DMA ...) + + (#)Initialize the heth low level resources through the ETH_MspInit() API: + (##) Enable the Ethernet interface clock using + (+++) RCC_ETHMAC_CLK_ENABLE() + (+++) RCC_ETHTX_CLK_ENABLE() + (+++) RCC_ETHRX_CLK_ENABLE() + + (##) Initialize the related GPIO clocks + (##) Configure Ethernet pinout + (##) Configure Ethernet NVIC interrupt (in Interrupt mode) + + (#) Ethernet data reception is asynchronous, so call the following API + to start the listening mode: + (##) ETH_Start(): + This API starts the MAC and DMA transmission and reception process, + without enabling end of transfer interrupts, in this mode user + has to poll for data reception by calling ETH_ReadData() + (##) ETH_Start_IT(): + This API starts the MAC and DMA transmission and reception process, + end of transfer interrupts are enabled in this mode, + ETH_RxCpltCallback() will be executed when an Ethernet packet is received + + (#) When data is received user can call the following API to get received data: + (##) ETH_ReadData(): Read a received packet + + (#) For transmission path, two APIs are available: + (##) ETH_Transmit(): Transmit an heth frame in blocking mode + (##) ETH_Transmit_IT(): Transmit an heth frame in interrupt mode, + ETH_TxCpltCallback() will be executed when end of transfer occur + + (#) Communication with an external PHY device: + (##) ETH_ReadPHYRegister(): Read a register from an external PHY + (##) ETH_WritePHYRegister(): Write data to an external RHY register + + (#) Configure the Ethernet MAC after heth peripheral initialization + (##) ETH_GetMACConfig(): Get MAC actual configuration into ETH_MACConfigTypeDef + (##) ETH_SetMACConfig(): Set MAC configuration based on ETH_MACConfigTypeDef + + (#) Configure the Ethernet DMA after heth peripheral initialization + (##) ETH_GetDMAConfig(): Get DMA actual configuration into ETH_DMAConfigTypeDef + (##) ETH_SetDMAConfig(): Set DMA configuration based on ETH_DMAConfigTypeDef + + (#) Configure the Ethernet PTP after heth peripheral initialization + (##) Define ETH_USE_PTP to use PTP APIs. + (##) ETH_PTP_GetConfig(): Get PTP actual configuration into ETH_PTP_ConfigTypeDef + (##) ETH_PTP_SetConfig(): Set PTP configuration based on ETH_PTP_ConfigTypeDef + (##) ETH_PTP_GetTime(): Get Seconds and Nanoseconds for the Ethernet PTP registers + (##) ETH_PTP_SetTime(): Set Seconds and Nanoseconds for the Ethernet PTP registers + (##) ETH_PTP_AddTimeOffset(): Add Seconds and Nanoseconds offset for the Ethernet PTP registers + (##) ETH_PTP_InsertTxTimestamp(): Insert Timestamp in transmission + (##) ETH_PTP_GetTxTimestamp(): Get transmission timestamp + (##) ETH_PTP_GetRxTimestamp(): Get reception timestamp + + + @endverbatim + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx_eth.h" +#include "ft32f4xx_misc.h" + +//#if defined(eth) + +/** @defgroup eth eth + * @brief eth module driver + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @addtogroup ETH_Private_Constants heth Private Constants + * @{ + */ +#define ETH_MAC_CFG_MASK 0x0FFBFF7FU +#define ETH_MAC_EXTDCFG_MASK 0x3F073FFFU +#define ETH_MAC_PKTFILT_MASK 0x800107FFU +#define ETH_MAC_WTDTO_MASK 0x0000010FU +#define ETH_MAC_TXFLCTL_MASK 0xFFFF00F3U +#define ETH_MAC_RXFLCTL_MASK 0x00000003U +#define ETH_MTL_TXQOPMODE_MASK 0x00000073U +#define ETH_MTL_RXQOPMODE_MASK 0x0000007BU + +#define ETH_DMA_OPMODE_MASK 0x00037A03U +#define ETH_DMA_SYSBUSMODE_MASK 0x0000D001U +#define ETH_DMA_CTL_MASK 0x001D0000U +#define ETH_DMA_TXCTL_MASK 0x007F0011U +#define ETH_DMA_RXCTL_MASK 0x807F7FFFU +#define ETH_MAC_PMTCTLSTU_MASK (ETH_MAC_PMTCTLSTU_PWRDWN | ETH_MAC_PMTCTLSTU_RWKPKTEN | \ + ETH_MAC_PMTCTLSTU_MGKPKTEN | ETH_MAC_PMTCTLSTU_GLBLUCAST | \ + ETH_MAC_PMTCTLSTU_RWKPFE) + +/* Timeout values */ +#define ETH_DMARXNDESCWBF_ERRORS_MASK ((uint32_t) (ETH_DMARXNDESCWBF_DE | ETH_DMARXNDESCWBF_RE | \ + ETH_DMARXNDESCWBF_OE | ETH_DMARXNDESCWBF_RWT |\ + ETH_DMARXNDESCWBF_GP | ETH_DMARXNDESCWBF_CE)) + +#define ETH_PTP_TSCTL_MASK 0x110FFF3FU +#define ETH_PTP_SYSTMSECUPDT 0xFFFFFFFFU +#define ETH_PTP_SYSTMNSECUPDT 0xFFFFFFFFU +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup ETH_Private_Macros heth Private Macros + * @{ + */ +/* Helper macros for TX descriptor handling */ +#define INCR_TX_DESC_INDEX(inx, offset) do {\ + (inx) += (offset);\ + if ((inx) >= (uint32_t)ETH_TX_DESC_CNT){\ + (inx) = ((inx) - (uint32_t)ETH_TX_DESC_CNT);}\ + } while (0) + +/* Helper macros for RX descriptor handling */ +#define INCR_RX_DESC_INDEX(inx, offset) do {\ + (inx) += (offset);\ + if ((inx) >= (uint32_t)ETH_RX_DESC_CNT){\ + (inx) = ((inx) - (uint32_t)ETH_RX_DESC_CNT);}\ + } while (0) + + +//#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))) + +/** + * @} + */ + +/* Private function prototypes -----------------------------------------------*/ +/** @defgroup ETH_Private_Functions heth Private Functions + * @{ + */ + + +/** + * @} + */ + +/* Exported functions ---------------------------------------------------------*/ +/** @defgroup ETH_Exported_Functions heth Exported Functions + * @{ + */ + +/** @defgroup ETH_Exported_Functions_Group1 Initialization and deinitialization functions + * @brief Initialization and Configuration functions + * +@verbatim +=============================================================================== + ##### Initialization and Configuration functions ##### + =============================================================================== + [..] This subsection provides a set of functions allowing to initialize and + deinitialize the heth peripheral: + + (+) User must Implement ETH_MspInit() function in which he configures + all related peripherals resources (CLOCK, GPIO and NVIC ). + + (+) Call the function ETH_Init() to configure the selected device with + the selected configuration: + (++) MAC address + (++) Media interface (MII or RMII) + (++) Rx DMA Descriptors Tab + (++) Tx DMA Descriptors Tab + (++) Length of Rx Buffers + + (+) Call the function ETH_DeInit() to restore the default configuration + of the selected heth peripheral. + +@endverbatim + * @{ + */ + +/** + * @brief Initialize the Ethernet peripheral registers. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval uint32_t + */ +uint32_t ETH_Init(ETH_HandleTypeDef *heth) +{ + uint32_t tickstart; + + if (heth->gState == ETH_STATE_RESET) + { + + heth->gState = ETH_STATE_BUSY; + /* Init the low level hardware : GPIO, CLOCK, NVIC. */ + ETH_MspInit(heth); + } + + /* TODO __RCC_SYSCFG_CLK_ENABLE();*/ + RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN; + if (heth->Init.MediaInterface == ETH_MII_MODE) + { + SYSCFG->PMC &= ~SYSCFG_PMC_MII_RMII_SEL; + } + else + { + SYSCFG->PMC |= SYSCFG_PMC_MII_RMII_SEL; + } + + /* Ethernet Software reset */ + /* Set the SWR bit: resets all MAC subsystem internal registers and logic */ + /* After reset all the registers holds their respective reset values */ + heth->Instance->ETH_DMA_OPMODE |= ETH_DMA_OPMODE_SWR; + + /* TODO Get tick */ + tickstart = GetTick();//somi + + /* TODO Wait for software reset */ + while (READ_BIT(heth->Instance->ETH_DMA_OPMODE, ETH_DMA_OPMODE_SWR) > 0U) + { + if (((GetTick() - tickstart) > ETH_SWRESET_TIMEOUT)) + { + heth->ErrorCode = ETH_ERROR_TIMEOUT; + heth->gState = ETH_STATE_ERROR; + return ERROR; + } + } + + /*------------------ MAC, MTL and DMA default Configuration ----------------*/ + ETH_MACDMAConfig(heth); + + /* SET DSL to 64 bit */ + heth->Instance->ETH_DMA_CTL |= ETH_DMA_CTL_DSL_64BIT; + + /* Set Receive Buffers Length (must be a multiple of 4) */ + if ((heth->Init.RxBuffLen % 0x4U) != 0x0U) + { + /* Set Error Code */ + heth->ErrorCode = ETH_ERROR_PARAM; + /* Set State as Error */ + heth->gState = ETH_STATE_ERROR; + /* Return Error */ + return HAL_ERROR; + } + else + { + /* Set Receive Buffers Length (must be a multiple of 4) */ + heth->Instance->ETH_DMA_RXCTL = (((heth->Instance->ETH_DMA_RXCTL) & (~(ETH_DMA_RXCTL_RBSZ))) | ((heth->Init.RxBuffLen) << 1)); + } + + /*------------------ DMA Tx Descriptors Configuration ----------------------*/ + ETH_DMATxDescListInit(heth); + + /*------------------ DMA Rx Descriptors Configuration ----------------------*/ + ETH_DMARxDescListInit(heth); + + /*--------------------- ETHERNET MAC Address Configuration ------------------*/ + /* Set MAC addr bits 32 to 47 */ + heth->Instance->ETH_MAC_ADDRH0 = (((uint32_t)(heth->Init.MACAddr[5]) << 8) | (uint32_t)heth->Init.MACAddr[4]); + /* Set MAC addr bits 0 to 31 */ + heth->Instance->ETH_MAC_ADDRL0 = (((uint32_t)(heth->Init.MACAddr[3]) << 24) | ((uint32_t)(heth->Init.MACAddr[2]) << 16) | + ((uint32_t)(heth->Init.MACAddr[1]) << 8) | (uint32_t)heth->Init.MACAddr[0]); + + /* Disable Rx MMC Interrupts */ + heth->Instance->ETH_MMC_RXIRMSK = (ETH_MMC_RXIRMSK_RXCRCERPIM | ETH_MMC_RXIRMSK_RXALGNERPIM | ETH_MMC_RXIRMSK_RXUCGPIM); + /* Disable Tx MMC Interrupts */ + heth->Instance->ETH_MMC_TXIRMSK = (ETH_MMC_TXIRMSK_TXSCOLGPIM | ETH_MMC_TXIRMSK_TXMCOLGPIM); + + heth->ErrorCode = ETH_ERROR_NONE; + heth->gState = ETH_STATE_READY; + + return HAL_OK; +} + +/** + * @brief DeInitializes the heth peripheral. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval uint32_t + */ +uint32_t ETH_DeInit(ETH_HandleTypeDef *heth) +{ + + /* Set the ETH peripheral state to BUSY */ + heth->gState = ETH_STATE_BUSY; + /* De-Init the low level hardware : GPIO, CLOCK, NVIC. */ + ETH_MspDeInit(heth); + /* Set ETH HAL state to Disabled */ + heth->gState = ETH_STATE_RESET; + + return HAL_OK; +} + +/** + * @brief Initializes the heth MSP. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ +//__weak void ETH_MspInit(ETH_HandleTypeDef *heth) +void __attribute__((weak)) ETH_MspInit(ETH_HandleTypeDef *heth) +{ + UNUSED(heth); +} + +/** + * @brief DeInitializes heth MSP. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ +//__weak void ETH_MspDeInit(ETH_HandleTypeDef *heth) +void __attribute__((weak)) ETH_MspDeInit(ETH_HandleTypeDef *heth) +{ + UNUSED(heth); +} + +/** @defgroup ETH_Exported_Functions_Group2 IO operation functions + * @brief heth Transmit and Receive functions + * +@verbatim + ============================================================================== + ##### IO operation functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to manage the heth + data transfer. +@endverbatim + * @{ + */ + +/** + * @brief Enables Ethernet MAC and DMA reception and transmission + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval uint32_t + */ +uint32_t ETH_Start(ETH_HandleTypeDef *heth) +{ + if (heth->gState == ETH_STATE_READY) + { + heth->gState = ETH_STATE_BUSY; + + /* Set number of descriptors to build */ + heth->RxDescList.RxBuildDescCnt = ETH_RX_DESC_CNT; + + /* Build all descriptors */ + ETH_UpdateDescriptor(heth); + + /* Enable the MAC transmission and reception*/ + heth->Instance->ETH_MAC_CFG |= (ETH_MAC_CFG_RE | ETH_MAC_CFG_TE); + + /* Set the Flush Transmit FIFO bit */ + heth->Instance->ETH_MTL_TXQOPMODE |= ETH_MTL_TXQOPMODE_FTQ; + + /* Enable the DMA transmission */ + heth->Instance->ETH_DMA_TXCTL |= ETH_DMA_TXCTL_ST; + + /* Enable the DMA reception */ + heth->Instance->ETH_DMA_RXCTL |= ETH_DMA_RXCTL_SR; + + /* Clear Tx and Rx process stopped flags */ + heth->Instance->ETH_DMA_STU |= (ETH_DMA_STU_RPS | ETH_DMA_STU_TPS); + + heth->gState = ETH_STATE_STARTED; + + return HAL_OK; + } + else + { + return HAL_ERROR; + } +} + +/** + * @brief Enables Ethernet MAC and DMA reception/transmission in Interrupt mode + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval uint32_t + */ +uint32_t ETH_Start_IT(ETH_HandleTypeDef *heth) +{ + if (heth->gState == ETH_STATE_READY) + { + heth->gState = ETH_STATE_BUSY; + + /* save IT mode to heth Handle */ + heth->RxDescList.ItMode = 1U; + + /* Set number of descriptors to build */ + heth->RxDescList.RxBuildDescCnt = ETH_RX_DESC_CNT; + + /* Build all descriptors */ + ETH_UpdateDescriptor(heth); + + /* Enable the DMA transmission */ + heth->Instance->ETH_DMA_TXCTL |= ETH_DMA_TXCTL_ST; + + /* Enable the DMA reception */ + heth->Instance->ETH_DMA_RXCTL |= ETH_DMA_RXCTL_SR; + + /* Clear Tx and Rx process stopped flags */ + heth->Instance->ETH_DMA_STU |= (ETH_DMA_STU_RPS | ETH_DMA_STU_TPS); + + /* Set the Flush Transmit FIFO bit */ + heth->Instance->ETH_MTL_TXQOPMODE |= ETH_MTL_TXQOPMODE_FTQ; + + /* Enable the MAC transmission */ + heth->Instance->ETH_MAC_CFG |= ETH_MAC_CFG_TE; + + /* Enable the MAC reception */ + heth->Instance->ETH_MAC_CFG |= ETH_MAC_CFG_RE; + + /* Enable heth DMA interrupts: + - Tx complete interrupt + - Rx complete interrupt + - Fatal bus interrupt + */ + heth->Instance->ETH_DMA_INTRENA |= (ETH_DMA_INTREN_NIE | ETH_DMA_INTREN_RIE | ETH_DMA_INTREN_TIE | + ETH_DMA_INTREN_FBEE | ETH_DMA_INTREN_AIE | ETH_DMA_INTREN_RBUE); + + heth->gState = ETH_STATE_STARTED; + return HAL_OK; + } + else + { + return HAL_ERROR; + } +} + +/** + * @brief Stop Ethernet MAC and DMA reception/transmission + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval uint32_t + */ +uint32_t ETH_Stop(ETH_HandleTypeDef *heth) +{ + if (heth->gState == ETH_STATE_STARTED) + { + /* Set the ETH peripheral state to BUSY */ + heth->gState = ETH_STATE_BUSY; + + /* Disable the DMA transmission */ + heth->Instance->ETH_DMA_TXCTL &= (~ETH_DMA_TXCTL_ST); + + /* Disable the DMA reception */ + heth->Instance->ETH_DMA_RXCTL &= (~ETH_DMA_RXCTL_SR); + + /* Disable the MAC reception */ + heth->Instance->ETH_MAC_CFG &= (~ETH_MAC_CFG_RE); + + /* Set the Flush Transmit FIFO bit */ + heth->Instance->ETH_MTL_TXQOPMODE |= ETH_MTL_TXQOPMODE_FTQ; + + /* Disable the MAC transmission */ + heth->Instance->ETH_MAC_CFG &= (~ETH_MAC_CFG_TE); + + heth->gState = ETH_STATE_READY; + + return HAL_OK; + } + else + { + return HAL_ERROR; + } +} + +/** + * @brief Stop Ethernet MAC and DMA reception/transmission in Interrupt mode + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval uint32_t + */ +uint32_t ETH_Stop_IT(ETH_HandleTypeDef *heth) +{ + ETH_DMADescTypeDef *dmarxdesc; + uint32_t descindex; + + if (heth->gState == ETH_STATE_STARTED) + { + /* Set the ETH peripheral state to BUSY */ + heth->gState = ETH_STATE_BUSY; + + /* Disable interrupts: + - Tx complete interrupt + - Rx complete interrupt + - Fatal bus interrupt + */ + heth->Instance->ETH_DMA_INTRENA &= (~(ETH_DMA_INTREN_NIE | ETH_DMA_INTREN_RIE | ETH_DMA_INTREN_TIE | + ETH_DMA_INTREN_FBEE | ETH_DMA_INTREN_AIE | ETH_DMA_INTREN_RBUE)); + + /* Disable the DMA transmission */ + heth->Instance->ETH_DMA_TXCTL &= (~ETH_DMA_TXCTL_ST); + + /* Disable the DMA reception */ + heth->Instance->ETH_DMA_RXCTL &= (~ETH_DMA_RXCTL_SR); + + /* Disable the MAC reception */ + heth->Instance->ETH_MAC_CFG &= (~ETH_MAC_CFG_RE); + + /* Set the Flush Transmit FIFO bit */ + heth->Instance->ETH_MTL_TXQOPMODE |= ETH_MTL_TXQOPMODE_FTQ; + + /* Disable the MAC reception */ + heth->Instance->ETH_MAC_CFG &= (~ETH_MAC_CFG_RE); + + /* Clear IOC bit to all Rx descriptors */ + for (descindex = 0; descindex < (uint32_t)ETH_RX_DESC_CNT; descindex++) + { + dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descindex]; + dmarxdesc->DESC3 &= (~ETH_DMARXNDESCRF_IOC); + } + + heth->RxDescList.ItMode = 0U; + + heth->gState = ETH_STATE_READY; + + return HAL_OK; + } + else + { + return HAL_ERROR; + } +} + +/** + * @brief Sends an Ethernet Packet in polling mode. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pTxConfig: Hold the configuration of packet to be transmitted + * @param Timeout: timeout value + * @retval uint32_t + */ +uint32_t ETH_Transmit(ETH_HandleTypeDef *heth, ETH_TxPacketConfigTypeDef *pTxConfig, uint32_t Timeout) +{ + uint32_t tickstart; + ETH_DMADescTypeDef *dmatxdesc; + + if (pTxConfig == NULL) + { + heth->ErrorCode |= ETH_ERROR_PARAM; + } + + if (heth->gState == ETH_STATE_STARTED) + { + /* Config DMA Tx descriptor by Tx Packet info */ + if (ETH_Prepare_Tx_Descriptors(heth, pTxConfig, 0) != ETH_ERROR_NONE) + { + /* Config DMA Tx descriptor by Tx Packet info */ + heth->ErrorCode |= ETH_ERROR_BUSY; + return HAL_ERROR; + } + + /* Ensure completion of descriptor preparation before transmission start */ + __DSB(); + + dmatxdesc = (ETH_DMADescTypeDef *)(&heth->TxDescList)->TxDesc[heth->TxDescList.CurTxDesc]; + + /* Incr current tx desc index */ + INCR_TX_DESC_INDEX(heth->TxDescList.CurTxDesc, 1U); + + tickstart = GetTick(); + + /* Start transmission */ + /* issue a poll command to Tx DMA by writing address of next immediate free descriptor */ + heth->Instance->ETH_DMA_TXDESCTAILPTR = ((uint32_t)(heth->TxDescList.TxDesc[heth->TxDescList.CurTxDesc])); + + + /* Wait for data to be transmitted or timeout occurred */ + while ((dmatxdesc->DESC3 & ETH_DMATXNDESCWBF_OWN) != (uint32_t)0U) + { + if ((heth->Instance->ETH_DMA_STU & ETH_DMA_STU_FBE) != (uint32_t)0U) + { + heth->ErrorCode |= ETH_ERROR_DMA; + heth->DMAErrorCode = heth->Instance->ETH_DMA_STU; + return HAL_ERROR; + } + + + /* Check for the Timeout */ + //if (Timeout != MAX_DELAY) + if (Timeout != 0xFFFFFFFFU) + { + if (((GetTick() - tickstart) > Timeout) || (Timeout == 0U)) + { + heth->ErrorCode |= ETH_ERROR_TIMEOUT; + /* Clear TX descriptor so that we can proceed */ + dmatxdesc->DESC3 = (ETH_DMATXNDESCWBF_FD | ETH_DMATXNDESCWBF_LD); + } + } + } + /* Return function status */ + return HAL_OK; + } + else + { + return HAL_ERROR; + } +} + +/** + * @brief Sends an Ethernet Packet in interrupt mode. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pTxConfig: Hold the configuration of packet to be transmitted + * @retval uint32_t + */ +uint32_t ETH_Transmit_IT(ETH_HandleTypeDef *heth, ETH_TxPacketConfigTypeDef *pTxConfig) +{ + if (pTxConfig == NULL) + { + heth->ErrorCode |= ETH_ERROR_PARAM; + //return ERROR; + return HAL_ERROR; + } + + if (heth->gState == ETH_STATE_STARTED) + { + /* Save the packet pointer to release. */ + heth->TxDescList.CurrentPacketAddress = (uint32_t *)pTxConfig->pData; + + /* Config DMA Tx descriptor by Tx Packet info */ + if (ETH_Prepare_Tx_Descriptors(heth, pTxConfig, 1) != ETH_ERROR_NONE) + { + heth->ErrorCode |= ETH_ERROR_BUSY; + return HAL_ERROR; + } + + /* Ensure completion of descriptor preparation before transmission start */ + __DSB(); + + /* Incr current tx desc index */ + INCR_TX_DESC_INDEX(heth->TxDescList.CurTxDesc, 1U); + + /* Start transmission */ + /* issue a poll command to Tx DMA by writing address of next immediate free descriptor */ + heth->Instance->ETH_DMA_TXDESCTAILPTR = ((uint32_t)(heth->TxDescList.TxDesc[heth->TxDescList.CurTxDesc])); + + return HAL_OK; + } + else + { + return HAL_ERROR; + } +} + +/** + * @brief Read a received packet. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pAppBuff: Pointer to an application buffer to receive the packet. + * @retval uint32_t + */ +uint32_t ETH_ReadData(ETH_HandleTypeDef *heth, void **pAppBuff) +{ + uint32_t descidx; + ETH_DMADescTypeDef *dmarxdesc; + uint32_t desccnt = 0U; + uint32_t desccntmax; + uint32_t bufflength; + uint8_t rxdataready = 0U; + + if (pAppBuff == NULL) + { + heth->ErrorCode |= ETH_ERROR_PARAM; + return HAL_ERROR; + } + + if (heth->gState != ETH_STATE_STARTED) + { + return HAL_ERROR; + } + + descidx = heth->RxDescList.RxDescIdx; + dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descidx]; + desccntmax = ETH_RX_DESC_CNT - heth->RxDescList.RxBuildDescCnt; + + /* Check if descriptor is not owned by DMA */ + while ((((dmarxdesc->DESC3)Ð_DMARXNDESCWBF_OWN) == (uint32_t)(0x0U)) && (desccnt < desccntmax) && (rxdataready == 0U)) + { + if (((dmarxdesc->DESC3)Ð_DMARXNDESCWBF_CTXT) != (uint32_t)(0x0U)) + { + /* Get timestamp high */ + heth->RxDescList.TimeStamp.TimeStampHigh = dmarxdesc->DESC1; + /* Get timestamp low */ + heth->RxDescList.TimeStamp.TimeStampLow = dmarxdesc->DESC0; + } + + if ((((dmarxdesc->DESC3)Ð_DMARXNDESCWBF_FD) != (uint32_t)(0x0U)) || (heth->RxDescList.pRxStart != NULL)) + { + /* Check if first descriptor */ + if (((dmarxdesc->DESC3)Ð_DMARXNDESCWBF_FD) != (uint32_t)(0x0U)) + { + heth->RxDescList.RxDescCnt = 0; + heth->RxDescList.RxDataLength = 0; + } + + /* Get the Frame Length of the received packet: substruct 4 bytes of the CRC */ + bufflength = ((dmarxdesc->DESC3) & ETH_DMARXNDESCWBF_PL) - heth->RxDescList.RxDataLength; + + /* Check if last descriptor */ + if (((dmarxdesc->DESC3)Ð_DMARXNDESCWBF_LD) != (uint32_t)(0x0U)) + { + /* Save Last descriptor index */ + heth->RxDescList.pRxLastRxDesc = dmarxdesc->DESC3; + + /* Packet ready */ + rxdataready = 1; + } + + /* Link data */ + WRITE_REG(dmarxdesc->BackupAddr0, dmarxdesc->DESC0); + /* Link callback */ + ETH_RxLinkCallback(&heth->RxDescList.pRxStart, &heth->RxDescList.pRxEnd, + (uint8_t *)dmarxdesc->BackupAddr0, (uint16_t) bufflength); + + heth->RxDescList.RxDescCnt++; + + heth->RxDescList.RxDataLength += bufflength; + + /* Clear buffer pointer */ + dmarxdesc->BackupAddr0 = 0; + } + + /* Increment current rx descriptor index */ + INCR_RX_DESC_INDEX(descidx, 1U); + /* Get current descriptor address */ + dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descidx]; + desccnt++; + } + + heth->RxDescList.RxBuildDescCnt += desccnt; + if ((heth->RxDescList.RxBuildDescCnt) != 0U) + { + /* Update Descriptors */ + ETH_UpdateDescriptor(heth); + } + + heth->RxDescList.RxDescIdx = descidx; + + if (rxdataready == 1U) + { + /* Return received packet */ + *pAppBuff = heth->RxDescList.pRxStart; + /* Reset first element */ + heth->RxDescList.pRxStart = NULL; + + return HAL_OK; + } + + return HAL_ERROR; +} + +/** + * @brief This function gives back Rx Desc of the last received Packet + * to the DMA, so heth DMA will be able to use these descriptors + * to receive next Packets. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval void + */ +static void ETH_UpdateDescriptor(ETH_HandleTypeDef *heth) +{ + uint32_t descidx; + uint32_t tailidx; + uint32_t desccount; + ETH_DMADescTypeDef *dmarxdesc; + uint8_t *buff = NULL; + uint8_t allocStatus = 1U; + + descidx = heth->RxDescList.RxBuildDescIdx; + dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descidx]; + desccount = heth->RxDescList.RxBuildDescCnt; + + while ((desccount > 0U) && (allocStatus != 0U)) + { + /* Check if a buffer's attached the descriptor */ + if ((dmarxdesc->BackupAddr0) == 0U) + { + /*Allocate callback*/ + ETH_RxAllocateCallback(&buff); + if (buff == NULL) + { + allocStatus = 0U; + } + else + { + dmarxdesc->BackupAddr0 = (uint32_t)buff; + dmarxdesc->DESC0 = (uint32_t)buff; + } + } + + if (allocStatus != 0U) + { + if (heth->RxDescList.ItMode != 0U) + { + dmarxdesc->DESC3 |= (ETH_DMARXNDESCRF_OWN | ETH_DMARXNDESCRF_BUF1V | ETH_DMARXNDESCRF_IOC); + } + else + { + dmarxdesc->DESC3 |= (ETH_DMARXNDESCRF_OWN | ETH_DMARXNDESCRF_BUF1V); + } + + /* Increment current rx descriptor index */ + INCR_RX_DESC_INDEX(descidx, 1U); + /* Get current descriptor address */ + dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descidx]; + desccount--; + } + } + + if (heth->RxDescList.RxBuildDescCnt != desccount) + { + /* Set the tail pointer index */ + tailidx = (descidx + 1U) % ETH_RX_DESC_CNT; + + /* DMB instruction to avoid race condition */ + __DMB(); + + /* Set the Tail pointer address */ + heth->Instance->ETH_DMA_RXDESCTAILPTR |= ((uint32_t)(heth->Init.RxDesc + (tailidx))); + + heth->RxDescList.RxBuildDescIdx = descidx; + heth->RxDescList.RxBuildDescCnt = desccount; + } +} + +/** + * @brief Register the Rx alloc callback. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param rxAllocateCallback: pointer to function to alloc buffer + * @retval int + */ +uint32_t ETH_RegisterRxAllocateCallback(ETH_HandleTypeDef *heth, + pETH_rxAllocateCallbackTypeDef rxAllocateCallback) +{ + if (rxAllocateCallback == NULL) + { + /* No buffer to save */ + //return ERROR; + return HAL_ERROR; + } + + /* Set function to allocate buffer */ + heth->rxAllocateCallback = rxAllocateCallback; + + return HAL_OK; +} + +/** + * @brief Unregister the Rx alloc callback. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval void + */ +void ETH_UnRegisterRxAllocateCallback(ETH_HandleTypeDef *heth) +{ + /* Set function to allocate buffer */ + heth->rxAllocateCallback = ETH_RxAllocateCallback; +} + +/** + * @brief Rx Allocate callback. + * @param buff: pointer to allocated buffer + * @retval None + */ + +/*The definition belowed need to exit at ft32f4xx_def.h file*/ +/*TODO*/ + + +//__weak void ETH_RxAllocateCallback(uint8_t **buff) +void __attribute__((weak)) ETH_RxAllocateCallback(uint8_t **buff) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(buff); + /* NOTE : This function Should not be modified, when the callback is needed, + the ETH_RxAllocateCallback could be implemented in the user file + */ +} + + +/** + * @brief Rx Link callback. + * @param pStart: pointer to packet start + * @param pEnd: pointer to packet end + * @param buff: pointer to received data + * @param Length: received data length + * @retval None + */ +//__weak void ETH_RxLinkCallback(void **pStart, void **pEnd, uint8_t *buff, uint16_t Length) +void __attribute__((weak)) ETH_RxLinkCallback(void **pStart, void **pEnd, uint8_t *buff, uint16_t Length) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(pStart); + UNUSED(pEnd); + UNUSED(buff); + UNUSED(Length); + /* NOTE : This function Should not be modified, when the callback is needed, + the ETH_RxLinkCallback could be implemented in the user file + */ +} + +/** + * @brief Set the Rx link data function. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param rxLinkCallback: pointer to function to link data + * @retval int + */ +uint32_t ETH_RegisterRxLinkCallback(ETH_HandleTypeDef *heth, pETH_rxLinkCallbackTypeDef rxLinkCallback) +{ + if (rxLinkCallback == NULL) + { + /* No buffer to save */ + //return ERROR; + return HAL_ERROR; + } + + /* Set function to link data */ + heth->rxLinkCallback = rxLinkCallback; + + return HAL_OK; +} + +/** + * @brief Unregister the Rx link callback. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval void + */ +void ETH_UnRegisterRxLinkCallback(ETH_HandleTypeDef *heth) +{ + /* Set function to allocate buffer */ + heth->rxLinkCallback = ETH_RxLinkCallback; +} + +/** + * @brief Get the error state of the last received packet. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pErrorCode: pointer to uint32_t to hold the error code + * @retval void + */ +void ETH_GetRxDataErrorCode(const ETH_HandleTypeDef *heth, uint32_t *pErrorCode) +{ + /* Get error bits. */ + *pErrorCode = ((heth->RxDescList.pRxLastRxDesc) & ETH_DMARXNDESCWBF_ERRORS_MASK); +} + +/** + * @brief Set the Tx free function. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param txFreeCallback: pointer to function to release the packet + * @retval int + */ +uint32_t ETH_RegisterTxFreeCallback(ETH_HandleTypeDef *heth, pETH_txFreeCallbackTypeDef txFreeCallback) +{ + if (txFreeCallback == NULL) + { + /* No buffer to save */ + //return ERROR; + return HAL_ERROR; + } + + /* Set function to free transmmitted packet */ + heth->txFreeCallback = txFreeCallback; + + return HAL_OK; +} + +/** + * @brief Unregister the Tx free callback. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval void + */ +void ETH_UnRegisterTxFreeCallback(ETH_HandleTypeDef *heth) +{ + /* Set function to allocate buffer */ + heth->txFreeCallback = ETH_TxFreeCallback; + + //return OK; +} + +/** + * @brief Tx Free callback. + * @param buff: pointer to buffer to free + * @retval None + */ +//__weak void ETH_TxFreeCallback(uint32_t *buff) +void __attribute__((weak)) ETH_TxFreeCallback(uint32_t *buff) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(buff); + /* NOTE : This function Should not be modified, when the callback is needed, + the ETH_TxFreeCallback could be implemented in the user file + */ +} + +/** + * @brief Release transmitted Tx packets. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval void + */ +void ETH_ReleaseTxPacket(ETH_HandleTypeDef *heth) +{ + ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList; + uint32_t numOfBuf = dmatxdesclist->BuffersInUse; + uint32_t idx = dmatxdesclist->releaseIndex; + uint8_t pktTxStatus = 1U; + uint8_t pktInUse; +#ifdef ETH_USE_PTP + ETH_TimeStampTypeDef *timestamp = &heth->TxTimestamp; +#endif /* ETH_USE_PTP */ + + /* Loop through buffers in use. */ + while ((numOfBuf != 0U) && (pktTxStatus != 0U)) + { + pktInUse = 1U; + numOfBuf--; + /* If no packet, just examine the next packet. */ + if (dmatxdesclist->PacketAddress[idx] == NULL) + { + /* No packet in use, skip to next. */ + INCR_TX_DESC_INDEX(idx, 1U); + pktInUse = 0U; + } + + if (pktInUse != 0U) + { + /* Determine if the packet has been transmitted. */ + if ((heth->Init.TxDesc[idx].DESC3 & ETH_DMATXNDESCRF_OWN) == 0U) + { +#ifdef ETH_USE_PTP + /* Disable Ptp transmission */ + heth->Init.TxDesc[idx].DESC3 &= (~(0x40000000U)); + + if ((heth->Init.TxDesc[idx].DESC3 & ETH_DMATXNDESCWBF_LD) + && (heth->Init.TxDesc[idx].DESC3 & ETH_DMATXNDESCWBF_TTSS)) + { + /* Get timestamp low */ + timestamp->TimeStampLow = heth->Init.TxDesc[idx].DESC0; + /* Get timestamp high */ + timestamp->TimeStampHigh = heth->Init.TxDesc[idx].DESC1; + } + else + { + timestamp->TimeStampHigh = timestamp->TimeStampLow = UINT32_MAX; + } + + /* Handle Ptp */ + if (timestamp->TimeStampHigh != UINT32_MAX && timestamp->TimeStampLow != UINT32_MAX) + { + ETH_TxPtpCallback(dmatxdesclist->PacketAddress[idx], timestamp); + } + +#endif /* ETH_USE_PTP */ + + /* Release the packet. */ + ETH_TxFreeCallback(dmatxdesclist->PacketAddress[idx]); + + /* Clear the entry in the in-use array. */ + dmatxdesclist->PacketAddress[idx] = NULL; + + /* Update the transmit relesae index and number of buffers in use. */ + INCR_TX_DESC_INDEX(idx, 1U); + dmatxdesclist->BuffersInUse = numOfBuf; + dmatxdesclist->releaseIndex = idx; + } + else + { + /* Get out of the loop! */ + pktTxStatus = 0U; + } + } + } + //return HAL_OK; +} + +#ifdef ETH_USE_PTP +/** + * @brief Set the Ethernet PTP configuration. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param ptpconfig: pointer to a ETH_PTP_ConfigTypeDef structure that contains + * the configuration information for PTP + * @retval int + */ +uint32_t ETH_PTP_SetConfig(ETH_HandleTypeDef *heth, ETH_PTP_ConfigTypeDef *ptpconfig) +{ + uint32_t tmpTSCR; + ETH_TimeTypeDef time; + + if (ptpconfig == NULL) + { + //return ERROR; + return HAL_ERROR; + } + + tmpTSCR = ptpconfig->Timestamp | + ((uint32_t)ptpconfig->TimestampUpdate << ETH_PTP_TSCTL_TSUPDT_Pos) | + ((uint32_t)ptpconfig->TimestampAll << ETH_PTP_TSCTL_TSENALL_Pos) | + ((uint32_t)ptpconfig->TimestampRolloverMode << ETH_PTP_TSCTL_TSCTRLSSR_Pos) | + ((uint32_t)ptpconfig->TimestampV2 << ETH_PTP_TSCTL_TSVER2ENA_Pos) | + ((uint32_t)ptpconfig->TimestampEthernet << ETH_PTP_TSCTL_TSIPENA_Pos) | + ((uint32_t)ptpconfig->TimestampIPv6 << ETH_PTP_TSCTL_TSIPV6ENA_Pos) | + ((uint32_t)ptpconfig->TimestampIPv4 << ETH_PTP_TSCTL_TSIPV4ENA_Pos) | + ((uint32_t)ptpconfig->TimestampEvent << ETH_PTP_TSCTL_TSEVNTENA_Pos) | + ((uint32_t)ptpconfig->TimestampMaster << ETH_PTP_TSCTL_TSENMACADDR_Pos) | + ((uint32_t)ptpconfig->TimestampSnapshots << ETH_PTP_TSCTL_SNAPTYPSEL_Pos) | + ((uint32_t)ptpconfig->TimestampFilter << ETH_PTP_TSCTL_TSENMACADDR_Pos) | + ((uint32_t)ptpconfig->TimestampChecksumCorrection << ETH_PTP_TSCTL_CSC_Pos) | + ((uint32_t)ptpconfig->TimestampStatusMode << ETH_PTP_TSCTL_TXTSSISM_Pos); + + /* Write to PTP_TSCTL */ + heth->Instance->ETH_PTP_TSCTL = (((heth->Instance->ETH_PTP_TSCTL) & ((~ETH_PTP_TSCTL_MASK))) | (tmpTSCR)); + + /* Enable Timestamp */ + heth->Instance->ETH_PTP_TSCTL |= ETH_PTP_TSCTL_TSENA; + heth->Instance->ETH_PTP_SUBSECINR = (ptpconfig->TimestampSubsecondInc); + heth->Instance->ETH_PTP_TSADD = ptpconfig->TimestampAddend; + + /* Enable Timestamp */ + if (ptpconfig->TimestampAddendUpdate == ENABLE) + { + heth->Instance->ETH_PTP_TSCTL |= ETH_PTP_TSCTL_TSADDREG; + while (((heth->Instance->ETH_PTP_TSCTL)Ð_PTP_TSCTL_TSADDREG) != 0) + { + + } + } + + /* Ptp Init */ + heth->Instance->ETH_PTP_TSCTL |= ETH_PTP_TSCTL_TSINIT; + + /* Set PTP Configuration done */ + heth->IsPtpConfigured = ETH_PTP_CONFIGURED; + + /* Set Seconds */ + time.Seconds = heth->Instance->ETH_PTP_SYSTMSEC; + + /* Set NanoSeconds */ + time.NanoSeconds = heth->Instance->ETH_PTP_SYSTMNSEC; + + ETH_PTP_SetTime(heth, &time); + + return HAL_OK; +} + +/** + * @brief Get the Ethernet PTP configuration. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param ptpconfig: pointer to a ETH_PTP_ConfigTypeDef structure that contains + * the configuration information for PTP + * @retval int + */ + +uint32_t ETH_PTP_GetConfig(ETH_HandleTypeDef *heth, ETH_PTP_ConfigTypeDef *ptpconfig) +{ + if (ptpconfig == NULL) + { + //return ERROR; + return HAL_ERROR; + } + ptpconfig->Timestamp = ((heth->Instance->ETH_PTP_TSCTL) & ETH_PTP_TSCTL_TSENA); + + ptpconfig->TimestampUpdate = ((((heth->Instance->ETH_PTP_TSCTL) & ETH_PTP_TSCTL_TSCFUPDT)\ + >> ETH_PTP_TSCTL_TSCFUPDT_Pos) > 0U) ? ENABLE : DISABLE; + + ptpconfig->TimestampAll = ((((heth->Instance->ETH_PTP_TSCTL) & ETH_PTP_TSCTL_TSENALL)\ + >> ETH_PTP_TSCTL_TSENALL_Pos) > 0U) ? ENABLE : DISABLE; + + ptpconfig->TimestampRolloverMode = ((((heth->Instance->ETH_PTP_TSCTL) & ETH_PTP_TSCTL_TSCTRLSSR)\ + >> ETH_PTP_TSCTL_TSCTRLSSR_Pos) > 0U) ? ENABLE : DISABLE; + + ptpconfig->TimestampV2 = ((((heth->Instance->ETH_PTP_TSCTL) & ETH_PTP_TSCTL_TSVER2ENA)\ + >> ETH_PTP_TSCTL_TSVER2ENA_Pos) > 0U) ? ENABLE : DISABLE; + + ptpconfig->TimestampEthernet = ((((heth->Instance->ETH_PTP_TSCTL) & ETH_PTP_TSCTL_TSIPENA)\ + >> ETH_PTP_TSCTL_TSIPENA_Pos) > 0U) ? ENABLE : DISABLE; + + ptpconfig->TimestampIPv6 = ((((heth->Instance->ETH_PTP_TSCTL) & ETH_PTP_TSCTL_TSIPV6ENA)\ + >> ETH_PTP_TSCTL_TSIPV6ENA_Pos) > 0U) ? ENABLE : DISABLE; + + ptpconfig->TimestampIPv4 = ((((heth->Instance->ETH_PTP_TSCTL) & ETH_PTP_TSCTL_TSIPV4ENA)\ + >> ETH_PTP_TSCTL_TSIPV4ENA_Pos) > 0U) ? ENABLE : DISABLE; + + ptpconfig->TimestampEvent = ((((heth->Instance->ETH_PTP_TSCTL) & ETH_PTP_TSCTL_TSEVNTENA)\ + >> ETH_PTP_TSCTL_TSEVNTENA_Pos) > 0U) ? ENABLE : DISABLE; + + ptpconfig->TimestampMaster = ((((heth->Instance->ETH_PTP_TSCTL) & ETH_PTP_TSCTL_TSMSTRENA)\ + >> ETH_PTP_TSCTL_TSMSTRENA_Pos) > 0U) ? ENABLE : DISABLE; + + ptpconfig->TimestampSnapshots = ((((heth->Instance->ETH_PTP_TSCTL) & ETH_PTP_TSCTL_TSMSTRENA)\ + >> ETH_PTP_TSCTL_TSMSTRENA_Pos) > 0U) ? ENABLE : DISABLE; + + ptpconfig->TimestampFilter = ((((heth->Instance->ETH_PTP_TSCTL) & ETH_PTP_TSCTL_TSENMACADDR)\ + >> ETH_PTP_TSCTL_TSENMACADDR_Pos) > 0U) ? ENABLE : DISABLE; + + ptpconfig->TimestampChecksumCorrection = ((((heth->Instance->ETH_PTP_TSCTL) & ETH_PTP_TSCTL_CSC)\ + >> ETH_PTP_TSCTL_CSC_Pos) > 0U) ? ENABLE : DISABLE; + + ptpconfig->TimestampStatusMode = ((((heth->Instance->ETH_PTP_TSCTL) & ETH_PTP_TSCTL_TXTSSISM)\ + >> ETH_PTP_TSCTL_TXTSSISM_Pos) > 0U) ? ENABLE : DISABLE; + + return HAL_OK; +} + +/** + * @brief Set Seconds and Nanoseconds for the Ethernet PTP registers. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param time: pointer to a ETH_TimeTypeDef structure that contains + * time to set + * @retval int + */ +uint32_t ETH_PTP_SetTime(ETH_HandleTypeDef *heth, ETH_TimeTypeDef *time) +{ + if (heth->IsPtpConfigured == ETH_PTP_CONFIGURED) + { + /* Set Seconds */ + heth->Instance->ETH_PTP_SYSTMSECUPDT = time->Seconds; + + /* Set NanoSeconds */ + heth->Instance->ETH_PTP_SYSTMNSECUPDT = time->NanoSeconds; + + /* the system time is updated */ + heth->Instance->ETH_PTP_TSCTL = ETH_PTP_TSCTL_TSUPDT; + } + else + { + /* Return function status */ + //return ERROR; + return HAL_ERROR; + } +} + +/** + * @brief Get Seconds and Nanoseconds for the Ethernet PTP registers. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param time: pointer to a ETH_TimeTypeDef structure that contains + * time to get + * @retval int + */ +uint32_t ETH_PTP_GetTime(ETH_HandleTypeDef *heth, ETH_TimeTypeDef *time) +{ + if (heth->IsPtpConfigured == ETH_PTP_CONFIGURED) + { + /* Get Seconds */ + time->Seconds = heth->Instance->ETH_PTP_SYSTMSEC; + /* Get NanoSeconds */ + time->NanoSeconds = heth->Instance->ETH_PTP_SYSTMNSEC; + } + else + { + /* Return function status */ + //return ERROR; + return HAL_ERROR; + } +} + +/** + * @brief Update time for the Ethernet PTP registers. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param timeoffset: pointer to a ETH_PtpUpdateTypeDef structure that contains + * the time update information + * @retval int + */ +uint32_t ETH_PTP_AddTimeOffset(ETH_HandleTypeDef *heth, ETH_PtpUpdateTypeDef ptpoffsettype, + ETH_TimeTypeDef *timeoffset) +{ + if (heth->IsPtpConfigured == ETH_PTP_CONFIGURED) + { + if (ptpoffsettype == ETH_PTP_NEGATIVE_UPDATE) + { + /* Set Seconds update */ + heth->Instance->ETH_PTP_SYSTMSECUPDT = ETH_MACSTSUR_VALUE - timeoffset->Seconds + 1U; + + if (((heth->Instance->ETH_PTP_TSCTL)Ð_PTP_TSCTL_TSCTRLSSR) == ETH_PTP_TSCTL_TSCTRLSSR) + { + /* Set nanoSeconds update */ + heth->Instance->ETH_PTP_SYSTMNSECUPDT = ETH_MACSTNUR_VALUE - timeoffset->NanoSeconds; + } + else + { + /* Set nanoSeconds update */ + heth->Instance->ETH_PTP_SYSTMNSECUPDT = ETH_MACSTSUR_VALUE - timeoffset->NanoSeconds + 1U; + } + } + else + { + /* Set Seconds update */ + heth->Instance->ETH_PTP_SYSTMSECUPDT = timeoffset->Seconds; + /* Set nanoSeconds update */ + heth->Instance->ETH_PTP_SYSTMNSECUPDT = timeoffset->NanoSeconds; + } + + heth->Instance->ETH_PTP_TSCTL |= ETH_PTP_TSCTL_TSUPDT; + + return HAL_OK; + } + else + { + /* Return function status */ + //return ERROR; + return HAL_ERROR; + } +} + +/** + * @brief Insert Timestamp in transmission. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval int + */ +uint32_t ETH_PTP_InsertTxTimestamp(ETH_HandleTypeDef *heth) +{ + ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList; + uint32_t descidx = dmatxdesclist->CurTxDesc; + ETH_DMADescTypeDef *dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx]; + + if (heth->IsPtpConfigured == ETH_PTP_CONFIGURED) + { + /* Enable Time Stamp transmission */ + dmatxdesc->DESC2 |= ETH_DMATXNDESCRF_TTSE; + + return HAL_OK; + } + else + { + /* Return function status */ + // return ERROR; + return HAL_ERROR; + } +} + +/** + * @brief Get transmission timestamp. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param timestamp: pointer to ETH_TIMESTAMPTypeDef structure that contains + * transmission timestamp + * @retval int + */ +uint32_t ETH_PTP_GetTxTimestamp(ETH_HandleTypeDef *heth, ETH_TimeStampTypeDef *timestamp) +{ + ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList; + uint32_t idx = dmatxdesclist->releaseIndex; + ETH_DMADescTypeDef *dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[idx]; + + if (heth->IsPtpConfigured == ETH_PTP_CONFIGURED) + { + /* Get timestamp low */ + timestamp->TimeStampLow = dmatxdesc->DESC0; + /* Get timestamp high */ + timestamp->TimeStampHigh = dmatxdesc->DESC1; + + return HAL_OK; + } + else + { + /* Return function status */ + //return ERROR; + return HAL_ERROR; + } +} + +/** + * @brief Get receive timestamp. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param timestamp: pointer to ETH_TIMESTAMPTypeDef structure that contains + * receive timestamp + * @retval int + */ +uint32_t ETH_PTP_GetRxTimestamp(ETH_HandleTypeDef *heth, ETH_TimeStampTypeDef *timestamp) +{ + if (heth->IsPtpConfigured == ETH_PTP_CONFIGURED) + { + /* Get timestamp low */ + timestamp->TimeStampLow = heth->RxDescList.TimeStamp.TimeStampLow; + /* Get timestamp high */ + timestamp->TimeStampHigh = heth->RxDescList.TimeStamp.TimeStampHigh; + + return HAL_OK; + } + else + { + /* Return function status */ + //return ERROR; + return HAL_ERROR; + } +} + +/** + * @brief Register the Tx Ptp callback. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param txPtpCallback: Function to handle Ptp transmission + * @retval int + */ +uint32_t ETH_RegisterTxPtpCallback(ETH_HandleTypeDef *heth, pETH_txPtpCallbackTypeDef txPtpCallback) +{ + if (txPtpCallback == NULL) + { + /* No buffer to save */ + //return ERROR; + return HAL_ERROR; + } + /* Set Function to handle Tx Ptp */ + heth->txPtpCallback = txPtpCallback; + + return HAL_OK; +} + +/** + * @brief Unregister the Tx Ptp callback. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval int + */ +uint32_t ETH_UnRegisterTxPtpCallback(ETH_HandleTypeDef *heth) +{ + /* Set function to allocate buffer */ + heth->txPtpCallback = ETH_TxPtpCallback; + + //return OK; + return HAL_OK; +} + +/** + * @brief Tx Ptp callback. + * @param buff: pointer to application buffer + * @param timestamp: pointer to ETH_TimeStampTypeDef structure that contains + * transmission timestamp + * @retval None + */ +//__weak void ETH_TxPtpCallback(uint32_t *buff, ETH_TimeStampTypeDef *timestamp) +void __attribute__((weak)) ETH_TxPtpCallback(uint32_t *buff, ETH_TimeStampTypeDef *timestamp) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(buff); + /* NOTE : This function Should not be modified, when the callback is needed, + the ETH_TxPtpCallback could be implemented in the user file + */ +} +#endif /* ETH_USE_PTP */ + +/** + * @brief This function handles heth interrupt request. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval void + */ +void ETH_IRQHandler(ETH_HandleTypeDef *heth) +{ + uint32_t mac_flag = (heth->Instance->ETH_MAC_IRSTU); + uint32_t dma_flag = (heth->Instance->ETH_DMA_STU); + uint32_t dma_itsource = (heth->Instance->ETH_DMA_INTRENA); + uint32_t exti_flag = (EXTI->PR); + + /* Packet received */ + if (((dma_flag & ETH_DMA_STU_RI) != 0U) && ((dma_itsource & ETH_DMA_INTREN_RIE) != 0U)) + { + /* Clear the heth DMA Rx IT pending bits */ + heth->Instance->ETH_DMA_STU = (ETH_DMA_STU_RI | ETH_DMA_STU_NIS); + /* Receive complete callback */ + ETH_RxCpltCallback(heth); + } + + /* Packet transmitted */ + if (((dma_flag & ETH_DMA_STU_TI) != 0U) && ((dma_itsource & ETH_DMA_INTREN_TIE) != 0U)) + { + /* Clear the heth DMA Tx IT pending bits */ + heth->Instance->ETH_DMA_STU = (ETH_DMA_STU_TI | ETH_DMA_STU_NIS); + + ETH_TxCpltCallback(heth); + } + + /* heth DMA Error */ + if (((dma_flag & ETH_DMA_STU_AIS) != 0U) && ((dma_itsource & ETH_DMA_INTREN_AIE) != 0U)) + { + heth->ErrorCode |= ETH_ERROR_DMA; + /* if fatal bus error occurred */ + if ((dma_flag & ETH_DMA_STU_FBE) != 0U) + { + /* Get DMA error code */ + heth->DMAErrorCode = ((heth->Instance->ETH_DMA_STU) & (ETH_DMA_STU_FBE | ETH_DMA_STU_TPS | ETH_DMA_STU_RPS)); + + /* Disable all interrupts */ + __ETH_DMA_DISABLE_IT(heth, ETH_DMA_INTREN_NIE | ETH_DMA_INTREN_AIE); + + /* Set state to ERROR */ + heth->gState = ETH_STATE_ERROR; + } + else + { + /* Get DMA error status */ + heth->DMAErrorCode = ((heth->Instance->ETH_DMA_STU) & (ETH_DMA_STU_CDE | ETH_DMA_STU_ETI | ETH_DMA_STU_RWT | + ETH_DMA_STU_RBU | ETH_DMA_STU_AIS)); + + /* Clear the interrupt summary flag */ + __ETH_DMA_CLEAR_IT(heth, (ETH_DMA_STU_CDE | ETH_DMA_STU_ETI | ETH_DMA_STU_RWT | + ETH_DMA_STU_RBU | ETH_DMA_STU_AIS)); + } + + /* Ethernet DMA Error callback */ + ETH_ErrorCallback(heth); + } + + /* heth MAC Error IT */ + if (((mac_flag & ETH_MAC_IREN_RXSTSIE) == ETH_MAC_IREN_RXSTSIE) || \ + ((mac_flag & ETH_MAC_IREN_TXSTSIE) == ETH_MAC_IREN_TXSTSIE)) + { + heth->ErrorCode |= ETH_ERROR_MAC; + + /* Get MAC Rx Tx status and clear Status register pending bit */ + heth->MACErrorCode = (heth->Instance->ETH_MAC_RXTXSTU); + + heth->gState = ETH_STATE_ERROR; + + /* Ethernet Error callback */ + ETH_ErrorCallback(heth); + + heth->MACErrorCode = (uint32_t)(0x0U); + } + + /* heth PMT IT */ + if ((mac_flag & ETH_MAC_PMT_IT) != 0U) + { + /* Get MAC Wake-up source and clear the status register pending bit */ + heth->MACWakeUpEvent = ((heth->Instance->ETH_MAC_PMTCTLSTU) & (ETH_MAC_PMTCTLSTU_RWKPRCVD | ETH_MAC_PMTCTLSTU_MGKPRCVD)); + + /* Ethernet PMT callback */ + ETH_PMTCallback(heth); + + heth->MACWakeUpEvent = (uint32_t)(0x0U); + } + + /* check heth WAKEUP exti flag */ + if ((exti_flag & ETH_WAKEUP_EXTI_LINE) != 0U) + { + /* Clear heth WAKEUP Exti pending bit */ + __ETH_WAKEUP_EXTI_CLEAR_FLAG(ETH_WAKEUP_EXTI_LINE); + + /* heth WAKEUP callback */ + ETH_WakeUpCallback(heth); + } +} + + +/** + * @brief Tx Transfer completed callbacks. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ +//__weak void ETH_TxCpltCallback(ETH_HandleTypeDef *heth) +void __attribute__((weak)) ETH_TxCpltCallback(ETH_HandleTypeDef *heth) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(heth); + /* NOTE : This function Should not be modified, when the callback is needed, + the ETH_TxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Rx Transfer completed callbacks. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ +//__weak void ETH_RxCpltCallback(ETH_HandleTypeDef *heth) +void __attribute__((weak)) ETH_RxCpltCallback(ETH_HandleTypeDef *heth) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(heth); + /* NOTE : This function Should not be modified, when the callback is needed, + the ETH_RxCpltCallback could be implemented in the user file + */ +} + +/** +* @brief Ethernet transfer error callbacks +* @param heth: pointer to a ETH_HandleTypeDef structure that contains +* the configuration information for ETHERNET module +* @retval None +*/ +//__weak void ETH_ErrorCallback(ETH_HandleTypeDef *heth) +void __attribute__((weak)) ETH_ErrorCallback(ETH_HandleTypeDef *heth) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(heth); + /* NOTE : This function Should not be modified, when the callback is needed, + the ETH_ErrorCallback could be implemented in the user file + */ +} + +/** + * @brief Ethernet Power Management module IT callback + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ +//__weak void ETH_PMTCallback(ETH_HandleTypeDef *heth) +void __attribute__((weak)) ETH_PMTCallback(ETH_HandleTypeDef *heth) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(heth); + /* NOTE : This function Should not be modified, when the callback is needed, + the ETH_PMTCallback could be implemented in the user file + */ +} + +/** + * @brief heth WAKEUP interrupt callback + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ +//__weak void ETH_WakeUpCallback(ETH_HandleTypeDef *heth) +void __attribute__((weak)) ETH_WakeUpCallback(ETH_HandleTypeDef *heth) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(heth); + /* NOTE : This function Should not be modified, when the callback is needed, + the ETH_WakeUpCallback could be implemented in the user file + */ +} + +/** + * @brief Read a PHY register + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param PHYAddr: PHY port address, must be a value from 0 to 31 + * @param PHYReg: PHY register address, must be a value from 0 to 31 + * @param pRegValue: parameter to hold read value + * @retval int + */ +uint32_t ETH_ReadPHYRegister(ETH_HandleTypeDef *heth, uint32_t PHYAddr, uint32_t PHYReg, + uint32_t *pRegValue) +{ + uint32_t tickstart; + uint32_t tmpreg; + + /* Check for the Busy flag */ + if (((heth->Instance->ETH_MAC_MDIOADDR)Ð_MAC_MDIOADDR_GB) != (uint32_t)(0x0U)) + { + //return ERROR; + return HAL_ERROR; + } + + /* Get the MAC_MDIOADDR value */ + tmpreg = heth->Instance->ETH_MAC_MDIOADDR; + + /* Prepare the MDIO Address Register value + - Set the PHY device address + - Set the PHY register address + - Set the read mode + - Set the MII Busy bit */ + + MODIFY_REG(tmpreg, ETH_MAC_MDIOADDR_PA, (PHYAddr << 21)); + MODIFY_REG(tmpreg, ETH_MAC_MDIOADDR_RDA, (PHYReg << 16)); + MODIFY_REG(tmpreg, ETH_MAC_MDIOADDR_GOC, ETH_MAC_MDIOADDR_GOC_RD); + tmpreg |= ETH_MAC_MDIOADDR_GB; + + /* Write the result value into the MII Address register */ + WRITE_REG(heth->Instance->ETH_MAC_MDIOADDR, tmpreg); + + /*TODO*/ + tickstart = GetTick(); + + /* Wait for the Busy flag */ + while (((heth->Instance->ETH_MAC_MDIOADDR)Ð_MAC_MDIOADDR_GB) > 0U) + { + if (((GetTick() - tickstart) > ETH_MDIO_BUS_TIMEOUT)) + { + return ERROR; + } + } + + /* Get ETH_MAC_MDIODATA value */ + WRITE_REG(*pRegValue, (uint16_t)heth->Instance->ETH_MAC_MDIODATA); + + return HAL_OK; +} + +/** + * @brief Writes to a PHY register. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param PHYAddr: PHY port address, must be a value from 0 to 31 + * @param PHYReg: PHY register address, must be a value from 0 to 31 + * @param RegValue: the value to write + * @retval void + */ +uint32_t ETH_WritePHYRegister(const ETH_HandleTypeDef *heth, uint32_t PHYAddr, uint32_t PHYReg, + uint32_t RegValue) +{ + uint32_t tickstart; + uint32_t tmpreg; + + /* Check for the Busy flag */ + if (((heth->Instance->ETH_MAC_MDIOADDR)Ð_MAC_MDIOADDR_GB) != (uint32_t)(0x0U)) + { + return HAL_ERROR; + } + + /* Get the ETH_MAC_MDIOADDR value */ + WRITE_REG(tmpreg, heth->Instance->ETH_MAC_MDIOADDR); + + /* Prepare the MDIO Address Register value + - Set the PHY device address + - Set the PHY register address + - Set the write mode + - Set the MII Busy bit */ + MODIFY_REG(tmpreg, ETH_MAC_MDIOADDR_PA, (PHYAddr << 21)); + MODIFY_REG(tmpreg, ETH_MAC_MDIOADDR_RDA, (PHYReg << 16)); + MODIFY_REG(tmpreg, ETH_MAC_MDIOADDR_GOC, ETH_MAC_MDIOADDR_GOC_WR); + tmpreg |= ETH_MAC_MDIOADDR_GB; + + /* Give the value to the MII data register */ + WRITE_REG(heth->Instance->ETH_MAC_MDIODATA, (uint16_t)RegValue); + + /* Write the result value into the MII Address register */ + WRITE_REG(heth->Instance->ETH_MAC_MDIOADDR, tmpreg); + + /*TODO*/ + //tickstart = GetTick(); + + /* Wait for the Busy flag */ + while (((heth->Instance->ETH_MAC_MDIOADDR)Ð_MAC_MDIOADDR_GB) > 0U) + { + // if (((GetTick() - tickstart) > ETH_MDIO_BUS_TIMEOUT)) + // { + // return ERROR; + // } + } + + return HAL_OK; +} +/** + * @} + */ + +/** @defgroup ETH_Exported_Functions_Group3 Peripheral Control functions + * @brief heth control functions + * +@verbatim + ============================================================================== + ##### Peripheral Control functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to control the heth + peripheral. + +@endverbatim + * @{ + */ + +/** + * @brief Get the configuration of the MAC and MTL subsystems. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param macconf: pointer to a ETH_MACConfigTypeDef structure that will hold + * the configuration of the MAC. + * @retval int + */ +uint32_t ETH_GetMACConfig(const ETH_HandleTypeDef *heth, ETH_MACConfigTypeDef *macconf) +{ + if (macconf == NULL) + { + //return ERROR; + return HAL_ERROR; + } + + /* Get MAC parameters */ + macconf->PreambleLength = ((heth->Instance->ETH_MAC_CFG)Ð_MAC_CFG_PRELEN); + macconf->DeferralCheck = ((((heth->Instance->ETH_MAC_CFG)Ð_MAC_CFG_DC) >> 4) > 0U) ? ENABLE : DISABLE; + macconf->BackOffLimit = ((heth->Instance->ETH_MAC_CFG)Ð_MAC_CFG_BL); + macconf->RetryTransmission = ((((heth->Instance->ETH_MAC_CFG)Ð_MAC_CFG_DR) >> 8) == 0U) ? ENABLE : DISABLE; + macconf->CarrierSenseDuringTransmit = ((((heth->Instance->ETH_MAC_CFG)Ð_MAC_CFG_DCRS) >> 9) == 0U) ? ENABLE : DISABLE; + macconf->ReceiveOwn = ((((heth->Instance->ETH_MAC_CFG)Ð_MAC_CFG_DO) >> 10) == 0U) ? ENABLE : DISABLE; + macconf->CarrierSenseBeforeTransmit = ((((heth->Instance->ETH_MAC_CFG)Ð_MAC_CFG_ECRSFD) >> 11) > 0U) ? ENABLE : DISABLE; + macconf->LoopbackMode = ((((heth->Instance->ETH_MAC_CFG)Ð_MAC_CFG_LM) >> 12) > 0U) ? ENABLE : DISABLE; + macconf->DuplexMode = ((heth->Instance->ETH_MAC_CFG)Ð_MAC_CFG_DM); + macconf->Speed = ((heth->Instance->ETH_MAC_CFG)Ð_MAC_CFG_FES); + macconf->JumboPacket = ((((heth->Instance->ETH_MAC_CFG)Ð_MAC_CFG_JE) >> 16) > 0U) ? ENABLE : DISABLE; + macconf->Jabber = ((((heth->Instance->ETH_MAC_CFG)Ð_MAC_CFG_JD) >> 17) > 0U) ? ENABLE : DISABLE; + macconf->Watchdog = ((((heth->Instance->ETH_MAC_CFG)Ð_MAC_CFG_WD) >> 19) > 0U) ? ENABLE : DISABLE; + macconf->AutomaticPadCRCStrip = ((((heth->Instance->ETH_MAC_CFG)Ð_MAC_CFG_ACS) >> 20) > 0U) ? ENABLE : DISABLE; + macconf->CRCStripTypePacket = ((((heth->Instance->ETH_MAC_CFG)Ð_MAC_CFG_CST) >> 21) > 0U) ? ENABLE : DISABLE; + macconf->Support2KPacket = ((((heth->Instance->ETH_MAC_CFG)Ð_MAC_CFG_S2KP) >> 22) > 0U) ? ENABLE : DISABLE; + macconf->GiantPacketSizeLimitControl = ((((heth->Instance->ETH_MAC_CFG)Ð_MAC_CFG_GPSLCE) >> 23) > 0U) ? ENABLE : DISABLE; + macconf->InterPacketGapVal = ((heth->Instance->ETH_MAC_CFG)Ð_MAC_CFG_IPG); + macconf->ChecksumOffload = ((((heth->Instance->ETH_MAC_CFG)Ð_MAC_CFG_IPC) >> 27) > 0U) ? ENABLE : DISABLE; + + macconf->GiantPacketSizeLimit = ((heth->Instance->ETH_MAC_EXTDCFG)Ð_MAC_EXTDCFG_GPSL); + macconf->CRCCheckingRxPackets = ((((heth->Instance->ETH_MAC_EXTDCFG)Ð_MAC_EXTDCFG_DCRCC) >> 16) > 0U) ? ENABLE : DISABLE; + macconf->SlowProtocolDetect = ((((heth->Instance->ETH_MAC_EXTDCFG)Ð_MAC_EXTDCFG_SPEN) >> 17) > 0U) ? ENABLE : DISABLE; + macconf->UnicastSlowProtocolPacketDetect = ((((heth->Instance->ETH_MAC_EXTDCFG)Ð_MAC_EXTDCFG_USP) >> 18) > 0U) ? ENABLE : DISABLE; + macconf->ExtendedInterPacketGap = ((((heth->Instance->ETH_MAC_EXTDCFG)Ð_MAC_EXTDCFG_EIPGEN) >> 24) > 0U) ? ENABLE : DISABLE; + macconf->ExtendedInterPacketGapVal = (((heth->Instance->ETH_MAC_EXTDCFG)Ð_MAC_EXTDCFG_EIPG) >> 25); + + macconf->ProgrammableWatchdog = ((((heth->Instance->ETH_MAC_WTDTO)Ð_MAC_WTDTO_PWE) >> 8) > 0U) ? ENABLE : DISABLE; + macconf->WatchdogTimeout = ((heth->Instance->ETH_MAC_WTDTO)Ð_MAC_WTDTO_WTO); + + macconf->TransmitFlowControl = ((((heth->Instance->ETH_MAC_TXFLCTL)Ð_MAC_TXFLCTL_TFE) >> 1) > 0U) ? ENABLE : DISABLE; + macconf->ZeroQuantaPause = ((((heth->Instance->ETH_MAC_TXFLCTL)Ð_MAC_TXFLCTL_DZPQ) >> 7) == 0U) ? ENABLE : DISABLE; + macconf->PauseLowThreshold = ((heth->Instance->ETH_MAC_TXFLCTL)Ð_MAC_TXFLCTL_PLT); + macconf->PauseTime = (((heth->Instance->ETH_MAC_TXFLCTL)Ð_MAC_TXFLCTL_PT) >> 16); + + macconf->ReceiveFlowControl = (((heth->Instance->ETH_MAC_RXFLCTL)Ð_MAC_RXFLCTL_RFE) > 0U) ? ENABLE : DISABLE; + macconf->UnicastPausePacketDetect = ((((heth->Instance->ETH_MAC_RXFLCTL)Ð_MAC_RXFLCTL_UP) >> 1) > 0U) ? ENABLE : DISABLE; + + macconf->TransmitQueueMode = ((heth->Instance->ETH_MTL_TXQOPMODE) & (ETH_MTL_TXQOPMDDE_TTC | ETH_MTL_TXQOPMDDE_TSF)); + + macconf->ReceiveQueueMode = ((heth->Instance->ETH_MTL_RXQOPMODE) & (ETH_MTL_RXQOPMODE_RTC | ETH_MTL_RXQ0OPMD_RSF)); + macconf->ForwardRxUndersizedGoodPacket = ((((heth->Instance->ETH_MTL_RXQOPMODE)Ð_MTL_RXQOPMODE_FUP) >> 3) > 0U) ? ENABLE : DISABLE; + macconf->ForwardRxErrorPacket = ((((heth->Instance->ETH_MTL_RXQOPMODE)Ð_MTL_RXQOPMODE_FEP) >> 4) > 0U) ? ENABLE : DISABLE; + macconf->DropTCPIPChecksumErrorPacket = ((((heth->Instance->ETH_MTL_RXQOPMODE)Ð_MTL_RXQOPMODE_DIS_TCP_EF) >> 6) > 0U) ? ENABLE : DISABLE; + + return HAL_OK; +} + +/** + * @brief Get the configuration of the DMA. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param dmaconf: pointer to a ETH_DMAConfigTypeDef structure that will hold + * the configuration of the heth DMA. + * @retval int + */ +uint32_t ETH_GetDMAConfig(const ETH_HandleTypeDef *heth, ETH_DMAConfigTypeDef *dmaconf) +{ + if (dmaconf == NULL) + { + //return ERROR; + return HAL_ERROR; + } + + dmaconf->AddressAlignedBeats = ((((heth->Instance->ETH_DMA_SYSBUSMODE)Ð_DMA_SYSBMODE_AAL) >> 12) > 0U) ? ENABLE : DISABLE; + dmaconf->BurstMode = ((heth->Instance->ETH_DMA_SYSBUSMODE) & (ETH_DMA_SYSBMODE_FB | ETH_DMA_SYSBMODE_MB)); + dmaconf->RebuildINCRxBurst = ((((heth->Instance->ETH_DMA_SYSBUSMODE)Ð_DMA_SYSBMODE_RB) >> 15) > 0U) ? ENABLE : DISABLE; + + dmaconf->DMAArbitration = ((heth->Instance->ETH_DMA_OPMODE) & (ETH_DMA_OPMODE_TXPR | ETH_DMA_OPMODE_PR | ETH_DMA_OPMODE_DA)); + + dmaconf->PBLx8Mode = ((((heth->Instance->ETH_DMA_CTL)Ð_DMA_CTL_8PBL) >> 16) > 0U) ? ENABLE : DISABLE; + + dmaconf->FlushRxPacket = ((((heth->Instance->ETH_DMA_RXCTL)Ð_DMA_CH0RXCTL_RPF) >> 31) > 0U) ? ENABLE : DISABLE; + dmaconf->RxDMABurstLength = ((heth->Instance->ETH_DMA_RXCTL)Ð_DMA_RXCTL_RPBL); + + dmaconf->SecondPacketOperate = ((((heth->Instance->ETH_DMA_TXCTL)Ð_DMA_CH0TXCTL_OSF) >> 4) > 0U) ? ENABLE : DISABLE; + dmaconf->TxDMABurstLength = ((heth->Instance->ETH_DMA_TXCTL)Ð_DMA_TXCTL_TPBL); + + return HAL_OK; +} + +/** + * @brief Configures the Clock range of heth MDIO interface. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ +void ETH_SetMDIOClockRange(ETH_HandleTypeDef *heth) +{ + uint32_t hclk; + uint32_t tmpreg; + uint32_t tmpreg1 = 0; + + uint32_t pllp = 2; + uint32_t pllsource = 0; + uint32_t pllm = 2; + uint32_t pllvco = 0; + + /* Get the ETHERNET MAC_MDIOADDR value */ + tmpreg = (heth->Instance)->ETH_MAC_MDIOADDR; + + /* Clear CSR Clock Range bits */ + tmpreg &= ~ETH_MAC_MDIOADDR_CR; + + /* Get hclk frequency value */ + //hclk = RCC_GetHCLKFreq(); + + /*TODO*/ + tmpreg1 = RCC->CFGR & RCC_CFGR_SWS; + switch (tmpreg1) + { + case 0x00: + hclk = 16000000; + break; + case 0x04: + hclk = 25000000; + break; + case 0x08: + pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) >> 14; + pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM; + + if (pllsource != 0) + { + /*HSE used as PLL clock source*/ + pllvco = (25000000U / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6); + } + else + { + /*HSI used as PLL clock source*/ + pllvco = (16000000U / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6); + } + + pllp = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >> 17) + 1) * 2; + hclk = pllvco / pllp; + } + + + /* Set CR bits depending on hclk value */ + if (hclk < 35000000U) + { + /* CSR Clock Range between 20-35 MHz */ + tmpreg |= (uint32_t)ETH_MAC_MDIOADDR_CR_DIV16; + } + else if (hclk < 60000000U) + { + /* CSR Clock Range between 35-60 MHz */ + tmpreg |= (uint32_t)ETH_MAC_MDIOADDR_CR_DIV26; + } + else if (hclk < 100000000U) + { + /* CSR Clock Range between 60-100 MHz */ + tmpreg |= (uint32_t)ETH_MAC_MDIOADDR_CR_DIV42; + } + else if (hclk < 150000000U) + { + /* CSR Clock Range between 100-150 MHz */ + tmpreg |= (uint32_t)ETH_MAC_MDIOADDR_CR_DIV62; + } + else + { + /* CSR Clock Range between 150-250 MHz */ + tmpreg |= (uint32_t)ETH_MAC_MDIOADDR_CR_DIV102; + } + + /* Configure the CSR Clock Range */ + (heth->Instance)-> ETH_MAC_MDIOADDR = (uint32_t)tmpreg; +} + +/** + * @brief Set the heth MAC (L2) Filters configuration. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pFilterConfig: pointer to a ETH_MACFilterConfigTypeDef structure that contains + * the configuration of the heth MAC filters. + * @retval int + */ +uint32_t ETH_SetMACFilterConfig(ETH_HandleTypeDef *heth, const ETH_MACFilterConfigTypeDef *pFilterConfig) +{ + uint32_t filterconfig; + + if (pFilterConfig == NULL) + { + //return ERROR; + return HAL_ERROR; + } + + filterconfig = ((uint32_t)pFilterConfig->PromiscuousMode | + ((uint32_t)pFilterConfig->HashUnicast << 1) | + ((uint32_t)pFilterConfig->HashMulticast << 2) | + ((uint32_t)pFilterConfig->DestAddrInverseFiltering << 3) | + ((uint32_t)pFilterConfig->PassAllMulticast << 4) | + ((uint32_t)((pFilterConfig->BroadcastFilter == DISABLE) ? 1U : 0U) << 5) | + ((uint32_t)pFilterConfig->SrcAddrInverseFiltering << 8) | + ((uint32_t)pFilterConfig->SrcAddrFiltering << 9) | + ((uint32_t)pFilterConfig->HachOrPerfectFilter << 10) | + ((uint32_t)pFilterConfig->ReceiveAllMode << 31) | + pFilterConfig->ControlPacketsFilter); + + MODIFY_REG(heth->Instance->ETH_MAC_PKTFILT, ETH_MAC_PKTFILT_MASK, filterconfig); + + return HAL_OK; +} + +/** + * @brief Get the heth MAC (L2) Filters configuration. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pFilterConfig: pointer to a ETH_MACFilterConfigTypeDef structure that will hold + * the configuration of the heth MAC filters. + * @retval int + */ +uint32_t ETH_GetMACFilterConfig(const ETH_HandleTypeDef *heth, ETH_MACFilterConfigTypeDef *pFilterConfig) +{ + if (pFilterConfig == NULL) + { + //return ERROR; + return HAL_ERROR; + } + + pFilterConfig->PromiscuousMode = (((heth->Instance->ETH_MAC_PKTFILT)Ð_MAC_PKTFILT_PR) > 0U) ? ENABLE : DISABLE; + pFilterConfig->HashUnicast = ((((heth->Instance->ETH_MAC_PKTFILT)Ð_MAC_PKTFILT_HUC) >> 1) > 0U) ? ENABLE : DISABLE; + pFilterConfig->HashMulticast = ((((heth->Instance->ETH_MAC_PKTFILT)Ð_MAC_PKTFILT_HMC) >> 2) > 0U) ? ENABLE : DISABLE; + pFilterConfig->DestAddrInverseFiltering = ((((heth->Instance->ETH_MAC_PKTFILT)& + ETH_MAC_PKTFILT_DAIF) >> 3) > 0U) ? ENABLE : DISABLE; + pFilterConfig->PassAllMulticast = ((((heth->Instance->ETH_MAC_PKTFILT)Ð_MAC_PKTFILT_PM) >> 4) > 0U) ? ENABLE : DISABLE; + pFilterConfig->BroadcastFilter = ((((heth->Instance->ETH_MAC_PKTFILT)Ð_MAC_PKTFILT_DBF) >> 5) == 0U) ? ENABLE : DISABLE; + pFilterConfig->ControlPacketsFilter = ((heth->Instance->ETH_MAC_PKTFILT)Ð_MAC_PKTFILT_PCF); + pFilterConfig->SrcAddrInverseFiltering = ((((heth->Instance->ETH_MAC_PKTFILT)& + ETH_MAC_PKTFILT_SAIF) >> 8) > 0U) ? ENABLE : DISABLE; + pFilterConfig->SrcAddrFiltering = ((((heth->Instance->ETH_MAC_PKTFILT)Ð_MAC_PKTFILT_SAF) >> 9) > 0U) ? ENABLE : DISABLE; + pFilterConfig->HachOrPerfectFilter = ((((heth->Instance->ETH_MAC_PKTFILT)Ð_MAC_PKTFILT_HPF) >> 10) > 0U) + ? ENABLE : DISABLE; + pFilterConfig->ReceiveAllMode = ((((heth->Instance->ETH_MAC_PKTFILT)Ð_MAC_PKTFILT_RA) >> 31) > 0U) ? ENABLE : DISABLE; + + return HAL_OK; +} + +/** + * @brief Set the source MAC Address to be matched. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param AddrNbr: The MAC address to configure + * This parameter must be a value of the following: + * ETH_MAC_ADDRESS1 + * ETH_MAC_ADDRESS2 + * ETH_MAC_ADDRESS3 + * @param pMACAddr: Pointer to MAC address buffer data (6 bytes) + * @retval int + */ +uint32_t ETH_SetSourceMACAddrMatch(const ETH_HandleTypeDef *heth, uint32_t AddrNbr, + const uint8_t *pMACAddr) +{ + uint32_t macaddrlr; + uint32_t macaddrhr; + + if (pMACAddr == NULL) + { + //return ERROR; + return HAL_ERROR; + } + + /* Get mac addr high reg offset */ + macaddrhr = ((uint32_t) & (heth->Instance->ETH_MAC_ADDRH0) + AddrNbr); + /* Get mac addr low reg offset */ + macaddrlr = ((uint32_t) & (heth->Instance->ETH_MAC_ADDRL0) + AddrNbr); + + /* Set MAC addr bits 32 to 47 */ + (*(__IO uint32_t *)macaddrhr) = (((uint32_t)(pMACAddr[5]) << 8) | (uint32_t)pMACAddr[4]); + /* Set MAC addr bits 0 to 31 */ + (*(__IO uint32_t *)macaddrlr) = (((uint32_t)(pMACAddr[3]) << 24) | ((uint32_t)(pMACAddr[2]) << 16) | + ((uint32_t)(pMACAddr[1]) << 8) | (uint32_t)pMACAddr[0]); + + /* Enable address and set source address bit */ + (*(__IO uint32_t *)macaddrhr) |= (ETH_MAC_ADDRH_SA | ETH_MAC_ADDRH_AE); + + return HAL_OK; +} + +/** + * @brief Set the heth Hash Table Value. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pHashTable: pointer to a table of two 32 bit values, that contains + * the 64 bits of the hash table. + * @retval int + */ +uint32_t ETH_SetHashTable(ETH_HandleTypeDef *heth, uint32_t *pHashTable) +{ + if (pHashTable == NULL) + { + //return ERROR; + return HAL_ERROR; + } + + heth->Instance->ETH_MAC_HASHTB0 = pHashTable[0]; + heth->Instance->ETH_MAC_HASHTB1 = pHashTable[1]; + + //return OK; + return HAL_OK; +} + +/** + * @brief Set the VLAN Identifier for Rx packets + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param ComparisonBits: 12 or 16 bit comparison mode + must be a value of @ref ETH_VLAN_Tag_Comparison + * @param VLANIdentifier: VLAN Identifier value + * @retval None + */ +void ETH_SetRxVLANIdentifier(ETH_HandleTypeDef *heth, uint32_t ComparisonBits, uint32_t VLANIdentifier) +{ + if (ComparisonBits == ETH_VLANTAGCOMPARISON_16BIT) + { + MODIFY_REG(heth->Instance->ETH_MAC_VLANT, ETH_MAC_VLANT_VL, VLANIdentifier); + (heth->Instance->ETH_MAC_VLANT) &= (~ETH_MAC_VLANT_ETV); + } + else + { + MODIFY_REG(heth->Instance->ETH_MAC_VLANT, ETH_MAC_VLANT_VL_VID, VLANIdentifier); + //SET_BIT(heth->Instance->ETH_MAC_VLANT, ETH_MAC_VLANT_ETV); + heth->Instance->ETH_MAC_VLANT |= ETH_MAC_VLANT_ETV; + } +} + +/** + * @brief Enters the Power down mode. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pPowerDownConfig: a pointer to ETH_PowerDownConfigTypeDef structure + * that contains the Power Down configuration + * @retval None. + */ +void ETH_EnterPowerDownMode(ETH_HandleTypeDef *heth, const ETH_PowerDownConfigTypeDef *pPowerDownConfig) +{ + uint32_t powerdownconfig; + + powerdownconfig = (((uint32_t)pPowerDownConfig->MagicPacket << 1) | + ((uint32_t)pPowerDownConfig->WakeUpPacket << 2) | + ((uint32_t)pPowerDownConfig->GlobalUnicast << 9) | + ((uint32_t)pPowerDownConfig->WakeUpForward << 10) | + ETH_MAC_PMTCTLSTU_PWRDWN); + + /* Enable PMT interrupt */ + __ETH_MAC_ENABLE_IT(heth, ETH_MAC_IREN_PMTIE); + + MODIFY_REG(heth->Instance->ETH_MAC_PMTCTLSTU, ETH_MAC_PMTCTLSTU_MASK, powerdownconfig); +} + +/** + * @brief Exits from the Power down mode. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None. + */ +void ETH_ExitPowerDownMode(ETH_HandleTypeDef *heth) +{ + /* clear wake up sources */ + heth->Instance->ETH_MAC_PMTCTLSTU &= (~(ETH_MAC_PMTCTLSTU_RWKPKTEN | ETH_MAC_PMTCTLSTU_MGKPKTEN | ETH_MAC_PMTCTLSTU_GLBLUCAST | + ETH_MAC_PMTCTLSTU_RWKPFE)); + + if (((heth->Instance->ETH_MAC_PMTCTLSTU) & (ETH_MAC_PMTCTLSTU_PWRDWN)) != ((uint32_t)0x0U)) + { + /* Exit power down mode */ + (heth->Instance->ETH_MAC_PMTCTLSTU) &= (~(ETH_MAC_PMTCTLSTU_PWRDWN)); + } + + /* Disable PMT interrupt */ + __ETH_MAC_DISABLE_IT(heth, ETH_MAC_IREN_PMTIE); +} + +/** + * @brief Set the WakeUp filter. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pFilter: pointer to filter registers values + * @param Count: number of filter registers, must be from 1 to 8. + * @retval int. + */ +uint32_t ETH_SetWakeUpFilter(ETH_HandleTypeDef *heth, uint32_t *pFilter, uint32_t Count) +{ + uint32_t regindex; + + if (pFilter == NULL) + { + //return ERROR; + return HAL_ERROR; + } + + /* Reset Filter Pointer */ + (heth->Instance->ETH_MAC_PMTCTLSTU) |= (ETH_MAC_PMTCTLSTU_RWKFILTRST); + + /* Wake up packet filter config */ + for (regindex = 0; regindex < Count; regindex++) + { + /* Write filter regs */ + ((heth->Instance->ETH_MAC_RWKPKTFILT) &= (pFilter[regindex])); + } + + //return OK; + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup ETH_Exported_Functions_Group4 Peripheral State and Errors functions + * @brief heth State and Errors functions + * +@verbatim + ============================================================================== + ##### Peripheral State and Errors functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to return the State of + heth communication process, return Peripheral Errors occurred during communication + process + + +@endverbatim + * @{ + */ + +/** + * @brief Returns the heth state. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL state + */ +uint32_t ETH_GetState(const ETH_HandleTypeDef *heth) +{ + return heth->gState; +} + +/** + * @brief Returns the heth error code + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval heth Error Code + */ +uint32_t ETH_GetError(const ETH_HandleTypeDef *heth) +{ + //return heth->ErrorCode; + return heth->ErrorCode; +} + +/** + * @brief Returns the heth DMA error code + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval heth DMA Error Code + */ +uint32_t ETH_GetDMAError(const ETH_HandleTypeDef *heth) +{ + return heth->DMAErrorCode; +} + +/** + * @brief Returns the heth MAC error code + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval heth MAC Error Code + */ +uint32_t ETH_GetMACError(const ETH_HandleTypeDef *heth) +{ + return heth->MACErrorCode; +} + +/** + * @brief Returns the heth MAC WakeUp event source + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval heth MAC WakeUp event source + */ +uint32_t ETH_GetMACWakeUpSource(const ETH_HandleTypeDef *heth) +{ + return heth->MACWakeUpEvent; +} + +/** + * @} + */ + +/** + * @} + */ + +/** @addtogroup ETH_Private_Functions heth Private Functions + * @{ + */ +uint32_t ETH_SetMACConfig(ETH_HandleTypeDef *heth, ETH_MACConfigTypeDef *macconf) +{ + if (macconf == NULL) + { + return HAL_ERROR; + } + else + { + HAL_ETH_SetMACConfig(heth, macconf); + + return HAL_OK; + } + +} +static void HAL_ETH_SetMACConfig(ETH_HandleTypeDef *heth, const ETH_MACConfigTypeDef *macconf) +{ + uint32_t macregval; + + /*------------------------ ETH_MAC_CFG Configuration --------------------*/ + macregval = (macconf->InterPacketGapVal | + ((uint32_t)macconf->ChecksumOffload << 27) | + ((uint32_t)macconf->GiantPacketSizeLimitControl << 23) | + ((uint32_t)macconf->Support2KPacket << 22) | + ((uint32_t)macconf->CRCStripTypePacket << 21) | + ((uint32_t)macconf->AutomaticPadCRCStrip << 20) | + ((uint32_t)((macconf->Watchdog == DISABLE) ? 1U : 0U) << 19) | + ((uint32_t)((macconf->Jabber == DISABLE) ? 1U : 0U) << 17) | + ((uint32_t)macconf->JumboPacket << 16) | + macconf->Speed | + macconf->DuplexMode | + ((uint32_t)macconf->LoopbackMode << 12) | + ((uint32_t)macconf->CarrierSenseBeforeTransmit << 11) | + ((uint32_t)((macconf->ReceiveOwn == DISABLE) ? 1U : 0U) << 10) | + ((uint32_t)((macconf->CarrierSenseDuringTransmit == DISABLE) ? 1U : 0U) << 9) | + ((uint32_t)((macconf->RetryTransmission == DISABLE) ? 1U : 0U) << 8) | + macconf->BackOffLimit | + ((uint32_t)macconf->DeferralCheck << 4) | + macconf->PreambleLength); + + /* Write to ETH_MAC_CFG */ + MODIFY_REG(heth->Instance->ETH_MAC_CFG, ETH_MAC_CFG_MASK, macregval); + + /*------------------------ ETH_MAC_EXTDCFG Configuration --------------------*/ + macregval = ((macconf->ExtendedInterPacketGapVal << 25) | + ((uint32_t)macconf->ExtendedInterPacketGap << 24) | + ((uint32_t)macconf->UnicastSlowProtocolPacketDetect << 18) | + ((uint32_t)macconf->SlowProtocolDetect << 17) | + ((uint32_t)((macconf->CRCCheckingRxPackets == DISABLE) ? 1U : 0U) << 16) | + macconf->GiantPacketSizeLimit); + + /* Write to ETH_MAC_EXTDCFG */ + MODIFY_REG(heth->Instance->ETH_MAC_EXTDCFG, ETH_MAC_EXTDCFG_MASK, macregval); + + /*------------------------ ETH_MAC_WTDTO Configuration --------------------*/ + macregval = (((uint32_t)macconf->ProgrammableWatchdog << 8) | + macconf->WatchdogTimeout); + + /* Write to ETH_MAC_WTDTO */ + MODIFY_REG(heth->Instance->ETH_MAC_WTDTO, ETH_MAC_WTDTO_MASK, macregval); + + /*------------------------ ETH_MAC_TXFLCTL Configuration --------------------*/ + macregval = (((uint32_t)macconf->TransmitFlowControl << 1) | + macconf->PauseLowThreshold | + ((uint32_t)((macconf->ZeroQuantaPause == DISABLE) ? 1U : 0U) << 7) | + (macconf->PauseTime << 16)); + + /* Write to ETH_MAC_TXFLCTL */ + MODIFY_REG(heth->Instance->ETH_MAC_TXFLCTL, ETH_MAC_TXFLCTL_MASK, macregval); + + /*------------------------ ETH_MAC_RXFLCTL Configuration --------------------*/ + macregval = ((uint32_t)macconf->ReceiveFlowControl | + ((uint32_t)macconf->UnicastPausePacketDetect << 1)); + + /* Write to ETH_MAC_RXFLCTL */ + MODIFY_REG(heth->Instance->ETH_MAC_RXFLCTL, ETH_MAC_RXFLCTL_MASK, macregval); + + /*------------------------ ETH_MTL_TXQOPMODE Configuration --------------------*/ + /* Write to ETH_MTL_TXQOPMODE */ + MODIFY_REG(heth->Instance->ETH_MTL_TXQOPMODE, ETH_MTL_TXQOPMODE_MASK, macconf->TransmitQueueMode); + + /*------------------------ ETH_MTL_RXQOPMODE Configuration --------------------*/ + macregval = (macconf->ReceiveQueueMode | + ((uint32_t)((macconf->DropTCPIPChecksumErrorPacket == DISABLE) ? 1U : 0U) << 6) | + ((uint32_t)macconf->ForwardRxErrorPacket << 4) | + ((uint32_t)macconf->ForwardRxUndersizedGoodPacket << 3)); + + /* Write to ETH_MTL_RXQOPMODE */ + MODIFY_REG(heth->Instance->ETH_MTL_RXQOPMODE, ETH_MTL_RXQOPMODE_MASK, macregval); +} + + +static void ETH_SetDMAConfig(ETH_HandleTypeDef *heth, const ETH_DMAConfigTypeDef *dmaconf) +{ + uint32_t dmaregval; + + /*------------------------ETH_DMA_OPMODE Configuration --------------------*/ + MODIFY_REG(heth->Instance->ETH_DMA_OPMODE, ETH_DMA_OPMODE_MASK, dmaconf->DMAArbitration); + + /*------------------------ETH_DMA_SYSBUSMODE_MASK Configuration --------------------*/ + dmaregval = (((uint32_t)dmaconf->AddressAlignedBeats << 12) | + dmaconf->BurstMode | + ((uint32_t)dmaconf->RebuildINCRxBurst << 15)); + + MODIFY_REG(heth->Instance->ETH_DMA_SYSBUSMODE, ETH_DMA_SYSBUSMODE_MASK, dmaregval); + + /*------------------------ ETH_DMA_CTL Configuration --------------------*/ + dmaregval = ((uint32_t)dmaconf->PBLx8Mode << 16) ; + + MODIFY_REG(heth->Instance->ETH_DMA_CTL, ETH_DMA_CTL_MASK, dmaregval); + + /*------------------------ ETH_DMA_TXCTL Configuration --------------------*/ + dmaregval = (dmaconf->TxDMABurstLength | ((uint32_t)dmaconf->SecondPacketOperate << 4)); + + MODIFY_REG(heth->Instance->ETH_DMA_TXCTL, ETH_DMA_TXCTL_MASK, dmaregval); + + /*------------------------ ETH_DMA_RXCTL Configuration --------------------*/ + dmaregval = (((uint32_t)dmaconf->FlushRxPacket << 31) | dmaconf->RxDMABurstLength); + + /* Write to ETH_DMA_RXCTL */ + MODIFY_REG(heth->Instance->ETH_DMA_RXCTL, ETH_DMA_RXCTL_MASK, dmaregval); +} + +/** + * @brief Configures Ethernet MAC and DMA with default parameters. + * called by ETH_Init() API. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval none + */ +static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth) +{ + ETH_MACConfigTypeDef macDefaultConf; + ETH_DMAConfigTypeDef dmaDefaultConf; + + /*--------------- ETHERNET MAC registers default Configuration --------------*/ + macDefaultConf.AutomaticPadCRCStrip = ENABLE; + macDefaultConf.BackOffLimit = ETH_BACKOFFLIMIT_10; + macDefaultConf.CarrierSenseBeforeTransmit = DISABLE; + macDefaultConf.CarrierSenseDuringTransmit = ENABLE; + macDefaultConf.ChecksumOffload = ENABLE; + macDefaultConf.CRCCheckingRxPackets = ENABLE; + macDefaultConf.CRCStripTypePacket = ENABLE; + macDefaultConf.DeferralCheck = DISABLE; + macDefaultConf.DropTCPIPChecksumErrorPacket = ENABLE; + macDefaultConf.DuplexMode = ETH_FULLDUPLEX_MODE; + macDefaultConf.ExtendedInterPacketGap = DISABLE; + macDefaultConf.ExtendedInterPacketGapVal = 0x0U; + macDefaultConf.ForwardRxErrorPacket = DISABLE; + macDefaultConf.ForwardRxUndersizedGoodPacket = DISABLE; + macDefaultConf.GiantPacketSizeLimit = 0x618U; + macDefaultConf.GiantPacketSizeLimitControl = DISABLE; + macDefaultConf.InterPacketGapVal = ETH_INTERPACKETGAP_96BIT; + macDefaultConf.Jabber = ENABLE; + macDefaultConf.JumboPacket = DISABLE; + macDefaultConf.LoopbackMode = DISABLE; + macDefaultConf.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS_4; + macDefaultConf.PauseTime = 0x0U; + macDefaultConf.PreambleLength = ETH_PREAMBLELENGTH_7; + macDefaultConf.ProgrammableWatchdog = DISABLE; + macDefaultConf.ReceiveFlowControl = DISABLE; + macDefaultConf.ReceiveOwn = ENABLE; + macDefaultConf.ReceiveQueueMode = ETH_RECEIVESTOREFORWARD; + macDefaultConf.RetryTransmission = ENABLE; + macDefaultConf.SlowProtocolDetect = DISABLE; + macDefaultConf.Speed = ETH_SPEED_100M; + macDefaultConf.Support2KPacket = DISABLE; + macDefaultConf.TransmitQueueMode = ETH_TRANSMITSTOREFORWARD; + macDefaultConf.TransmitFlowControl = DISABLE; + macDefaultConf.UnicastPausePacketDetect = DISABLE; + macDefaultConf.UnicastSlowProtocolPacketDetect = DISABLE; + macDefaultConf.Watchdog = ENABLE; + macDefaultConf.WatchdogTimeout = ETH_WATCHDOGTIMEOUT_2KB; + macDefaultConf.ZeroQuantaPause = ENABLE; + + /* MAC default configuration */ + ETH_SetMACConfig(heth, &macDefaultConf); + + /*--------------- ETHERNET DMA registers default Configuration --------------*/ + dmaDefaultConf.AddressAlignedBeats = ENABLE; + dmaDefaultConf.BurstMode = ETH_BURSTLENGTH_FIXED; + dmaDefaultConf.DMAArbitration = ETH_DMAARBITRATION_RX1_TX1; + dmaDefaultConf.FlushRxPacket = DISABLE; + dmaDefaultConf.PBLx8Mode = DISABLE; + dmaDefaultConf.RebuildINCRxBurst = DISABLE; + dmaDefaultConf.RxDMABurstLength = ETH_RXDMABURSTLENGTH_32BEAT; + dmaDefaultConf.SecondPacketOperate = DISABLE; + dmaDefaultConf.TxDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT; + + /* DMA default configuration */ + ETH_SetDMAConfig(heth, &dmaDefaultConf); +} + +/** + * @brief Initializes the DMA Tx descriptors. + * called by ETH_Init() API. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ +static void ETH_DMATxDescListInit(ETH_HandleTypeDef *heth) +{ + ETH_DMADescTypeDef *dmatxdesc; + uint32_t i; + + /* Fill each DMATxDesc descriptor with the right values */ + for (i = 0; i < (uint32_t)ETH_TX_DESC_CNT; i++) + { + dmatxdesc = heth->Init.TxDesc + i; + + WRITE_REG(dmatxdesc->DESC0, 0x0U); + WRITE_REG(dmatxdesc->DESC1, 0x0U); + WRITE_REG(dmatxdesc->DESC2, 0x0U); + WRITE_REG(dmatxdesc->DESC3, 0x0U); + + WRITE_REG(heth->TxDescList.TxDesc[i], (uint32_t)dmatxdesc); + + /*TODO*/ + //printf("TxDescList TxDesc[%d] addr = %p\n",i,heth->TxDescList.TxDesc[i]); + } + + heth->TxDescList.CurTxDesc = 0; + + /* Set Transmit Descriptor Ring Length */ + WRITE_REG(heth->Instance->ETH_DMA_TXDESCRINGLEN, (ETH_TX_DESC_CNT - 1U)); + + /* Set Transmit Descriptor List Address */ + WRITE_REG(heth->Instance->ETH_DMA_TXDESCLSTADDR, (uint32_t) heth->Init.TxDesc); + + /* Set Transmit Descriptor Tail pointer */ + WRITE_REG(heth->Instance->ETH_DMA_TXDESCTAILPTR, (uint32_t) heth->Init.TxDesc); +} + +/** + * @brief Initializes the DMA Rx descriptors in chain mode. + * called by ETH_Init() API. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ +static void ETH_DMARxDescListInit(ETH_HandleTypeDef *heth) +{ + ETH_DMADescTypeDef *dmarxdesc; + uint32_t i; + + for (i = 0; i < (uint32_t)ETH_RX_DESC_CNT; i++) + { + dmarxdesc = heth->Init.RxDesc + i; + + WRITE_REG(dmarxdesc->DESC0, 0x0U); + WRITE_REG(dmarxdesc->DESC1, 0x0U); + WRITE_REG(dmarxdesc->DESC2, 0x0U); + WRITE_REG(dmarxdesc->DESC3, 0x0U); + WRITE_REG(dmarxdesc->BackupAddr0, 0x0U); + WRITE_REG(dmarxdesc->BackupAddr1, 0x0U); + + /* Set Rx descritors addresses */ + WRITE_REG(heth->RxDescList.RxDesc[i], (uint32_t)dmarxdesc); + + /*TODO*/ + //printf("RxDescList RxDesc[%d] addr = %p\n",i,heth->RxDescList.RxDesc[i]); + } + + WRITE_REG(heth->RxDescList.RxDescIdx, 0U); + WRITE_REG(heth->RxDescList.RxDescCnt, 0U); + WRITE_REG(heth->RxDescList.RxBuildDescIdx, 0U); + WRITE_REG(heth->RxDescList.RxBuildDescCnt, 0U); + WRITE_REG(heth->RxDescList.ItMode, 0U); + + /* Set Receive Descriptor Ring Length */ + WRITE_REG(heth->Instance->ETH_DMA_RXCTL2, ((uint32_t)(ETH_RX_DESC_CNT - 1U))); + + /* Set Receive Descriptor List Address */ + WRITE_REG(heth->Instance->ETH_DMA_RXDESCLSTADDR, (uint32_t) heth->Init.RxDesc); + + /* Set Receive Descriptor Tail pointer Address */ + WRITE_REG(heth->Instance->ETH_DMA_RXDESCTAILPTR, ((uint32_t)(heth->Init.RxDesc + (uint32_t)(ETH_RX_DESC_CNT - 1U)))); +} + +/** + * @brief Prepare Tx DMA descriptor before transmission. + * called by ETH_Transmit and ETH_Transmit_IT() API. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pTxConfig: Tx packet configuration + * @param ItMode: Enable or disable Tx EOT interrept + * @retval Status + */ +static uint32_t ETH_Prepare_Tx_Descriptors(ETH_HandleTypeDef *heth, const ETH_TxPacketConfigTypeDef *pTxConfig, + uint32_t ItMode) +{ + ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList; + uint32_t descidx = dmatxdesclist->CurTxDesc; + uint32_t firstdescidx = dmatxdesclist->CurTxDesc; + uint32_t idx; + uint32_t descnbr = 0; + ETH_DMADescTypeDef *dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx]; + + ETH_BufferTypeDef *txbuffer = pTxConfig->TxBuffer; + + /*TODO*/ + //printf("Prepare TxDESC[%d],addr=%p\n",descidx,dmatxdesclist->TxDesc[descidx]); + //printf("ETH Buffer addr = %p\n",*txbuffer); + + uint32_t bd_count = 0; + uint32_t primask_bit; + + /* Current Tx Descriptor Owned by DMA: cannot be used by the application */ + if ((((dmatxdesc->DESC3)Ð_DMATXNDESCWBF_OWN) == ETH_DMATXNDESCWBF_OWN) + || (dmatxdesclist->PacketAddress[descidx] != NULL)) + { + return ETH_ERROR_BUSY; + } + + + + /***************************************************************************/ + /***************** Normal descriptors configuration *****************/ + /***************************************************************************/ + descnbr += 1U; + + /* Set header or buffer 1 address */ + WRITE_REG(dmatxdesc->DESC0, (uint32_t)txbuffer->buffer); + /* Set header or buffer 1 Length */ + MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B1L, txbuffer->len); + + //if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_CSUM) != (uint32_t)RESET) + if ((((pTxConfig->Attributes)Ð_TX_PACKETS_FEATURES_CSUM)) != (uint32_t)(0x0U)) + { + MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_CIC, pTxConfig->ChecksumCtrl); + } + + //if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_CRCPAD) != (uint32_t)RESET) + if (((pTxConfig->Attributes)Ð_TX_PACKETS_FEATURES_CRCPAD) != (uint32_t)(0x0U)) + { + MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_CPC, pTxConfig->CRCPadCtrl); + } + //} + + if (((pTxConfig->Attributes)Ð_TX_PACKETS_FEATURES_VLANTAG) != (uint32_t)(0x0U)) + { + /* Set Vlan Tag control */ + MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_VTIR, pTxConfig->VlanCtrl); + } + + if (txbuffer->next != NULL) + { + txbuffer = txbuffer->next; + /* Set buffer 2 address */ + WRITE_REG(dmatxdesc->DESC1, (uint32_t)txbuffer->buffer); + /* Set buffer 2 Length */ + MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B2L, (txbuffer->len << 16)); + } + else + { + WRITE_REG(dmatxdesc->DESC1, 0x0U); + /* Set buffer 2 Length */ + MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B2L, 0x0U); + } + //if (((pTxConfig->Attributes)Ð_TX_PACKETS_FEATURES_TSO) != (uint32_t)(0x0U)) + //{ + // /* Set TCP Header length */ + // MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_THL, (pTxConfig->TCPHeaderLen << 19)); + // /* Set TCP payload length */ + // MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_TPL, pTxConfig->PayloadLen); + // /* Set TCP Segmentation Enabled bit */ + // dmatxdesc->DESC3 |= ETH_DMATXNDESCRF_TSE; + //} + //else + //{ + MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_FL, pTxConfig->Length); + + /* Mark it as First Descriptor */ + //SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_FD); + dmatxdesc->DESC3 |= ETH_DMATXNDESCRF_FD; + /* Mark it as NORMAL descriptor */ + //CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_CTXT); + dmatxdesc->DESC3 &= (~(ETH_DMATXNDESCRF_CTXT)); + /* Ensure rest of descriptor is written to RAM before the OWN bit */ + __DMB(); + /* set OWN bit of FIRST descriptor */ + //SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_OWN); + dmatxdesc->DESC3 |= ETH_DMATXNDESCRF_OWN; + + /* If source address insertion/replacement is enabled for this packet */ + if (((pTxConfig->Attributes)Ð_TX_PACKETS_FEATURES_SAIC) != (uint32_t)(0x0U)) + { + MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_SAIC, pTxConfig->SrcAddrCtrl); + } + + /* only if the packet is split into more than one descriptors > 1 */ + while (txbuffer->next != NULL) + { + /* Clear the LD bit of previous descriptor */ + //CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_LD); + dmatxdesc->DESC3 &= (~(ETH_DMATXNDESCRF_LD)); + /* Increment current tx descriptor index */ + INCR_TX_DESC_INDEX(descidx, 1U); + /* Get current descriptor address */ + dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx]; + + /* Clear the FD bit of new Descriptor */ + //CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_FD); + dmatxdesc->DESC3 &= (~(ETH_DMATXNDESCRF_FD)); + + /* Current Tx Descriptor Owned by DMA: cannot be used by the application */ + if ((((dmatxdesc->DESC3)Ð_DMATXNDESCRF_OWN) == ETH_DMATXNDESCRF_OWN) + || (dmatxdesclist->PacketAddress[descidx] != NULL)) + { + descidx = firstdescidx; + dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx]; + + /* clear previous desc own bit */ + for (idx = 0; idx < descnbr; idx ++) + { + /* Ensure rest of descriptor is written to RAM before the OWN bit */ + __DMB(); + + //CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_OWN); + dmatxdesc->DESC3 &= (~(ETH_DMATXNDESCRF_OWN)); + + /* Increment current tx descriptor index */ + INCR_TX_DESC_INDEX(descidx, 1U); + /* Get current descriptor address */ + dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx]; + } + + return ETH_ERROR_BUSY; + } + + descnbr += 1U; + + /* Get the next Tx buffer in the list */ + txbuffer = txbuffer->next; + + /* Set header or buffer 1 address */ + WRITE_REG(dmatxdesc->DESC0, (uint32_t)txbuffer->buffer); + /* Set header or buffer 1 Length */ + MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B1L, txbuffer->len); + + if (txbuffer->next != NULL) + { + /* Get the next Tx buffer in the list */ + txbuffer = txbuffer->next; + /* Set buffer 2 address */ + WRITE_REG(dmatxdesc->DESC1, (uint32_t)txbuffer->buffer); + /* Set buffer 2 Length */ + MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B2L, (txbuffer->len << 16)); + } + else + { + WRITE_REG(dmatxdesc->DESC1, 0x0U); + /* Set buffer 2 Length */ + MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B2L, 0x0U); + } + + //if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_TSO) != (uint32_t)RESET) + //if (((pTxConfig->Attributes) & ETH_TX_PACKETS_FEATURES_TSO) != (uint32_t)(0x0U)) + //{ + // /* Set TCP payload length */ + // MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_TPL, pTxConfig->PayloadLen); + // /* Set TCP Segmentation Enabled bit */ + // //SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_TSE); + // dmatxdesc->DESC3 |= ETH_DMATXNDESCRF_TSE; + //} + //else + //{ + /* Set the packet length */ + MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_FL, pTxConfig->Length); + + //if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_CSUM) != (uint32_t)RESET) + if (((pTxConfig->Attributes) & ETH_TX_PACKETS_FEATURES_CSUM) != (uint32_t)(0x0U)) + { + /* Checksum Insertion Control */ + MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_CIC, pTxConfig->ChecksumCtrl); + } + //} + + bd_count += 1U; + + /* Ensure rest of descriptor is written to RAM before the OWN bit */ + __DMB(); + /* Set Own bit */ + //SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_OWN); + dmatxdesc->DESC3 |= ETH_DMATXNDESCRF_OWN; + /* Mark it as NORMAL descriptor */ + //CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_CTXT); + dmatxdesc->DESC3 &= (~(ETH_DMATXNDESCRF_CTXT)); + } + + //if (ItMode != ((uint32_t)RESET)) + if (ItMode != ((uint32_t)(0x0U))) + { + /* Set Interrupt on completion bit */ + //SET_BIT(dmatxdesc->DESC2, ETH_DMATXNDESCRF_IOC); + dmatxdesc->DESC2 |= ETH_DMATXNDESCRF_IOC; + } + else + { + /* Clear Interrupt on completion bit */ + //CLEAR_BIT(dmatxdesc->DESC2, ETH_DMATXNDESCRF_IOC); + dmatxdesc->DESC2 &= (~(ETH_DMATXNDESCRF_IOC)); + } + + /* Mark it as LAST descriptor */ + //SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_LD); + dmatxdesc->DESC3 |= ETH_DMATXNDESCRF_LD; + /* Save the current packet address to expose it to the application */ + dmatxdesclist->PacketAddress[descidx] = dmatxdesclist->CurrentPacketAddress; + + dmatxdesclist->CurTxDesc = descidx; + + /* Enter critical section */ + primask_bit = __get_PRIMASK(); + __set_PRIMASK(1); + + dmatxdesclist->BuffersInUse += bd_count + 1U; + + /* Exit critical section: restore previous priority mask */ + __set_PRIMASK(primask_bit); + + /* Return function status */ + return ETH_ERROR_NONE; +} + +/** + * @} + */ + +/** + * @} + */ + +//#endif /* heth */ + +/** + * @} + */ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_exti.c b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_exti.c new file mode 100644 index 00000000000..c3c2d5daf86 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_exti.c @@ -0,0 +1,211 @@ +/** + ****************************************************************************** + * @file ft32f4xx_exti.c + ****************************************************************************** + */ + + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx_exti.h" + + + +/** @defgroup EXTI + * @brief EXTI driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +#define EXTI_LINENONE ((uint32_t)0x00000) /* No interrupt selected */ + + +/** + * @brief Deinitializes the EXTI peripheral registers to their default reset + * values. + * @param None + * @retval None + */ +void EXTI_DeInit(void) +{ + EXTI->IMR = 0x60000000; + EXTI->EMR = 0x00000000; + EXTI->RTSR = 0x00000000; + EXTI->FTSR = 0x00000000; + EXTI->SWIER = 0x00000000; + EXTI->PR = 0x00000000; +} + + +/** + * @brief Initializes the EXTI peripheral according to the specified + * parameters in the EXTI_InitStruct. + * @param EXTI_InitStruct: pointer to a EXTI_InitTypeDef structure that + * contains the configuration information for the EXTI peripheral. + * @retval None + */ +void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct) +{ + uint32_t tmp = 0; + + /* Check the parameters */ + assert_param(IS_EXTI_MODE(EXTI_InitStruct->EXTI_Mode)); + assert_param(IS_EXTI_TRIGGER(EXTI_InitStruct->EXTI_Trigger)); + assert_param(IS_GET_EXTI_LINE(EXTI_InitStruct->EXTI_Line)); + assert_param(IS_FUNCTIONAL_STATE(EXTI_InitStruct->EXTI_LineCmd)); + + tmp = (uint32_t)EXTI_BASE; + + if (EXTI_InitStruct->EXTI_LineCmd != DISABLE) + { + /* Clear EXTI line configuration */ + EXTI->IMR &= ~EXTI_InitStruct->EXTI_Line; + EXTI->EMR &= ~EXTI_InitStruct->EXTI_Line; + + tmp += EXTI_InitStruct->EXTI_Mode; + + *(__IO uint32_t *) tmp |= EXTI_InitStruct->EXTI_Line; + + /* Clear Rising Falling edge configuration */ + EXTI->RTSR &= ~EXTI_InitStruct->EXTI_Line; + EXTI->FTSR &= ~EXTI_InitStruct->EXTI_Line; + + /* Select the trigger for the selected interrupts */ + if (EXTI_InitStruct->EXTI_Trigger == EXTI_Trigger_Rising_Falling) + { + /* Rising Falling edge */ + EXTI->RTSR |= EXTI_InitStruct->EXTI_Line; + EXTI->FTSR |= EXTI_InitStruct->EXTI_Line; + } + else + { + tmp = (uint32_t)EXTI_BASE; + tmp += EXTI_InitStruct->EXTI_Trigger; + + *(__IO uint32_t *) tmp |= EXTI_InitStruct->EXTI_Line; + } + } + else + { + tmp += EXTI_InitStruct->EXTI_Mode; + + /* Disable the selected external lines */ + *(__IO uint32_t *) tmp &= ~EXTI_InitStruct->EXTI_Line; + } +} + + +/** + * @brief Fills each EXTI_InitStruct member with its reset value. + * @param EXTI_InitStruct: pointer to a EXTI_InitTypeDef structure which will + * be initialized. + * @retval None + */ +void EXTI_StructInit(EXTI_InitTypeDef* EXTI_InitStruct) +{ + EXTI_InitStruct->EXTI_Line = EXTI_LINENONE; + EXTI_InitStruct->EXTI_Mode = EXTI_Mode_Interrupt; + EXTI_InitStruct->EXTI_Trigger = EXTI_Trigger_Falling; + EXTI_InitStruct->EXTI_LineCmd = DISABLE; +} + + +/** + * @brief Generates a Software interrupt on selected EXTI line. + * @param EXTI_Line: specifies the EXTI line on which the software interrupt + * will be generated. + * This parameter can be any combination of EXTI_Linex where x can be (0..28). + * Line29(LPTIM)&Line30(LPUART) are don't have flag status. + * @retval None + */ +void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line) +{ + /* Check the parameters */ + assert_param(IS_GET_EXTI_LINE(EXTI_Line)); + + EXTI->SWIER |= EXTI_Line; +} + + +/** + * @brief Checks whether the specified EXTI line flag is set or not. + * @param EXTI_Line: specifies the EXTI line flag to check. + * This parameter can be EXTI_Linex where x can be (0..28). + * Line29(LPTIM)&Line30(LPUART) are don't have flag status. + * @retval The new state of EXTI_Line (SET or RESET). + */ +FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line) +{ + FlagStatus bitstatus = RESET; + /* Check the parameters */ + assert_param(IS_GET_EXTI_LINE(EXTI_Line)); + + if ((EXTI->PR & EXTI_Line) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + return bitstatus; +} + + +/** + * @brief Clears the EXTI's line pending flags. + * @param EXTI_Line: specifies the EXTI lines flags to clear. + * This parameter can be any combination of EXTI_Linex where x can be (0..28). + * @retval None + */ +void EXTI_ClearFlag(uint32_t EXTI_Line) +{ + /* Check the parameters */ + assert_param(IS_GET_EXTI_LINE(EXTI_Line)); + + EXTI->PR = EXTI_Line; +} + + +/** + * @brief Checks whether the specified EXTI line is asserted or not. + * @param EXTI_Line: specifies the EXTI line to check. + * This parameter can be EXTI_Linex where x can be (0..28). + * @retval The new state of EXTI_Line (SET or RESET). + */ +ITStatus EXTI_GetITStatus(uint32_t EXTI_Line) +{ + ITStatus bitstatus = RESET; + + /* Check the parameters */ + assert_param(IS_GET_EXTI_LINE(EXTI_Line)); + + if ((EXTI->PR & EXTI_Line) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + return bitstatus; +} + + +/** + * @brief Clears the EXTI's line pending bits. + * @param EXTI_Line: specifies the EXTI lines to clear. + * This parameter can be any combination of EXTI_Linex where x can be (0..28). + * @retval None + */ +void EXTI_ClearITPendingBit(uint32_t EXTI_Line) +{ + /* Check the parameters */ + assert_param(IS_GET_EXTI_LINE(EXTI_Line)); + + EXTI->PR = EXTI_Line; +} + + + +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_fdcan.c b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_fdcan.c new file mode 100644 index 00000000000..aa973233394 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_fdcan.c @@ -0,0 +1,2449 @@ +/** + ****************************************************************************** + * @file ft32f4xx_fdcan.c + * @author FMD AE + * @brief FDCAN module driver. + * This file provides firmware functions to manage the following + * functionalities of the Flexible DataRate Controller Area Network + * (FDCAN) peripheral:: + * + Initialization and de-initialization functions + * + IO operation functions + * + Peripheral Configuration and Control functions + * + Peripheral State and Error functions + * + Interrupts and flags management + * @version V1.0.0 + * @data 2025-03-06 + * @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + (#) Initialize the FDCAN peripheral using FDCAN_Init function. + (++) FDCAN_Init + (++) FDCAN_DeInit + (#) If needed , configure the reception filters and optional features using + the following configuration functions: + (++) FDCAN_ConfigFilter + (++) FDCAN_ConfigRxFifoOverwrite + (++) FDCAN_ConfigTimestampLocation + (++) FDCAN_EnableTimestampCounter + (++) FDCAN_ConfigTxDelayCompensation + (++) FDCAN_EnableTxDelayCompensation + (++) FDCAN_EnableISOMode + (++) FDCAN_DisableISOMode + + (#) If needed , configure the TxBuffer and get RxBuffer and other value using + the following configuration functions: + (++) FDCAN_ConfigTxBuffer + (++) FDCAN_GetRxBuffer + (++) FDCAN_GetArbLostCap + (++) FDCAN_GetErrorCnt + + (#) Start the FDCAN module using FDCAN_Start function. At this level + the node is active on the bus: it can send and receive messages. + + (#) The following Tx control functions can only be called when the FDCAN + module is started: + (++) FDCAN_AddMessageToTxPTB + (++) FDCAN_AddMessageToTxSTBFifoQ + (++) FDCAN_AbortTxRequest + + (#) After having submitted a Tx request in Tx Fifo or Queue, it is possible to + get STB Tx buffer status if used STB for transmission thanks to + FDCAN_GetSecondaryBufferStatus API. + It is then possible to abort transmission from STB which has been requested + but not started yet using FDCAN_AbortTxRequest API. + + (#) When a message is received into the FDCAN message RAM, it can be + retrieved using the FDCAN_GetRxMessage function. + + (#) Calling the FDCAN_Stop function stops the FDCAN module by entering + it to initialization mode and re-enabling access to configuration + registers through the configuration functions listed here above. + + (#) All other control functions can be called any time after initialization + phase, no matter if the FDCAN module is started or stopped. + + *** Polling mode operation *** + ============================== + [..] + (#) Reception and transmission states can be monitored via the following + functions: + (++) HAL_FDCAN_GetRxFifoFillStatus + (++) FDCAN_GetSecondaryBufferStatus + + *** Interrupt mode operation *** + ================================ + [..] + (#) There are one interrupt line for each FDCAN: line 0. + By default, all interrupts are assigned to line 0. + + (#) Notifications are activated using FDCAN_ActivateNotification + function. Then, the process can be controlled through one of the + available user callbacks: CANx_Handler. + + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx_fdcan.h" +#include "ft32f4xx_rcc.h" + + +/** + * @brief Calculate each RAM block start address and size + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @retval none + */ +//static void FDCAN_CalcultateBlockBaseAddresses(FDCAN_TypeDef* fdcan) //zhujia +//{ +//} + +//arbitration need handle process how or just leave function head file? + +/* ============================================================================== + ##### Initialization and de-initialization functions ##### + ============================================================================== + [..] This section provides functions allowing to: + (+) Initialize and configure the FDCAN. + (+) De-initialize the FDCAN. + (+) Enter FDCAN peripheral in power down mode. +*/ +/** + * @brief Initializes the FDCAN peripheral according to the specified + * parameters in the FDCAN_InitTypeDef structure. + * @param fdcan: specifies the instance. + * This parameter can be any combination of the following values: + * @arg FDCAN1: the instance is can1 + * @arg FDCAN2: the instance is can2 + * @arg FDCAN3: the instance is can3 + * @arg FDCAN4: the instance is can4 + * @param fdcanInit: specifies the fdcan initial config value + * @arg FrameFormat: Specifies the FDCAN frame format + * The value of FrameFormat: FDCAN_FRAME_CLASSIC + * FDCAN_FRAME_FD_NO_BRS + * FDCAN_FRAME_FD_BRS + * @arg AutoPrimaryRetransmission: Enable or disable the automatic retransmission mode for PTB + * The value of AutoPrimaryRetransmission: ENABLE + * DISABLE + * @arg AutoSecondaryRetransmission: Enable or disable the automatic retransmission mode for STB + * The value of AutoSecondaryRetransmission: ENABLE + * DISABLE + * @arg TTCANMode: Enable or disable the Time Trigger CAN + * The value of TTCANMode: ENABLE + * DISABLE + * @arg FDCANSACK: Specifies the Self-ACKnowledge in External LoopBack mode + * The value of FDCANSACK: FDCAN_NO_SACK + * FDCAN_SACK + * @arg ReceiveBufferStoreAllFrames: Specifies the receive buffer stores all frames or normal frames + * The value of ReceiveBufferStoreAllFrames: FDCAN_RBUF_STORE_NORMAL_OPERATION + * FDCAN_RBUF_STORE_ALL_DATA_FRAMES + * CAN_S_SEG_UNIT_SET: Config the follow parameter in this register: + * @arg NominalPrescaler: Specifies the value by which the oscillator frequency + * is divided for generating the nominal bit time quanta + * The value of NominalPrescaler: 1 and 255 + * @arg NominalSyncJumpWidth: Specifies the maximum number of time quanta the FDCAN hardware + * is allowed to lengthen or shorten a bit to performresynchronization + * The value of NominalSyncJumpWidth: 2 and 127 + * @arg NominalTimeSeg1: Specifies the number of time quanta in Bit Segment 1 + * The value of NominalTimeSeg1: 3 and 255 + * @arg NominalTimeSeg2: Specifies the number of time quanta in Bit Segment 2 + * The value of NominalTimeSeg2: 2 and 127 + * CAN_F_SEG_UNIT_SET: Config the follow parameter in this register: + * @arg DataPrescaler: Specifies the value by which the oscillator frequency + * is divided for generating the data bit time quanta + * The value of DataPrescaler: 1 and 255 + * @arg DataSyncJumpWidth: Specifies the maximum number of time quanta the FDCAN hardware + * is allowed to lengthen or shorten a data bit to perform resynchronization + * The value of DataSyncJumpWidth: 2 and 15 + * @arg DataTimeSeg1: Specifies the number of time quanta in Data Bit Segment 1 + * The value of DataTimeSeg1: 3 and 31 + * @arg DataTimeSeg2: Specifies the number of time quanta in Data Bit Segment 2 + * The value of DataTimeSeg2: 2 and 15 + * @arg TimeTriggerPrescaler: Specifies the value by which bit time is divided for time trigger timer + * The value of TimeTriggerPrescaler: FDCAN_TIME_TRIGGER_PRESCALER_1 + * FDCAN_TIME_TRIGGER_PRESCALER_2 + * FDCAN_TIME_TRIGGER_PRESCALER_4 + * FDCAN_TIME_TRIGGER_PRESCALER_8 + * @arg TimeTriggerType: Specifies the kind of trigger in Time Trigger mode CAN_TRIG_CFG[TTYPE] + * The value of TimeTriggerType: FDCAN_TTCAN_IMMEDIATE_TRIG + * FDCAN_TTCAN_TIME_TRIG + * FDCAN_TTCAN_SINGLE_SHOT_TRIG + * FDCAN_TTCAN_TRANSMIT_START_TRIG + * FDCAN_TTCAN_TRANSMIT_STOP_TRIG + * @arg TransmitEnableWindow: Specifies the ticks of transmit enable window CAN_TRIG_CFG[TEW] + * The value of TransmitEnableWindow: 0 and 15 + * @arg TriggerTime: Specifies the cycle time for a trigger CAN_TRIG_CFG[TT_TRIG] + * The value of TriggerTime: 0 and 255 + * @arg WatchTriggerTime: Specifies the cycle time for a watch trigger CAN_TRANS_INT_STAT[TT_WTRIG] + * The value of WatchTriggerTime: 0 and 255 + * @retval None. + */ + +void FDCAN_Init(FDCAN_TypeDef* fdcan, FDCAN_InitTypeDef* fdcanInit) +{ + /* Check function parameters */ + assert_param(IS_FDCAN_ALL_INSTANCE(fdcan));/*Check fdcan ?= FDCAN1/2/3/4*/ + + /* Check Init parameters */ + assert_param(IS_FDCAN_FRAME_FORMAT(fdcanInit->FrameFormat)); + assert_param(IS_FUNCTIONAL_STATE(fdcanInit->AutoPrimaryRetransmission)); + assert_param(IS_FUNCTIONAL_STATE(fdcanInit->AutoSecondaryRetransmission)); + assert_param(IS_FDCAN_FDCANSACK(fdcanInit->FDCANSACK)); + assert_param(IS_FDCAN_RBUF_STORE_ALL(fdcanInit->ReceiveBufferStoreAllFrames)); + assert_param(IS_FDCAN_NOMINAL_PRESCALER(fdcanInit->NominalPrescaler)); + assert_param(IS_FDCAN_NOMINAL_SJW(fdcanInit->NominalSyncJumpWidth)); + assert_param(IS_FDCAN_NOMANAL_SEG1(fdcanInit->NominalTimeSeg1)); + assert_param(IS_FDCAN_NOMANAL_SEG2(fdcanInit->NominalTimeSeg2)); + assert_param(IS_FDCAN_DATA_PRESCALER(fdcanInit->DataPrescaler)); + assert_param(IS_FDCAN_DATA_SJW(fdcanInit->DataSyncJumpWidth)); + assert_param(IS_FDCAN_DATA_SEG1(fdcanInit->DataTimeSeg1)); + assert_param(IS_FDCAN_DATA_SEG2(fdcanInit->DataTimeSeg2)); + + if (fdcanInit->TTCANMode == ENABLE) /*The TTCAN is set*/ + { + assert_param(IS_FDCAN_TTCAN_PRESCALER(fdcanInit->TimeTriggerPrescaler)); + assert_param(IS_FDCAN_TTCAN_TYPE(fdcanInit->TimeTriggerType)); + assert_param(IS_FDCAN_TTCAN_TR_EN_WIN(fdcanInit->TransmitEnableWindow)); + assert_param(IS_FDCAN_TTCAN_TRIGGER_TIME(fdcanInit->TriggerTime)); + assert_param(IS_FDCAN_TTCAN_WATCH_TIME(fdcanInit->WatchTriggerTime)); + + /* Set the value by which bit time is divided for time trigger timer */ + fdcan->CAN_INT_FLAG2 |= fdcanInit->TimeTriggerPrescaler; + + uint32_t CAN_TRG_CFG_VALUE; + CAN_TRG_CFG_VALUE = fdcan->CAN_TRIG_CFG; + CAN_TRG_CFG_VALUE = (CAN_TRG_CFG_VALUE & ~CAN_TRIG_CFG_TTPTR); + /* Set the cycle time for a trigger */ + /* Set the kind of trigger in Time Trigger mode */ + /* Set the ticks of transmit enable window */ + fdcan->CAN_TRIG_CFG |= ((fdcanInit->TriggerTime << 16U) | + fdcanInit->TimeTriggerType | + (fdcanInit->TransmitEnableWindow << 12U) | + CAN_TRG_CFG_VALUE) ; + } + + if (fdcanInit->WatchTriggerTime != DISABLE) + { + /* Set the cycle time for a watch trigger */ + uint32_t CAN_TRANS_INT_STAT_VALUE; + CAN_TRANS_INT_STAT_VALUE = fdcan->CAN_TRANS_INT_STAT ; + CAN_TRANS_INT_STAT_VALUE = (CAN_TRANS_INT_STAT_VALUE & ~CAN_TRANS_INT_STAT_WTRIG); + fdcan->CAN_TRANS_INT_STAT = (CAN_TRANS_INT_STAT_VALUE | fdcanInit->WatchTriggerTime); + } + + /* Set the nominal bit timing register */ + fdcan->CAN_S_SEG_UNIT_SET = (((fdcanInit->NominalPrescaler) << 24U) | + ((fdcanInit->NominalSyncJumpWidth) << 16U) | + ((fdcanInit->NominalTimeSeg2) << 8U) | + ((fdcanInit->NominalTimeSeg1) << 0U)); + + /* If FD operation with BRS is selected, set the data bit timing register */ + fdcan->CAN_F_SEG_UNIT_SET = (((fdcanInit->DataPrescaler) << 24U) | + ((fdcanInit->DataSyncJumpWidth) << 16U) | + ((fdcanInit->DataTimeSeg2) << 8U) | + ((fdcanInit->DataTimeSeg1) << 0U)); + + /* If FD_CAN AutoPrimaryRetransmission is ENABLE */ + if (fdcanInit->AutoPrimaryRetransmission == ENABLE) + { + fdcan->CAN_CMD_CTRL |= CAN_CMD_CTRL_TPSS; + } + + /* If FD_CAN AutoSecondaryRetransmission is ENABLE */ + if (fdcanInit->AutoSecondaryRetransmission == ENABLE) + { + fdcan->CAN_CMD_CTRL |= CAN_CMD_CTRL_TSSS; + } + + if (fdcanInit->FDCANSACK == FDCAN_SACK) + { + /* Set FD_CAN Self_Acknowledg */ + fdcan->CAN_CMD_CTRL |= CAN_CMD_CTRL_SACK; + } + + if (fdcanInit->ReceiveBufferStoreAllFrames == ENABLE) + { + /* Set FD_CAN receive buffer stores all frames */ + fdcan->CAN_CMD_CTRL |= CAN_CMD_CTRL_RBALL; + } +} +/** + * @brief Deinitializes the CANx peripheral registers to their default + * reset values. + * @param fdcan: specifies the instance. + * This parameter can be any combination of the following values: + * @arg FDCAN1: the instance is can1 + * @arg FDCAN2: the instance is can2 + * @arg FDCAN3: the instance is can3 + * @arg FDCAN4: the instance is can4 + * @retval None + */ + +void FDCAN_DeInit(FDCAN_TypeDef* fdcan) +{ + /* Check the parameters */ + assert_param(IS_FDCAN_ALL_INSTANCE(fdcan)); + + if (fdcan == FDCAN1) + { + /* Enable CAN1 reset state */ + RCC_APB1PeriphResetCmd(RCC_APB1PeriphRst_CAN1, ENABLE); + /* Release CAN1 from reset state */ + RCC_APB1PeriphResetCmd(RCC_APB1PeriphRst_CAN1, DISABLE); + } + + if (fdcan == FDCAN2) + { + /* Enable CAN2 reset state */ + RCC_APB1PeriphResetCmd(RCC_APB1PeriphRst_CAN2, ENABLE); + /* Release CAN2 from reset state */ + RCC_APB1PeriphResetCmd(RCC_APB1PeriphRst_CAN2, DISABLE); + } + + if (fdcan == FDCAN3) + { + /* Enable CAN3 reset state */ + RCC_APB1PeriphResetCmd(RCC_APB1PeriphRst_CAN3, ENABLE); + /* Release CAN3 from reset state */ + RCC_APB1PeriphResetCmd(RCC_APB1PeriphRst_CAN3, DISABLE); + } + + if (fdcan == FDCAN4) + { + /* Enable CAN4 reset state */ + RCC_APB1PeriphResetCmd(RCC_APB1PeriphRst_CAN4, ENABLE); + /* Release CAN4 from reset state */ + RCC_APB1PeriphResetCmd(RCC_APB1PeriphRst_CAN4, DISABLE); + } +} + +/** + * @brief config can_ctrl in reset or run mode. + * @param fdcan: specifies the instance. + * This parameter can be any combination of the following values: + * @arg FDCAN1: the instance is can1 + * @arg FDCAN2: the instance is can2 + * @arg FDCAN3: the instance is can3 + * @arg FDCAN4: the instance is can4 + * @param NewState: new state of the specified instance's reset. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void FDCAN_Reset(FDCAN_TypeDef* fdcan, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FDCAN_ALL_INSTANCE(fdcan)); + + if (NewState == ENABLE) + { + fdcan->CAN_CMD_CTRL |= CAN_CMD_CTRL_RESET; + } + else + { + fdcan->CAN_CMD_CTRL &= ~CAN_CMD_CTRL_RESET; + } +} + +/** + * @brief config can_ctrl mode. + * @param fdcan: specifies the instance. + * This parameter can be any combination of the following values: + * @arg FDCAN1: the instance is can1 + * @arg FDCAN2: the instance is can2 + * @arg FDCAN3: the instance is can3 + * @arg FDCAN4: the instance is can4 + * @param Mode: Specifies the FDCAN mode + * This parameter can be any combination of the following values: + * @arg FDCAN_MODE_NORMAL + * @arg FDCAN_MODE_LOM + * @arg FDCAN_MODE_INTERNAL_LOOPBACK + * @arg FDCAN_MODE_EXTERNAL_LOOPBACK + * @retval None + */ +void FDCAN_ConfigMode(FDCAN_TypeDef* fdcan, uint32_t Mode) +{ + /* Check the parameters */ + assert_param(IS_FDCAN_ALL_INSTANCE(fdcan)); + assert_param(IS_FDCAN_MODE(Mode)); + + /* Set FD_CAN Mode */ + fdcan->CAN_CMD_CTRL |= Mode; +} + + + +/** + * @brief config can_ctrl in reset or run mode. + * @param fdcan: specifies the instance. + * This parameter can be any combination of the following values: + * @arg FDCAN1: the instance is can1 + * @arg FDCAN2: the instance is can2 + * @arg FDCAN3: the instance is can3 + * @arg FDCAN4: the instance is can4 + * @param ReceiveBufferAlmostFullWarningLimit: Specifies the limit value of recevie buffer almost full + * The value of ReceiveBufferAlmostFullWarningLimit: 1 and 6 + * @retval None + */ +void FDCAN_SetRxBufAFWL(FDCAN_TypeDef* fdcan, uint32_t ReceiveBufferAlmostFullWarningLimit) +{ + /* Check the parameters */ + assert_param(IS_FDCAN_ALL_INSTANCE(fdcan)); + assert_param(IS_FDCAN_RBUF_AF_LIMIT(ReceiveBufferAlmostFullWarningLimit)); + + /* get can int flag1 value */ + uint32_t can_int_flag1_value; + can_int_flag1_value = fdcan->CAN_INT_FLAG1; + + /* clear can int flag in this reg*/ + can_int_flag1_value = can_int_flag1_value & CAN_INT_FLAG1_MASK; + /* clear afwl value */ + can_int_flag1_value = can_int_flag1_value & ~CAN_INT_FLAG1_AFWL; + fdcan->CAN_INT_FLAG1 = (can_int_flag1_value | (ReceiveBufferAlmostFullWarningLimit << 28U)); +} + +/** + * @brief config can_ctrl in reset or run mode. + * @param fdcan: specifies the instance. + * This parameter can be any combination of the following values: + * @arg FDCAN1: the instance is can1 + * @arg FDCAN2: the instance is can2 + * @arg FDCAN3: the instance is can3 + * @arg FDCAN4: the instance is can4 + * @param ProgrammableErrorWarningLimit: Specifies the limit value of programmable error warning + * The value of ProgrammableErrorWarningLimit: 0 and 15 + * @retval None + */ + +void FDCAN_SetEWL(FDCAN_TypeDef* fdcan, uint32_t ProgrammableErrorWarningLimit) +{ + /* Check the parameters */ + assert_param(IS_FDCAN_ALL_INSTANCE(fdcan)); + assert_param(IS_FDCAN_PROG_ERROR_WARN_LIMIT(ProgrammableErrorWarningLimit)); + + /* get can int flag1 value */ + uint32_t can_int_flag1_value; + can_int_flag1_value = fdcan->CAN_INT_FLAG1; + + /* clear can int flag in this reg*/ + can_int_flag1_value = can_int_flag1_value & CAN_INT_FLAG1_MASK; + /* clear ewl value */ + can_int_flag1_value = can_int_flag1_value & ~CAN_INT_FLAG1_EWL; + + /* Config ewl value */ + fdcan->CAN_INT_FLAG1 = (can_int_flag1_value | (ProgrammableErrorWarningLimit << 24U)); +} + +/** + * @brief config can_ctrl in reset or run mode. + * @param fdcan: specifies the instance. + * This parameter can be any combination of the following values: + * @arg FDCAN1: the instance is can1 + * @arg FDCAN2: the instance is can2 + * @arg FDCAN3: the instance is can3 + * @arg FDCAN4: the instance is can4 + * @param TransBufferSelect: Selects the trransmit buffer + * This parameter can be any combination of the following values: + * @arg FDCAN_SELECT_PTB + * @arg FDCAN_SELECT_STB + * @retval None + */ +void FDCAN_TransBufferSelect(FDCAN_TypeDef* fdcan, uint32_t TransBufferSelect) +{ + /* Check the parameters */ + assert_param(IS_FDCAN_ALL_INSTANCE(fdcan)); + assert_param(IS_FDCAN_BUF_SEL(TransBufferSelect)); + if (TransBufferSelect == FDCAN_SELECT_STB) + { + /* Set FD_CAN TransBufferSelect is STB */ + fdcan->CAN_CMD_CTRL |= FDCAN_SELECT_STB; + } + else if (TransBufferSelect == FDCAN_SELECT_PTB) + { + /* Set FD_CAN TransBufferSelect is PTB */ + fdcan->CAN_CMD_CTRL &= ~FDCAN_SELECT_STB; + } +} + +/** + * @brief Select TTCAN trans buffer mode + * @param fdcan: specifies the instance. + * This parameter can be any combination of the following values: + * @arg FDCAN1: the instance is can1 + * @arg FDCAN2: the instance is can2 + * @arg FDCAN3: the instance is can3 + * @arg FDCAN4: the instance is can4 + * @param NewState: new state of the specified instance's reset. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void FDCAN_TTCANTransBufferMode(FDCAN_TypeDef* fdcan, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FDCAN_ALL_INSTANCE(fdcan)); + + if (NewState == ENABLE) + { + fdcan->CAN_CMD_CTRL |= CAN_CMD_CTRL_TTTBM; + } + else + { + fdcan->CAN_CMD_CTRL &= ~CAN_CMD_CTRL_TTTBM; + } +} + + +/** + * @brief Start PTB trans + * @param fdcan: specifies the instance. + * This parameter can be any combination of the following values: + * @arg FDCAN1: the instance is can1 + * @arg FDCAN2: the instance is can2 + * @arg FDCAN3: the instance is can3 + * @arg FDCAN4: the instance is can4 + * @param NewState: new state of the specified instance's reset. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void FDCAN_PTBTrans(FDCAN_TypeDef* fdcan, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FDCAN_ALL_INSTANCE(fdcan)); + + if (NewState == ENABLE) + { + fdcan->CAN_CMD_CTRL |= CAN_CMD_CTRL_TPE; + } + else + { + fdcan->CAN_CMD_CTRL &= ~CAN_CMD_CTRL_TPE; + } +} + +/** + * @brief Abort PTB trans + * @param fdcan: specifies the instance. + * This parameter can be any combination of the following values: + * @arg FDCAN1: the instance is can1 + * @arg FDCAN2: the instance is can2 + * @arg FDCAN3: the instance is can3 + * @arg FDCAN4: the instance is can4 + * @param NewState: new state of the specified instance's reset. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void FDCAN_PTBAbort(FDCAN_TypeDef* fdcan, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FDCAN_ALL_INSTANCE(fdcan)); + + if (NewState == ENABLE) + { + fdcan->CAN_CMD_CTRL |= CAN_CMD_CTRL_TPA; + } + else + { + fdcan->CAN_CMD_CTRL &= ~CAN_CMD_CTRL_TPA; + } +} + +/** + * @brief Start STB trans + * @param fdcan: specifies the instance. + * This parameter can be any combination of the following values: + * @arg FDCAN1: the instance is can1 + * @arg FDCAN2: the instance is can2 + * @arg FDCAN3: the instance is can3 + * @arg FDCAN4: the instance is can4 + * @param STBFifoPriorityMode the STB transmit fifo or priority Mode selection + * This parameter can be any combination of the following values: + * @arg FDCAN_STB_FIFO: stb in fifo mode + * @arg FDCAN_STB_PRIORITY: stb in priority mode + * @retval None + */ +void FDCAN_TransSTBMode(FDCAN_TypeDef* fdcan, uint32_t STBFifoPriorityMode) +{ + /* Check the parameters */ + assert_param(IS_FDCAN_ALL_INSTANCE(fdcan)); + assert_param(IS_FDCAN_STB_FP_MODE(STBFifoPriorityMode)); + + /* Set FD_CAN STB transmit is fifo or priority */ + fdcan->CAN_CMD_CTRL |= STBFifoPriorityMode; + +} + +/** + * @brief Start STB trans + * @param fdcan: specifies the instance. + * This parameter can be any combination of the following values: + * @arg FDCAN1: the instance is can1 + * @arg FDCAN2: the instance is can2 + * @arg FDCAN3: the instance is can3 + * @arg FDCAN4: the instance is can4 + * @param STBTransmitOneAllMode:Specifies the STB transmit one frame or all frame Mode selection + * @arg FDCAN_STB_NO_TRANSMIT + * @arg FDCAN_STB_NO_TRANSMIT_ONE + * @arg FDCAN_STB_NO_TRANSMIT_ALL + * @param NewState: new state of the specified instance's reset. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void FDCAN_STBTrans(FDCAN_TypeDef* fdcan, uint32_t STBTransmitOneAllMode, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FDCAN_ALL_INSTANCE(fdcan)); + assert_param(IS_FDCAN_STB_OA_MODE(STBTransmitOneAllMode)); + + uint32_t can_cmd_ctrl_value; + can_cmd_ctrl_value = fdcan->CAN_CMD_CTRL; + /* clr tsnext value */ + can_cmd_ctrl_value = (can_cmd_ctrl_value & (~CAN_CMD_CTRL_TSNEXT)); + + if (NewState == ENABLE) + { + /* Set FD_CAN STB transmit is one or all and don't set tsnext */ + fdcan->CAN_CMD_CTRL = (can_cmd_ctrl_value | STBTransmitOneAllMode); + } + else + { + fdcan->CAN_CMD_CTRL = (can_cmd_ctrl_value & (~STBTransmitOneAllMode)); + } +} + +/** + * @brief Abort STB trans + * @param fdcan: specifies the instance. + * This parameter can be any combination of the following values: + * @arg FDCAN1: the instance is can1 + * @arg FDCAN2: the instance is can2 + * @arg FDCAN3: the instance is can3 + * @arg FDCAN4: the instance is can4 + * @param NewState: new state of the specified instance's reset. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void FDCAN_STBAbort(FDCAN_TypeDef* fdcan, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FDCAN_ALL_INSTANCE(fdcan)); + + if (NewState == ENABLE) + { + fdcan->CAN_CMD_CTRL |= CAN_CMD_CTRL_TSA; + } + else + { + fdcan->CAN_CMD_CTRL &= ~CAN_CMD_CTRL_TSA; + } +} + +/** + * @brief Get arbitration lost position + * @param fdcan: specifies the instance. + * This parameter can be any combination of the following values: + * @arg FDCAN1: the instance is can1 + * @arg FDCAN2: the instance is can2 + * @arg FDCAN3: the instance is can3 + * @arg FDCAN4: the instance is can4 + * @retval None + */ +uint8_t FDCAN_GetArbLostPosition(FDCAN_TypeDef* fdcan) +{ + uint8_t temp; + /* Check the parameters */ + assert_param(IS_FDCAN_ALL_INSTANCE(fdcan)); + + temp = ((fdcan->CAN_ERR_CNT) & CAN_ERR_CNT_ALC); + + return temp; +} + +/** + * @brief Get kind of error + * @param fdcan: specifies the instance. + * This parameter can be any combination of the following values: + * @arg FDCAN1: the instance is can1 + * @arg FDCAN2: the instance is can2 + * @arg FDCAN3: the instance is can3 + * @arg FDCAN4: the instance is can4 + * @retval None + */ +uint8_t FDCAN_GetKindOfError(FDCAN_TypeDef* fdcan) +{ + uint8_t temp; + /* Check the parameters */ + assert_param(IS_FDCAN_ALL_INSTANCE(fdcan)); + + temp = (((fdcan->CAN_ERR_CNT) & CAN_ERR_CNT_KOER) >> 5U); + + return temp; +} + +/** + * @brief Release RxBuffer + * @param fdcan: specifies the instance. + * This parameter can be any combination of the following values: + * @arg FDCAN1: the instance is can1 + * @arg FDCAN2: the instance is can2 + * @arg FDCAN3: the instance is can3 + * @arg FDCAN4: the instance is can4 + * @param NewState: new state of the specified instance's reset. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void FDCAN_RxBufRelease(FDCAN_TypeDef* fdcan, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FDCAN_ALL_INSTANCE(fdcan)); + + if (NewState == ENABLE) + { + fdcan->CAN_CMD_CTRL |= CAN_CMD_CTRL_RREL; + } + else + { + fdcan->CAN_CMD_CTRL &= ~CAN_CMD_CTRL_RREL; + } +} + +/** + * @brief Enable CAN standby + * @param fdcan: specifies the instance. + * This parameter can be any combination of the following values: + * @arg FDCAN1: the instance is can1 + * @arg FDCAN2: the instance is can2 + * @arg FDCAN3: the instance is can3 + * @arg FDCAN4: the instance is can4 + * @param NewState: new state of the specified instance's reset. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void FDCAN_StandbyMode(FDCAN_TypeDef* fdcan, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FDCAN_ALL_INSTANCE(fdcan)); + + if (NewState == ENABLE) + { + fdcan->CAN_CMD_CTRL |= CAN_CMD_CTRL_STBY; + } + else + { + fdcan->CAN_CMD_CTRL &= ~CAN_CMD_CTRL_STBY; + } +} + +/** + * @brief Enable CAN standby + * @param fdcan: specifies the instance. + * This parameter can be any combination of the following values: + * @arg FDCAN1: the instance is can1 + * @arg FDCAN2: the instance is can2 + * @arg FDCAN3: the instance is can3 + * @arg FDCAN4: the instance is can4 + * @param FDCAN_ReceiveBufferOverflow_Mode: specifies the ROM value. + * This parameter can be any combination of the following values: + * @arg FDCAN_RECEIVE_OVERFLOW_OVERWRITTEN: ROM=0,The oldest message will be overwritten + * @arg FDCAN_RECEIVE_OVERFLOW_DISCARD: ROM=1,The new message will not be stored + * @retval None + */ +void FDCAN_RbufOverFlowMode(FDCAN_TypeDef* fdcan, uint32_t FDCAN_ReceiveBufferOverflow_Mode) +{ + /* Check the parameters */ + assert_param(IS_FDCAN_ALL_INSTANCE(fdcan)); + assert_param(IS_RECEIVE_BUFFER_OVERFLOW_MODE(FDCAN_ReceiveBufferOverflow_Mode)); + + fdcan->CAN_CMD_CTRL |= FDCAN_ReceiveBufferOverflow_Mode; +} + + +/** @defgroup FDCAN_Exported_Functions_Group2 Configuration functions + * @brief FDCAN Configuration functions. + * +@verbatim + ============================================================================== + ##### Configuration functions ##### + ============================================================================== + [..] This section provides functions allowing to: + (+) FDCAN_ConfigFilter : Configure the FDCAN reception filters + (+) FDCAN_ConfigRxFifoOverwrite : Configure the Rx FIFO operation mode + (+) FDCAN_ConfigTimestampLocation : Configure the timestamp Location in SOF or EOF + (+) FDCAN_EnableTimestampCounter : Enable or Disable the timestamp counter + (+) FDCAN_ConfigTxDelayCompensation : Configure the transmitter delay compensation + (+) FDCAN_EnableTxDelayCompensation : Enable or Disable the transmitter delay compensation + (+) FDCAN_EnableISOMode : Enable ISO 11898-1 protocol mode + (+) FDCAN_DisableISOMode : Disable ISO 11898-1 protocol mode + +@endverbatim + * @{ + */ + +/** + * @brief Configure the FDCAN reception filter according to the specified + * parameters in the FDCAN_FilterTypeDef structure. + * @param fdcan: specifies the instance. + * This parameter can be any combination of the following values: + * @arg FDCAN1: the instance is can1 + * @arg FDCAN2: the instance is can2 + * @arg FDCAN3: the instance is can3 + * @arg FDCAN4: the instance is can4 + * @param sFilterConfig pointer to an FDCAN_FilterTypeDef structure that + * contains the filter configuration information + * This parameter can be any combination of the following values: + * @arg FilterAddress: Specifies the filter which will be initialized + * The value of FilterAddress: 0 and 15 + * @arg SelectAcceptanceMask: Enable or disable the filter mask + * The value of SelectAcceptanceMask: ENABLE + * DISABLE + * @arg FilterAcceptanceCODE: Specifies the filter identification + * The value of FilterAcceptanceCODE: 0 and 0x7FF for standard frames + * 0 and 0x1FFFFFFF for extended frames + * @arg FilterAcceptanceMASK: Specifies the filter acceptance mask + * 1: acceptance check for these bis of receive ID with AC_CODE disable + * 0: acceptance check for these bis of receive ID with AC_CODE enable + * The value of FilterAcceptanceMASK: 0 and 0x7FF for standard frames + * 0 and 0x1FFFFFFF for extended frames + * @arg FilterAcceptanceMaskIDECheck: Specifies the filter acceptance mask IDE bit check enable + * The value of FilterAcceptanceMaskIDECheck: FDCAN_ACCEP_MASK_AIDE_DISABLE + * FDCAN_ACCEP_MASK_AIDE_ENABLE + * @arg FilterAcceptanceMaskIDE: Specifies the filter acceptance mask IDE bit value + * The value of FilterAcceptanceMaskIDE: FDCAN_ACCEP_MASK_IDE_STANDARD + * FDCAN_ACCEP_MASK_IDE_EXTENDED + * @retval HAL status + */ + +void FDCAN_ConfigFilter(FDCAN_TypeDef* fdcan, FDCAN_FilterTypeDef* sFilterConfig) +{ + /* Check the parameters */ + assert_param(IS_FDCAN_ALL_INSTANCE(fdcan)); + assert_param(IS_FDCAN_FILTER_ADDR(sFilterConfig->FilterAddress)); + assert_param(IS_FUNCTIONAL_STATE(sFilterConfig->SelectAcceptanceMask)); + assert_param(IS_FDCAN_FILTER_ACODE(sFilterConfig->FilterAcceptanceCODE)); + assert_param(IS_FDCAN_FILTER_AMASK(sFilterConfig->FilterAcceptanceMASK)); + assert_param(IS_FDCAN_FILTER_AMASK_IDEE(sFilterConfig->FilterAcceptanceMaskIDECheck)); + assert_param(IS_FDCAN_FILTER_AMASK_IDE(sFilterConfig->FilterAcceptanceMaskIDE)); + + uint32_t CAN_FILTER_CTRL_VALUE; + /* GET CAN_FILTER_CTRL_VALUE */ + CAN_FILTER_CTRL_VALUE = fdcan->CAN_FILTER_CTRL; + /* CLR ACFADR BUT REMAIN OTHERS BITS*/ + CAN_FILTER_CTRL_VALUE = (CAN_FILTER_CTRL_VALUE & ~CAN_FILTER_CTRL_ACFADR); + /* CLR SELMASK */ + CAN_FILTER_CTRL_VALUE = (CAN_FILTER_CTRL_VALUE & ~CAN_FILTER_CTRL_SELMASK); + /* Set filter address, choose which filter be set */ + fdcan->CAN_FILTER_CTRL = (CAN_FILTER_CTRL_VALUE | sFilterConfig->FilterAddress); + + /* Set acceptance code */ + fdcan->CAN_ACF = (sFilterConfig->FilterAcceptanceCODE); + + /* If select acceptance mask, set mask value */ + if (sFilterConfig->SelectAcceptanceMask == ENABLE) + { + /* Select MASK, CAN_ACF Point to AMASK */ + fdcan->CAN_FILTER_CTRL |= CAN_FILTER_CTRL_SELMASK; + + /* Set mask value, 0 and 0x7FF for standard frames, 0 and 0x1FFFFFFF for extended frames */ + fdcan->CAN_ACF = (sFilterConfig->FilterAcceptanceMASK); + } + + /* If FilterAcceptanceMaskIDECheck is 0 AIDEE=0, Accept Filter accepts both standard and extended frames*/ + /* If FilterAcceptanceMaskIDECheck is 1 AIDEE=1, set FilterAcceptanceMaskIDE(accepts standard or extended frames)*/ + if (sFilterConfig->FilterAcceptanceMaskIDECheck == FDCAN_ACCEP_MASK_AIDE_ENABLE) + { + /* Set AIDEE, If AIDEE=1, Accept Filter accepts standard and extended frames decided by AIDE*/ + fdcan->CAN_ACF |= CAN_ACF_AIDEE; + + /* Set AIDE, If AIDEE=1,AIDE=0, only accept standard frames */ + /* Set AIDE, If AIDEE=1,AIDE=1, only accept extended frames */ + if (sFilterConfig->FilterAcceptanceMaskIDE == FDCAN_ACCEP_MASK_IDE_EXTENDED) + { + fdcan->CAN_ACF |= CAN_ACF_AIDE; + } + else if (sFilterConfig->FilterAcceptanceMaskIDE == FDCAN_ACCEP_MASK_IDE_STANDARD) + { + fdcan->CAN_ACF &= ~CAN_ACF_AIDE; + } + } +} + +/** + * @brief Configure the FDCAN reception filter according to the specified + * parameters in the FDCAN_FilterTypeDef structure. + * @param fdcan: specifies the instance. + * This parameter can be any combination of the following values: + * @arg FDCAN1: the instance is can1 + * @arg FDCAN2: the instance is can2 + * @arg FDCAN3: the instance is can3 + * @arg FDCAN4: the instance is can4 + * @param FDCAN_ACE: specifies the filter. + * This parameter can be any combination of the following values: + * @arg FDCAN_CAN_FILTER0: choose filter0 + * @arg FDCAN_CAN_FILTER1: choose filter1 + * @arg FDCAN_CAN_FILTER2: choose filter2 + * @arg FDCAN_CAN_FILTER3: choose filter3 + * @arg FDCAN_CAN_FILTER4: choose filter4 + * @arg FDCAN_CAN_FILTER5: choose filter5 + * @arg FDCAN_CAN_FILTER6: choose filter6 + * @arg FDCAN_CAN_FILTER7: choose filter7 + * @arg FDCAN_CAN_FILTER8: choose filter8 + * @arg FDCAN_CAN_FILTER9: choose filter9 + * @arg FDCAN_CAN_FILTER10: choose filter10 + * @arg FDCAN_CAN_FILTER11: choose filter11 + * @arg FDCAN_CAN_FILTER12: choose filter12 + * @arg FDCAN_CAN_FILTER13: choose filter13 + * @arg FDCAN_CAN_FILTER14: choose filter14 + * @arg FDCAN_CAN_FILTER15: choose filter15 + * @arg FDCAN_CAN_FILTER_ALL: choose all filter + * @param NewState: new state of the specified instance's TxDelay. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void FDCAN_EnableFilter(FDCAN_TypeDef* fdcan, uint32_t FDCAN_ACE, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FDCAN_ALL_INSTANCE(fdcan)); + assert_param(IS_FDCAN_FILTER_ACE(FDCAN_ACE)); + + /* Set the Fdcan Filter NewState */ + if (NewState == ENABLE) + { + fdcan->CAN_FILTER_CTRL |= FDCAN_ACE; + } + else + { + fdcan->CAN_FILTER_CTRL &= ~FDCAN_ACE; + } +} + +/** + * @brief Select the Receive Buffer accept mode while full. + * @param fdcan: specifies the instance. + * This parameter can be any combination of the following values: + * @arg FDCAN1: the instance is can1 + * @arg FDCAN2: the instance is can2 + * @arg FDCAN3: the instance is can3 + * @arg FDCAN4: the instance is can4 + * @param FdcanRbOverMode: specifies the ROM. + * This parameter can be any combination of the following values: + * @arg FDCAN_RECEIVE_OVERFLOW_OVERWRITTEN: the new message will be writen in receive buffer + * @arg FDCAN_RECEIVE_OVERFLOW_DISCARD: the new message will not be written + * @retval None + */ +void FDCAN_ConfigRxFifoOverwrite(FDCAN_TypeDef* fdcan, uint32_t FdcanRbOverMode) +{ + /* Check the parameters */ + assert_param(IS_FDCAN_RBUF_OVERFLOW_MODE(FdcanRbOverMode)); + + /* Set the Receive Buffer write mode while it's full */ + fdcan->CAN_CMD_CTRL |= FdcanRbOverMode; +} + + +/** + * @brief Select the Fdcan TimeStamp location. + * @param fdcan: specifies the instance. + * This parameter can be any combination of the following values: + * @arg FDCAN1: the instance is can1 + * @arg FDCAN2: the instance is can2 + * @arg FDCAN3: the instance is can3 + * @arg FDCAN4: the instance is can4 + * @param FdcanTimeStampLocation: specifies the TimeStamp Location. + * This parameter can be any combination of the following values: + * @arg FDCAN_TIMESTAMP_SOF: the TimeStamp in SOF + * @arg FDCAN_TIMESTAMP_EOF: the TimeStamp in EOF + * @retval None + */ +void FDCAN_ConfigTimestampLocation(FDCAN_TypeDef* fdcan, uint32_t FdcanTimeStampLocation) +{ + /* Check the parameters */ + assert_param(IS_FDCAN_ALL_INSTANCE(fdcan)); + assert_param(IS_FDCAN_TIME_STAMP_LOCATION(FdcanTimeStampLocation)); + + /* Set the Fdcan TimeStamp Location SOF or EOF*/ + fdcan->CAN_FILTER_CTRL |= FdcanTimeStampLocation; +} + +/** + * @brief Enable or Disable the Fdcan TimeStamp. + * @param fdcan: specifies the instance. + * This parameter can be any combination of the following values: + * @arg FDCAN1: the instance is can1 + * @arg FDCAN2: the instance is can2 + * @arg FDCAN3: the instance is can3 + * @arg FDCAN4: the instance is can4 + * @param NewState: new state of the specified instance's timestamp. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void FDCAN_EnableTimestampCounter(FDCAN_TypeDef* fdcan, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FDCAN_ALL_INSTANCE(fdcan)); + + /* Set the Fdcan TimeStamp NewState */ + if (NewState == ENABLE) + { + fdcan->CAN_FILTER_CTRL |= FDCAN_TIMESTAMP_ENABLE; + } + else + { + fdcan->CAN_FILTER_CTRL &= ~FDCAN_TIMESTAMP_ENABLE; + /* wait timestamp disable success */ + while ((fdcan->CAN_FILTER_CTRL & FDCAN_TIMESTAMP_DISABLE) == FDCAN_TIMESTAMP_DISABLE); + } +} + +/** + * @brief Config the txdelay value. + * @param fdcan: specifies the instance. + * This parameter can be any combination of the following values: + * @arg FDCAN1: the instance is can1 + * @arg FDCAN2: the instance is can2 + * @arg FDCAN3: the instance is can3 + * @arg FDCAN4: the instance is can4 + * @param FdcanTxDelayValue: specifies the TXDelay value. + * This parameter can be the range of 0~0x7F + * @retval None + */ +void FDCAN_ConfigTxDelayCompensation(FDCAN_TypeDef* fdcan, uint32_t FdcanTxDelayValue) +{ + /* Check the parameters */ + assert_param(IS_FDCAN_ALL_INSTANCE(fdcan)); + assert_param(IS_FDCAN_TXDELAY_VALUE(FdcanTxDelayValue)); + + /* Set the Fdcan TimeStamp Location */ + fdcan->CAN_ERR_CNT |= (FdcanTxDelayValue << 8U); +} + +/** + * @brief Enable or Disable the txdelay. + * @param fdcan: specifies the instance. + * This parameter can be any combination of the following values: + * @arg FDCAN1: the instance is can1 + * @arg FDCAN2: the instance is can2 + * @arg FDCAN3: the instance is can3 + * @arg FDCAN4: the instance is can4 + * @param NewState: new state of the specified instance's TxDelay. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void FDCAN_EnableTxDelayCompensation(FDCAN_TypeDef* fdcan, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FDCAN_ALL_INSTANCE(fdcan)); + + /* Set the Fdcan TxDelay NewState*/ + if (NewState == ENABLE) + { + fdcan->CAN_ERR_CNT |= FDCAN_TXDELAY_ENABLE; + } + else + { + fdcan->CAN_ERR_CNT &= ~FDCAN_TXDELAY_ENABLE; + /* wait txdelay disable success */ + while ((fdcan->CAN_ERR_CNT & FDCAN_TXDELAY_DISABLE) == FDCAN_TXDELAY_DISABLE); + } +} + +/** + * @brief Enable ISO 11898-1 protocol mode. + * CAN FD frame format is according to ISO 11898-1 standard. + * @param fdcan: specifies the instance. + * This parameter can be any combination of the following values: + * @arg FDCAN1: the instance is can1 + * @arg FDCAN2: the instance is can2 + * @arg FDCAN3: the instance is can3 + * @arg FDCAN4: the instance is can4 + * @retval None + */ +void FDCAN_EnableISOMode(FDCAN_TypeDef* fdcan) +{ + /* Check the parameters */ + assert_param(IS_FDCAN_ALL_INSTANCE(fdcan)); + + /* Enable ISO mode */ + fdcan->CAN_CMD_CTRL |= CAN_CMD_CTRL_FD_ISO; + +} + +/** + * @brief Disable ISO 11898-1 protocol mode. + * CAN FD frame format is according to Bosch CAN FD specification. + * @param fdcan: specifies the instance. + * This parameter can be any combination of the following values: + * @arg FDCAN1: the instance is can1 + * @arg FDCAN2: the instance is can2 + * @arg FDCAN3: the instance is can3 + * @arg FDCAN4: the instance is can4 + * @retval None + */ +void FDCAN_DisableISOMode(FDCAN_TypeDef* fdcan) +{ + /* Check the parameters */ + assert_param(IS_FDCAN_ALL_INSTANCE(fdcan)); + + /* Disable ISO mode */ + fdcan->CAN_CMD_CTRL &= ~CAN_CMD_CTRL_FD_ISO; + + /* Wait ISO bit clear */ + while ((fdcan->CAN_CMD_CTRL & CAN_CMD_CTRL_FD_ISO) == CAN_CMD_CTRL_FD_ISO); +} + + +/** @defgroup FDCAN_Exported_Functions_Group3 Configuration TxBuffer And Get RxBuffer + * @brief FDCAN Configuration TxBuffer And Get RxBuffer. + * +@verbatim + ============================================================================== + ##### Configuration functions ##### + ============================================================================== + [..] This section provides functions allowing to: + (+) FDCAN_ConfigTxBuffer: Configure the FDCAN TxBuffer + (+) FDCAN_GetRxBuffer: Get the FDCAN RxBuffer + (+) FDCAN_GetArbLostCap: Get the FDCAN ArbitrationLostCapture + (+) FDCAN_GetErrorCnt: Get the FDCAN ErrorCounter TECNT, RECNT and KOER + (+) FDCAN_ConfigTsnext: Set TSNEXT and Clear by hardware + + @endverbatim + * @{ + */ + +/** + * @brief Config TxBuffer. + * @param fdcan: specifies the instance. + * This parameter can be any combination of the following values: + * @arg FDCAN1: the instance is can1 + * @arg FDCAN2: the instance is can2 + * @arg FDCAN3: the instance is can3 + * @arg FDCAN4: the instance is can4 + * @param TxHeader: specifies the TxBuffer config. + * @arg Identifier: Specifies the identifier + * The value of Identifier: 0 and 0x7FF, if IdType is FDCAN_STANDARD_ID + * 0 and 0x1FFFFFFF, if IdType is FDCAN_EXTENDED_ID + * @arg IdType: Specifies the identifier type for the transmitted message + * The value of IdType: FDCAN_STANDARD_ID + * FDCAN_EXTENDED_ID + * @arg TxFrameType: Specifies the frame type of the transmitted message + * The value of TxFrameType: FDCAN_DATA_FRAME + * FDCAN_REMOTE_FRAME + * @arg DataLength: Specifies the data length of the transmitted frame + * The value of DataLength: FDCAN_DLC_BYTES_0 + * FDCAN_DLC_BYTES_1 + * FDCAN_DLC_BYTES_2 + * FDCAN_DLC_BYTES_3 + * FDCAN_DLC_BYTES_4 + * FDCAN_DLC_BYTES_5 + * FDCAN_DLC_BYTES_6 + * FDCAN_DLC_BYTES_7 + * FDCAN_DLC_BYTES_8 + * FDCAN_DLC_BYTES_12 + * FDCAN_DLC_BYTES_16 + * FDCAN_DLC_BYTES_20 + * FDCAN_DLC_BYTES_24 + * FDCAN_DLC_BYTES_32 + * FDCAN_DLC_BYTES_48 + * FDCAN_DLC_BYTES_64 + * @arg BitRateSwitch: Specifies whether the Tx frame is transmitted with or without bit rate switching + * The value of BitRateSwitch: FDCAN_BRS_OFF + * FDCAN_BRS_ON + * @arg FDFormat: Specifies whether the Tx frame is transmitted in classic or FD format + * The value of FDFormat: FDCAN_CLASSIC_CAN + * FDCAN_FD_CAN + * @arg TTSEN: Specifies the enable if transmit Time-Stamp in CiA 603 + * The value of TTSEN: FDCAN_TTS_DISABLE + * FDCAN_TTS_ENABLE + * @retval None + */ +void FDCAN_ConfigTxBuffer(FDCAN_TypeDef* fdcan, FDCAN_TxHeaderTypeDef* TxHeader, uint8_t message_data[16][4]) +{ + uint32_t i; + + /* Check the parameters */ + assert_param(IS_FDCAN_ALL_INSTANCE(fdcan)); + assert_param(IS_FDCAN_ID(TxHeader->Identifier)); + assert_param(IS_FDCAN_IDTYPE(TxHeader->IdType)); + assert_param(IS_FDCAN_FRAME_TYPE(TxHeader->TxFrameType)); + assert_param(IS_FDCAN_TYPE(TxHeader->FDFormat)); + assert_param(IS_FDCAN_BRS(TxHeader->BitRateSwitch)); + assert_param(IS_FDCAN_DATA_LENGTH(TxHeader->DataLength)); + assert_param(IS_FDCAN_TTS_STATE(TxHeader->TTSEN)); + + /* Config frame ID and TTSEN */ + fdcan->CAN_TRANSMIT_BUFFER0 = (TxHeader->Identifier | + TxHeader->TTSEN); + + /* Config IDE RTR FDF BRS and DLC*/ + fdcan->CAN_TRANSMIT_BUFFER1 = (TxHeader->IdType | /* Config id type */ + TxHeader->TxFrameType | /* Config frame type */ + TxHeader->FDFormat | /* Config fdcan format */ + TxHeader->BitRateSwitch | /* Config fdcan bit rate switch */ + TxHeader->DataLength); /* Config date length */ + + if (TxHeader->TxFrameType == FDCAN_DATA_FRAME) + { + if (TxHeader->DataLength == FDCAN_DLC_BYTES_1) + { + fdcan->CAN_TRANSMIT_BUFFER[0] = (message_data[0][0]) ; + } + if (TxHeader->DataLength == FDCAN_DLC_BYTES_2) + { + fdcan->CAN_TRANSMIT_BUFFER[0] = (message_data[0][0]) | + (message_data[0][1] << 8) ; + } + if (TxHeader->DataLength == FDCAN_DLC_BYTES_3) + { + fdcan->CAN_TRANSMIT_BUFFER[0] = (message_data[0][0]) | + (message_data[0][1] << 8) | + (message_data[0][2] << 16) ; + } + if (TxHeader->DataLength == FDCAN_DLC_BYTES_4) + { + fdcan->CAN_TRANSMIT_BUFFER[0] = (message_data[0][0]) | + (message_data[0][1] << 8) | + (message_data[0][2] << 16) | + (message_data[0][3] << 24) ; + } + if (TxHeader->DataLength == FDCAN_DLC_BYTES_5) + { + fdcan->CAN_TRANSMIT_BUFFER[0] = (message_data[0][0]) | + (message_data[0][1] << 8) | + (message_data[0][2] << 16) | + (message_data[0][3] << 24) ; + + fdcan->CAN_TRANSMIT_BUFFER[1] = (message_data[1][0]) ; + } + if (TxHeader->DataLength == FDCAN_DLC_BYTES_6) + { + fdcan->CAN_TRANSMIT_BUFFER[0] = (message_data[0][0]) | + (message_data[0][1] << 8) | + (message_data[0][2] << 16) | + (message_data[0][3] << 24) ; + + fdcan->CAN_TRANSMIT_BUFFER[1] = (message_data[1][0]) | + (message_data[1][1] << 8) ; + } + if (TxHeader->DataLength == FDCAN_DLC_BYTES_7) + { + fdcan->CAN_TRANSMIT_BUFFER[0] = (message_data[0][0]) | + (message_data[0][1] << 8) | + (message_data[0][2] << 16) | + (message_data[0][3] << 24) ; + + fdcan->CAN_TRANSMIT_BUFFER[1] = (message_data[1][0]) | + (message_data[1][1] << 8) | + (message_data[1][2] << 16) ; + } + if (TxHeader->DataLength == FDCAN_DLC_BYTES_8) + { + fdcan->CAN_TRANSMIT_BUFFER[0] = (message_data[0][0]) | + (message_data[0][1] << 8) | + (message_data[0][2] << 16) | + (message_data[0][3] << 24) ; + + fdcan->CAN_TRANSMIT_BUFFER[1] = (message_data[1][0]) | + (message_data[1][1] << 8) | + (message_data[1][2] << 16) | + (message_data[1][3] << 24) ; + } + if (TxHeader->DataLength == FDCAN_DLC_BYTES_12) + { + if (TxHeader->FDFormat != FDCAN_FD_CAN) + { + for (i = 0; i < 2; i++) + { + fdcan->CAN_TRANSMIT_BUFFER[i] = (message_data[i][0]) | + (message_data[i][1] << 8) | + (message_data[i][2] << 16) | + (message_data[i][3] << 24) ; + } + } + else + { + for (i = 0; i < 3; i++) + { + fdcan->CAN_TRANSMIT_BUFFER[i] = (message_data[i][0]) | + (message_data[i][1] << 8) | + (message_data[i][2] << 16) | + (message_data[i][3] << 24) ; + } + } + } + if (TxHeader->DataLength == FDCAN_DLC_BYTES_16) + { + if (TxHeader->FDFormat != FDCAN_FD_CAN) + { + for (i = 0; i < 2; i++) + { + fdcan->CAN_TRANSMIT_BUFFER[i] = (message_data[i][0]) | + (message_data[i][1] << 8) | + (message_data[i][2] << 16) | + (message_data[i][3] << 24) ; + } + } + else + { + for (i = 0; i < 4; i++) + { + fdcan->CAN_TRANSMIT_BUFFER[i] = (message_data[i][0]) | + (message_data[i][1] << 8) | + (message_data[i][2] << 16) | + (message_data[i][3] << 24) ; + } + } + } + if (TxHeader->DataLength == FDCAN_DLC_BYTES_20) + { + if (TxHeader->FDFormat != FDCAN_FD_CAN) + { + for (i = 0; i < 2; i++) + { + fdcan->CAN_TRANSMIT_BUFFER[i] = (message_data[i][0]) | + (message_data[i][1] << 8) | + (message_data[i][2] << 16) | + (message_data[i][3] << 24) ; + } + } + else + { + for (i = 0; i < 5; i++) + { + fdcan->CAN_TRANSMIT_BUFFER[i] = (message_data[i][0]) | + (message_data[i][1] << 8) | + (message_data[i][2] << 16) | + (message_data[i][3] << 24) ; + } + } + } + if (TxHeader->DataLength == FDCAN_DLC_BYTES_24) + { + if (TxHeader->FDFormat != FDCAN_FD_CAN) + { + for (i = 0; i < 2; i++) + { + fdcan->CAN_TRANSMIT_BUFFER[i] = (message_data[i][0]) | + (message_data[i][1] << 8) | + (message_data[i][2] << 16) | + (message_data[i][3] << 24) ; + } + } + else + { + for (i = 0; i < 6; i++) + { + fdcan->CAN_TRANSMIT_BUFFER[i] = (message_data[i][0]) | + (message_data[i][1] << 8) | + (message_data[i][2] << 16) | + (message_data[i][3] << 24) ; + } + } + } + if (TxHeader->DataLength == FDCAN_DLC_BYTES_32) + { + if (TxHeader->FDFormat != FDCAN_FD_CAN) + { + for (i = 0; i < 2; i++) + { + fdcan->CAN_TRANSMIT_BUFFER[i] = (message_data[i][0]) | + (message_data[i][1] << 8) | + (message_data[i][2] << 16) | + (message_data[i][3] << 24) ; + } + } + else + { + for (i = 0; i < 8; i++) + { + fdcan->CAN_TRANSMIT_BUFFER[i] = (message_data[i][0]) | + (message_data[i][1] << 8) | + (message_data[i][2] << 16) | + (message_data[i][3] << 24) ; + } + } + } + if (TxHeader->DataLength == FDCAN_DLC_BYTES_48) + { + if (TxHeader->FDFormat != FDCAN_FD_CAN) + { + for (i = 0; i < 2; i++) + { + fdcan->CAN_TRANSMIT_BUFFER[i] = (message_data[i][0]) | + (message_data[i][1] << 8) | + (message_data[i][2] << 16) | + (message_data[i][3] << 24) ; + } + } + else + { + for (i = 0; i < 11; i++) + { + fdcan->CAN_TRANSMIT_BUFFER[i] = (message_data[i][0]) | + (message_data[i][1] << 8) | + (message_data[i][2] << 16) | + (message_data[i][3] << 24) ; + } + } + } + if (TxHeader->DataLength == FDCAN_DLC_BYTES_64) + { + if (TxHeader->FDFormat != FDCAN_FD_CAN) + { + for (i = 0; i < 2; i++) + { + fdcan->CAN_TRANSMIT_BUFFER[i] = (message_data[i][0]) | + (message_data[i][1] << 8) | + (message_data[i][2] << 16) | + (message_data[i][3] << 24) ; + } + } + else + { + for (i = 0; i < 16; i++) + { + fdcan->CAN_TRANSMIT_BUFFER[i] = (message_data[i][0]) | + (message_data[i][1] << 8) | + (message_data[i][2] << 16) | + (message_data[i][3] << 24) ; + } + } + } + } +} + + +/** + * @brief Get RxBuffer. + * @param fdcan: specifies the instance. + * This parameter can be any combination of the following values: + * @arg FDCAN1: the instance is can1 + * @arg FDCAN2: the instance is can2 + * @arg FDCAN3: the instance is can3 + * @arg FDCAN4: the instance is can4 + * @param RxHeader: specifies the RxBuffer Value. + * This parameter can be any combination of the following values: + * @arg Identifier: Specifies the identifier + * The value of Identifier: 0 and 0x7FF, if IdType is FDCAN_STANDARD_ID + * 0 and 0x1FFFFFFF, if IdType is FDCAN_EXTENDED_ID + * @arg IdType: Specifies the identifier type of the received message + * The value of IdType: FDCAN_STANDARD_ID + * FDCAN_EXTENDED_ID + * @arg RxFrameType: Specifies the the received message frame type + * The value of RxFrameType: FDCAN_DATA_FRAME + * FDCAN_REMOTE_FRAME + * @arg DataLength: pecifies the received frame length + * The value of DataLength: FDCAN_DLC_BYTES_0 + * FDCAN_DLC_BYTES_1 + * FDCAN_DLC_BYTES_2 + * FDCAN_DLC_BYTES_3 + * FDCAN_DLC_BYTES_4 + * FDCAN_DLC_BYTES_5 + * FDCAN_DLC_BYTES_6 + * FDCAN_DLC_BYTES_7 + * FDCAN_DLC_BYTES_8 + * FDCAN_DLC_BYTES_12 + * FDCAN_DLC_BYTES_16 + * FDCAN_DLC_BYTES_20 + * FDCAN_DLC_BYTES_24 + * FDCAN_DLC_BYTES_32 + * FDCAN_DLC_BYTES_48 + * FDCAN_DLC_BYTES_64 + * @arg ErrorStateIndicator: Specifies the error state indicator + * The value of ErrorStateIndicator: FDCAN_ESI_ACTIVE + * FDCAN_ESI_PASSIVE + * @arg BitRateSwitch: Specifies whether the Rx frame is received with or without bit rate switching + * The value of BitRateSwitch: FDCAN_BRS_OFF + * FDCAN_BRS_ON + * @arg FDFormat: Specifies whether the Rx frame is received in classic or FD format + * The value of FDFormat: FDCAN_CLASSIC_CAN + * FDCAN_FD_CAN + * @arg RxKOER: Specifies the kind of ERROR of receive frames + * The value of RxKOER: FDCAN_NO_ERROR + * FDCAN_BIT_ERROR + * FDCAN_FORM_ERROR + * FDCAN_STUFF_ERROR + * FDCAN_ACK_ERROR + * FDCAN_CRC_ERROR + * FDCAN_OTHER_ERROR + * FDCAN_NOT_USED + * @arg CycleTime: Specifies the time-stamp cycle time only in TTCAN mode + * The value of CycleTime: This parameter must be a number between 0 and 0xFFFF + * @retval None + */ +void FDCAN_GetRxBuffer(FDCAN_TypeDef* fdcan, FDCAN_RxHeaderTypeDef* RxHeader, uint8_t message_data[16][4]) +{ + uint32_t i; + uint32_t j; + + /* Check the parameters */ + assert_param(IS_FDCAN_ALL_INSTANCE(fdcan)); + + /* Get ID type */ + RxHeader->IdType = (fdcan->CAN_RECEIVE_BUFFER1 & FDCAN_EXTENDED_ID); + + /* Get ID value */ + RxHeader->Identifier = fdcan->CAN_RECEIVE_BUFFER0; + + /* Get Rx frame type */ + RxHeader->RxFrameType = (fdcan->CAN_RECEIVE_BUFFER1 & FDCAN_REMOTE_FRAME); + + /* Get FDCAN format */ + RxHeader->FDFormat = (fdcan->CAN_RECEIVE_BUFFER1 & FDCAN_FD_CAN); + + /* Get the error state indicator */ + RxHeader->ErrorStateIndicator = (fdcan->CAN_RECEIVE_BUFFER0 & FDCAN_ESI_PASSIVE); + + /* Get whether the Rx frame is received with or without bit rate switching*/ + RxHeader->BitRateSwitch = (fdcan->CAN_RECEIVE_BUFFER1 & FDCAN_BRS_ON); + + /* Get the kind of ERROR of receive frames */ + RxHeader->RxKOER = ((fdcan->CAN_RECEIVE_BUFFER1 & 0x0000E000) >> 13U); + + /* Get the time-stamp cycle time only in TTCAN mode */ + if ((fdcan->CAN_FILTER_CTRL & FDCAN_TIMESTAMP_ENABLE) == FDCAN_TIMESTAMP_ENABLE) + { + RxHeader->CycleTime = ((fdcan->CAN_RECEIVE_BUFFER1 & 0xffff0000) >> 16U); + } + + /* Get RX date length */ + RxHeader->DataLength = (fdcan->CAN_RECEIVE_BUFFER1 & FDCAN_DLC_BYTES_64); + + /* Only data frame can read rxbuf data */ + if (RxHeader->RxFrameType == FDCAN_DATA_FRAME) + { + /*Get Rx date value*/ + if (RxHeader->DataLength == FDCAN_DLC_BYTES_1) + { + uint32_t rbuf_data0_value; + rbuf_data0_value = fdcan->CAN_RECEIVE_BUFFER[0]; + message_data[0][0] = (rbuf_data0_value & 0x000000ff); + } + if (RxHeader->DataLength == FDCAN_DLC_BYTES_2) + { + uint32_t rbuf_data0_value; + rbuf_data0_value = fdcan->CAN_RECEIVE_BUFFER[0]; + message_data[0][0] = (rbuf_data0_value & 0x000000ff); + message_data[0][1] = ((rbuf_data0_value & 0x0000ff00) >> 8U); + } + if (RxHeader->DataLength == FDCAN_DLC_BYTES_3) + { + uint32_t rbuf_data0_value; + rbuf_data0_value = fdcan->CAN_RECEIVE_BUFFER[0]; + message_data[0][0] = (rbuf_data0_value & 0x000000ff); + message_data[0][1] = ((rbuf_data0_value & 0x0000ff00) >> 8U); + message_data[0][2] = ((rbuf_data0_value & 0x00ff0000) >> 16U); + } + if (RxHeader->DataLength == FDCAN_DLC_BYTES_4) + { + uint32_t rbuf_data0_value; + rbuf_data0_value = fdcan->CAN_RECEIVE_BUFFER[0]; + message_data[0][0] = (rbuf_data0_value & 0x000000ff); + message_data[0][1] = ((rbuf_data0_value & 0x0000ff00) >> 8U); + message_data[0][2] = ((rbuf_data0_value & 0x00ff0000) >> 16U); + message_data[0][3] = ((rbuf_data0_value & 0xff000000) >> 24U); + } + if (RxHeader->DataLength == FDCAN_DLC_BYTES_5) + { + uint32_t rbuf_data0_value; + uint32_t rbuf_data1_value; + rbuf_data0_value = fdcan->CAN_RECEIVE_BUFFER[0]; + rbuf_data1_value = fdcan->CAN_RECEIVE_BUFFER[1]; + message_data[0][0] = (rbuf_data0_value & 0x000000ff); + message_data[0][1] = ((rbuf_data0_value & 0x0000ff00) >> 8U); + message_data[0][2] = ((rbuf_data0_value & 0x00ff0000) >> 16U); + message_data[0][3] = ((rbuf_data0_value & 0xff000000) >> 24U); + + message_data[1][0] = (rbuf_data1_value & 0x000000ff); + } + if (RxHeader->DataLength == FDCAN_DLC_BYTES_6) + { + uint32_t rbuf_data0_value; + uint32_t rbuf_data1_value; + rbuf_data0_value = fdcan->CAN_RECEIVE_BUFFER[0]; + rbuf_data1_value = fdcan->CAN_RECEIVE_BUFFER[1]; + message_data[0][0] = (rbuf_data0_value & 0x000000ff); + message_data[0][1] = ((rbuf_data0_value & 0x0000ff00) >> 8U); + message_data[0][2] = ((rbuf_data0_value & 0x00ff0000) >> 16U); + message_data[0][3] = ((rbuf_data0_value & 0xff000000) >> 24U); + + message_data[1][0] = (rbuf_data1_value & 0x000000ff); + message_data[1][1] = ((rbuf_data1_value & 0x0000ff00) >> 8U); + } + if (RxHeader->DataLength == FDCAN_DLC_BYTES_7) + { + uint32_t rbuf_data0_value; + uint32_t rbuf_data1_value; + rbuf_data0_value = fdcan->CAN_RECEIVE_BUFFER[0]; + rbuf_data1_value = fdcan->CAN_RECEIVE_BUFFER[1]; + message_data[0][0] = (rbuf_data0_value & 0x000000ff); + message_data[0][1] = ((rbuf_data0_value & 0x0000ff00) >> 8U); + message_data[0][2] = ((rbuf_data0_value & 0x00ff0000) >> 16U); + message_data[0][3] = ((rbuf_data0_value & 0xff000000) >> 24U); + + message_data[1][0] = (rbuf_data1_value & 0x000000ff); + message_data[1][1] = ((rbuf_data1_value & 0x0000ff00) >> 8U); + message_data[1][2] = ((rbuf_data1_value & 0x00ff0000) >> 16U); + } + if (RxHeader->DataLength == FDCAN_DLC_BYTES_8) + { + uint32_t message_data_one[2]; + for (i = 0; i < 2; i++) + { + message_data_one[i] = fdcan->CAN_RECEIVE_BUFFER[i]; + } + for (j = 0; j < 2; j++) + { + message_data[j][0] = (message_data_one[j] & 0x000000ff); + message_data[j][1] = ((message_data_one[j] & 0x0000ff00) >> 8U); + message_data[j][2] = ((message_data_one[j] & 0x00ff0000) >> 16U); + message_data[j][3] = ((message_data_one[j] & 0xff000000) >> 24U); + } + } + if (RxHeader->DataLength == FDCAN_DLC_BYTES_12) + { + if (RxHeader->FDFormat == FDCAN_CLASSIC_CAN) + { + uint32_t message_data_one[2]; + for (i = 0; i < 2; i++) + { + message_data_one[i] = fdcan->CAN_RECEIVE_BUFFER[i]; + } + for (j = 0; j < 2; j++) + { + message_data[j][0] = (message_data_one[j] & 0x000000ff); + message_data[j][1] = ((message_data_one[j] & 0x0000ff00) >> 8U); + message_data[j][2] = ((message_data_one[j] & 0x00ff0000) >> 16U); + message_data[j][3] = ((message_data_one[j] & 0xff000000) >> 24U); + } + } + else + { + uint32_t message_data_one[3]; + for (i = 0; i < 3; i++) + { + message_data_one[i] = fdcan->CAN_RECEIVE_BUFFER[i]; + } + for (j = 0; j < 3; j++) + { + message_data[j][0] = (message_data_one[j] & 0x000000ff); + message_data[j][1] = ((message_data_one[j] & 0x0000ff00) >> 8U); + message_data[j][2] = ((message_data_one[j] & 0x00ff0000) >> 16U); + message_data[j][3] = ((message_data_one[j] & 0xff000000) >> 24U); + } + } + } + if (RxHeader->DataLength == FDCAN_DLC_BYTES_16) + { + if (RxHeader->FDFormat == FDCAN_CLASSIC_CAN) + { + uint32_t message_data_one[2]; + for (i = 0; i < 2; i++) + { + message_data_one[i] = fdcan->CAN_RECEIVE_BUFFER[i]; + } + for (j = 0; j < 2; j++) + { + message_data[j][0] = (message_data_one[j] & 0x000000ff); + message_data[j][1] = ((message_data_one[j] & 0x0000ff00) >> 8U); + message_data[j][2] = ((message_data_one[j] & 0x00ff0000) >> 16U); + message_data[j][3] = ((message_data_one[j] & 0xff000000) >> 24U); + } + } + else + { + uint32_t message_data_one[4]; + for (i = 0; i < 4; i++) + { + message_data_one[i] = fdcan->CAN_RECEIVE_BUFFER[i]; + } + for (j = 0; j < 4; j++) + { + message_data[j][0] = (message_data_one[j] & 0x000000ff); + message_data[j][1] = ((message_data_one[j] & 0x0000ff00) >> 8U); + message_data[j][2] = ((message_data_one[j] & 0x00ff0000) >> 16U); + message_data[j][3] = ((message_data_one[j] & 0xff000000) >> 24U); + } + } + } + if (RxHeader->DataLength == FDCAN_DLC_BYTES_20) + { + if (RxHeader->FDFormat == FDCAN_CLASSIC_CAN) + { + uint32_t message_data_one[2]; + for (i = 0; i < 2; i++) + { + message_data_one[i] = fdcan->CAN_RECEIVE_BUFFER[i]; + } + for (j = 0; j < 2; j++) + { + message_data[j][0] = (message_data_one[j] & 0x000000ff); + message_data[j][1] = ((message_data_one[j] & 0x0000ff00) >> 8U); + message_data[j][2] = ((message_data_one[j] & 0x00ff0000) >> 16U); + message_data[j][3] = ((message_data_one[j] & 0xff000000) >> 24U); + } + } + else + { + uint32_t message_data_one[5]; + for (i = 0; i < 5; i++) + { + message_data_one[i] = fdcan->CAN_RECEIVE_BUFFER[i]; + } + for (j = 0; j < 5; j++) + { + message_data[j][0] = (message_data_one[j] & 0x000000ff); + message_data[j][1] = ((message_data_one[j] & 0x0000ff00) >> 8U); + message_data[j][2] = ((message_data_one[j] & 0x00ff0000) >> 16U); + message_data[j][3] = ((message_data_one[j] & 0xff000000) >> 24U); + } + } + } + if (RxHeader->DataLength == FDCAN_DLC_BYTES_24) + { + if (RxHeader->FDFormat == FDCAN_CLASSIC_CAN) + { + uint32_t message_data_one[2]; + for (i = 0; i < 2; i++) + { + message_data_one[i] = fdcan->CAN_RECEIVE_BUFFER[i]; + } + for (j = 0; j < 2; j++) + { + message_data[j][0] = (message_data_one[j] & 0x000000ff); + message_data[j][1] = ((message_data_one[j] & 0x0000ff00) >> 8U); + message_data[j][2] = ((message_data_one[j] & 0x00ff0000) >> 16U); + message_data[j][3] = ((message_data_one[j] & 0xff000000) >> 24U); + } + } + else + { + uint32_t message_data_one[6]; + for (i = 0; i < 6; i++) + { + message_data_one[i] = fdcan->CAN_RECEIVE_BUFFER[i]; + } + for (j = 0; j < 6; j++) + { + message_data[j][0] = (message_data_one[j] & 0x000000ff); + message_data[j][1] = ((message_data_one[j] & 0x0000ff00) >> 8U); + message_data[j][2] = ((message_data_one[j] & 0x00ff0000) >> 16U); + message_data[j][3] = ((message_data_one[j] & 0xff000000) >> 24U); + } + } + } + if (RxHeader->DataLength == FDCAN_DLC_BYTES_32) + { + if (RxHeader->FDFormat == FDCAN_CLASSIC_CAN) + { + uint32_t message_data_one[2]; + for (i = 0; i < 2; i++) + { + message_data_one[i] = fdcan->CAN_RECEIVE_BUFFER[i]; + } + for (j = 0; j < 2; j++) + { + message_data[j][0] = (message_data_one[j] & 0x000000ff); + message_data[j][1] = ((message_data_one[j] & 0x0000ff00) >> 8U); + message_data[j][2] = ((message_data_one[j] & 0x00ff0000) >> 16U); + message_data[j][3] = ((message_data_one[j] & 0xff000000) >> 24U); + } + } + else + { + uint32_t message_data_one[8]; + for (i = 0; i < 8; i++) + { + message_data_one[i] = fdcan->CAN_RECEIVE_BUFFER[i]; + } + for (j = 0; j < 8; j++) + { + message_data[j][0] = (message_data_one[j] & 0x000000ff); + message_data[j][1] = ((message_data_one[j] & 0x0000ff00) >> 8U); + message_data[j][2] = ((message_data_one[j] & 0x00ff0000) >> 16U); + message_data[j][3] = ((message_data_one[j] & 0xff000000) >> 24U); + } + } + } + if (RxHeader->DataLength == FDCAN_DLC_BYTES_48) + { + if (RxHeader->FDFormat == FDCAN_CLASSIC_CAN) + { + uint32_t message_data_one[2]; + for (i = 0; i < 2; i++) + { + message_data_one[i] = fdcan->CAN_RECEIVE_BUFFER[i]; + } + for (j = 0; j < 2; j++) + { + message_data[j][0] = (message_data_one[j] & 0x000000ff); + message_data[j][1] = ((message_data_one[j] & 0x0000ff00) >> 8U); + message_data[j][2] = ((message_data_one[j] & 0x00ff0000) >> 16U); + message_data[j][3] = ((message_data_one[j] & 0xff000000) >> 24U); + } + } + else + { + uint32_t message_data_one[12]; + for (i = 0; i < 12; i++) + { + message_data_one[i] = fdcan->CAN_RECEIVE_BUFFER[i]; + } + for (j = 0; j < 12; j++) + { + message_data[j][0] = (message_data_one[j] & 0x000000ff); + message_data[j][1] = ((message_data_one[j] & 0x0000ff00) >> 8U); + message_data[j][2] = ((message_data_one[j] & 0x00ff0000) >> 16U); + message_data[j][3] = ((message_data_one[j] & 0xff000000) >> 24U); + } + } + } + if (RxHeader->DataLength == FDCAN_DLC_BYTES_64) + { + if (RxHeader->FDFormat == FDCAN_CLASSIC_CAN) + { + uint32_t message_data_one[2]; + for (i = 0; i < 2; i++) + { + message_data_one[i] = fdcan->CAN_RECEIVE_BUFFER[i]; + } + for (j = 0; j < 2; j++) + { + message_data[j][0] = (message_data_one[j] & 0x000000ff); + message_data[j][1] = ((message_data_one[j] & 0x0000ff00) >> 8U); + message_data[j][2] = ((message_data_one[j] & 0x00ff0000) >> 16U); + message_data[j][3] = ((message_data_one[j] & 0xff000000) >> 24U); + } + } + else + { + uint32_t message_data_one[16]; + for (i = 0; i < 16; i++) + { + message_data_one[i] = fdcan->CAN_RECEIVE_BUFFER[i]; + } + for (j = 0; j < 16; j++) + { + message_data[j][0] = (message_data_one[j] & 0x000000ff); + message_data[j][1] = ((message_data_one[j] & 0x0000ff00) >> 8U); + message_data[j][2] = ((message_data_one[j] & 0x00ff0000) >> 16U); + message_data[j][3] = ((message_data_one[j] & 0xff000000) >> 24U); + } + } + } + } +} + +/** + * @brief Get Arbitration Lost Capture Value. + * @param fdcan: specifies the instance. + * This parameter can be any combination of the following values: + * @arg FDCAN1: the instance is can1 + * @arg FDCAN2: the instance is can2 + * @arg FDCAN3: the instance is can3 + * @arg FDCAN4: the instance is can4 + * @param ArbLostCap: specifies the ALC value. + * This parameter can be any combination of the following values: + * @arg ArbitrationLostCapture:Specifies the bit position in the frame where the arbitration has been lost + * The value of ArbitrationLostCapture: This parameter must be a number between 0 and 31 + * @retval None + */ +void FDCAN_GetArbLostCap(FDCAN_TypeDef* fdcan, FDCAN_ArbitrationLostCaptureTypeDef* ArbLostCap) +{ + /* Check the parameters */ + assert_param(IS_FDCAN_ALL_INSTANCE(fdcan)); + + /* Get ALC value */ + ArbLostCap->ArbitrationLostCapture = fdcan->CAN_ERR_CNT; +} + +/** + * @brief Get TECNT, RECNT and KOER. + * @param fdcan: specifies the instance. + * This parameter can be any combination of the following values: + * @arg FDCAN1: the instance is can1 + * @arg FDCAN2: the instance is can2 + * @arg FDCAN3: the instance is can3 + * @arg FDCAN4: the instance is can4 + * @param ErrorCnt: specifies the TECNT, RECNT and KOER value. + * This parameter can be any combination of the following values: + * @arg TxErrorCnt: Specifies the Transmit Error Counter Value + * The value of TxErrorCnt: This parameter can be a number between 0 and 255 + * @arg RxErrorCnt: Specifies the Receive Error Counter Value + * The value of RxErrorCnt: This parameter can be a number between 0 and 255 + * @arg KOER: Specifies the kind of Error + * The value of KOER: FDCAN_NO_ERROR + * FDCAN_BIT_ERROR + * FDCAN_FORM_ERROR + * FDCAN_STUFF_ERROR + * FDCAN_ACK_ERROR + * FDCAN_CRC_ERROR + * FDCAN_OTHER_ERROR + * FDCAN_NOT_USED + * @retval None + */ +void FDCAN_GetErrorCnt(FDCAN_TypeDef* fdcan, FDCAN_ErrorCountersTypeDef* ErrorCnt) +{ + /* Check the parameters */ + assert_param(IS_FDCAN_ALL_INSTANCE(fdcan)); + + /* Get TECNT, RECNT and KOER */ + ErrorCnt->TxErrorCnt = ((fdcan->CAN_ERR_CNT & 0xff000000) >> 24U); + ErrorCnt->RxErrorCnt = ((fdcan->CAN_ERR_CNT & 0x00ff0000) >> 16U); + ErrorCnt->KOER = ((fdcan->CAN_ERR_CNT & 0x000000E0) >> 5U); +} + +/** + * @brief Get TECNT, RECNT and KOER. + * @param fdcan: specifies the instance. + * This parameter can be any combination of the following values: + * @arg FDCAN1: the instance is can1 + * @arg FDCAN2: the instance is can2 + * @arg FDCAN3: the instance is can3 + * @arg FDCAN4: the instance is can4 + * @retval None + */ +void FDCAN_ConfigTsnext(FDCAN_TypeDef* fdcan) +{ + /* Check the parameters */ + assert_param(IS_FDCAN_ALL_INSTANCE(fdcan)); + + /* Set TSNEXT */ + fdcan->CAN_CMD_CTRL |= CAN_CMD_CTRL_TSNEXT; + + /* Wait TSNEXT be clear by hardware */ + while ((fdcan->CAN_CMD_CTRL & CAN_CMD_CTRL_TSNEXT) == CAN_CMD_CTRL_TSNEXT); +} + +/** + * @brief Get TECNT, RECNT and KOER. + * @param fdcan: specifies the instance. + * This parameter can be any combination of the following values: + * @arg FDCAN1: the instance is can1 + * @arg FDCAN2: the instance is can2 + * @arg FDCAN3: the instance is can3 + * @arg FDCAN4: the instance is can4 + * @retval None + */ +void FDCAN_ConfigInitialOffset(FDCAN_TypeDef* fdcan) +{ + /* Check the parameters */ + assert_param(IS_FDCAN_ALL_INSTANCE(fdcan)); + + if (fdcan == FDCAN1) + { + fdcan->CAN_INIT_CFG_OFFSET = 0x000; + } + + if (fdcan == FDCAN2) + { + fdcan->CAN_INIT_CFG_OFFSET = 0x0F4; + } + + if (fdcan == FDCAN3) + { + fdcan->CAN_INIT_CFG_OFFSET = 0x1E8; + } + + if (fdcan == FDCAN4) + { + fdcan->CAN_INIT_CFG_OFFSET = 0x2DC; + } +} + +/** @defgroup FDCAN_Exported_Functions_Group4 Interrupts management + * @brief Interrupts management + * +@verbatim + ============================================================================== + ##### Interrupts management ##### + ============================================================================== + [..] This section provides functions allowing to: + (+) FDCAN_ActivateNotification : Enable interrupts + (+) FDCAN_DeactivateNotification : Disable interrupts + +@endverbatim + * @{ + */ + +/** + * @brief Enable interrupts. + * @param fdcan pointer to an FDCAN_TypeDef structure that contains + * the configuration information for the specified FDCAN. + * @param FDCAN_INT_REG: specifies the int in which reg. + * This parameter can be one of the following values: + * FDCAN_INT_REG_FLAG1: int in CAN_INT_FLAG1 + * FDCAN_INT_REG_FLAG2: int in CAN_INT_FLAG2 + * @param ActiveITs indicates which interrupts will be enabled. + * This parameter can be any combination of the following values: + * FDCAN_IT_RECEIVE: Receive interrupt enable + * FDCAN_IT_RBUF_OVERRUN: Receive buffer overrun interrupt enable + * FDCAN_IT_RBUF_FULL: Receive buffer full interupt enable + * FDCAN_IT_RB_ALMOST_FULL: Receive buffer almost full interupt enable + * FDCAN_IT_TRANSMISSION_PRIMARY : Transmission primary successfully interupt enable + * FDCAN_IT_TRANSMISSION_SECONDARY: Transmission secondary successfully interupt enable + * FDCAN_IT_ERROR: Error interupt enable + * FDCAN_IT_ERROR_PASSIVE: Node is error passive interupt enable + * FDCAN_IT_ARBITRATION_LOST: Lost arbitration interupt enable + * FDCAN_IT_BUS_ERROR: Bus error interupt enable + * FDCAN_IT_TIME_TRIGGER: Time Trigger interupt enable + * FDCAN_IT_WATCH_TRIGGER: Watch Trigger interupt enable + * @retval None. + */ +void FDCAN_ActivateNotification(FDCAN_TypeDef* fdcan, uint32_t FDCAN_INT_REG, uint32_t ActiveITs) +{ + + /* Check function parameters */ + assert_param(IS_FDCAN_ALL_INSTANCE(fdcan)); + assert_param(IS_FDCAN_IT(ActiveITs)); + assert_param(IS_FDCAN_INT_REG(FDCAN_INT_REG)); + + + if (FDCAN_INT_REG == FDCAN_INT_REG_FLAG1) + { + /* get can int enable value */ + uint32_t can_int_flag1_value; + can_int_flag1_value = fdcan->CAN_INT_FLAG1; + + /* clear can int flag in this reg*/ + can_int_flag1_value = can_int_flag1_value & CAN_INT_FLAG1_MASK; + + /* Enable choosed Interrupt */ + fdcan->CAN_INT_FLAG1 = can_int_flag1_value | ActiveITs; + } + + if (FDCAN_INT_REG == FDCAN_INT_REG_FLAG2) + { + /* Enable Interrupt */ + fdcan->CAN_INT_FLAG2 |= ActiveITs; + } +} + +/** + * @brief Disable interrupts. + * @param fdcan pointer to an FDCAN_TypeDef structure that contains + * the configuration information for the specified FDCAN. + * @param FDCAN_INT_REG: specifies the int in which reg. + * This parameter can be one of the following values: + * FDCAN_INT_REG_FLAG1: int in CAN_INT_FLAG1 + * FDCAN_INT_REG_FLAG2: int in CAN_INT_FLAG2 + * @param InactiveITs indicates which interrupts will be disabled. + * This parameter can be any combination of @arg FDCAN_Interrupts: + * FDCAN_IT_RECEIVE: Receive interrupt enable + * FDCAN_IT_RBUF_OVERRUN: Receive buffer overrun interrupt enable + * FDCAN_IT_RBUF_FULL: Receive buffer full interupt enable + * FDCAN_IT_RB_ALMOST_FULL: Receive buffer almost full interupt enable + * FDCAN_IT_TRANSMISSION_PRIMARY : Transmission primary successfully interupt enable + * FDCAN_IT_TRANSMISSION_SECONDARY: Transmission secondary successfully interupt enable + * FDCAN_IT_ERROR: Error interupt enable + * FDCAN_IT_ERROR_PASSIVE: Node is error passive interupt enable + * FDCAN_IT_ARBITRATION_LOST: Lost arbitration interupt enable + * FDCAN_IT_BUS_ERROR: Bus error interupt enable + * FDCAN_IT_TIME_TRIGGER: Time Trigger interupt enable + * FDCAN_IT_WATCH_TRIGGER: Watch Trigger interupt enable + * @retval None. + */ +void FDCAN_DeactivateNotification(FDCAN_TypeDef* fdcan, uint32_t FDCAN_INT_REG, uint32_t InactiveITs) +{ + /* Check function parameters */ + assert_param(IS_FDCAN_ALL_INSTANCE(fdcan)); + assert_param(IS_FDCAN_IT(InactiveITs)); + assert_param(IS_FDCAN_INT_REG(FDCAN_INT_REG)); + + if (FDCAN_INT_REG == FDCAN_INT_REG_FLAG1) + { + /* get can int enable value */ + uint32_t can_int_flag1_value; + can_int_flag1_value = fdcan->CAN_INT_FLAG1; + + /* clear can int flag in this reg*/ + can_int_flag1_value = can_int_flag1_value & CAN_INT_FLAG1_MASK; + + /* disable choosed int enable bit */ + fdcan->CAN_INT_FLAG1 = (can_int_flag1_value & (~InactiveITs)); + + if (((InactiveITs & FDCAN_IT_RECEIVE) != 0U) || ((InactiveITs & FDCAN_IT_RBUF_OVERRUN) != 0U) || \ + ((InactiveITs & FDCAN_IT_RBUF_FULL) != 0U) || ((InactiveITs & FDCAN_IT_RB_ALMOST_FULL) != 0U) || \ + ((InactiveITs & FDCAN_IT_TRANSMISSION_PRIMARY) != 0U) || ((InactiveITs & FDCAN_IT_TRANSMISSION_SECONDARY) != 0U) || \ + ((InactiveITs & FDCAN_IT_ERROR) != 0U) || ((InactiveITs & FDCAN_IT_ERROR_PASSIVE) != 0U) || \ + ((InactiveITs & FDCAN_IT_ARBITRATION_LOST) != 0U) || ((InactiveITs & FDCAN_IT_BUS_ERROR) != 0U)) + { + /* Wait choosed Interrupts are disabled */ + while ((fdcan->CAN_INT_FLAG1 & InactiveITs) == InactiveITs); + + } + + } + + if (FDCAN_INT_REG == FDCAN_INT_REG_FLAG2) + { + fdcan->CAN_INT_FLAG2 &= ~InactiveITs; + + /* Check which interrupts are enabled before */ + if (((InactiveITs & FDCAN_IT_TIME_TRIGGER) != 0U) || ((InactiveITs & FDCAN_IT_WATCH_TRIGGER) != 0U)) + { + /* Wait choosed Interrupts are disabled */ + while ((fdcan->CAN_INT_FLAG2 & InactiveITs) == InactiveITs); + } + } + +} +/** + * @} + */ + +/** + * @brief get single bit STAT status. + * @param fdcan pointer to an FDCAN_TypeDef structure that contains + * the configuration information for the specified FDCAN. + * @param FDCAN_FLAG_REG: specifies the flag in which reg. + * This parameter can be one of the following values: + * FDCAN_FLAG_REG_CMD: flag in CAN_CMD_CTRL + * FDCAN_FLAG_REG_FLAG1: flag in CAN_INT_FLAG1 + * FDCAN_FLAG_REG_FLAG2: flag in CAN_INT_FLAG2 + * @param FDCAN_FLAG: specifies the flag to check. + * This parameter can be one of the following values: + * FDCAN_FLAG_ROV: receive buffer overflow + * FDCAN_FLAG_RACTIVE: receiving + * FDCAN_FLAG_TACTIVE: transmiting + * FDCAN_FLAG_EPIF: passive error interrupt flag + * FDCAN_FLAG_ALIF: arbit lose interrupt flag + * FDCAN_FLAG_BEIF: bus error interrupt flag + * FDCAN_FLAG_RIF: receive interrupr flag + * FDCAN_FLAG_ROIF: receive overflow interrupt flag + * FDCAN_FLAG_RFIF: receive full interrupt flag + * FDCAN_FLAG_RAFIF: receive almost full interrupr flag + * FDCAN_FLAG_TPIF: transmit primary interrupt flag + * FDCAN_FLAG_TSIF: transmit secondry interrupt flag + * FDCAN_FLAG_EIF: error interrupt flag + * FDCAN_FLAG_AIF: abort interrupr flag + * FDCAN_FLAG_WTIF: watch dog trig interrupt flag + * FDCAN_FLAG_TEIF: timer trig error interrupt flag + * FDCAN_FLAG_TTIF: timer trig interrupt flag + * @retval None. + */ +FlagStatus FDCAN_GetFlagStatus(FDCAN_TypeDef* fdcan, uint32_t FDCAN_FLAG_REG, uint32_t FDCAN_FLAG) +{ + FlagStatus bitstatus = RESET; + assert_param(IS_FDCAN_FLAG(FDCAN_FLAG)); + assert_param(IS_FDCAN_FLAG_REG(FDCAN_FLAG_REG)); + + if (FDCAN_FLAG_REG == FDCAN_FLAG_REG_CMD) + { + if ((fdcan->CAN_CMD_CTRL & FDCAN_FLAG) != (uint16_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + } + + if (FDCAN_FLAG_REG == FDCAN_FLAG_REG_FLAG1) + { + if ((fdcan->CAN_INT_FLAG1 & FDCAN_FLAG) != (uint16_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + } + + if (FDCAN_FLAG_REG == FDCAN_FLAG_REG_FLAG2) + { + if ((fdcan->CAN_INT_FLAG2 & FDCAN_FLAG) != (uint16_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + } + + return bitstatus; +} + +/** + * @brief get single bit STAT status. + * @param fdcan pointer to an FDCAN_TypeDef structure that contains + * the configuration information for the specified FDCAN. + * @param FDCAN_FLAG_REG: specifies the flag in which reg. + * This parameter can be one of the following values: + * FDCAN_FLAG_REG_FLAG1: flag in CAN_INT_FLAG1 + * FDCAN_FLAG_REG_FLAG2: flag in CAN_INT_FLAG2 + * @param FDCAN_FLAG: specifies the flag to check. + * This parameter can be one of the following values: + * FDCAN_FLAG_EPIF: passive error interrupt flag + * FDCAN_FLAG_ALIF: arbit lose interrupt flag + * FDCAN_FLAG_BEIF: bus error interrupt flag + * FDCAN_FLAG_RIF: receive interrupr flag + * FDCAN_FLAG_ROIF: receive overflow interrupt flag + * FDCAN_FLAG_RFIF: receive full interrupt flag + * FDCAN_FLAG_RAFIF: receive almost full interrupr flag + * FDCAN_FLAG_TPIF: transmit primary interrupt flag + * FDCAN_FLAG_TSIF: transmit secondry interrupt flag + * FDCAN_FLAG_EIF: error interrupt flag + * FDCAN_FLAG_AIF: abort interrupr flag + * FDCAN_FLAG_WTIF: watch dog trig interrupt flag + * FDCAN_FLAG_TEIF: timer trig error interrupt flag + * FDCAN_FLAG_TTIF: timer trig interrupt flag + * FDCAN_FLAG_RTIF_ALL: can_rtif all flag + * @retval None. + */ +void FDCAN_ClearInterruptFlag(FDCAN_TypeDef* fdcan, uint32_t FDCAN_FLAG_REG, uint32_t FDCAN_FLAG) +{ + assert_param(IS_FDCAN_FLAG(FDCAN_FLAG)); + assert_param(IS_FDCAN_FLAG_REG(FDCAN_FLAG_REG)); + + if (FDCAN_FLAG_REG == FDCAN_FLAG_REG_FLAG1) + { + /* get can int enable value */ + uint32_t can_int_flag1_value; + can_int_flag1_value = fdcan->CAN_INT_FLAG1; + + /* clear can int flag in this reg*/ + can_int_flag1_value = can_int_flag1_value & CAN_INT_FLAG1_MASK; + + fdcan->CAN_INT_FLAG1 = (can_int_flag1_value | FDCAN_FLAG); + } + else if (FDCAN_FLAG_REG == FDCAN_FLAG_REG_FLAG2) + { + fdcan->CAN_INT_FLAG2 |= FDCAN_FLAG; + } +} + +/** + * @brief get dual bits STAT status. + * @param fdcan pointer to an FDCAN_TypeDef structure that contains + * the configuration information for the specified FDCAN. + * @param FDCAN_BUF_TYPE: specifies the buffer status. + * This parameter can be one of the following values: + * @arg FDCAN_TRANS_BUFFER_STAT: Transmission Secondary buffer Status + * @arg FDCAN_RECEIVE_BUFFER_STAT: Receive buffer status + * + * @retval None. + */ +int FDCAN_GetFifoStatus(FDCAN_TypeDef* fdcan, uint32_t FDCAN_BUF_TYPE) +{ + int dual_bitstatus = Empty; + + if (FDCAN_BUF_TYPE == FDCAN_TRANS_BUFFER_STAT) + { + if (((fdcan->CAN_CMD_CTRL & FDCAN_TBUF_FULL) >> 16) == 0x0) + { + dual_bitstatus = Empty; + } + else if (((fdcan->CAN_CMD_CTRL & FDCAN_TBUF_FULL) >> 16) == 0x1) + { + dual_bitstatus = Less_HalfFull; + } + else if (((fdcan->CAN_CMD_CTRL & FDCAN_TBUF_FULL) >> 16) == 0x2) + { + dual_bitstatus = More_HalfFull; + } + else if (((fdcan->CAN_CMD_CTRL & FDCAN_TBUF_FULL) >> 16) == 0x3) + { + dual_bitstatus = Full; + } + } + else if (FDCAN_BUF_TYPE == FDCAN_RECEIVE_BUFFER_STAT) + { + if (((fdcan->CAN_CMD_CTRL & FDCAN_RBUF_FULL) >> 24) == 0x0) + { + dual_bitstatus = Empty; + } + else if (((fdcan->CAN_CMD_CTRL & FDCAN_RBUF_FULL) >> 24) == 0x1) + { + dual_bitstatus = Less_HalfFull; + } + else if (((fdcan->CAN_CMD_CTRL & FDCAN_RBUF_FULL) >> 24) == 0x2) + { + dual_bitstatus = More_HalfFull; + } + else if (((fdcan->CAN_CMD_CTRL & FDCAN_RBUF_FULL) >> 24) == 0x3) + { + dual_bitstatus = Full; + } + } + return dual_bitstatus; +} + + +/** + * @brief Set reference message + * @param fdcan: specifies the instance. + * This parameter can be any combination of the following values: + * @arg FDCAN1: the instance is can1 + * @arg FDCAN2: the instance is can2 + * @arg FDCAN3: the instance is can3 + * @arg FDCAN4: the instance is can4 + * @param FDCAN_REF_MSG_IDE:ref_msg id type + * This parameter can be any combination of the following values: + * @arg FDCAN_REF_MSG_STD:standard id + * @arg FDCAN_REF_MSG_EXT:externed id + * @param FDCAN_REF_MSG_ID:reference id value + * @retval None + */ + +void FDCAN_RefMessageSet(FDCAN_TypeDef* fdcan, uint32_t FDCAN_REF_MSG_IDE, uint32_t FDCAN_REF_MSG_ID) +{ + /* Check function parameters */ + assert_param(IS_FDCAN_ALL_INSTANCE(fdcan)); + assert_param(IS_FDCAN_REF_MSG_IDTYPE(FDCAN_REF_MSG_IDE)); + assert_param(IS_FDCAN_REF_MSG_ID_VALUE(FDCAN_REF_MSG_ID)); + + fdcan->CAN_REF_MSG = (FDCAN_REF_MSG_IDE | FDCAN_REF_MSG_ID); +} + +/** + * @brief Set reference message + * @param fdcan: specifies the instance. + * This parameter can be any combination of the following values: + * @arg FDCAN1: the instance is can1 + * @arg FDCAN2: the instance is can2 + * @arg FDCAN3: the instance is can3 + * @arg FDCAN4: the instance is can4 + * @param FDCAN_TBPTR:point tbuf ptb or stb + * @retval None + */ + +void FDCAN_TbufSoltPoint(FDCAN_TypeDef* fdcan, uint32_t FDCAN_TBPTR) +{ + /* Check function parameters */ + assert_param(IS_FDCAN_ALL_INSTANCE(fdcan)); + assert_param(IS_FDCAN_TBPTR_VALUE(FDCAN_TBPTR)); + + /* CLR OLD TBPTR VALUE */ + uint32_t CAN_INT_FLAG2_VALUE; + CAN_INT_FLAG2_VALUE = fdcan->CAN_INT_FLAG2; + CAN_INT_FLAG2_VALUE = (CAN_INT_FLAG2_VALUE & ~CAN_INT_FLAG2_TBPTR); + /* SET NEW TBPTR VALUE */ + fdcan->CAN_INT_FLAG2 = ((FDCAN_TBPTR << 16U) | CAN_INT_FLAG2_VALUE); +} + +void FDCAN_TransmitSoltPoint(FDCAN_TypeDef* fdcan, uint32_t FDCAN_TTPTR) +{ + /* Check function parameters */ + assert_param(IS_FDCAN_ALL_INSTANCE(fdcan)); + assert_param(IS_FDCAN_TTPTR_VALUE(FDCAN_TTPTR)); + + /* CLR OLD TTPTR VALUE */ + uint32_t CAN_TRG_CFG_VALUE; + CAN_TRG_CFG_VALUE = fdcan->CAN_TRIG_CFG; + CAN_TRG_CFG_VALUE = (CAN_TRG_CFG_VALUE & ~CAN_TRIG_CFG_TTPTR); + CAN_TRG_CFG_VALUE = (CAN_TRG_CFG_VALUE & ~0xFFFF0000); + /* SET NEW TTPTR VALUE */ + fdcan->CAN_TRIG_CFG = (FDCAN_TTPTR | CAN_TRG_CFG_VALUE); +} + + +void FDCAN_SetTbufSoltEmpty(FDCAN_TypeDef* fdcan, FunctionalState NewState) +{ + /* Check function parameters */ + assert_param(IS_FDCAN_ALL_INSTANCE(fdcan)); + + if (NewState == ENABLE) + { + fdcan->CAN_INT_FLAG2 |= CAN_INT_FLAG2_TBE; + while ((fdcan->CAN_INT_FLAG2 & CAN_INT_FLAG2_TBE) == CAN_INT_FLAG2_TBE); + } + else if (NewState == DISABLE) + { + fdcan->CAN_INT_FLAG2 &= ~CAN_INT_FLAG2_TBE; + } +} + +void FDCAN_SetTbufSoltFull(FDCAN_TypeDef* fdcan, FunctionalState NewState) +{ + /* Check function parameters */ + assert_param(IS_FDCAN_ALL_INSTANCE(fdcan)); + + if (NewState == ENABLE) + { + fdcan->CAN_INT_FLAG2 |= CAN_INT_FLAG2_TBF; + while ((fdcan->CAN_INT_FLAG2 & CAN_INT_FLAG2_TBF) == CAN_INT_FLAG2_TBF); + } + else if (NewState == DISABLE) + { + fdcan->CAN_INT_FLAG2 &= ~CAN_INT_FLAG2_TBF; + } +} + +void FDCAN_TimeTrigEnable(FDCAN_TypeDef* fdcan, FunctionalState NewState)/* Function used enbale tten*/ +{ + /* Check function parameters */ + assert_param(IS_FDCAN_ALL_INSTANCE(fdcan)); + + if (NewState == ENABLE) + { + /* Set the Time_Triger Enable */ + fdcan->CAN_INT_FLAG2 |= CAN_INT_FLAG2_TTEN; + } + else if (NewState == DISABLE) + { + /* clr the Time_Triger Enable */ + fdcan->CAN_INT_FLAG2 &= ~CAN_INT_FLAG2_TTEN; + } +} +/** + * @param FDCAN_TIMEPOS:time stamp position + * This parameter can be any combination of the following values: + * @arg FDCAN_TIMEPOS_SOF:time stamp position in sof + * @arg FDCAN_TIMEPOS_EOF:time stamp position in eof +*/ +void FDCAN_TimeStampPosition(FDCAN_TypeDef* fdcan, uint32_t FDCAN_TIMEPOS)/* Function used set timepos*/ +{ + /* Check function parameters */ + assert_param(IS_FDCAN_ALL_INSTANCE(fdcan)); + assert_param(IS_FDCAN_TIME_POS(FDCAN_TIMEPOS)); + + if (FDCAN_TIMEPOS == FDCAN_TIMEPOS_SOF) + { + /* Set the Time_Stamp Position in SOF */ + fdcan->CAN_FILTER_CTRL &= ~CAN_FILTER_CTRL_TIMEPOS; + } + else if (FDCAN_TIMEPOS == FDCAN_TIMEPOS_EOF) + { + /* Set the Time_Stamp Position in EOF */ + fdcan->CAN_FILTER_CTRL |= FDCAN_TIMEPOS_EOF; + } +} + +void FDCAN_TimeStampEnable(FDCAN_TypeDef* fdcan, FunctionalState NewState)/* Function used enbale timestamp*/ +{ + /* Check function parameters */ + assert_param(IS_FDCAN_ALL_INSTANCE(fdcan)); + + if (NewState == ENABLE) + { + /* Set the Time_Stamp Enable */ + fdcan->CAN_FILTER_CTRL |= CAN_FILTER_CTRL_TIMEEN; + } + else if (NewState == DISABLE) + { + /* Clr the Time_Stamp Enable */ + fdcan->CAN_FILTER_CTRL &= ~CAN_FILTER_CTRL_TIMEEN; + } +} + +void FDCAN_GetCanTransmisionTs(FDCAN_TypeDef* fdcan, uint32_t can_transmission_ts[2]) +{ + /* Check function parameters */ + assert_param(IS_FDCAN_ALL_INSTANCE(fdcan)); + + uint32_t i; + for (i = 0; i < 2; i++) + { + can_transmission_ts[i] = fdcan->CAN_TRANSMISION_TS[i]; + } + +} + + +/** + * @} + */ + + diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_flash.c b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_flash.c new file mode 100644 index 00000000000..b6b1f61f3f0 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_flash.c @@ -0,0 +1,900 @@ +/** + ****************************************************************************** + * @file ft32f4xx_flash.c + * @author FMD xzhang + * @brief This file provides firmware functions to manage the following + * functionalities of the FLASH peripheral: + * - FLASH Interface configuration + * - FLASH Memory Programming + * - Option Bytes Programming + * - Interrupts and flags management + * @version V1.0.0 + * @data 2025-03-13 + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx_flash.h" + +/** + * @brief Sets the code latency value. + * @param FLASH_Latency: specifies the FLASH Latency value. + * This parameter can be one of the following values: + * @arg FLASH_Latency_0: FLASH 0 Latency cycle + * @arg FLASH_Latency_1: FLASH 1 Latency cycle + * @arg FLASH_Latency_2: FLASH 2 Latency cycle + * @arg FLASH_Latency_3: FLASH 3 Latency cycle + * @arg FLASH_Latency_4: FLASH 4 Latency cycle + * @arg FLASH_Latency_5: FLASH 5 Latency cycle + * @arg FLASH_Latency_6: FLASH 6 Latency cycle + * @arg FLASH_Latency_7: FLASH 7 Latency cycle + * @retval None + */ +void FLASH_SetLatency(uint32_t FLASH_Latency) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_FLASH_LATENCY(FLASH_Latency)); + + /* Read the RDC register */ + tmpreg = FLASH->RDC; + + /* Sets the Latency value */ + tmpreg &= (uint32_t)(~((uint32_t)FLASH_RDC_LATENCY)); + tmpreg |= FLASH_Latency; + + /* Write the RDC register */ + FLASH->RDC = tmpreg; +} + +/** + * @brief Enables or disables the Prefetch Buffer. + * @param NewState: new state of the FLASH prefetch buffer. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void FLASH_PrefetchBufferCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + FLASH->RDC |= FLASH_RDC_PRFTBE ; + } + else + { + FLASH->RDC &= ~FLASH_RDC_PRFTBE; + } +} + +/** + * @brief Checks whether the FLASH Prefetch Buffer status is set or not. + * @param None + * @retval FLASH Prefetch Buffer Status (SET or RESET). + */ +FlagStatus FLASH_GetPrefetchBufferStatus(void) +{ + FlagStatus bitstatus = RESET; + + if ((FLASH->RDC & FLASH_RDC_PRFTBS) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + /* Return the new state of FLASH Prefetch Buffer Status (SET or RESET) */ + return bitstatus; +} + +/** + * @brief UnLocks the Program memory access. + * @param None + * @retval None + */ +void FLASH_Unlock(void) +{ + unsigned int read_data; + do + { + read_data = FLASH->FR ; + } + while ((read_data & FLASH_FR_BSY) != 0); + /*KEYR write key1 0x45670123 key2 0xCDEF89AB*/ + if ((FLASH->WRC & FLASH_WRC_LOCK) != 0) + { + FLASH->KEYR = FLASH_KEY1; + FLASH->KEYR = FLASH_KEY2; + } +} +/** + * @brief Locks the Program memory access. + * @param None + * @retval None + */ +void FLASH_Lock(void) +{ + /* Set the LOCK Bit to lock the FLASH control register and program memory access */ + FLASH->WRC |= FLASH_WRC_LOCK; +} + + +/** + * @brief Erases a specified page in program memory. + * @note To correctly run this function, the FLASH_Unlock() function must be called before. + * @note Call the FLASH_Lock() to disable the flash memory access (recommended + * to protect the FLASH memory against possible unwanted operation) + * @param page_num: The page number in program memory to be erased. + * @param erase_size: The size of erase : + * This parameter can be: + * @arg ERASE_SIZE_0:Erase size is 512B (default value) + * @arg ERASE_SIZE_1: Erase size is 2KB + * @arg ERASE_SIZE_2: Erase size is 16KB + * @note A Page is erased in the Program memory only if the address to load + * is the start address of a page (multiple of 512 bytes). + * @retval FLASH Status: The returned value can be: + * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ +FLASH_Status FLASH_ErasePage(uint32_t page_num, uint32_t erase_size) +{ + FLASH_Status status = FLASH_COMPLETE; + uint32_t erase_page_num; + + /* Check the parameters */ + assert_param(IS_FLASH_ERASE_PAGE_NUM(page_num)); + assert_param(IS_ERASE_SIZE(erase_size)); + + FLASH_PrefetchBufferCmd(DISABLE); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + + if (status == FLASH_COMPLETE) + { + /* If the previous operation is completed, proceed to erase the page */ + /*PNB in bit6-15 of WRC reg*/ + erase_page_num = (page_num << 6); + /*clear status flag*/ + FLASH->FR |= FLASH_FR_CLEAR; + /*clear page number*/ + FLASH->WRC &= (~FLASH_WRC_PNB); + /*Active page Erase function*/ + FLASH->WRC |= FLASH_WRC_PER; + /*select erase size*/ + FLASH->WRC |= erase_size; + /*Page ERASE ERASE start*/ + FLASH->WRC |= (erase_page_num) | FLASH_WRC_STRT; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + /*clear FLASH_WRC_PER & FLASH_WRC_STRT*/ + FLASH->WRC &= (~FLASH_WRC_STRT) & (~FLASH_WRC_PER); + + } + + FLASH_PrefetchBufferCmd(ENABLE); + /* Return the Erase Status */ + return status; +} + + +/** + * @brief Erases all FLASH pages. + * @note To correctly run this function, the FLASH_Unlock() function must be called before. + * @note Call the FLASH_Lock() to disable the flash memory access (recommended + * to protect the FLASH memory against possible unwanted operation) + * @param None + * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG, + * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ +FLASH_Status FLASH_EraseAllPages(void) +{ + FLASH_Status status = FLASH_COMPLETE; + + FLASH_PrefetchBufferCmd(DISABLE); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + + if (status == FLASH_COMPLETE) + { + + /* If the previous operation is completed, proceed to erase the page */ + /*clear status flag; clear page numbe; ERASE start*/ + FLASH->FR |= FLASH_FR_CLEAR; + FLASH->WRC |= FLASH_WRC_MER | FLASH_WRC_STRT; + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + /*clear FLASH_WRC_MER & FLASH_WRC_STRT*/ + FLASH->WRC &= (~FLASH_WRC_MER) & (~FLASH_WRC_STRT); + + } + + FLASH_PrefetchBufferCmd(ENABLE); + + return status; +} + +/** + * @brief Programs 4 word continued at a specified address. + * @note To correctly run this function, the FLASH_Unlock() FLASH_ErasePage() function must be called before. + * @note Call the FLASH_Lock() to disable the flash memory access (recommended + * to protect the FLASH memory against possible unwanted operation) + * @param Address: specifies the address to be programmed,address is the first address of Data0 + * @param Datax: specifies the 4 data to be programmed. + * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG, + * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ +FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data3, uint32_t Data2, uint32_t Data1, uint32_t Data0) +{ + /*clear status flag*/ + FLASH->FR |= FLASH_FR_CLEAR; + FLASH_Status status = FLASH_COMPLETE; + + /* Check the parameters */ + assert_param(IS_FLASH_PROGRAM_ADDRESS(Address)); + + FLASH_PrefetchBufferCmd(DISABLE); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + + if (status == FLASH_COMPLETE) + { + //enable function of program firstly + FLASH->WRC |= FLASH_WRC_PG; + + /* proceed to program the data3 */ + *(__IO uint32_t*)Address = (uint32_t)Data0; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + + if (status == FLASH_COMPLETE) + { + /* If the previous operation is completed, proceed to program the new word */ + *(__IO uint32_t*)(Address + 0x4) = (uint32_t) Data1; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + if (status == FLASH_COMPLETE) + { + /* If the previous operation is completed, proceed to program the new word */ + *(__IO uint32_t*)(Address + 0x8) = (uint32_t) Data2; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + + if (status == FLASH_COMPLETE) + { + /* If the previous operation is completed, proceed to program the new word */ + *(__IO uint32_t*)(Address + 0xc) = (uint32_t) Data3; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + + /* Disable the PG Bit */ + FLASH->WRC &= ~FLASH_WRC_PG; + } + } + } + + } + else + { + /* Disable the PG Bit */ + FLASH->WRC &= ~FLASH_WRC_PG; + } + FLASH_PrefetchBufferCmd(ENABLE); + + return status; +} + + +/** + * @brief Programs a word at a specified address. + * @note To correctly run this function, the FLASH_Unlock() FLASH_ErasePage() function must be called before. + * @note Call the FLASH_Lock() to disable the flash memory access (recommended + * to protect the FLASH memory against possible unwanted operation) + * @param Address: specifies the address to be programmed + * @param Data0: specifies the data to be programmed. + * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG, + * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ +FLASH_Status FLASH_Program_oneWord(uint32_t Address, uint32_t Data0) +{ + /*clear status flag*/ + FLASH->FR |= FLASH_FR_CLEAR; + FLASH_Status status = FLASH_COMPLETE; + + /* Check the parameters */ + assert_param(IS_FLASH_PROGRAM_ADDRESS(Address)); + + FLASH_PrefetchBufferCmd(DISABLE); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + + if (status == FLASH_COMPLETE) + { + //enable function of program firstly + FLASH->WRC |= FLASH_WRC_PG; + + /* proceed to program the data3 */ + *(__IO uint32_t*)Address = (uint32_t)Data0; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + + /* Disable the PG Bit */ + FLASH->WRC &= ~FLASH_WRC_PG; + } + else + { + /* Disable the PG Bit */ + FLASH->WRC &= ~FLASH_WRC_PG; + } + + FLASH_PrefetchBufferCmd(ENABLE); + return status; +} +/** + * @brief Programs a half word at a specified address. + * @note To correctly run this function, the FLASH_Unlock() FLASH_ErasePage() function must be called before. + * @note Call the FLASH_Lock() to disable the flash memory access (recommended + * to protect the FLASH memory against possible unwanted operation) + * @param Address: specifies the address to be programmed,address is the first address of Datax. + * @param Datax: specifies the data to be programmed. + * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG, + * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ +FLASH_Status FLASH_Program_HalfWord(uint32_t Address, uint16_t Data0) +{ + /*clear status flag*/ + FLASH->FR |= FLASH_FR_CLEAR; + FLASH_Status status = FLASH_COMPLETE; + + /* Check the parameters */ + assert_param(IS_FLASH_PROGRAM_ADDRESS(Address)); + + FLASH_PrefetchBufferCmd(DISABLE); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + + if (status == FLASH_COMPLETE) + { + //enable function of program + FLASH->WRC |= FLASH_WRC_PG; + /* proceed to program the data0 */ + *(__IO uint16_t*)Address = (uint16_t)Data0; + + while ((FLASH->FR & FLASH_FR_BSY) != 0); + + /* Disable the PG Bit */ + FLASH->WRC &= ~FLASH_WRC_PG; + } + else + { + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + } + + FLASH_PrefetchBufferCmd(ENABLE); + return status; +} + + +/** + * @brief Programs 1 Byte at a specified address. + * @note To correctly run this function, the FLASH_Unlock() FLASH_ErasePage() function must be called before. + * @note Call the FLASH_Lock() to disable the flash memory access (recommended + * to protect the FLASH memory against possible unwanted operation) + * @param Address: specifies the address to be programmed,address is the first address of Datax. + * @param Datax: specifies the data to be programmed. + * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG, + * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ +FLASH_Status FLASH_Program_Byte(uint32_t Address, uint8_t Data0) +{ + /*clear status flag*/ + FLASH->FR |= FLASH_FR_CLEAR; + FLASH_Status status = FLASH_COMPLETE; + + /* Check the parameters */ + assert_param(IS_FLASH_PROGRAM_ADDRESS(Address)); + + FLASH_PrefetchBufferCmd(DISABLE); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + + if (status == FLASH_COMPLETE) + { + /*enable function of program*/ + FLASH->WRC |= FLASH_WRC_PG; + + /*proceed to program the data3 */ + *(__IO uint8_t*)Address = (uint8_t)Data0; + + while ((FLASH->FR & FLASH_FR_BSY) != 0); + + /* Disable the PG Bit */ + FLASH->WRC &= ~FLASH_WRC_PG; + } + else + { + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + } + + FLASH_PrefetchBufferCmd(ENABLE); + return status; +} + +/** + * @brief Unlocks the option bytes block access. + * @param None + * @retval None + */ +void FLASH_OPBC_Unlock(void) +{ + unsigned int read_data; + + do + { + read_data = FLASH->FR ; + } + /*flash is not busy now*/ + while ((read_data & FLASH_FR_BSY) != 0); + + /*option byte is unlock*/ + if ((FLASH->OPBC & FLASH_OPBC_OPTLOCK) != 0) + { + /* Unlocking the option bytes block access */ + FLASH->OPTKEYR = FLASH_OPTKEY1; + FLASH->OPTKEYR = FLASH_OPTKEY2; + } +} + +/** + * @brief Locks the option bytes block access. + * @param None + * @retval None + */ +void FLASH_OPBC_Lock(void) +{ + /* Set the OPTLOCK Bit to lock the option bytes block access */ + FLASH->OPBC |= FLASH_OPBC_OPTLOCK; +} + + +/** + * @brief Write protects the desired pages + * @note To correctly run this function, the FLASH_OPBC_Unlock() function must be called before. + * @note Call the FLASH_OPBC_lock() to disable the flash control register access and the option after FLASH_OPBC_Unlock + * bytes (recommended to protect the FLASH memory against possible unwanted operation) + * @param WRPR_WRP: specifies the address of the pages to be write protected. + * This parameter can be: + * @arg WRP_PAGE0_31 to WRP_PAGE992_1023 + * @arg WRP_AllPAGES + * @retval FLASH Status: The returned value can be: + * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ +FLASH_Status FLASH_WRPR_EnableWRP(uint32_t WRPR_WRP) +{ + FLASH_Status status = FLASH_COMPLETE; + /* Check the parameters */ + assert_param(IS_WRPR_WRP(WRPR_WRP)); + + FLASH_PrefetchBufferCmd(DISABLE); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + if (status == FLASH_COMPLETE) + { + FLASH->WRPR = WRPR_WRP; + FLASH->OPBC |= FLASH_OPBC_OPTSTRT;//update OPBC reg value + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + if (status != FLASH_TIMEOUT) + { + /* if the program operation is completed, disable the OPTSTART Bit */ + FLASH->OPBC &= ~FLASH_OPBC_OPTSTRT; + } + } + + FLASH_PrefetchBufferCmd(ENABLE); + return status; +} + + +/** + * @brief Enables or disables the read out protection. + * @note To correctly run this function, the FLASH_OPBC_Unlock() function must be called before. + * @note Call the FLASH_OPBC_lock() to disable the flash control register access and the option after FLASH_OPBC_Unlock + * bytes (recommended to protect the FLASH memory against possible unwanted operation) + * @param FLASH_ReadProtection_Level: specifies the read protection level. + * This parameter can be: + * @arg OPBC_RDP_Level_0: Read protection 0 of the memory + * @arg OPBC_RDP_Level_1: Read protection 1 of the memory + * @arg OPBC_RDP_Level_2: Read protection 2 of the memory (Be CAREFUL !! to use protection 2) + * @note When enabling OPBC_RDP level 2 it's no more possible to go back to level 1 or 0 + * @retval FLASH Status: The returned value can be: + * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ +FLASH_Status FLASH_OPBC_RDPConfig(uint8_t OPBC_RDP) +{ + FLASH_Status status = FLASH_COMPLETE; + + /* Check the parameters */ + assert_param(IS_OPBC_RDP(OPBC_RDP)); + + uint32_t opbc_data; + opbc_data = (FLASH->OPBC); + opbc_data &= ~(0xff << 8); + opbc_data |= (OPBC_RDP << 8); + + FLASH_PrefetchBufferCmd(DISABLE); + + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + if (status == FLASH_COMPLETE) + { + FLASH->OPBC = opbc_data | FLASH_OPBC_OPTSTRT ; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + if (status != FLASH_TIMEOUT) + { + /* if the program operation is completed, disable the OPTSTART Bit */ + FLASH->OPBC &= ~FLASH_OPBC_OPTSTRT; + } + } + + FLASH_PrefetchBufferCmd(ENABLE); + return status; +} + + +/** + * @brief Programs the FLASH User Option Byte: IWDG_SW / RST_STOP / RST_STDBY. + * @note To correctly run this function, the FLASH_OPBC_Unlock() function must be called before. + * @note Call the FLASH_OPBC_lock() to disable the flash control register access and the optio after FLASH_OPBC_Unlock + * bytes (recommended to protect the FLASH memory against possible unwanted operation) + * @param OPBC_IWDG: Selects the WDG mode + * This parameter can be one of the following values: + * @arg OPBC_IWDG_SW: Software WDG selected 1 + * @arg OPBC_IWDG_HW: Hardware WDG selected 0 + * @param OPBC_STOP: Reset event when entering STOP mode. + * This parameter can be one of the following values: + * @arg OPBC_STOP_NoRST: No reset generated when entering in STOP + * @arg OPBC_STOP_RST: Reset generated when entering in STOP + * @param OPBC_STDBY: Reset event when entering Standby mode. + * This parameter can be one of the following values: + * @arg OPBC_STDBY_NoRST: No reset generated when entering in STANDBY + * @arg OPBC_STDBY_RST: Reset generated when entering in STANDBY + * @retval FLASH Status: The returned value can be: + * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ +FLASH_Status FLASH_OPBC_UserConfig(uint8_t OPBC_IWDG, uint8_t OPBC_STOP, uint8_t OPBC_STDBY) +{ + FLASH_Status status = FLASH_COMPLETE; + + /* Check the parameters */ + assert_param(IS_OPBC_IWDG_SOURCE(OPBC_IWDG)); + assert_param(IS_OPBC_STOP_SOURCE(OPBC_STOP)); + assert_param(IS_OPBC_STDBY_SOURCE(OPBC_STDBY)); + + FLASH_PrefetchBufferCmd(DISABLE); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + + uint32_t opbc_data; + opbc_data = (FLASH->OPBC); + opbc_data &= ~(0xff); + opbc_data |= OPBC_IWDG | OPBC_STOP | OPBC_STDBY; + + + if (status == FLASH_COMPLETE) + { + FLASH->OPBC = (opbc_data | FLASH_OPBC_OPTSTRT); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + + if (status != FLASH_TIMEOUT) + { + /* If the program operation is completed, disable the OPTPG Bit */ + FLASH->OPBC &= ~FLASH_OPBC_OPTSTRT; + } + } + + FLASH_PrefetchBufferCmd(ENABLE); + /* Return the Option Byte program Status */ + return status; +} + + +/** + * @brief Set the BOR Level. + * @note To correctly run this function, the FLASH_OPBC_Unlock() function must be called before. + * @param BORR_Level specifies the Option Bytes posedge threshold voltage Level. + * This parameter can be one of the following values: + * @arg OPBC_BORR_LEVEL0: Supply threshold voltage 2.1v + * @arg OPBC_BORR_LEVEL1: Supply threshold voltage 2.3v + * @arg OPBC_BORR_LEVEL2: Supply threshold voltage 2.6v + * @arg OPBC_BORR_LEVEL3: Supply threshold voltage 2.9v + * @param BORF_Level specifies the Option Bytes negedge threshold voltage Level. + * This parameter can be one of the following values: * + * @arg OPBC_BORF_LEVEL0: Supply threshold voltage 2.0v + * @arg OPBC_BORF_LEVEL1: Supply threshold voltage 2.2v + * @arg OPBC_BORF_LEVEL2: Supply threshold voltage 2.5v + * @arg OPBC_BORF_LEVEL3: Supply threshold voltage 2.8v + * @param NewState: new state of the configed undervoltage reset :BOR_EN. + * This parameter can be: ENABLE or DISABLE. + * @retval HAL Status + */ +FLASH_Status FLASH_OPBC_BOR_LevelConfig(uint32_t BORR_Level, uint32_t BORF_Level, FunctionalState NewState) +{ + FLASH_Status status = FLASH_COMPLETE; + + /* Check the parameters */ + assert_param(IS_OPBC_BORR_LEVEL(BORR_Level)); + assert_param(IS_OPBC_BORF_LEVEL(BORR_Level)); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + + FLASH_PrefetchBufferCmd(DISABLE); + + uint32_t opbc_data; + opbc_data = (FLASH->OPBC); + opbc_data &= ~(0xff << 16); + opbc_data |= BORR_Level | BORF_Level; + + + if (NewState != DISABLE) + { + if (status == FLASH_COMPLETE) + { + /*enable configed undervoltage reset,config BOR Level,Wait for last operation to be completed*/ + FLASH->OPBC = FLASH_OPBC_BOR_EN | opbc_data | FLASH_OPBC_OPTSTRT; + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + + if (status != FLASH_TIMEOUT) + { + /* If the program operation is completed, disable the OPTSTRT Bit */ + FLASH->OPBC &= ~FLASH_OPBC_OPTSTRT; + } + } + } + else + { + /*disable configed undervoltage reset*/ + FLASH->OPBC &= ~FLASH_OPBC_BOR_EN; + /*update OPBC reg value*/ + FLASH->OPBC = opbc_data | FLASH_OPBC_OPTSTRT; + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + if (status != FLASH_TIMEOUT) + { + /* If the program operation is completed, disable the OPTSTRT Bit */ + FLASH->OPBC &= ~FLASH_OPBC_OPTSTRT; + } + } + + FLASH_PrefetchBufferCmd(ENABLE); + /* Return the Option Byte program Status */ + return status; +} + + + +/** + * @brief Clears the FLASH's pending flags. + * @param FLASH_FLAG: specifies the FLASH flags to clear. + * This parameter can be any combination of the following values: + * @arg FLASH_FLAG_PGERR: FLASH Programming error flag flag + * @arg FLASH_FLAG_WRPERR: FLASH Write protected error flag + * @arg FLASH_FLAG_EOP: FLASH End of Programming flag + * @arg FLASH_FLAG_PGSERR:FLASH Programming sequence error flag + * @arg FLASH_FLAG_OPBERR:user option and factory are not load correctly flag + * @note Can not clear FLASH_FLAG_BSY flag + * @retval None + */ +void FLASH_ClearFlag(uint32_t FLASH_FLAG) +{ + /* Check the parameters */ + assert_param(IS_FLASH_CLEAR_FLAG(FLASH_FLAG)); + + /* Clear the flags( RC_W1 )*/ + FLASH->FR |= FLASH_FLAG; +} + + +/** + * @brief Checks whether the specified FLASH flag is set or not. + * @param FLASH_FLAG: specifies the FLASH flag to check. + * This parameter can be one of the following values: + * @arg FLASH_FLAG_BSY: FLASH write/erase operations in progress flag + * @arg FLASH_FLAG_PGERR: FLASH Programming error flag flag + * @arg FLASH_FLAG_WRPERR: FLASH Write protected error flag + * @arg FLASH_FLAG_EOP: FLASH End of Programming flag + * @arg FLASH_FLAG_PGSERR:FLASH Programming sequence error flag + * @arg FLASH_FLAG_OPBERR:user option and factory are not load correctly flag + * @retval The new state of FLASH_FLAG (SET or RESET). + */ +FlagStatus FLASH_GetFlagStatus(uint32_t FLASH_FLAG) +{ + FlagStatus bitstatus = RESET; + + /* Check the parameters */ + assert_param(IS_FLASH_GET_FLAG(FLASH_FLAG)); + + if ((FLASH->FR & FLASH_FLAG) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + /* Return the new state of FLASH_FLAG (SET or RESET) */ + return bitstatus; +} + + +/** + * @brief Returns the FLASH Write Protection Option Bytes value. + * @param None + * @retval The FLASH Write Protection Option Bytes value + */ +uint32_t FLASH_OPBC_GetWRP(void) +{ + /* Return the FLASH write protection Register value */ + return (uint32_t)(FLASH->WRPR); +} + + +/** + * @brief Checks whether the FLASH Read out Protection Status is set or not. + * @param None + * @retval FLASH ReadOut Protection Status(SET or RESET) + */ +FlagStatus FLASH_OPBC_GetRDP(void) +{ + FlagStatus readstatus = RESET; + uint32_t Temp = ((FLASH -> OPBC) & FLASH_OPBC_RDP_Msk); + if (Temp == (OPBC_RDP_Level_1 << 8) || Temp == (OPBC_RDP_Level_2 << 8)) + { + readstatus = SET; + } + else + { + readstatus = RESET; + } + return readstatus; +} + + +/** + * @brief Enables or disables the specified FLASH interrupts. + * @param FLASH_IT: specifies the FLASH interrupt sources to be enabled or + * disabled. + * This parameter can be any combination of the following values: + * @arg FLASH_IT_EOP: FLASH end of programming Interrupt + * @arg FLASH_IT_ERR: FLASH Error Interrupt + * @param NewState: new state of the flash Interrupt + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void FLASH_ITConfig(uint32_t FLASH_IT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FLASH_IT(FLASH_IT)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the interrupt sources */ + FLASH->WRC |= FLASH_IT; + } + else + { + /* Disable the interrupt sources */ + FLASH->WRC &= ~(uint32_t)FLASH_IT; + } +} + + +/** + * @brief Returns the FLASH Status. + * @param None + * @retval FLASH Status: The returned value can be: + * FLASH_BUSY, FLASH_ERROR_PROGRAM,FLASH_ERROR_PGSERR, FLASH_ERROR_WRP or FLASH_COMPLETE. + */ +FLASH_Status FLASH_GetStatus(void) +{ + FLASH_Status FLASHstatus = FLASH_COMPLETE; + + if ((FLASH->FR & (uint32_t)FLASH_FLAG_BSY) != (uint32_t)0x00) + { + FLASHstatus = FLASH_BUSY; + } + else + { + if ((FLASH->FR & (uint32_t)FLASH_FLAG_WRPERR) != (uint32_t)0x00) + { + FLASHstatus = FLASH_ERROR_WRP; + } + else + { + if ((FLASH->FR & (uint32_t)(FLASH_FLAG_PGERR)) != (uint32_t)0x00) + { + FLASHstatus = FLASH_ERROR_PROGRAM; + } + else + { + if ((FLASH->FR & (uint32_t)(FLASH_FLAG_PGSERR)) != (uint32_t)0x00) + { + FLASHstatus = FLASH_ERROR_PGSERR; + } + else + { + FLASHstatus = FLASH_COMPLETE; + } + } + } + } + /* Return the FLASH Status */ + return FLASHstatus; +} + + +/** + * @brief Waits for a FLASH operation to complete or a TIMEOUT to occur. + * @param Timeout: FLASH programming Timeout + * @retval FLASH Status: The returned value can be: FLASH_BUSY, + * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ +FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout) +{ + FLASH_Status status = FLASH_COMPLETE; + /* Check for the FLASH Status */ + status = FLASH_GetStatus(); + + /* Wait for a FLASH operation to complete or a TIMEOUT to occur */ + while ((status == FLASH_BUSY) && (Timeout != 0x00)) + { + status = FLASH_GetStatus(); + Timeout--; + } + + if (Timeout == 0x00) + { + status = FLASH_TIMEOUT; + } + /* Return the operation status */ + return status; +} + +/** + * @} + */ + +/** + * @} + */ + +/** +* @} +*/ + +/** + * @} + */ + +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_fmc.c b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_fmc.c new file mode 100644 index 00000000000..fe822663ad6 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_fmc.c @@ -0,0 +1,1251 @@ +/** + ****************************************************************************** + * @file ft32f4xx__fmc.c + * @author FMD AE + * @brief This file provides firmware functions to manage the following + * functionalities of the Flexible Memory Controller (FMC) peripheral + * memories: + * + Initialization/de-initialization functions + * + Peripheral Control functions + * + Peripheral State functions + * @version V1.0.0 + * @date 2025-04-16 + ****************************************************************************** + @verbatim + ============================================================================== + ##### FMC peripheral features ##### + ============================================================================== + [..] The Flexible memory controller (FMC) includes following memory controllers: + (+) The NOR/PSRAM memory controller + (+) The NAND memory controller + (+) The Synchronous DRAM (SDRAM) controller + + [..] The FMC functional block makes the interface with synchronous and asynchronous static + memories, SDRAM memories. Its main purposes are: + (+) to translate AHB transactions into the appropriate external device protocol + (+) to meet the access time requirements of the external memory devices + + [..] All external memories share the addresses, data and control signals with the controller. + Each external device is accessed by means of a unique Chip Select. The FMC performs + only one access at a time to an external device. + The main features of the FMC controller are the following: + (+) Interface with static-memory mapped devices including: + (++) Static random access memory (SRAM) + (++) Read-only memory (ROM) + (++) NOR Flash memory/OneNAND Flash memory + (++) PSRAM (4 memory banks) + (++) Two banks of NAND Flash memory with ECC hardware to check up to 8 Kbytes of + data + (+) Interface with synchronous DRAM (SDRAM) memories + (+) Independent Chip Select control for each memory bank + (+) Independent configuration for each memory bank + + @endverbatim + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx_fmc.h" + +/** @defgroup + * @brief FMC driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ + +/** @defgroup FMC_Private_Constants FMC Private Constants + * @{ + */ + +/* ----------------------- FMC registers bit mask --------------------------- */ + +#if defined(FMC_Bank1) +/* --- BCR Register ---*/ +/* BCR register clear mask */ + +/* --- BTR Register ---*/ +/* BTR register clear mask */ +#define BTR_CLEAR_MASK ((uint32_t)(FMC_BTR1_ADDSET | FMC_BTR1_ADDHLD |\ + FMC_BTR1_DATAST | FMC_BTR1_BUSTURN |\ + FMC_BTR1_CLKDIV | FMC_BTR1_DATLAT |\ + FMC_BTR1_ACCMOD)) + +/* --- BWTR Register ---*/ +/* BWTR register clear mask */ +#define BWTR_CLEAR_MASK ((uint32_t)(FMC_BWTR1_ADDSET | FMC_BWTR1_ADDHLD |\ + FMC_BWTR1_DATAST | FMC_BWTR1_BUSTURN |\ + FMC_BWTR1_ACCMOD)) +#endif /* FMC_Bank1 */ + +#if defined(FMC_Bank3) || defined(FMC_Bank2_3) +/* --- PCR Register ---*/ +/* PCR register clear mask */ +#define PCR_CLEAR_MASK ((uint32_t)(FMC_PCR2_PWAITEN | FMC_PCR2_PBKEN | \ + FMC_PCR2_PTYP | FMC_PCR2_PWID | \ + FMC_PCR2_ECCEN | FMC_PCR2_TCLR | \ + FMC_PCR2_TAR | FMC_PCR2_ECCPS)) +/* --- PMEM Register ---*/ +/* PMEM register clear mask */ +#define PMEM_CLEAR_MASK ((uint32_t)(FMC_PMEM2_MEMSET2 | FMC_PMEM2_MEMWAIT2 |\ + FMC_PMEM2_MEMHOLD2 | FMC_PMEM2_MEMHIZ2)) + +/* --- PATT Register ---*/ +/* PATT register clear mask */ +#define PATT_CLEAR_MASK ((uint32_t)(FMC_PATT2_ATTSET2 | FMC_PATT2_ATTWAIT2 |\ + FMC_PATT2_ATTHOLD2 | FMC_PATT2_ATTHIZ2)) + +#endif /* FMC_Bank3) || defined(FMC_Bank2_3 */ + +#if defined(FMC_Bank5_6) +/* --- SDCR Register ---*/ +/* SDCR register clear mask */ +#define SDCR_CLEAR_MASK ((uint32_t)(FMC_SDCR1_NC | FMC_SDCR1_NR | \ + FMC_SDCR1_MWID | FMC_SDCR1_NB | \ + FMC_SDCR1_CAS | FMC_SDCR1_WP | \ + FMC_SDCR1_SDCLK | FMC_SDCR1_RBURST | \ + FMC_SDCR1_RPIPE)) + +/* --- SDTR Register ---*/ +/* SDTR register clear mask */ +#define SDTR_CLEAR_MASK ((uint32_t)(FMC_SDTR1_TMRD | FMC_SDTR1_TXSR | \ + FMC_SDTR1_TRAS | FMC_SDTR1_TRC | \ + FMC_SDTR1_TWR | FMC_SDTR1_TRP | \ + FMC_SDTR1_TRCD)) +#endif /* FMC_Bank5_6 */ + +/** + * @} + */ + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup FMC_Exported_Functions FMC Exported Functions + * @{ + */ + +#if defined(FMC_Bank1) + +/** @defgroup FMC_Exported_Functions_NORSRAM FMC NOR SRAM Exported Functions + * @brief NORSRAM Controller functions + * + @verbatim + ============================================================================== + ##### How to use NORSRAM device driver ##### + ============================================================================== + + [..] + This driver contains a set of APIs to interface with the FMC NORSRAM banks in order + to run the NORSRAM external devices. + + (+) FMC NORSRAM bank reset using the function FMC_NORSRAM_DeInit() + (+) FMC NORSRAM bank control configuration using the function FMC_NORSRAM_Init() + (+) FMC NORSRAM bank timing configuration using the function FMC_NORSRAM_Timing_Init() + (+) FMC NORSRAM bank extended timing configuration using the function + FMC_NORSRAM_Extended_Timing_Init() + (+) FMC NORSRAM bank enable/disable write operation using the functions + FMC_NORSRAM_WriteOperation_Enable()/FMC_NORSRAM_WriteOperation_Disable() + +@endverbatim + * @{ + */ + +/** @defgroup FMC_NORSRAM_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * + @verbatim + ============================================================================== + ##### Initialization and de_initialization functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Initialize and configure the FMC NORSRAM interface + (+) De-initialize the FMC NORSRAM interface + (+) Configure the FMC clock and associated GPIOs + +@endverbatim + * @{ + */ + +/** + * @brief Initialize the FMC_NORSRAM device according to the specified + * control parameters in the FMC_NORSRAM_InitTypeDef + * @param Device Pointer to NORSRAM device instance + * This paramater can be FMC_NORSRAM_DEVICE + * @param Init Pointer to NORSRAM Initialization structure + * @retval None + */ +void FMC_NORSRAM_Init(FMC_NORSRAM_TypeDef *Device, FMC_NORSRAM_InitTypeDef *Init) +{ + uint32_t flashaccess; + uint32_t btcr_reg; + uint32_t mask; + uint32_t tmpreg; + + /* Check the parameters */ + assert_param(IS_FMC_NORSRAM_DEVICE(Device)); + assert_param(IS_FMC_NORSRAM_BANK(Init->NSBank)); + assert_param(IS_FMC_MUX(Init->DataAddressMux)); + assert_param(IS_FMC_MEMORY(Init->MemoryType)); + assert_param(IS_FMC_NORSRAM_MEMORY_WIDTH(Init->MemoryDataWidth)); + assert_param(IS_FMC_BURSTMODE(Init->BurstAccessMode)); + assert_param(IS_FMC_WAIT_POLARITY(Init->WaitSignalPolarity)); + assert_param(IS_FMC_WAIT_SIGNAL_ACTIVE(Init->WaitSignalActive)); + assert_param(IS_FMC_WRITE_OPERATION(Init->WriteOperation)); + assert_param(IS_FMC_WAITE_SIGNAL(Init->WaitSignal)); + assert_param(IS_FMC_EXTENDED_MODE(Init->ExtendedMode)); + assert_param(IS_FMC_ASYNWAIT(Init->AsynchronousWait)); + assert_param(IS_FMC_WRITE_BURST(Init->WriteBurst)); + assert_param(IS_FMC_CONTINOUS_CLOCK(Init->ContinuousClock)); + assert_param(IS_FMC_PAGESIZE(Init->PageSize)); + + /* Disable NORSRAM Device */ + __FMC_NORSRAM_DISABLE(Device, Init->NSBank); + + /* Set NORSRAM device control parameters */ + if (Init->MemoryType == FMC_MEMORY_TYPE_NOR) + { + flashaccess = FMC_NORSRAM_FLASH_ACCESS_ENABLE; + } + else + { + flashaccess = FMC_NORSRAM_FLASH_ACCESS_DISABLE; + } + + btcr_reg = (flashaccess | \ + Init->DataAddressMux | \ + Init->MemoryType | \ + Init->MemoryDataWidth | \ + Init->BurstAccessMode | \ + Init->WaitSignalPolarity | \ + Init->WaitSignalActive | \ + Init->WriteOperation | \ + Init->WaitSignal | \ + Init->ExtendedMode | \ + Init->AsynchronousWait | \ + Init->WriteBurst); + + btcr_reg |= Init->ContinuousClock; + btcr_reg |= Init->PageSize; + + mask = (FMC_BCR1_MBKEN | + FMC_BCR1_MUXEN | + FMC_BCR1_MTYP | + FMC_BCR1_MWID | + FMC_BCR1_FACCEN | + FMC_BCR1_BURSTEN | + FMC_BCR1_WAITPOL | + FMC_BCR1_WAITCFG | + FMC_BCR1_WREN | + FMC_BCR1_WAITEN | + FMC_BCR1_EXTMOD | + FMC_BCR1_ASYNCWAIT | + FMC_BCR1_CBURSTRW); + + mask |= FMC_BCR1_CCLKEN; + mask |= FMC_BCR1_CPSIZE; + + tmpreg = Device->BTCR[Init->NSBank]; + tmpreg &= (uint32_t)~((uint32_t)mask); + tmpreg |= btcr_reg; + + Device->BTCR[Init->NSBank] = tmpreg; + + /* Configure synchronous mode when Continuous clock is enabled for bank2..4 */ + if ((Init->ContinuousClock == FMC_CONTINUOUS_CLOCK_SYNC_ASYNC) && (Init->NSBank != FMC_NORSRAM_BANK1)) + { + tmpreg = Device->BTCR[FMC_NORSRAM_BANK1]; + tmpreg &= (uint32_t)~((uint32_t)FMC_BCR1_CCLKEN); + tmpreg |= Init->ContinuousClock; + + Device->BTCR[FMC_NORSRAM_BANK1] = tmpreg; + } +} + +/** + * @brief DeInitialize the FMC_NORSRAM peripheral + * @param Device Pointer to NORSRAM device instance + * This paramater can be FMC_NORSRAM_DEVICE + * @param ExDevice Pointer to NORSRAM extended mode device instance + * This paramater can be FMC_NORSRAM_EXTENDED_DEVICE + * @param Bank NORSRAM bank number + * This paramater can be one of the following values: + * @arg FMC_NORSRAM_BANK1 + * @arg FMC_NORSRAM_BANK2 + * @arg FMC_NORSRAM_BANK3 + * @arg FMC_NORSRAM_BANK4 + * @retval None + */ +void FMC_NORSRAM_DeInit(FMC_NORSRAM_TypeDef *Device, FMC_NORSRAM_EXTENDED_TypeDef *ExDevice, uint32_t Bank) +{ + /* Check the parameters */ + assert_param(IS_FMC_NORSRAM_DEVICE(Device)); + assert_param(IS_FMC_NORSRAM_EXTENDED_DEVICE(ExDevice)); + assert_param(IS_FMC_NORSRAM_BANK(Bank)); + + /* Disable the FMC_NORSRAM device */ + __FMC_NORSRAM_DISABLE(Device, Bank); + + /* De-initialize the FMC_NORSRAM device */ + /* FMC_NORSRAM_BANK1 */ + if (Bank == FMC_NORSRAM_BANK1) + { + Device->BTCR[Bank] = 0x000030DBU; + } + /* FMC_NORSRAM_BANK2, FMC_NORSRAM_BANK3 or FMC_NORSRAM_BANK4 */ + else + { + Device->BTCR[Bank] = 0x000030D2U; + } + + Device->BTCR[Bank + 1U] = 0x0FFFFFFFU; + ExDevice->BWTR[Bank] = 0x0FFFFFFFU; +} + +/** + * @brief Initialize the FMC_NORSRAM Timing according to the specified + * parameters in the FMC_NORSRAM_TimingTypeDef + * @param Device Pointer to NORSRAM device instance + * This paramater can be FMC_NORSRAM_DEVICE + * @param Timing Pointer to NORSRAM Timing structure + * @param Bank NORSRAM bank number + * This paramater can be one of the following values: + * @arg FMC_NORSRAM_BANK1 + * @arg FMC_NORSRAM_BANK2 + * @arg FMC_NORSRAM_BANK3 + * @arg FMC_NORSRAM_BANK4 + * @retval None + */ +void FMC_NORSRAM_Timing_Init(FMC_NORSRAM_TypeDef *Device, + FMC_NORSRAM_TimingTypeDef *Timing, uint32_t Bank) +{ + uint32_t tmpr; + uint32_t tmpreg; + + /* Check the parameters */ + assert_param(IS_FMC_NORSRAM_DEVICE(Device)); + assert_param(IS_FMC_ADDRESS_SETUP_TIME(Timing->AddressSetupTime)); + assert_param(IS_FMC_ADDRESS_HOLD_TIME(Timing->AddressHoldTime)); + assert_param(IS_FMC_DATASETUP_TIME(Timing->DataSetupTime)); + assert_param(IS_FMC_TURNAROUND_TIME(Timing->BusTurnAroundDuration)); + assert_param(IS_FMC_CLK_DIV(Timing->CLKDivision)); + assert_param(IS_FMC_DATA_LATENCY(Timing->DataLatency)); + assert_param(IS_FMC_ACCESS_MODE(Timing->AccessMode)); + assert_param(IS_FMC_NORSRAM_BANK(Bank)); + + /* Set FMC_NORSRAM device timing parameters */ + tmpreg = Device->BTCR[Bank + 1U]; + tmpreg &= (uint32_t)~((uint32_t)BTR_CLEAR_MASK); + tmpreg |= (Timing->AddressSetupTime | + ((Timing->AddressHoldTime) << FMC_BTR1_ADDHLD_Pos) | + ((Timing->DataSetupTime) << FMC_BTR1_DATAST_Pos) | + (((Timing->BusTurnAroundDuration) - 1U) << FMC_BTR1_BUSTURN_Pos) | + (((Timing->CLKDivision) - 1U) << FMC_BTR1_CLKDIV_Pos) | + (((Timing->DataLatency) - 2U) << FMC_BTR1_DATLAT_Pos) | + (Timing->AccessMode)); + + Device->BTCR[Bank + 1U] = tmpreg; + + /* Configure Clock division value (in NORSRAM bank 1) when continuous clock is enabled */ + if ((Device->BTCR[FMC_NORSRAM_BANK1] & FMC_BCR1_CCLKEN) != 0U) + { + tmpr = (uint32_t)(Device->BTCR[FMC_NORSRAM_BANK1 + 1U] & ~((0x0FU) << FMC_BTR1_CLKDIV_Pos)); + tmpr |= (uint32_t)(((Timing->CLKDivision) - 1U) << FMC_BTR1_CLKDIV_Pos); + + tmpreg = Device->BTCR[FMC_NORSRAM_BANK1 + 1U]; + tmpreg &= (uint32_t)~((uint32_t)FMC_BTR1_CLKDIV); + tmpreg |= tmpr; + + Device->BTCR[FMC_NORSRAM_BANK1 + 1U] = tmpreg; + } +} + +/** + * @brief Initialize the FMC_NORSRAM Extended mode Timing according to the specified + * parameters in the FMC_NORSRAM_TimingTypeDef + * @param Device Pointer to NORSRAM device instance + * This paramater can be FMC_NORSRAM_EXTENDED_DEVICE + * @param Timing Pointer to NORSRAM Timing structure + * @param Bank NORSRAM bank number + * This paramater can be one of the following values: + * @arg FMC_NORSRAM_BANK1 + * @arg FMC_NORSRAM_BANK2 + * @arg FMC_NORSRAM_BANK3 + * @arg FMC_NORSRAM_BANK4 + * @param ExtendedMode FMC Extended Mode + * This parameter can be one of the following values: + * @arg FMC_EXTENDED_MODE_DISABLE + * @arg FMC_EXTENDED_MODE_ENABLE + * @retval None + */ +void FMC_NORSRAM_Extended_Timing_Init(FMC_NORSRAM_EXTENDED_TypeDef *Device, + FMC_NORSRAM_TimingTypeDef *Timing, uint32_t Bank, + uint32_t ExtendedMode) +{ + uint32_t tmpreg; + + /* Check the parameters */ + assert_param(IS_FMC_EXTENDED_MODE(ExtendedMode)); + + /* Set NORSRAM device timing register for write configuration, if extended mode is used */ + if (ExtendedMode == FMC_EXTENDED_MODE_ENABLE) + { + /* Check the parameters */ + assert_param(IS_FMC_NORSRAM_EXTENDED_DEVICE(Device)); + assert_param(IS_FMC_ADDRESS_SETUP_TIME(Timing->AddressSetupTime)); + assert_param(IS_FMC_ADDRESS_HOLD_TIME(Timing->AddressHoldTime)); + assert_param(IS_FMC_DATASETUP_TIME(Timing->DataSetupTime)); + assert_param(IS_FMC_TURNAROUND_TIME(Timing->BusTurnAroundDuration)); + assert_param(IS_FMC_ACCESS_MODE(Timing->AccessMode)); + assert_param(IS_FMC_NORSRAM_BANK(Bank)); + + /* Set NORSRAM device timing register for write configuration, if extended mode is used */ + tmpreg = Device->BWTR[Bank]; + tmpreg &= (uint32_t)~((uint32_t)BWTR_CLEAR_MASK); + tmpreg |= (Timing->AddressSetupTime | + ((Timing->AddressHoldTime) << FMC_BWTR1_ADDHLD_Pos) | + ((Timing->DataSetupTime) << FMC_BWTR1_DATAST_Pos) | + Timing->AccessMode | + (((Timing->BusTurnAroundDuration) - 1U) << FMC_BTR1_BUSTURN_Pos)); + + Device->BWTR[Bank] = tmpreg; + } + else + { + Device->BWTR[Bank] = 0x0FFFFFFFU; + } + +} +/** + * @} + */ + +/** @addtogroup FMC_NORSRAM_Private_Functions_Group2 + * @brief management functions + * +@verbatim + ============================================================================== + ##### FMC_NORSRAM Control functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to control dynamically + the FMC NORSRAM interface. + +@endverbatim + * @{ + */ + +/** + * @brief Enables dynamically FMC_NORSRAM write operation. + * @param Device Pointer to NORSRAM device instance + * This paramater can be FMC_NORSRAM_DEVICE + * @param Bank NORSRAM bank number + * This paramater can be one of the following values: + * @arg FMC_NORSRAM_BANK1 + * @arg FMC_NORSRAM_BANK2 + * @arg FMC_NORSRAM_BANK3 + * @arg FMC_NORSRAM_BANK4 + * @retval None + */ +void FMC_NORSRAM_WriteOperation_Enable(FMC_NORSRAM_TypeDef *Device, uint32_t Bank) +{ + /* Check the parameters */ + assert_param(IS_FMC_NORSRAM_DEVICE(Device)); + assert_param(IS_FMC_NORSRAM_BANK(Bank)); + + /* Enable write operation */ + Device->BTCR[Bank] |= FMC_WRITE_OPERATION_ENABLE; +} + +/** + * @brief Disables dynamically FMC_NORSRAM write operation. + * @param Device Pointer to NORSRAM device instance + * This paramater can be FMC_NORSRAM_DEVICE + * @param Bank NORSRAM bank number + * This paramater can be one of the following values: + * @arg FMC_NORSRAM_BANK1 + * @arg FMC_NORSRAM_BANK2 + * @arg FMC_NORSRAM_BANK3 + * @arg FMC_NORSRAM_BANK4 + * @retval None + */ +void FMC_NORSRAM_WriteOperation_Disable(FMC_NORSRAM_TypeDef *Device, uint32_t Bank) +{ + /* Check the parameters */ + assert_param(IS_FMC_NORSRAM_DEVICE(Device)); + assert_param(IS_FMC_NORSRAM_BANK(Bank)); + + /* Disable write operation */ + Device->BTCR[Bank] &= (uint32_t)~((uint32_t)FMC_WRITE_OPERATION_ENABLE); +} + +/** + * @} + */ + +/** + * @} + */ +#endif /* FMC_Bank1 */ + +#if defined(FMC_Bank2_3) + +/** @defgroup FMC_Exported_Functions_NAND FMC NAND Exported Functions + * @brief NAND Controller functions + * + @verbatim + ============================================================================== + ##### How to use NAND device driver ##### + ============================================================================== + [..] + This driver contains a set of APIs to interface with the FMC NAND banks in order + to run the NAND external devices. + + (+) FMC NAND bank reset using the function FMC_NAND_DeInit() + (+) FMC NAND bank control configuration using the function FMC_NAND_Init() + (+) FMC NAND bank common space timing configuration using the function + FMC_NAND_CommonSpace_Timing_Init() + (+) FMC NAND bank attribute space timing configuration using the function + FMC_NAND_AttributeSpace_Timing_Init() + (+) FMC NAND bank enable/disable ECC correction feature using the functions + FMC_NAND_ECC_Enable()/FMC_NAND_ECC_Disable() + (+) FMC NAND bank get ECC correction code using the function FMC_NAND_GetECC() + +@endverbatim + * @{ + */ + +/** @defgroup FMC_NAND_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * +@verbatim + ============================================================================== + ##### Initialization and de_initialization functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Initialize and configure the FMC NAND interface + (+) De-initialize the FMC NAND interface + (+) Configure the FMC clock and associated GPIOs + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the FMC_NAND device according to the specified + * control parameters in the FMC_NAND_HandleTypeDef + * @param Device Pointer to NAND device instance + * This paramater can be FMC_NAND_DEVICE + * @param Init Pointer to NAND Initialization structure + * @retval None + */ +void FMC_NAND_Init(FMC_NAND_TypeDef *Device, FMC_NAND_InitTypeDef *Init) +{ + uint32_t tmpreg; + + /* Check the parameters */ + assert_param(IS_FMC_NAND_DEVICE(Device)); + assert_param(IS_FMC_NAND_BANK(Init->NandBank)); + assert_param(IS_FMC_WAIT_FEATURE(Init->Waitfeature)); + assert_param(IS_FMC_NAND_MEMORY_WIDTH(Init->MemoryDataWidth)); + assert_param(IS_FMC_ECC_STATE(Init->EccComputation)); + assert_param(IS_FMC_ECCPAGE_SIZE(Init->ECCPageSize)); + assert_param(IS_FMC_TCLR_TIME(Init->TCLRSetupTime)); + assert_param(IS_FMC_TAR_TIME(Init->TARSetupTime)); + + /* Set NAND device control parameters */ + if (Init->NandBank == FMC_NAND_BANK2) + { + /* NAND bank 2 registers configuration */ + tmpreg = Device->PCR2; + tmpreg &= (uint32_t)~((uint32_t)PCR_CLEAR_MASK); + tmpreg |= (Init->Waitfeature | + FMC_PCR_MEMORY_TYPE_NAND | + Init->MemoryDataWidth | + Init->EccComputation | + Init->ECCPageSize | + (((Init->TCLRSetupTime) - 0x1U) << FMC_PCR2_TCLR_Pos) | + (((Init->TARSetupTime) - 0x1U) << FMC_PCR2_TAR_Pos)); + + Device->PCR2 = tmpreg; + } + else + { + /* NAND bank 3 registers configuration */ + tmpreg = Device->PCR3; + tmpreg &= (uint32_t)~((uint32_t)PCR_CLEAR_MASK); + tmpreg |= (Init->Waitfeature | + FMC_PCR_MEMORY_TYPE_NAND | + Init->MemoryDataWidth | + Init->EccComputation | + Init->ECCPageSize | + (((Init->TCLRSetupTime) - 0x1U) << FMC_PCR3_TCLR_Pos) | + (((Init->TARSetupTime) - 0x1U) << FMC_PCR3_TAR_Pos)); + + Device->PCR3 = tmpreg; + } +} + +/** + * @brief Initializes the FMC_NAND Common space Timing according to the specified + * parameters in the FMC_NAND_TimingTypeDef + * @param Device Pointer to NAND device instance + * This paramater can be FMC_NAND_DEVICE + * @param Timing Pointer to NAND timing structure + * @param Bank NAND bank number + * This paramater can be one of the following values: + * @arg FMC_NAND_BANK2 + * @arg FMC_NAND_BANK3 + * @retval None + */ +void FMC_NAND_CommonSpace_Timing_Init(FMC_NAND_TypeDef *Device, + FMC_NAND_TimingTypeDef *Timing, uint32_t Bank) +{ + uint32_t tmpreg; + + /* Check the parameters */ + assert_param(IS_FMC_NAND_DEVICE(Device)); + assert_param(IS_FMC_SETUP_TIME(Timing->SetupTime)); + assert_param(IS_FMC_WAIT_TIME(Timing->WaitSetupTime)); + assert_param(IS_FMC_HOLD_TIME(Timing->HoldSetupTime)); + assert_param(IS_FMC_HIZ_TIME(Timing->HiZSetupTime)); + assert_param(IS_FMC_NAND_BANK(Bank)); + + /* Set FMC_NAND device timing parameters */ + if (Bank == FMC_NAND_BANK2) + { + /* NAND bank 2 registers configuration */ + tmpreg = Device->PMEM2; + tmpreg &= (uint32_t)~((uint32_t)PMEM_CLEAR_MASK); + tmpreg |= (Timing->SetupTime | + ((Timing->WaitSetupTime) << FMC_PMEM2_MEMWAIT2_Pos) | + ((Timing->HoldSetupTime) << FMC_PMEM2_MEMHOLD2_Pos) | + ((Timing->HiZSetupTime) << FMC_PMEM2_MEMHIZ2_Pos)); + + Device->PMEM2 = tmpreg; + } + else + { + /* NAND bank 3 registers configuration */ + tmpreg = Device->PMEM3; + tmpreg &= (uint32_t)~((uint32_t)PMEM_CLEAR_MASK); + tmpreg |= (Timing->SetupTime | + ((Timing->WaitSetupTime) << FMC_PMEM3_MEMWAIT3_Pos) | + ((Timing->HoldSetupTime) << FMC_PMEM3_MEMHOLD3_Pos) | + ((Timing->HiZSetupTime) << FMC_PMEM3_MEMHIZ3_Pos)); + + Device->PMEM3 = tmpreg; + } +} + +/** + * @brief Initializes the FMC_NAND Attribute space Timing according to the specified + * parameters in the FMC_NAND_TimingTypeDef + * @param Device Pointer to NAND device instance + * This paramater can be FMC_NAND_DEVICE + * @param Timing Pointer to NAND timing structure + * @param Bank NAND bank number + * This paramater can be one of the following values: + * @arg FMC_NAND_BANK2 + * @arg FMC_NAND_BANK3 + * @retval None + */ +void FMC_NAND_AttributeSpace_Timing_Init(FMC_NAND_TypeDef *Device, + FMC_NAND_TimingTypeDef *Timing, uint32_t Bank) +{ + uint32_t tmpreg; + + /* Check the parameters */ + assert_param(IS_FMC_NAND_DEVICE(Device)); + assert_param(IS_FMC_SETUP_TIME(Timing->SetupTime)); + assert_param(IS_FMC_WAIT_TIME(Timing->WaitSetupTime)); + assert_param(IS_FMC_HOLD_TIME(Timing->HoldSetupTime)); + assert_param(IS_FMC_HIZ_TIME(Timing->HiZSetupTime)); + assert_param(IS_FMC_NAND_BANK(Bank)); + + /* Set FMC_NAND device timing parameters */ + if (Bank == FMC_NAND_BANK2) + { + /* NAND bank 2 registers configuration */ + tmpreg = Device->PATT2; + tmpreg &= (uint32_t)((uint32_t)PATT_CLEAR_MASK); + tmpreg |= (Timing->SetupTime | + ((Timing->WaitSetupTime) << FMC_PATT2_ATTWAIT2_Pos) | + ((Timing->HoldSetupTime) << FMC_PATT2_ATTHOLD2_Pos) | + ((Timing->HiZSetupTime) << FMC_PATT2_ATTHIZ2_Pos)); + + Device->PATT2 = tmpreg; + } + else + { + /* NAND bank 3 registers configuration */ + tmpreg = Device->PATT3; + tmpreg &= (uint32_t)((uint32_t)PATT_CLEAR_MASK); + tmpreg |= (Timing->SetupTime | + ((Timing->WaitSetupTime) << FMC_PATT3_ATTWAIT3_Pos) | + ((Timing->HoldSetupTime) << FMC_PATT3_ATTHOLD3_Pos) | + ((Timing->HiZSetupTime) << FMC_PATT3_ATTHIZ3_Pos)); + + Device->PATT3 = tmpreg; + } +} + +/** + * @brief DeInitializes the FMC_NAND device + * @param Device Pointer to NAND device instance + * This paramater can be FMC_NAND_DEVICE + * @param Bank NAND bank number + * This paramater can be one of the following values: + * @arg FMC_NAND_BANK2 + * @arg FMC_NAND_BANK3 + * @retval None + */ +void FMC_NAND_DeInit(FMC_NAND_TypeDef *Device, uint32_t Bank) +{ + /* Check the parameters */ + assert_param(IS_FMC_NAND_DEVICE(Device)); + assert_param(IS_FMC_NAND_BANK(Bank)); + + /* Disable the NAND Bank */ + __FMC_NAND_DISABLE(Device, Bank); + + /* De-initialize the NAND Bank */ + if (Bank == FMC_NAND_BANK2) + { + /* Set the FMC_NAND_BANK2 registers to their reset values */ + Device->PCR2 = 0x00000018U; + Device->SR2 = 0x00000040U; + Device->PMEM2 = 0xFCFCFCFCU; + Device->PATT2 = 0xFCFCFCFCU; + } + /* FMC_Bank3_NAND */ + else + { + /* Set the FMC_NAND_BANK3 registers to their reset values */ + Device->PCR3 = 0x00000018U; + Device->SR3 = 0x00000040U; + Device->PMEM3 = 0xFCFCFCFCU; + Device->PATT3 = 0xFCFCFCFCU; + } +} + +/** + * @} + */ + +/** @defgroup FMC_NAND_Group2 Peripheral Control functions + * @brief management functions + * +@verbatim + ============================================================================== + ##### FMC_NAND Control functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to control dynamically + the FMC NAND interface. + +@endverbatim + * @{ + */ + + +/** + * @brief Enables dynamically FMC_NAND ECC feature. + * @param Device Pointer to NAND device instance + * This paramater can be FMC_NAND_DEVICE + * @param Bank NAND bank number + * This paramater can be one of the following values: + * @arg FMC_NAND_BANK2 + * @arg FMC_NAND_BANK3 + * @retval None + */ +void FMC_NAND_ECC_Enable(FMC_NAND_TypeDef *Device, uint32_t Bank) +{ + /* Check the parameters */ + assert_param(IS_FMC_NAND_DEVICE(Device)); + assert_param(IS_FMC_NAND_BANK(Bank)); + + /* Enable ECC feature */ + if (Bank == FMC_NAND_BANK2) + { + Device->PCR2 |= FMC_PCR2_ECCEN; + } + else + { + Device->PCR3 |= FMC_PCR3_ECCEN; + } +} + + +/** + * @brief Disables dynamically FMC_NAND ECC feature. + * @param Device Pointer to NAND device instance + * This paramater can be FMC_NAND_DEVICE + * @param Bank NAND bank number + * This paramater can be one of the following values: + * @arg FMC_NAND_BANK2 + * @arg FMC_NAND_BANK3 + * @retval None + */ +void FMC_NAND_ECC_Disable(FMC_NAND_TypeDef *Device, uint32_t Bank) +{ + /* Check the parameters */ + assert_param(IS_FMC_NAND_DEVICE(Device)); + assert_param(IS_FMC_NAND_BANK(Bank)); + + /* Disable ECC feature */ + if (Bank == FMC_NAND_BANK2) + { + Device->PCR2 &= (uint32_t)~((uint32_t)FMC_PCR2_ECCEN); + } + else + { + Device->PCR3 &= (uint32_t)~((uint32_t)FMC_PCR3_ECCEN); + } +} + +/** + * @brief Disables dynamically FMC_NAND ECC feature. + * @param Device Pointer to NAND device instance + * This paramater can be FMC_NAND_DEVICE + * @param ECCval Pointer to ECC value + * @param Bank NAND bank number + * This paramater can be one of the following values: + * @arg FMC_NAND_BANK2 + * @arg FMC_NAND_BANK3 + * @param Timeout Timeout wait value + * @retval None + */ +void FMC_NAND_GetECC(FMC_NAND_TypeDef *Device, uint32_t *ECCval, uint32_t Bank) +{ + /* Check the parameters */ + assert_param(IS_FMC_NAND_DEVICE(Device)); + assert_param(IS_FMC_NAND_BANK(Bank)); + + /* Wait until FIFO is empty */ + while (__FMC_NAND_GET_FLAG(Device, Bank, FMC_FLAG_FEMPT) == RESET) + { + } + + if (Bank == FMC_NAND_BANK2) + { + /* Get the ECCR2 register value */ + *ECCval = (uint32_t)Device->ECCR2; + } + else + { + /* Get the ECCR3 register value */ + *ECCval = (uint32_t)Device->ECCR3; + } +} + +/** + * @} + */ +#endif /* FMC_Bank2_3 */ + +#if defined(FMC_Bank5_6) + +/** @defgroup FMC_SDRAM + * @brief SDRAM Controller functions + * + @verbatim + ============================================================================== + ##### How to use SDRAM device driver ##### + ============================================================================== + [..] + This driver contains a set of APIs to interface with the FMC SDRAM banks in order + to run the SDRAM external devices. + + (+) FMC SDRAM bank reset using the function FMC_SDRAM_DeInit() + (+) FMC SDRAM bank control configuration using the function FMC_SDRAM_Init() + (+) FMC SDRAM bank timing configuration using the function FMC_SDRAM_Timing_Init() + (+) FMC SDRAM bank enable/disable write operation using the functions + FMC_SDRAM_WriteOperation_Enable()/FMC_SDRAM_WriteOperation_Disable() + (+) FMC SDRAM bank send command using the function FMC_SDRAM_SendCommand() + +@endverbatim + * @{ + */ + +/** @addtogroup FMC_SDRAM_Private_Functions_Group1 + * @brief Initialization and Configuration functions + * +@verbatim + ============================================================================== + ##### Initialization and de_initialization functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Initialize and configure the FMC SDRAM interface + (+) De-initialize the FMC SDRAM interface + (+) Configure the FMC clock and associated GPIOs + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the FMC_SDRAM device according to the specified + * control parameters in the FMC_SDRAM_InitTypeDef + * @param Device Pointer to SDRAM device instance + * This paramater can be FMC_SDRAM_DEVICE + * @param Init Pointer to SDRAM Initialization structure + * @retval None + */ +void FMC_SDRAM_Init(FMC_SDRAM_TypeDef *Device, FMC_SDRAM_InitTypeDef *Init) +{ + uint32_t tmpreg; + + /* Check the parameters */ + assert_param(IS_FMC_SDRAM_DEVICE(Device)); + assert_param(IS_FMC_SDRAM_BANK(Init->SDBank)); + assert_param(IS_FMC_COLUMNBITS_NUMBER(Init->ColumnBitsNumber)); + assert_param(IS_FMC_ROWBITS_NUMBER(Init->RowBitsNumber)); + assert_param(IS_FMC_SDMEMORY_WIDTH(Init->MemoryDataWidth)); + assert_param(IS_FMC_INTERNALBANK_NUMBER(Init->InternalBankNumber)); + assert_param(IS_FMC_CAS_LATENCY(Init->CASLatency)); + assert_param(IS_FMC_WRITE_PROTECTION(Init->WriteProtection)); + assert_param(IS_FMC_SDCLOCK_PERIOD(Init->SDClockPeriod)); + assert_param(IS_FMC_READ_BURST(Init->ReadBurst)); + assert_param(IS_FMC_READPIPE_DELAY(Init->ReadPipeDelay)); + + /* Set SDRAM bank configuration parameters */ + if (Init->SDBank == FMC_SDRAM_BANK1) + { + tmpreg = Device->SDCR[FMC_SDRAM_BANK1]; + tmpreg &= (uint32_t)~((uint32_t)SDCR_CLEAR_MASK); + tmpreg |= (Init->ColumnBitsNumber | + Init->RowBitsNumber | + Init->MemoryDataWidth | + Init->InternalBankNumber | + Init->CASLatency | + Init->WriteProtection | + Init->SDClockPeriod | + Init->ReadBurst | + Init->ReadPipeDelay); + + Device->SDCR[FMC_SDRAM_BANK1] = tmpreg; + } + else /* FMC_Bank2_SDRAM */ + { + tmpreg = Device->SDCR[FMC_SDRAM_BANK1]; + tmpreg &= (uint32_t)~((uint32_t)(FMC_SDCR1_SDCLK | + FMC_SDCR1_RBURST | + FMC_SDCR1_RPIPE)); + tmpreg |= (Init->SDClockPeriod | + Init->ReadBurst | + Init->ReadPipeDelay); + + Device->SDCR[FMC_SDRAM_BANK1] = tmpreg; + + tmpreg = Device->SDCR[FMC_SDRAM_BANK2]; + tmpreg &= (uint32_t)~((uint32_t)SDCR_CLEAR_MASK); + tmpreg |= (Init->ColumnBitsNumber | + Init->RowBitsNumber | + Init->MemoryDataWidth | + Init->InternalBankNumber | + Init->CASLatency | + Init->WriteProtection); + + Device->SDCR[FMC_SDRAM_BANK2] = tmpreg; + } +} + + +/** + * @brief Initializes the FMC_SDRAM device timing according to the specified + * parameters in the FMC_SDRAM_TimingTypeDef + * @param Device Pointer to SDRAM device instance + * This paramater can be FMC_SDRAM_DEVICE + * @param Timing Pointer to SDRAM Timing structure + * @param Bank SDRAM bank number + * This paramater can be one of the following values: + * @arg FMC_SDRAM_BANK1 + * @arg FMC_SDRAM_BANK2 + * @retval None + */ +void FMC_SDRAM_Timing_Init(FMC_SDRAM_TypeDef *Device, + FMC_SDRAM_TimingTypeDef *Timing, uint32_t Bank) +{ + uint32_t tmpreg; + + /* Check the parameters */ + assert_param(IS_FMC_SDRAM_DEVICE(Device)); + assert_param(IS_FMC_LOADTOACTIVE_DELAY(Timing->LoadToActiveDelay)); + assert_param(IS_FMC_EXITSELFREFRESH_DELAY(Timing->ExitSelfRefreshDelay)); + assert_param(IS_FMC_SELFREFRESH_TIME(Timing->SelfRefreshTime)); + assert_param(IS_FMC_ROWCYCLE_DELAY(Timing->RowCycleDelay)); + assert_param(IS_FMC_WRITE_RECOVERY_TIME(Timing->WriteRecoveryTime)); + assert_param(IS_FMC_RP_DELAY(Timing->RPDelay)); + assert_param(IS_FMC_RCD_DELAY(Timing->RCDDelay)); + assert_param(IS_FMC_SDRAM_BANK(Bank)); + + /* Set SDRAM device timing parameters */ + if (Bank == FMC_SDRAM_BANK1) + { + tmpreg = Device->SDTR[FMC_SDRAM_BANK1]; + tmpreg &= (uint32_t)~((uint32_t)SDTR_CLEAR_MASK); + tmpreg |= (((Timing->LoadToActiveDelay) - 1U) | + (((Timing->ExitSelfRefreshDelay) - 1U) << FMC_SDTR1_TXSR_Pos) | + (((Timing->SelfRefreshTime) - 1U) << FMC_SDTR1_TRAS_Pos) | + (((Timing->RowCycleDelay) - 1U) << FMC_SDTR1_TRC_Pos) | + (((Timing->WriteRecoveryTime) - 1U) << FMC_SDTR1_TWR_Pos) | + (((Timing->RPDelay) - 1U) << FMC_SDTR1_TRP_Pos) | + (((Timing->RCDDelay) - 1U) << FMC_SDTR1_TRCD_Pos)); + + Device->SDTR[FMC_SDRAM_BANK1] = tmpreg; + } + else /* FMC_Bank2_SDRAM */ + { + tmpreg = Device->SDTR[FMC_SDRAM_BANK1]; + tmpreg &= (uint32_t)~((uint32_t)(FMC_SDTR1_TRC | + FMC_SDTR1_TRP)); + tmpreg |= ((((Timing->RowCycleDelay) - 1U) << FMC_SDTR1_TRC_Pos) | + (((Timing->RPDelay) - 1U) << FMC_SDTR1_TRP_Pos)); + + Device->SDTR[FMC_SDRAM_BANK1] = tmpreg; + + tmpreg = Device->SDTR[FMC_SDRAM_BANK2]; + tmpreg &= (uint32_t)~((uint32_t)SDTR_CLEAR_MASK); + tmpreg |= (((Timing->LoadToActiveDelay) - 1U) | + (((Timing->ExitSelfRefreshDelay) - 1U) << FMC_SDTR1_TXSR_Pos) | + (((Timing->SelfRefreshTime) - 1U) << FMC_SDTR1_TRAS_Pos) | + (((Timing->WriteRecoveryTime) - 1U) << FMC_SDTR1_TWR_Pos) | + (((Timing->RCDDelay) - 1U) << FMC_SDTR1_TRCD_Pos)); + + Device->SDTR[FMC_SDRAM_BANK2] = tmpreg; + } +} + +/** + * @brief DeInitializes the FMC_SDRAM peripheral + * @param Device Pointer to SDRAM device instance + * This paramater can be FMC_SDRAM_DEVICE + * @param Bank SDRAM bank number + * This paramater can be one of the following values: + * @arg FMC_SDRAM_BANK1 + * @arg FMC_SDRAM_BANK2 + * @retval None + */ +void FMC_SDRAM_DeInit(FMC_SDRAM_TypeDef *Device, uint32_t Bank) +{ + /* Check the parameters */ + assert_param(IS_FMC_SDRAM_DEVICE(Device)); + assert_param(IS_FMC_SDRAM_BANK(Bank)); + + /* De-initialize the SDRAM device */ + Device->SDCR[Bank] = 0x000002D0U; + Device->SDTR[Bank] = 0x0FFFFFFFU; + Device->SDCMR = 0x00000000U; + Device->SDRTR = 0x00000000U; + Device->SDSR = 0x00000000U; +} + +/** + * @} + */ + +/** @addtogroup FMC_SDRAMPrivate_Functions_Group2 + * @brief management functions + * +@verbatim + ============================================================================== + ##### FMC_SDRAM Control functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to control dynamically + the FMC SDRAM interface. + +@endverbatim + * @{ + */ + +/** + * @brief Enables dynamically FMC_SDRAM write protection. + * @param Device Pointer to SDRAM device instance + * This paramater can be FMC_SDRAM_DEVICE + * @param Bank SDRAM bank number + * This paramater can be one of the following values: + * @arg FMC_SDRAM_BANK1 + * @arg FMC_SDRAM_BANK2 + * @retval None + */ +void FMC_SDRAM_WriteProtection_Enable(FMC_SDRAM_TypeDef *Device, uint32_t Bank) +{ + /* Check the parameters */ + assert_param(IS_FMC_SDRAM_DEVICE(Device)); + assert_param(IS_FMC_SDRAM_BANK(Bank)); + + /* Enable write protection */ + Device->SDCR[Bank] |= FMC_SDRAM_WRITE_PROTECTION_ENABLE; +} + +/** + * @brief Disables dynamically FMC_SDRAM write protection. + * @param Device Pointer to SDRAM device instance + * This paramater can be FMC_SDRAM_DEVICE + * @param Bank SDRAM bank number + * This paramater can be one of the following values: + * @arg FMC_SDRAM_BANK1 + * @arg FMC_SDRAM_BANK2 + * @retval None + */ +void FMC_SDRAM_WriteProtection_Disable(FMC_SDRAM_TypeDef *Device, uint32_t Bank) +{ + /* Check the parameters */ + assert_param(IS_FMC_SDRAM_DEVICE(Device)); + assert_param(IS_FMC_SDRAM_BANK(Bank)); + + /* Disable write protection */ + Device->SDCR[Bank] &= (uint32_t)~((uint32_t)FMC_SDRAM_WRITE_PROTECTION_ENABLE); +} + +/** + * @brief Send Command to the FMC SDRAM bank + * @param Device Pointer to SDRAM device instance + * This paramater can be FMC_SDRAM_DEVICE + * @param Command Pointer to SDRAM command structure + * @param Timing Pointer to SDRAM Timing structure + * @param Timeout Timeout wait value + * @retval None + */ +void FMC_SDRAM_SendCommand(FMC_SDRAM_TypeDef *Device, + FMC_SDRAM_CommandTypeDef *Command) +{ + uint32_t tmpreg; + uint32_t tickstart = 0U; + + /* Check the parameters */ + assert_param(IS_FMC_SDRAM_DEVICE(Device)); + assert_param(IS_FMC_COMMAND_MODE(Command->CommandMode)); + assert_param(IS_FMC_COMMAND_TARGET(Command->CommandTarget)); + assert_param(IS_FMC_AUTOREFRESH_NUMBER(Command->AutoRefreshNumber)); + assert_param(IS_FMC_MODE_REGISTER(Command->ModeRegisterDefinition)); + + /* Set command register */ + tmpreg = Device->SDCMR; + tmpreg &= (uint32_t)~((uint32_t)(FMC_SDCMR_MODE | + FMC_SDCMR_CTB2 | + FMC_SDCMR_CTB1 | + FMC_SDCMR_NRFS | + FMC_SDCMR_MRD)); + tmpreg |= ((Command->CommandMode) | + (Command->CommandTarget) | + (((Command->AutoRefreshNumber) - 1U) << FMC_SDCMR_NRFS_Pos) | + ((Command->ModeRegisterDefinition) << FMC_SDCMR_MRD_Pos)); + + Device->SDCMR = tmpreg; + + /* wait until command is send */ + while ((Device->SDSR & FMC_SDSR_BUSY) != 0U) + { + } +} + +/** + * @brief Program the SDRAM Memory Refresh rate. + * @param Device Pointer to SDRAM device instance + * This paramater can be FMC_SDRAM_DEVICE + * @param RefreshRate The SDRAM refresh rate value. + * @retval None + */ +void FMC_SDRAM_ProgramRefreshRate(FMC_SDRAM_TypeDef *Device, uint32_t RefreshRate) +{ + uint32_t tmpreg; + + /* Check the parameters */ + assert_param(IS_FMC_SDRAM_DEVICE(Device)); + assert_param(IS_FMC_REFRESH_RATE(RefreshRate)); + + /* Set the refresh rate in command register */ + tmpreg = Device->SDRTR; + tmpreg &= (uint32_t)~((uint32_t)FMC_SDRTR_COUNT); + tmpreg |= (RefreshRate << FMC_SDRTR_COUNT_Pos); + + Device->SDRTR = tmpreg; +} + +/** + * @brief Set the Number of consecutive SDRAM Memory auto Refresh commands. + * @param Device Pointer to SDRAM device instance + * This paramater can be FMC_SDRAM_DEVICE + * @param AutoRefreshNumber Specifies the auto Refresh number. + * @retval None + */ +void FMC_SDRAM_SetAutoRefreshNumber(FMC_SDRAM_TypeDef *Device, + uint32_t AutoRefreshNumber) +{ + uint32_t tmpreg; + + /* Check the parameters */ + assert_param(IS_FMC_SDRAM_DEVICE(Device)); + assert_param(IS_FMC_AUTOREFRESH_NUMBER(AutoRefreshNumber)); + + /* Set the Auto-refresh number in command register */ + tmpreg = Device->SDCMR; + tmpreg &= (uint32_t)~((uint32_t)FMC_SDCMR_NRFS); + tmpreg |= ((AutoRefreshNumber - 1U) << FMC_SDCMR_NRFS_Pos); + + Device->SDCMR = tmpreg; +} + +/** + * @brief Returns the indicated FMC SDRAM bank mode status. + * @param Device Pointer to SDRAM device instance + * This paramater can be FMC_SDRAM_DEVICE + * @param Bank SDRAM bank number + * This paramater can be one of the following values: + * @arg FMC_SDRAM_BANK1 + * @arg FMC_SDRAM_BANK2 + * @retval The FMC SDRAM bank mode status, could be on of the following values: + * FMC_SDRAM_NORMAL_MODE, FMC_SDRAM_SELF_REFRESH_MODE or + * FMC_SDRAM_POWER_DOWN_MODE. + */ +uint32_t FMC_SDRAM_GetModeStatus(const FMC_SDRAM_TypeDef *Device, uint32_t Bank) +{ + uint32_t tmpreg; + + /* Check the parameters */ + assert_param(IS_FMC_SDRAM_DEVICE(Device)); + assert_param(IS_FMC_SDRAM_BANK(Bank)); + + /* Get the corresponding bank mode */ + if (Bank == FMC_SDRAM_BANK1) + { + tmpreg = (uint32_t)(Device->SDSR & FMC_SDSR_MODES1); + } + else + { + tmpreg = ((uint32_t)(Device->SDSR & FMC_SDSR_MODES2) >> 2U); + } + + /* Return the mode status */ + return tmpreg; +} + +/** + * @} + */ + +/** + * @} + */ + +#endif /* FMC_Bank5_6 */ + +/** + * @} + */ + +/** + * @} + */ +/** + * @} + */ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_gpio.c b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_gpio.c new file mode 100644 index 00000000000..4471271373f --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_gpio.c @@ -0,0 +1,395 @@ +/** + ****************************************************************************** + * @file ft32f4xx_gpio.c + * @author FMD AE + * @brief This file provides firmware functions to manage the following + * functionalities of the GPIO peripheral: + * + Initialization and Configuration functions + * + GPIO Read and Write functions + * + GPIO Alternate functions configuration functions + * @version V1.0.0 + * @date 2025-03-27 + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx_gpio.h" +#include "ft32f4xx_rcc.h" + +/** + * @brief Deinitializes the GPIOx peripheral registers to their default reset + * values. + * @param GPIOx: where x can be (A, B, C, D, E or H) to select the GPIO peripheral. + * @retval None + */ +void GPIO_DeInit(GPIO_TypeDef* GPIOx) +{ + /* Check the parameters */ + assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); + + if (GPIOx == GPIOA) + { + RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOA, ENABLE); + RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOA, DISABLE); + } + else if (GPIOx == GPIOB) + { + RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOB, ENABLE); + RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOB, DISABLE); + } + else if (GPIOx == GPIOC) + { + RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOC, ENABLE); + RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOC, DISABLE); + } + else if (GPIOx == GPIOD) + { + RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOD, ENABLE); + RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOD, DISABLE); + } + else if (GPIOx == GPIOE) + { + RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOE, ENABLE); + RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOE, DISABLE); + } + else if (GPIOx == GPIOH) + { + RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOH, ENABLE); + RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOH, DISABLE); + } +} + +/** + * @brief Initializes the GPIOx peripheral according to the specified + * parameters in the GPIO_InitStruct. + * @param GPIOx: where x can be (A, B, C, D, E or H) to select the GPIO peripheral. + * @param GPIO_InitStruct: pointer to a GPIO_InitTypeDef structure that contains + * the configuration information for the specified GPIO peripheral. + * @retval None + */ +void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct) +{ + uint32_t pinpos = 0x00, pos = 0x00, currentpin = 0x00; + + /* Check the parameters */ + assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); + assert_param(IS_GPIO_PIN(GPIO_InitStruct->GPIO_Pin)); + assert_param(IS_GPIO_MODE(GPIO_InitStruct->GPIO_Mode)); + assert_param(IS_GPIO_PUPD(GPIO_InitStruct->GPIO_PuPd)); + + /*-------------------------- Configure the port pins -----------------------*/ + /*-- GPIO Mode Configuration --*/ + for (pinpos = 0x00; pinpos < 0x10; pinpos++) + { + pos = ((uint32_t)0x01) << pinpos; + + /* Get the port pins position */ + currentpin = (GPIO_InitStruct->GPIO_Pin) & pos; + + if (currentpin == pos) + { + if ((GPIO_InitStruct->GPIO_Mode == GPIO_Mode_OUT) || (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_AF)) + { + /* Check Speed mode parameters */ + assert_param(IS_GPIO_SPEED(GPIO_InitStruct->GPIO_Speed)); + + /* Speed mode configuration */ + GPIOx->OSPEEDR &= ~(GPIO_OSPEEDR_OSPEEDR0 << (pinpos * 2)); + GPIOx->OSPEEDR |= ((uint32_t)(GPIO_InitStruct->GPIO_Speed) << (pinpos * 2)); + + /* Check Output mode parameters */ + assert_param(IS_GPIO_OTYPE(GPIO_InitStruct->GPIO_OType)); + + /* Output mode configuration */ + GPIOx->OTYPER &= ~((GPIO_OTYPER_OT0) << ((uint16_t)pinpos)); + GPIOx->OTYPER |= (uint16_t)(((uint16_t)GPIO_InitStruct->GPIO_OType) << ((uint16_t)pinpos)); + } + + GPIOx->MODER &= ~(GPIO_MODER_MODER0 << (pinpos * 2)); + + GPIOx->MODER |= (((uint32_t)GPIO_InitStruct->GPIO_Mode) << (pinpos * 2)); + + /* Pull-up Pull down resistor configuration */ + GPIOx->PUPDR &= ~(GPIO_PUPDR_PUPDR0 << ((uint16_t)pinpos * 2)); + GPIOx->PUPDR |= (((uint32_t)GPIO_InitStruct->GPIO_PuPd) << (pinpos * 2)); + } + } +} + +/** + * @brief Fills each GPIO_InitStruct member with its default value. + * @param GPIO_InitStruct: pointer to a GPIO_InitTypeDef structure which will + * be initialized. + * @retval None + */ +void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct) +{ + /* Reset GPIO init structure parameters values */ + GPIO_InitStruct->GPIO_Pin = GPIO_Pin_All; + GPIO_InitStruct->GPIO_Mode = GPIO_Mode_AN; + GPIO_InitStruct->GPIO_Speed = GPIO_Speed_Level_0; + GPIO_InitStruct->GPIO_OType = GPIO_OType_PP; + GPIO_InitStruct->GPIO_PuPd = GPIO_PuPd_NOPULL; +} + +/** + * @brief Locks 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 device reset. + * @param GPIOx: where x can be (A, B, C, D, E or H) to select the GPIO peripheral. + * @param GPIO_Pin: specifies the port bit to be written. + * @note This parameter can be GPIO_Pin_x where x can be: + * (0..15) for GPIOA, GPIOB, GPIOC, GPIOD, GPIOE, (0,1) for GPIOH. + * @retval None + */ +void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) +{ + __IO uint32_t tmp = 0x00010000; + + /* Check the parameters */ + assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); + assert_param(IS_GPIO_PIN(GPIO_Pin)); + + tmp |= GPIO_Pin; + /* Set LCKK bit */ + GPIOx->LCKR = tmp; + /* Reset LCKK bit */ + GPIOx->LCKR = GPIO_Pin; + /* Set LCKK bit */ + GPIOx->LCKR = tmp; + /* Read LCKK bit */ + tmp = GPIOx->LCKR; + /* Read LCKK bit */ + tmp = GPIOx->LCKR; +} +/** + * @} + */ + +/** + * @brief Reads the specified input port pin. + * @param GPIOx: where x can be (A, B, C, D, E or H) to select the GPIO peripheral. + + * @param GPIO_Pin: specifies the port bit to read. + * @note This parameter can be GPIO_Pin_x where x can be: + * (0..15) for GPIOA, GPIOB, GPIOC, GPIOD, GPIOE, (0,1) for GPIOH. + * @retval The input port pin value. + */ +uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) +{ + uint8_t bitstatus = 0x00; + + /* Check the parameters */ + assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); + assert_param(IS_GET_GPIO_PIN(GPIO_Pin)); + + if ((GPIOx->IDR & GPIO_Pin) != (uint32_t)Bit_RESET) + { + bitstatus = (uint8_t)Bit_SET; + } + else + { + bitstatus = (uint8_t)Bit_RESET; + } + return bitstatus; +} + +/** + * @brief Reads the specified input port pin. + * @param GPIOx: where x can be (A, B, C, D, E or H) to select the GPIO peripheral. + * @note This parameter can be GPIO_Pin_x where x can be: + * (0..15) for GPIOA, GPIOB, GPIOC, GPIOD, GPIOE, (0,1) for GPIOH. + * @retval The input port pin value. + */ +uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx) +{ + /* Check the parameters */ + assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); + + return ((uint16_t)GPIOx->IDR); +} + +/** + * @brief Reads the specified output data port bit. + * @param GPIOx: where x can be (A, B, C, D, E or H) to select the GPIO peripheral. + * @param GPIO_Pin: Specifies the port bit to read. + * @note This parameter can be GPIO_Pin_x where x can be: + * (0..15) for GPIOA, GPIOB, GPIOC, GPIOD, GPIOE, (0,1) for GPIOH. + * @retval The output port pin value. + */ +uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) +{ + uint8_t bitstatus = 0x00; + + /* Check the parameters */ + assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); + assert_param(IS_GET_GPIO_PIN(GPIO_Pin)); + + if ((GPIOx->ODR & GPIO_Pin) != (uint32_t)Bit_RESET) + { + bitstatus = (uint8_t)Bit_SET; + } + else + { + bitstatus = (uint8_t)Bit_RESET; + } + return bitstatus; +} + +/** + * @brief Reads the specified GPIO output data port. + * @param GPIOx: where x can be (A, B, C, D, E or H) to select the GPIO peripheral. + * @retval GPIO output data port value. + */ +uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx) +{ + /* Check the parameters */ + assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); + + return ((uint16_t)GPIOx->ODR); +} + +/** + * @brief Sets the selected data port bits. + * @param GPIOx: where x can be (A, B, C, D, E or H) to select the GPIO peripheral. + * @param GPIO_Pin: specifies the port bits to be written. + * @note This parameter can be GPIO_Pin_x where x can be: + * (0..15) for GPIOA, GPIOB, GPIOC, GPIOD, GPIOE, (0..1) for GPIOH. + * @retval None + */ +void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) +{ + /* Check the parameters */ + assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); + assert_param(IS_GPIO_PIN(GPIO_Pin)); + + GPIOx->BSRR = GPIO_Pin; +} + +/** + * @brief Clears the selected data port bits. + * @param GPIOx: where x can be (A, B, C, D, E or H) to select the GPIO peripheral. + * @param GPIO_Pin: specifies the port bits to be written. + * @note This parameter can be GPIO_Pin_x where x can be: + * (0..15) for GPIOA, GPIOB, GPIOC, GPIOD, GPIOE, (0..1) for GPIOH. + * @retval None + */ +void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) +{ + /* Check the parameters */ + assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); + assert_param(IS_GPIO_PIN(GPIO_Pin)); + + GPIOx->BSRR = (uint32_t)GPIO_Pin << 16U; +} + +/** + * @brief Sets or clears the selected data port bit. + * @param GPIOx: where x can be (A, B, C, D, E or H) to select the GPIO peripheral. + * @param GPIO_Pin: specifies the port bit to be written. + * @note This parameter can be GPIO_Pin_x where x can be: + * (0..15) for GPIOA, GPIOB, GPIOC, GPIOD, GPIOE, (0,1) for GPIOH. + * @param BitVal: specifies the value to be written to the selected bit. + * This parameter can be one of the BitAction enumeration values: + * @arg Bit_RESET: to clear the port pin + * @arg Bit_SET: to set the port pin + * @retval None + */ +void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal) +{ + /* Check the parameters */ + assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); + assert_param(IS_GET_GPIO_PIN(GPIO_Pin)); + assert_param(IS_GPIO_BIT_ACTION(BitVal)); + + if (BitVal != Bit_RESET) + { + GPIOx->BSRR = GPIO_Pin; + } + else + { + GPIOx->BSRR = (uint32_t)GPIO_Pin << 16U; + } +} + +/** + * @brief Writes data to the specified GPIO data port. + * @param GPIOx: where x can be (A, B, C, D, E or H) to select the GPIO peripheral. + * @param PortVal: specifies the value to be written to the port output data register. + * @retval None + */ +void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal) +{ + /* Check the parameters */ + assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); + + GPIOx->ODR = PortVal; +} + +/** + * @} + */ + + +/** + * @brief Set GPIO port for alternate function. + * @param GPIOx: where x can be (A, B, C, D, E or H) to select the GPIO peripheral. + * @param GPIO_PinSource: specifies the pin for the Alternate function. + * This parameter can be GPIO_PinSourcex where x can be (0..15) for GPIOA, GPIOB, GPIOD, GPIOE + * and (0..12) for GPIOC. + * @param GPIO_AF: selects the pin to used as Alternate function. + * This parameter can be one of the following value: + * @arg GPIO_AF_0: SYS + * @arg GPIO_AF_1: TIM1/2, LPTIM + * @arg GPIO_AF_2: TIM3/4/5 + * @arg GPIO_AF_3: TIM8/9/10/11, CRS + * @arg GPIO_AF_4: I2C1/2/3, SPI3, I2S3 + * @arg GPIO_AF_5: SPI1/2, I2S2 + * @arg GPIO_AF_6: SPI3, I2S2, SDIO + * @arg GPIO_AF_7: USART1/2/3, UART7 + * @arg GPIO_AF_8: UART4/5, LPUART, USART6, COMP1/2/3/4/5/6 + * @arg GPIO_AF_9: CAN1/2/3/4, TIM12/13/14 + * @arg GPIO_AF_10: OTG_FS, QUADSPI + * @arg GPIO_AF_11: ETH, + * @arg GPIO_AF_12: OTH_HS, FMC + * @arg GPIO_AF_13: SSI, SPDIF + * @arg GPIO_AF_14: EPWM, EQEP, ECAP + * @arg GPIO_AF_15: EVENTOUT + * @note The pin should already been configured in Alternate Function mode(AF) + * using GPIO_InitStruct->GPIO_Mode = GPIO_Mode_AF + * @note Refer to the Alternate function mapping table in the device datasheet + * for the detailed mapping of the system and peripherals'alternate + * function I/O pins. + * @retval None + */ +void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF) +{ + uint32_t temp = 0x00; + uint32_t temp_2 = 0x00; + + /* Check the parameters */ + assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); + assert_param(IS_GPIO_PIN_SOURCE(GPIO_PinSource)); + assert_param(IS_GPIO_AF(GPIO_AF)); + + temp = ((uint32_t)(GPIO_AF) << ((uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07) * 4)); + GPIOx->AFR[GPIO_PinSource >> 0x03] &= ~((uint32_t)(0xF << ((uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07)) * 4)); + temp_2 = GPIOx->AFR[GPIO_PinSource >> 0x03] | temp; + GPIOx->AFR[GPIO_PinSource >> 0x03] = temp_2; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT FMD *****END OF FILE*******************/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_hcd_fs.c b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_hcd_fs.c new file mode 100644 index 00000000000..955f7ab8d4c --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_hcd_fs.c @@ -0,0 +1,1173 @@ +/** + ****************************************************************************** + * @file ft32f4xx_hcd_fs.c + * @author FMD XA + * @brief This file provides firmware functions to manage the following + * functionalities of the USB Peripheral Controller: + * + Initialization/de-initialization functions + * + Peripheral Control functions + * + Peripheral State functions + * @version V1.0.0 + * @data 2025-05-28 + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + (#)Declare a HCD_FS_HandleTypeDef handle structure, for example: + HCD_FS_HandleTypeDef hhcd; + + (#)Fill parameters of Init structure in HCD handle + + (#)Call HCD_FS_Init() API to initialize the HCD peripheral (Core, Host core, ...) + + (#)Initialize the HCD low level resources through the HCD_FS_MspInit() API: + (##) Enable the HCD/USB Low Level interface clock using the following macros + (##) Initialize the related GPIO clocks + (##) Configure HCD pin-out + (##) Configure HCD NVIC interrupt + + (#)Associate the Upper USB Host stack to the HCD Driver: + (##) hhcd.pData = phost; + + (#)Enable HCD transmission and reception: + (##) HCD_FS_Start(); + + @endverbatim + */ +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx.h" +#include "ft32f4xx_hcd_fs.h" + + +#ifdef HCD_FS_MODULE_ENABLED +#if defined (USB_OTG_FS) + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ + +static void HCD_FS_EP0_IRQHandler(HCD_FS_HandleTypeDef *hhcd, uint8_t ep_num); +static void HCD_FS_RXEP_IRQHandler(HCD_FS_HandleTypeDef *hhcd, uint8_t ep_num, uint8_t epnum); +static void HCD_FS_TXEP_IRQHandler(HCD_FS_HandleTypeDef *hhcd, uint8_t ep_num, uint8_t epnum); + +/* Exported functions --------------------------------------------------------*/ + +/** + * @brief Initialize the host driver. + * @param hhcd HCD handle + * @retval USB_FS status + */ +USB_FS_StatusTypeDef HCD_FS_Init(HCD_FS_HandleTypeDef *hhcd) +{ + + /* Check the HCD handle allocation */ + if (hhcd == NULL) + { + return USB_FS_ERROR; + } + + if (hhcd->State == HCD_FS_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hhcd->Lock = USB_FS_UNLOCKED; + + + /* Init the low level hardware : GPIO, CLOCK, NVIC... */ + HCD_FS_MspInit(hhcd); + } + + hhcd->State = HCD_FS_STATE_BUSY; + + /* Disable the Interrupts */ + USB_FS_SetUSBInt(0U); + + /* Init the Core (common init.) */ + if (USB_FS_CoreInit() != USB_FS_OK) + { + hhcd->State = HCD_FS_STATE_ERROR; + return USB_FS_ERROR; + } + + /* Init Host */ + if (USB_FS_HostInit(hhcd->Init) != USB_FS_OK) + { + hhcd->State = HCD_FS_STATE_ERROR; + return USB_FS_ERROR; + } + + hhcd->State = HCD_FS_STATE_READY; + hhcd->cur_ep = 0U; + + return USB_FS_OK; +} + +/** + * @brief Initialize a host endpoint. + * @param hhcd HCD handle + * @param epnum Endpoint number. + * This parameter can be a value from 1 to 15 + * @param dev_address Current device address + * This parameter can be a value from 0 to 255 + * @param speed Current device speed. + * This parameter can be one of these values: + * HCD_DEVICE_SPEED_FULL: Full speed mode, + * HCD_DEVICE_SPEED_LOW: Low speed mode + * @param ep_type Endpoint Type. + * This parameter can be one of these values: + * EP_TYPE_CTRL: Control type, + * EP_TYPE_ISOC: Isochronous type, + * EP_TYPE_BULK: Bulk type, + * EP_TYPE_INTR: Interrupt type + * @param mps Max Packet Size. + * @retval USB_FS status + */ +USB_FS_StatusTypeDef HCD_FS_EP_Init(HCD_FS_HandleTypeDef *hhcd, + uint8_t ep_num, + uint8_t epnum, + uint8_t dev_address, + uint8_t speed, + uint8_t ep_type, + uint16_t mps) +{ + USB_FS_StatusTypeDef status; + uint32_t HostCoreSpeed; + uint8_t ep_dir; + uint8_t interval; + + __USB_FS_LOCK(hhcd); + hhcd->cur_ep = ep_num; + + hhcd->ep[ep_num].dev_addr = dev_address; + hhcd->ep[ep_num].ep_type = ep_type; + hhcd->ep[ep_num].ep_num = ep_num; + hhcd->ep[ep_num].epnum = epnum & 0xFU; + + if ((epnum & 0x80U) == 0x80U) + { + hhcd->ep[ep_num].ep_is_in = 1U; + } + else + { + hhcd->ep[ep_num].ep_is_in = 0U; + } + + ep_dir = hhcd->ep[ep_num].ep_is_in; + interval = hhcd->ep[ep_num].interval; + HostCoreSpeed = USB_FS_GetSpeed(); + + hhcd->ep[ep_num].speed = speed; + hhcd->ep[ep_num].max_packet = (uint16_t)mps; + + status = USB_FS_HEP_Init(epnum, + dev_address, + ep_type, + interval, + mps); + __USB_FS_UNLOCK(hhcd); + + return status; +} + +/** + * @brief DeInitialize the host driver. + * @param hhcd HCD handle + * @retval USB_FS status + */ +USB_FS_StatusTypeDef HCD_FS_DeInit(HCD_FS_HandleTypeDef *hhcd) +{ + /* Check the HCD handle allocation */ + if (hhcd == NULL) + { + return USB_FS_ERROR; + } + + hhcd->State = HCD_FS_STATE_BUSY; + + USB_FS_SetUSBInt(0U); + + hhcd->State = HCD_FS_STATE_RESET; + hhcd->cur_ep = 0U; + + /* DeInit the low level hardware: CLOCK, NVIC.*/ + HCD_FS_MspDeInit(hhcd); + + return USB_FS_OK; +} + +/** + * @brief Initialize the HCD MSP. + * @param hhcd HCD handle + * @retval None + */ +void __attribute__((weak)) HCD_FS_MspInit(HCD_FS_HandleTypeDef *hhcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hhcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the PCD_FS_MspInit could be implemented in the user file + */ + + +} + +/** + * @brief DeInitialize the HCD MSP. + * @param hhcd HCD handle + * @retval None + */ +void __attribute__((weak)) HCD_FS_MspDeInit(HCD_FS_HandleTypeDef *hhcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hhcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the PCD_FS_MspDeInit could be implemented in the user file + */ + +} + +/** + * @} + */ + +/** @defgroup HCD_Exported_Functions_Group2 Input and Output operation functions + * @brief HCD IO operation functions + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + [..] This subsection provides a set of functions allowing to manage the USB Host Data + Transfer + +@endverbatim + * @{ + */ + +/** + * @brief Submit a new URB for processing. + * @param hhcd HCD handle + * @param ep_num Channel number. + * This parameter can be a value from 1 to 15 + * @param epnum endpoint number + * @param direction endpoint number. + * This parameter can be one of these values: + * 0 : Output / 1 : Input + * @param ep_type Endpoint Type. + * This parameter can be one of these values: + * EP_TYPE_CTRL: Control type/ + * EP_TYPE_ISOC: Isochronous type/ + * EP_TYPE_BULK: Bulk type/ + * EP_TYPE_INTR: Interrupt type/ + * @param token Endpoint Type. + * This parameter can be one of these values: + * 0: HC_PID_SETUP / 1: HC_PID_DATA1 + * @param pbuff pointer to URB data + * @param length Length of URB data + */ + +void HCD_FS_EP_SubmitRequest(HCD_FS_HandleTypeDef *hhcd, + uint8_t ep_num, uint8_t direction, + uint8_t ep_type, uint8_t token, + uint8_t *pbuff, uint16_t length, + uint8_t ctl_state) +{ + hhcd->cur_ep = ep_num; + hhcd->ep[ep_num].ep_is_in = direction; + hhcd->ep[ep_num].ep_type = ep_type; + + if (token == 0U) + { + hhcd->ep[ep_num].data_pid = EP_PID_SETUP; + } + else + { + hhcd->ep[ep_num].data_pid = EP_PID_DATA1; + } + + /* Manage Data Toggle */ + switch (ep_type) + { + case EP_TYPE_CTRL: + if (token == 1U) /* out send data */ + { + if (direction == 0U) + { + if (length == 0U) + { + /* For Status OUT stage, Length==0, Status Out PID = 1 */ + hhcd->ep[ep_num].toggle_out = 1U; + } + /* Set the Data Toggle bit as per the Flag */ + if (hhcd->ep[ep_num].toggle_out == 0U) + { + /* Put the PID 0 */ + hhcd->ep[ep_num].data_pid = EP_PID_DATA0; + } + else + { + /* Put the PID 1 */ + hhcd->ep[ep_num].data_pid = EP_PID_DATA1; + } + } + else + { + /*...*/ + } + } + break; + + case EP_TYPE_BULK: + if (direction == 0U) + { + /* Set the Data Toggle bit as per the Flag */ + if (hhcd->ep[ep_num].toggle_out == 0U) + { + /* Put the PID 0 */ + hhcd->ep[ep_num].data_pid = EP_PID_DATA0; + } + else + { + /* Put the PID 1 */ + hhcd->ep[ep_num].data_pid = EP_PID_DATA1; + } + } + else + { + if (hhcd->ep[ep_num].toggle_in == 0U) + { + hhcd->ep[ep_num].data_pid = EP_PID_DATA0; + } + else + { + hhcd->ep[ep_num].data_pid = EP_PID_DATA1; + } + } + break; + + case EP_TYPE_INTR: + if (direction == 0U) + { + /* Set the Data Toggle bit as per the Flag */ + if (hhcd->ep[ep_num].toggle_out == 0U) + { + /* Put the PID 0 */ + hhcd->ep[ep_num].data_pid = EP_PID_DATA0; + } + else + { + /* Put the PID 1 */ + hhcd->ep[ep_num].data_pid = EP_PID_DATA1; + } + } + else + { + if (hhcd->ep[ep_num].toggle_in == 0U) + { + hhcd->ep[ep_num].data_pid = EP_PID_DATA0; + } + else + { + hhcd->ep[ep_num].data_pid = EP_PID_DATA1; + } + } + break; + + case EP_TYPE_ISOC: + hhcd->ep[ep_num].data_pid = EP_PID_DATA0; + break; + + default: + break; + } + + hhcd->ep[ep_num].xfer_buff = pbuff; + hhcd->ep[ep_num].xfer_len = length; + hhcd->ep[ep_num].XferSize = 0U; + hhcd->ep[ep_num].urb_state = URB_IDLE; + hhcd->ep[ep_num].xfer_count = 0U; + hhcd->ep[ep_num].ep_num = ep_num; + hhcd->ep[ep_num].state = EP_IDLE; + if (ep_num <= 1U) + { + USB_FS_HEP0_StartXfer(&hhcd->ep[ep_num], ctl_state); + } + else + { + USB_FS_HEP_StartXfer(&hhcd->ep[ep_num]); + } +} + + + +//void HCD_FS_ResetCore(HCD_FS_CoreTypeDef *cP, uint8_t state) +//{ +// HCD_FS_EPTypeDef *eP; +// HCD_FS_CoreTypeDef *cP; +// +// cP->Resetting = 1U; +// cP->OTGState = 0U; +// +// /* Clear all pending Device Interrupts */ +// USB_FS_ClrEPInt(void); +// USB_FS->INTRTX1E = 0U; +// USB_FS->INTRRX1E = 0U; +// +// USB_FS_ClrUSBInt(void); +// USB_FS->INTRUSBE = 0U; +// +// USB_FS_SetAddress(0U); /* clear host address reg */ +// +// USB_FS_RstEP0Regs(void); +// for (i = 0; i < cP->NumEPDefs; i++) +// { +// eP = cP->EPA + i; +// USB_FS_RstEPRegs(eP->BltEP); +// HCD_FS_RstEPVars(eP); +// } +// USB_FS_SetUSBInt((~OTG_FS_INTRUSBE_SOFINTE)); +// USB_FS_SetEPInt(cP->IntEMask); +// USB_FS_ClrUSBInt(void); +// USB_FS_ClrEPInt(void); +// +// +//DBGVAR(DRCDBG_ENUM, "\n\r*ES*=", TRACE_B(state)); +// eP = cP->EPA; +//// MGC_SWOP_Setup(&cP->EP0Setup); /* order bytes for USB output */ +// cP->EP0State = state; +// if (!USB_Submit_URB(cP->EP0URB)) /* 0 on return is good to go */ +// return; +// MGC_Reset_DRC_Core(CRST_ENUM_FAILED, cP->CoreID);/* endpoints get reset*/ +// return; +//} +// +// +// +///* +// * MGC_Reset_EP_IO_Vars used to reset the soft I/O state variables for a +// * DRC endpoint object. +// */ +//void HCD_FS_RstEPVars(HCD_FS_EPTypeDef *eP) +//{ +// eP->IOState = 0; /* TX, no status phase is default */ +// +// if(eP->BltEP) +// { +// eP->URBP = (struct urb *)NULL; +// } +// eP->MaxEPSize = eP->FIFOSize; /* until negotiated differently */ +// eP->FifoRemain = 0; +// eP->BytesRequested = 0; +// eP->BytesProcessed = 0; +// eP->DRCInterval = 0; +// eP->intr_flag = 0; +// eP->TgtEP = 0; +// eP->Allocated = 0; +// eP->LastPacket = 0; +// eP->URBRestart = 0; +// eP->Halted = 0; +// +//} /* MGC_Reset_EP_IO_Vars */ + + + + +/** + * @brief Handle HCD interrupt request. + * @param hhcd HCD handle + * @retval None + */ +void HCD_FS_IRQHandler(HCD_FS_HandleTypeDef *hhcd) +{ + uint32_t i; + uint8_t tx_int; + uint8_t rx_int; + uint32_t reg_int; + + reg_int = USB_FS_ReadInterrupts(); + + tx_int = ((reg_int >> 8) & 0xFU); + rx_int = ((reg_int >> 16) & 0xFU); + + /* Ensure that we are in host mode */ + if ((USB_FS_GetMode() & USB_OTG_MODE_HOST) == USB_OTG_MODE_HOST) + { + /* Avoid spurious interrupt */ + if (reg_int == 0U) + { + return; + } + + /* Handle vbus error Interrupts */ + if ((reg_int & OTG_FS_INTRUSB_VERRINT) == OTG_FS_INTRUSB_VERRINT) + { + HCD_FS_VBusErr_Callback(hhcd); + } + + /* Handle session request Interrupts */ + if ((reg_int & OTG_FS_INTRUSB_SREQINT) == OTG_FS_INTRUSB_SREQINT) + { + HCD_FS_Session_Callback(hhcd); + } + + /* Handle Host Disconnect Interrupts */ + if ((reg_int & OTG_FS_INTRUSB_DISCINT) == OTG_FS_INTRUSB_DISCINT) + { + /* Handle Host Port Disconnect Interrupt */ + HCD_FS_Disconnect_Callback(hhcd); + } + + /* Handle Host Connect Interrupts */ + if ((reg_int & OTG_FS_INTRUSB_CONNINT) == OTG_FS_INTRUSB_CONNINT) + { + /* Handle Host Port Connect Interrupt */ + HCD_FS_Connect_Callback(hhcd); + } + + /* Handle Host SOF Interrupt */ + if ((reg_int & OTG_FS_INTRUSB_SOFINT) == OTG_FS_INTRUSB_SOFINT) + { + HCD_FS_SOF_Callback(hhcd); + } + /* Handle Host babble Interrupt */ + if ((reg_int & OTG_FS_INTRUSB_BABBINT) == OTG_FS_INTRUSB_BABBINT) + { + HCD_FS_Babble_Callback(hhcd); + } + /* Handle resume Interrupt */ + if ((reg_int & OTG_FS_INTRUSB_RESINT) == OTG_FS_INTRUSB_RESINT) + { + HCD_FS_Resume_Callback(hhcd); + } + + if ((tx_int & OTG_FS_INTRTX1_EP0INF) == OTG_FS_INTRTX1_EP0INF) + { + (void)USB_FS_IndexSel(0U); + HCD_FS_EP0_IRQHandler(hhcd, hhcd->cur_ep); + } + + /* Handle Tx endpoint Interrupt */ + for (i = 1U; i < hhcd->Init.endpoints; i++) + { + if (((tx_int >> i) & 0x01U) != 0U) + { + (void)USB_FS_IndexSel((uint8_t)i); + HCD_FS_TXEP_IRQHandler(hhcd, hhcd->cur_ep, (uint8_t)i); + } + } + + /* Handle Rx endpoint Interrupt */ + for (i = 1U; i < hhcd->Init.endpoints; i++) + { + if (((rx_int >> i) & 0x01U) != 0U) + { + (void)USB_FS_IndexSel((uint8_t)i); + HCD_FS_RXEP_IRQHandler(hhcd, hhcd->cur_ep, (uint8_t)i); + } + } + } +} + + +/** + * @brief Handles HCD Wakeup interrupt request. + * @param hhcd HCD handle + * @retval status + */ +void HCD_FS_WKUP_IRQHandler(HCD_FS_HandleTypeDef *hhcd) +{ + UNUSED(hhcd); +} + + +/** + * @brief SOF callback. + * @param hhcd HCD handle + * @retval None + */ +void __attribute__((weak)) HCD_FS_SOF_Callback(HCD_FS_HandleTypeDef *hhcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hhcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the HCD_FS_SOF_Callback could be implemented in the user file + */ +} + +/** + * @brief SOF callback. + * @param hhcd HCD handle + * @retval None + */ +void __attribute__((weak)) HCD_FS_VBusErr_Callback(HCD_FS_HandleTypeDef *hhcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hhcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the HCD_FS_SOF_Callback could be implemented in the user file + */ +} + +/** + * @brief SOF callback. + * @param hhcd HCD handle + * @retval None + */ +void __attribute__((weak)) HCD_FS_Session_Callback(HCD_FS_HandleTypeDef *hhcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hhcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the HCD_FS_SOF_Callback could be implemented in the user file + */ +} + +/** + * @brief SOF callback. + * @param hhcd HCD handle + * @retval None + */ +void __attribute__((weak)) HCD_FS_Babble_Callback(HCD_FS_HandleTypeDef *hhcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hhcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the HCD_FS_SOF_Callback could be implemented in the user file + */ +} + +/** + * @brief SOF callback. + * @param hhcd HCD handle + * @retval None + */ +void __attribute__((weak)) HCD_FS_Resume_Callback(HCD_FS_HandleTypeDef *hhcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hhcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the HCD_FS_SOF_Callback could be implemented in the user file + */ +} + + +/** + * @brief Connection Event callback. + * @param hhcd HCD handle + * @retval None + */ +void __attribute__((weak)) HCD_FS_Connect_Callback(HCD_FS_HandleTypeDef *hhcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hhcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the HCD_FS_Connect_Callback could be implemented in the user file + */ +} + +/** + * @brief Disconnection Event callback. + * @param hhcd HCD handle + * @retval None + */ +void __attribute__((weak)) HCD_FS_Disconnect_Callback(HCD_FS_HandleTypeDef *hhcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hhcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the HCD_FS_Disconnect_Callback could be implemented in the user file + */ +} + +/** + * @brief Notify URB state change callback. + * @param hhcd HCD handle + * @param chnum Channel number. + * This parameter can be a value from 1 to 15 + * @param urb_state: + * This parameter can be one of these values: + * URB_IDLE/ + * URB_DONE/ + * URB_NOTREADY/ + * URB_ERROR/ + * URB_STALL/ + * @retval None + */ +void __attribute__((weak)) HCD_FS_EP_NotifyURBChange_Callback(HCD_FS_HandleTypeDef *hhcd, uint8_t epnum, HCD_FS_URBStateTypeDef urb_state) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hhcd); + UNUSED(epnum); + UNUSED(urb_state); + + /* NOTE : This function should not be modified, when the callback is needed, + the HCD_FS_HC_NotifyURBChange_Callback could be implemented in the user file + */ +} + + +/** + * @} + */ + +/** @defgroup HCD_Exported_Functions_Group3 Peripheral Control functions + * @brief Management functions + * +@verbatim + =============================================================================== + ##### Peripheral Control functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to control the HCD data + transfers. + +@endverbatim + * @{ + */ + +/** + * @brief Start the host driver. + * @param hhcd HCD handle + * @retval USB_FS status + */ +USB_FS_StatusTypeDef HCD_FS_Start(HCD_FS_HandleTypeDef *hhcd) +{ + __USB_FS_LOCK(hhcd); + /* Enable port power */ + USB_FS_DrvSess(1U); + + /* Enable connect interrupt */ + USB_FS_SetUSBInt(OTG_FS_INTRUSBE_CONNINTE | OTG_FS_INTRUSBE_SOFINTE | OTG_FS_INTRUSBE_BABBINTE | OTG_FS_INTRUSBE_DISCINTE | OTG_FS_INTRUSBE_RESINTE); + __USB_FS_UNLOCK(hhcd); + + return USB_FS_OK; +} + +/** + * @brief Stop the host driver. + * @param hhcd HCD handle + * @retval USB_FS status + */ + +USB_FS_StatusTypeDef HCD_FS_Stop(HCD_FS_HandleTypeDef *hhcd) +{ + __USB_FS_LOCK(hhcd); + USB_FS_DrvSess(0U); + __USB_FS_UNLOCK(hhcd); + + return USB_FS_OK; +} + +/** + * @brief Reset the host port. + * @param hhcd HCD handle + * @retval none + */ +void HCD_FS_ResetPort(void) +{ + USB_FS_ResetPort(); +} + +/** + * @} + */ + +/** @defgroup HCD_Exported_Functions_Group4 Peripheral State functions + * @brief Peripheral State functions + * +@verbatim + =============================================================================== + ##### Peripheral State functions ##### + =============================================================================== + [..] + This subsection permits to get in run-time the status of the peripheral + and the data flow. + +@endverbatim + * @{ + */ + +/** + * @brief Return the HCD handle state. + * @param hhcd HCD handle + * @retval HCD state + */ +HCD_FS_StateTypeDef HCD_FS_GetState(HCD_FS_HandleTypeDef *hhcd) +{ + return hhcd->State; +} + +/** + * @brief Return URB state for a channel. + * @param hhcd HCD handle + * @param epnum endpoint number. + * This parameter can be a value from 1 to 15 + * @retval URB state. + * This parameter can be one of these values: + * URB_IDLE/ + * URB_DONE/ + * URB_NOTREADY/ + * URB_ERROR/ + * URB_STALL + */ +HCD_FS_URBStateTypeDef HCD_FS_EP_GetURBState(HCD_FS_HandleTypeDef *hhcd, uint8_t ep_num) +{ + return hhcd->ep[ep_num].urb_state; +} + + +/** + * @brief Return the last host transfer size. + * @param hhcd HCD handle + * @param epnum endpoint number. + * This parameter can be a value from 1 to 15 + * @retval last transfer size in byte + */ +uint32_t HCD_FS_EP_GetXferCount(HCD_FS_HandleTypeDef *hhcd, uint8_t ep_num) +{ + return hhcd->ep[ep_num].xfer_count; +} + +/** + * @brief Return the current endpoint pipe. + * @param hhcd HCD handle + * @param epnum endpoint number. + * This parameter can be a value from 1 to 15 + * @retval host transfer pieps + */ +uint32_t HCD_FS_GetCurrEp(HCD_FS_HandleTypeDef *hhcd) +{ + return hhcd->cur_ep; +} + +/** + * @brief Return the Host Channel state. + * @param hhcd HCD handle + * @param epnum endpoint number. + * This parameter can be a value from 1 to 15 + * @retval host endpoint state + * This parameter can be one of these values: + * EP_IDLE/ + * EP_XFRC/ + * EP_HALTED/ + * EP_NAK/ + * EP_STALL/ + * EP_XACTERR/ + * EP_BBLERR/ + * EP_DATATGLERR + */ +HCD_FS_EPStateTypeDef HCD_FS_EP_GetState(HCD_FS_HandleTypeDef *hhcd, uint8_t ep_num) +{ + return hhcd->ep[ep_num].state; +} + +/** + * @brief Return the current Host frame number. + * @param hhcd HCD handle + * @retval Current Host frame number + */ +uint32_t HCD_FS_GetCurrentFrame(void) +{ + return (USB_FS_GetCurrentFrame()); +} + +/** + * @brief Return the Host enumeration speed. + * @param hhcd HCD handle + * @retval Enumeration speed + */ +uint32_t HCD_FS_GetCurrentSpeed(void) +{ + return (USB_FS_GetSpeed()); +} + + +/** + * @} + */ + +/** @addtogroup HCD_Private_Functions + * @{ + */ + +/** + * @brief Handle Host endpoint0 interrupt requests. + * @param hhcd HCD handle + * @param epnum endpoint number. + * This parameter can be 0 + * @retval none + */ +static void HCD_FS_EP0_IRQHandler(HCD_FS_HandleTypeDef *hhcd, uint8_t epnum) +{ + uint8_t tmpreg; + uint8_t bytecount; + + tmpreg = USB_FS->CSR0; + + if ((tmpreg & OTG_FS_CSR0_NAKTMO) == OTG_FS_CSR0_NAKTMO) + { + hhcd->ep[epnum].ErrCnt = 0U; + hhcd->ep[epnum].state = EP_NAK; + if (hhcd->ep[epnum].ep_is_in == 0U) + { + USB_FS_FlushEp0Fifo(); /* flush fifo to halt transcation*/ + } + else + { + USB_FS->CSR0 &= (~OTG_FS_CSR0_REQPKT); /* clear reqpkt halt transcation */ + } + USB_FS->CSR0 &= (~OTG_FS_CSR0_NAKTMO); + } + else if ((tmpreg & OTG_FS_CSR0_RXSTALL) == OTG_FS_CSR0_RXSTALL) + { + hhcd->ep[epnum].state = EP_STALL; + hhcd->ep[epnum].urb_state = URB_STALL; + if ( hhcd->ep[epnum].ep_is_in == 0U) + { + USB_FS_FlushEp0Fifo(); /* flush fifo to halt transcation*/ + } + else + { + USB_FS->CSR0 &= (~OTG_FS_CSR0_REQPKT); /* clear reqpkt halt transcation */ + } + USB_FS->CSR0 &= (~OTG_FS_CSR0_RXSTALL); + HCD_FS_EP_NotifyURBChange_Callback(hhcd, epnum, hhcd->ep[epnum].urb_state); + } + else if ((tmpreg & OTG_FS_CSR0_ERR) == OTG_FS_CSR0_ERR) + { + hhcd->ep[epnum].state = EP_XACTERR; + hhcd->ep[epnum].urb_state = URB_ERROR; + if ( hhcd->ep[epnum].ep_is_in == 0U) + { + USB_FS_FlushEp0Fifo(); /* flush fifo to halt transcation*/ + } + else + { + USB_FS->CSR0 &= (~OTG_FS_CSR0_REQPKT); /* clear reqpkt halt transcation */ + } + USB_FS->CSR0 &= (~OTG_FS_CSR0_RXSTALL); + HCD_FS_EP_NotifyURBChange_Callback(hhcd, epnum, hhcd->ep[epnum].urb_state); + } + + else if ((tmpreg & OTG_FS_CSR0_RXPKTRDY) == OTG_FS_CSR0_RXPKTRDY) + { + bytecount = USB_FS_Read_Count0(); + hhcd->ep[epnum].toggle_in ^= 1U; + hhcd->ep[epnum].xfer_count = bytecount; + hhcd->ep[epnum].XferSize = hhcd->ep[epnum].XferSize + bytecount ; + hhcd->ep[epnum].ErrCnt = 0U; + if ((bytecount > 0U) && (hhcd->ep[epnum].xfer_buff != (void *)0)) + { + USB_FS_FIFORead(hhcd->ep[epnum].xfer_buff, 0U, bytecount); + } + if (bytecount == 0U) + { + hhcd->ep[epnum].state = EP_XFRC; + hhcd->ep[epnum].urb_state = URB_DONE; + } + else if (bytecount < 0x40) + { + hhcd->ep[epnum].state = EP_XFRC; + hhcd->ep[epnum].urb_state = URB_DONE; + } + else if (hhcd->ep[epnum].XferSize == hhcd->ep[epnum].xfer_len) + { + // if (hhcd->ep[epnum].xfer_len >= 0x40U) + if (bytecount == 0x40U) + { + USB_FS_HEP0_StartXfer(&hhcd->ep[epnum], CTRL_DATA); + } + else + { + hhcd->ep[epnum].state = EP_XFRC; + hhcd->ep[epnum].urb_state = URB_DONE; + } + } + else + { + USB_FS_HEP0_StartXfer(&hhcd->ep[epnum], CTRL_DATA); + } + HCD_FS_EP_NotifyURBChange_Callback(hhcd, epnum, hhcd->ep[epnum].urb_state); + } + else + { + hhcd->ep[epnum].ErrCnt = 0U; + hhcd->ep[epnum].toggle_out ^= 1U; + hhcd->ep[epnum].state = EP_XFRC; + hhcd->ep[epnum].urb_state = URB_DONE; + HCD_FS_EP_NotifyURBChange_Callback(hhcd, epnum, hhcd->ep[epnum].urb_state); + } +} + +/** + * @brief Handle Host endpoint RX interrupt requests. + * @param hhcd HCD handle + * @param epnum endpoint number. + * This parameter can be a value from 1 to 15 + * @retval none + */ +static void HCD_FS_RXEP_IRQHandler(HCD_FS_HandleTypeDef *hhcd, uint8_t ep_num, uint8_t epnum) +{ + uint8_t tmpreg; + uint16_t bytecount; + uint32_t maxpacket; + uint16_t fifo_size; + + tmpreg = USB_FS->RXCSR1; + maxpacket = (USB_FS->RXMAXP) << 3U; + + if ((tmpreg & OTG_FS_RXCSR1_NAKTMO) == OTG_FS_RXCSR1_NAKTMO) + { + hhcd->ep[ep_num].ErrCnt = 0U; + if ( hhcd->ep[epnum].ep_type == EP_TYPE_ISOC) + { + hhcd->ep[ep_num].state = EP_XACTERR; + USB_FS_FlushRxFifo(epnum); /* flush fifo to halt transcation*/ + } + else + { + hhcd->ep[ep_num].state = EP_NAK; + } + USB_FS->RXCSR1 &= (~OTG_FS_RXCSR1_REQPKT); /* clear reqpkt halt transcation */ + USB_FS->RXCSR1 &= (~OTG_FS_RXCSR1_NAKTMO); + } + else if ((tmpreg & OTG_FS_RXCSR1_RXSTALL) == OTG_FS_RXCSR1_RXSTALL) + { + hhcd->ep[ep_num].state = EP_STALL; + USB_FS->RXCSR1 &= (~OTG_FS_RXCSR1_REQPKT); /* clear reqpkt halt transcation */ + USB_FS->RXCSR1 &= (~OTG_FS_RXCSR1_RXSTALL); + } + else if ((tmpreg & OTG_FS_RXCSR1_ERR) == OTG_FS_RXCSR1_ERR) + { + hhcd->ep[ep_num].state = EP_XACTERR; + USB_FS->RXCSR1 &= (~OTG_FS_RXCSR1_REQPKT); /* clear reqpkt halt transcation */ + USB_FS->RXCSR1 &= (~OTG_FS_RXCSR1_RXSTALL); + } + else if ((tmpreg & OTG_FS_RXCSR1_RXPKTRDY) == OTG_FS_RXCSR1_RXPKTRDY) + { + bytecount = USB_FS_Read_RxCount(); + hhcd->ep[ep_num].state = EP_XFRC; + hhcd->ep[ep_num].ErrCnt = 0U; + hhcd->ep[ep_num].toggle_in ^= 1U; + hhcd->ep[ep_num].xfer_count = bytecount; + if ((bytecount > 0U) && (hhcd->ep[ep_num].xfer_buff != (void *)0)) + { + USB_FS_FIFORead(hhcd->ep[ep_num].xfer_buff, epnum, bytecount); + } + if (bytecount == 0U) + { + hhcd->ep[ep_num].state = EP_XFRC; + hhcd->ep[ep_num].urb_state = URB_DONE; + HCD_FS_EP_NotifyURBChange_Callback(hhcd, ep_num, hhcd->ep[ep_num].urb_state); + } + else if (hhcd->ep[ep_num].XferSize == hhcd->ep[ep_num].xfer_len) + { + if (bytecount == maxpacket) + { + USB_FS->RXCSR1 |= OTG_FS_RXCSR1_REQPKT; + } + else + { + hhcd->ep[ep_num].state = EP_XFRC; + hhcd->ep[ep_num].urb_state = URB_DONE; + HCD_FS_EP_NotifyURBChange_Callback(hhcd, epnum, hhcd->ep[ep_num].urb_state); + } + } + else + { + hhcd->ep[ep_num].xfer_len = hhcd->ep[ep_num].xfer_len - maxpacket; + hhcd->ep[ep_num].toggle_out ^= 1U; + USB_FS_HEP_StartXfer(&hhcd->ep[epnum]); + } + USB_FS->RXCSR1 &= ~OTG_FS_RXCSR1_RXPKTRDY; + } + else + { + /*...*/ + } +} + +/** + * @brief Handle Host endpoint TX interrupt requests. + * @param hhcd HCD handle + * @param epnum endpoint number. + * This parameter can be a value from 1 to 15 + * @retval none + */ +static void HCD_FS_TXEP_IRQHandler(HCD_FS_HandleTypeDef *hhcd, uint8_t ep_num, uint8_t epnum) +{ + uint8_t tmpreg; + uint32_t maxpacket; + uint16_t fifo_size; + + tmpreg = USB_FS->TXCSR1; + maxpacket = (USB_FS->TXMAXP) << 3U; + + if ((tmpreg & OTG_FS_TXCSR1_NAKTMO) == OTG_FS_TXCSR1_NAKTMO) + { + hhcd->ep[ep_num].ErrCnt = 0U; + hhcd->ep[ep_num].state = EP_NAK; + (void)USB_FS_FlushTxFifo(epnum); + (void)USB_FS_FlushTxFifo(epnum); /* flush txfifo to halt transcation */ + USB_FS->TXCSR1 &= (~OTG_FS_TXCSR1_NAKTMO); + } + else if ((tmpreg & OTG_FS_TXCSR1_RXSTALL) == OTG_FS_TXCSR1_RXSTALL) + { + hhcd->ep[ep_num].state = EP_STALL; + (void)USB_FS_FlushTxFifo(epnum); + (void)USB_FS_FlushTxFifo(epnum); /* flush txfifo to halt transcation */ + USB_FS->TXCSR1 &= (~OTG_FS_TXCSR1_RXSTALL); + } + else if ((tmpreg & OTG_FS_TXCSR1_ERR) == OTG_FS_TXCSR1_ERR) + { + hhcd->ep[ep_num].state = EP_XACTERR; + (void)USB_FS_FlushTxFifo(epnum); + (void)USB_FS_FlushTxFifo(epnum); /* flush txfifo to halt transcation */ + USB_FS->TXCSR1 &= (~OTG_FS_TXCSR1_RXSTALL); + } + else + { + hhcd->ep[ep_num].ErrCnt = 0U; + if (hhcd->ep[ep_num].xfer_len == hhcd->ep[ep_num].XferSize) + { + if (hhcd->ep[ep_num].xfer_len == maxpacket) + { + hhcd->ep[ep_num].toggle_out ^= 1U; + USB_FS->TXCSR1 = OTG_FS_TXCSR1_TXPKTRDY; + } + else + { + hhcd->ep[ep_num].state = EP_XFRC; + hhcd->ep[ep_num].toggle_out ^= 1U; + hhcd->ep[ep_num].urb_state = URB_DONE; + HCD_FS_EP_NotifyURBChange_Callback(hhcd, ep_num, hhcd->ep[ep_num].urb_state); + } + } + else + { + hhcd->ep[ep_num].xfer_len = hhcd->ep[ep_num].xfer_len - maxpacket; + hhcd->ep[ep_num].toggle_out ^= 1U; + USB_FS_HEP_StartXfer(&hhcd->ep[epnum]); + } + } +} + +/** + * @} + */ + + +#endif /* defined (USB_OTG_FS) */ +#endif /* HCD_FS_MODULE_ENABLED */ + diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_hcd_hs.c b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_hcd_hs.c new file mode 100644 index 00000000000..59ec4f01b57 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_hcd_hs.c @@ -0,0 +1,1573 @@ +/** + ****************************************************************************** + * @file ft32f4xx_hcd_hs.c + * @author FMD XA + * @brief This file provides firmware functions to manage the following + * functionalities of the USB Peripheral Controller: + * + Initialization/de-initialization functions + * + Peripheral Control functions + * + Peripheral State functions + * @version V1.0.0 + * @data 2025-03-26 + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + (#)Declare a HCD_HS_HandleTypeDef handle structure, for example: + HCD_HS_HandleTypeDef hhcd; + + (#)Fill parameters of Init structure in HCD handle + + (#)Call HCD_HS_Init() API to initialize the HCD peripheral (Core, Host core, ...) + + (#)Initialize the HCD low level resources through the HCD_HS_MspInit() API: + (##) Enable the HCD/USB Low Level interface clock using the following macros + (##) Initialize the related GPIO clocks + (##) Configure HCD pin-out + (##) Configure HCD NVIC interrupt + + (#)Associate the Upper USB Host stack to the HCD Driver: + (##) hhcd.pData = phost; + + (#)Enable HCD transmission and reception: + (##) HCD_HS_Start(); + + @endverbatim + */ +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx.h" +#include "ft32f4xx_hcd_hs.h" +#include "ft32f4xx_rcc.h" + + +/** @addtogroup FT32F4xx_DRIVER + * @{ + */ + +#ifdef HCD_MODULE_ENABLED +#if defined (USB_OTG_HS) +/** @defgroup HCD_HS HCD + * @brief HCD HS module driver + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/** @defgroup HCD_HS_Private_Functions HCD Private Functions + * @{ + */ +static void HCD_HS_HC_IN_IRQHandler(HCD_HS_HandleTypeDef *hhcd, uint8_t chnum); +static void HCD_HS_HC_OUT_IRQHandler(HCD_HS_HandleTypeDef *hhcd, uint8_t chnum); +static void HCD_HS_RXQLVL_IRQHandler(HCD_HS_HandleTypeDef *hhcd); +static void HCD_HS_Port_IRQHandler(HCD_HS_HandleTypeDef *hhcd); +/** + * @{ + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup HCD_HS_Exported_Functions HCD Exported Functions + * @{ + */ + +/** @defgroup HCD_HS_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + ##### Initialization and de-initialization functions ##### + =============================================================================== + [..] This section provides functions allowing to: + +@endverbatim + * @{ + */ + +/** + * @brief Initialize the host driver. + * @param hhcd HCD handle + * @retval USB_HS status + */ +USB_HS_StatusTypeDef HCD_HS_Init(HCD_HS_HandleTypeDef *hhcd) +{ + + /* Check the HCD handle allocation */ + if (hhcd == NULL) + { + return USB_HS_ERROR; + } + + if (hhcd->State == HCD_HS_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hhcd->Lock = USB_HS_UNLOCKED; + + + /* Init the low level hardware : GPIO, CLOCK, NVIC... */ + HCD_HS_MspInit(hhcd); + } + + hhcd->State = HCD_HS_STATE_BUSY; + + /* Disable the Interrupts */ + __HCD_HS_DISABLE(); + + /* Init the Core (common init.) */ + if (USB_HS_CoreInit(hhcd->Init) != USB_HS_OK) + { + hhcd->State = HCD_HS_STATE_ERROR; + return USB_HS_ERROR; + } + + /* Init Host */ + if (USB_HS_HostInit(hhcd->Init) != USB_HS_OK) + { + hhcd->State = HCD_HS_STATE_ERROR; + return USB_HS_ERROR; + } + + hhcd->State = HCD_HS_STATE_READY; + + return USB_HS_OK; +} + +/** + * @brief Initialize a host channel. + * @param hhcd HCD handle + * @param ch_num Channel number. + * This parameter can be a value from 1 to 15 + * @param epnum Endpoint number. + * This parameter can be a value from 1 to 15 + * @param dev_address Current device address + * This parameter can be a value from 0 to 255 + * @param speed Current device speed. + * This parameter can be one of these values: + * HCD_DEVICE_SPEED_HIGH: high speed mode, + * HCD_DEVICE_SPEED_FULL: Full speed mode, + * HCD_DEVICE_SPEED_LOW: Low speed mode + * @param ep_type Endpoint Type. + * This parameter can be one of these values: + * EP_TYPE_CTRL: Control type, + * EP_TYPE_ISOC: Isochronous type, + * EP_TYPE_BULK: Bulk type, + * EP_TYPE_INTR: Interrupt type + * @param mps Max Packet Size. + * This parameter can be a value from 0 to32K + * @retval USB_HS status + */ +USB_HS_StatusTypeDef HCD_HS_HC_Init(HCD_HS_HandleTypeDef *hhcd, + uint8_t ch_num, + uint8_t epnum, + uint8_t dev_address, + uint8_t speed, + uint8_t ep_type, + uint16_t mps) +{ + USB_HS_StatusTypeDef status; + uint32_t HostCoreSpeed; + uint32_t HCcharMps = mps; + + __USB_HS_LOCK(hhcd); + hhcd->hc[ch_num].do_ping = 0U; + hhcd->hc[ch_num].dev_addr = dev_address; + hhcd->hc[ch_num].ch_num = ch_num; + hhcd->hc[ch_num].ep_type = ep_type; + hhcd->hc[ch_num].ep_num = epnum & 0x7FU; + + HCD_HS_HC_ClearHubInfo(hhcd, ch_num); + + if ((epnum & 0x80U) == 0x80U) + { + hhcd->hc[ch_num].ep_is_in = 1U; + } + else + { + hhcd->hc[ch_num].ep_is_in = 0U; + } + + HostCoreSpeed = USB_HS_GetHostSpeed(); + + if (ep_type == EP_TYPE_ISOC) + { + /* FS device plugged to HS HUB */ + if ((speed == HCD_DEVICE_SPEED_FULL) && (HostCoreSpeed == HPRT0_PRTSPD_HIGH_SPEED)) + { + if (HCcharMps > ISO_SPLT_MPS) + { + /* ISO Max Packet Size for Split mode */ + HCcharMps = ISO_SPLT_MPS; + } + } + } + + hhcd->hc[ch_num].speed = speed; + hhcd->hc[ch_num].max_packet = (uint16_t)HCcharMps; + + status = USB_HS_HC_Init(ch_num, + epnum, + dev_address, + speed, + ep_type, + (uint16_t)HCcharMps); + __USB_HS_UNLOCK(hhcd); + + return status; +} + +/** + * @brief Halt a host channel. + * @param hhcd HCD handle + * @param ch_num Channel number. + * This parameter can be a value from 1 to 15 + * @retval USB_HS status + */ +USB_HS_StatusTypeDef HCD_HS_HC_Halt(HCD_HS_HandleTypeDef *hhcd, uint8_t ch_num) +{ + USB_HS_StatusTypeDef status = USB_HS_OK; + + __USB_HS_LOCK(hhcd); + (void)USB_HS_HC_Halt(ch_num); + __USB_HS_UNLOCK(hhcd); + + return status; +} + +/** + * @brief DeInitialize the host driver. + * @param hhcd HCD handle + * @retval USB_HS status + */ +USB_HS_StatusTypeDef HCD_HS_DeInit(HCD_HS_HandleTypeDef *hhcd) +{ + /* Check the HCD handle allocation */ + if (hhcd == NULL) + { + return USB_HS_ERROR; + } + + hhcd->State = HCD_HS_STATE_BUSY; + + __HCD_HS_DISABLE(); + + hhcd->State = HCD_HS_STATE_RESET; + + /* DeInit the low level hardware: CLOCK, NVIC.*/ + HCD_HS_MspDeInit(hhcd); + + return USB_HS_OK; +} + +/** + * @brief Initialize the HCD MSP. + * @param hhcd HCD handle + * @retval None + */ +void __attribute__((weak)) HCD_HS_MspInit(HCD_HS_HandleTypeDef *hhcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hhcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the HCD_HS_MspInit could be implemented in the user file + */ + + +} + +/** + * @brief DeInitialize the HCD MSP. + * @param hhcd HCD handle + * @retval None + */ +void __attribute__((weak)) HCD_HS_MspDeInit(HCD_HS_HandleTypeDef *hhcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hhcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the HCD_HS_MspDeInit could be implemented in the user file + */ + +} + +/** + * @} + */ + +/** @defgroup HCD_Exported_Functions_Group2 Input and Output operation functions + * @brief HCD IO operation functions + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + [..] This subsection provides a set of functions allowing to manage the USB Host Data + Transfer + +@endverbatim + * @{ + */ + +/** + * @brief Submit a new URB for processing. + * @param hhcd HCD handle + * @param ch_num Channel number. + * This parameter can be a value from 1 to 15 + * @param direction Channel number. + * This parameter can be one of these values: + * 0 : Output / 1 : Input + * @param ep_type Endpoint Type. + * This parameter can be one of these values: + * EP_TYPE_CTRL: Control type/ + * EP_TYPE_ISOC: Isochronous type/ + * EP_TYPE_BULK: Bulk type/ + * EP_TYPE_INTR: Interrupt type/ + * @param token Endpoint Type. + * This parameter can be one of these values: + * 0: HC_PID_SETUP / 1: HC_PID_DATA1 + * @param pbuff pointer to URB data + * @param length Length of URB data + * @param do_ping activate do ping protocol (for high speed only). + * This parameter can be one of these values: + * 0 : do ping inactive / 1 : do ping active + */ +void HCD_HS_HC_SubmitRequest(HCD_HS_HandleTypeDef *hhcd, + uint8_t ch_num, + uint8_t direction, + uint8_t ep_type, + uint8_t token, + uint8_t *pbuff, + uint16_t length, + uint8_t do_ping) +{ + hhcd->hc[ch_num].ep_is_in = direction; + hhcd->hc[ch_num].ep_type = ep_type; + + if (token == 0U) + { + hhcd->hc[ch_num].data_pid = HC_PID_SETUP; + hhcd->hc[ch_num].do_ping = do_ping; + } + else + { + hhcd->hc[ch_num].data_pid = HC_PID_DATA1; + } + + /* Manage Data Toggle */ + switch (ep_type) + { + case EP_TYPE_CTRL: + if (token == 1U) /* out send data */ + { + if (direction == 0U) + { + if (length == 0U) + { + /* For Status OUT stage, Length==0, Status Out PID = 1 */ + hhcd->hc[ch_num].toggle_out = 1U; + } + /* Set the Data Toggle bit as per the Flag */ + if (hhcd->hc[ch_num].toggle_out == 0U) + { + /* Put the PID 0 */ + hhcd->hc[ch_num].data_pid = HC_PID_DATA0; + } + else + { + /* Put the PID 1 */ + hhcd->hc[ch_num].data_pid = HC_PID_DATA1; + } + } + else + { + if (hhcd->hc[ch_num].do_ssplit == 1U) + { + if (hhcd->hc[ch_num].toggle_in == 0U) + { + hhcd->hc[ch_num].data_pid = HC_PID_DATA0; + } + else + { + hhcd->hc[ch_num].data_pid = HC_PID_DATA1; + } + } + } + } + break; + + case EP_TYPE_BULK: + if (direction == 0U) + { + /* Set the Data Toggle bit as per the Flag */ + if (hhcd->hc[ch_num].toggle_out == 0U) + { + /* Put the PID 0 */ + hhcd->hc[ch_num].data_pid = HC_PID_DATA0; + } + else + { + /* Put the PID 1 */ + hhcd->hc[ch_num].data_pid = HC_PID_DATA1; + } + } + else + { + if (hhcd->hc[ch_num].toggle_in == 0U) + { + hhcd->hc[ch_num].data_pid = HC_PID_DATA0; + } + else + { + hhcd->hc[ch_num].data_pid = HC_PID_DATA1; + } + } + + break; + + case EP_TYPE_INTR: + if (direction == 0U) + { + /* Set the Data Toggle bit as per the Flag */ + if (hhcd->hc[ch_num].toggle_out == 0U) + { + /* Put the PID 0 */ + hhcd->hc[ch_num].data_pid = HC_PID_DATA0; + } + else + { + /* Put the PID 1 */ + hhcd->hc[ch_num].data_pid = HC_PID_DATA1; + } + } + else + { + if (hhcd->hc[ch_num].toggle_in == 0U) + { + hhcd->hc[ch_num].data_pid = HC_PID_DATA0; + } + else + { + hhcd->hc[ch_num].data_pid = HC_PID_DATA1; + } + } + break; + + case EP_TYPE_ISOC: + hhcd->hc[ch_num].data_pid = HC_PID_DATA0; + break; + + default: + break; + } + + hhcd->hc[ch_num].xfer_buff = pbuff; + hhcd->hc[ch_num].xfer_len = length; + hhcd->hc[ch_num].urb_state = URB_IDLE; + hhcd->hc[ch_num].xfer_count = 0U; + hhcd->hc[ch_num].ch_num = ch_num; + hhcd->hc[ch_num].state = HC_IDLE; + + USB_HS_HC_StartXfer(&hhcd->hc[ch_num], (uint8_t)hhcd->Init.dma_enable); +} + +/** + * @brief Handle HCD interrupt request. + * @param hhcd HCD handle + * @retval None + */ +void HCD_HS_IRQHandler(HCD_HS_HandleTypeDef *hhcd) +{ + uint32_t i; + uint32_t interrupt; + + /* Ensure that we are in device mode */ + if (USB_HS_GetMode() == USB_OTG_MODE_HOST) + { + /* Avoid spurious interrupt */ + if (__HCD_HS_IS_INVALID_INTERRUPT()) + { + return; + } + + if (__HCD_HS_GET_FLAG(OTG_HS_GINTSTS_IPXFR_INCOMPISOOUT)) + { + /* Incorrect mode, acknowledge the interrupt */ + __HCD_HS_CLEAR_FLAG(OTG_HS_GINTSTS_IPXFR_INCOMPISOOUT); + } + + if (__HCD_HS_GET_FLAG(OTG_HS_GINTSTS_IISOIXFR)) + { + /* Incorrect mode, acknowledge the interrupt */ + __HCD_HS_CLEAR_FLAG(OTG_HS_GINTSTS_IISOIXFR); + } + + if (__HCD_HS_GET_FLAG(OTG_HS_GINTSTS_PTXFE)) + { + /* Incorrect mode, acknowledge the interrupt */ + __HCD_HS_CLEAR_FLAG(OTG_HS_GINTSTS_PTXFE); + } + + if (__HCD_HS_GET_FLAG(OTG_HS_GINTSTS_MMIS)) + { + /* Incorrect mode, acknowledge the interrupt */ + __HCD_HS_CLEAR_FLAG(OTG_HS_GINTSTS_MMIS); + } + + /* Handle Host Disconnect Interrupts */ + if (__HCD_HS_GET_FLAG(OTG_HS_GINTSTS_DISCINT)) + { + __HCD_HS_CLEAR_FLAG(OTG_HS_GINTSTS_DISCINT); + + if ((USB_HS_HPRT0 & OTG_HS_HPRT_PCSTS) == 0U) + { + /* Handle Host Port Disconnect Interrupt */ + HCD_HS_Disconnect_Callback(hhcd); + + } + } + + /* Handle Host Port Interrupts */ + if (__HCD_HS_GET_FLAG(OTG_HS_GINTSTS_HPRTINT)) + { + HCD_HS_Port_IRQHandler(hhcd); + } + + /* Handle Host SOF Interrupt */ + if (__HCD_HS_GET_FLAG(OTG_HS_GINTSTS_SOF)) + { + HCD_HS_SOF_Callback(hhcd); + + __HCD_HS_CLEAR_FLAG(OTG_HS_GINTSTS_SOF); + } + + /* Handle Host channel Interrupt */ + if (__HCD_HS_GET_FLAG(OTG_HS_GINTSTS_HCINT)) + { + interrupt = USB_HS_HC_ReadInterrupt(); + for (i = 0U; i < hhcd->Init.Host_channels; i++) + { + if ((interrupt & (1UL << (i & 0xFU))) != 0U) + { + if ((USB_HS_HC(i)->HCCHAR & OTG_HS_HCCHAR_EPDIR) == OTG_HS_HCCHAR_EPDIR) + { + HCD_HS_HC_IN_IRQHandler(hhcd, (uint8_t)i); + } + else + { + HCD_HS_HC_OUT_IRQHandler(hhcd, (uint8_t)i); + } + } + } + __HCD_HS_CLEAR_FLAG(OTG_HS_GINTSTS_HCINT); + } + + /* Handle Rx Queue Level Interrupts */ + if ((__HCD_HS_GET_FLAG(OTG_HS_GINTSTS_RXFLVL)) != 0U) + { + USB_HS_MASK_INTERRUPT(OTG_HS_GINTSTS_RXFLVL); + + HCD_HS_RXQLVL_IRQHandler(hhcd); + + USB_HS_UNMASK_INTERRUPT(OTG_HS_GINTSTS_RXFLVL); + } + } +} + + +/** + * @brief Handles HCD Wakeup interrupt request. + * @param hhcd HCD handle + * @retval status + */ +void HCD_HS_WKUP_IRQHandler(HCD_HS_HandleTypeDef *hhcd) +{ + UNUSED(hhcd); +} + + +/** + * @brief SOF callback. + * @param hhcd HCD handle + * @retval None + */ +__attribute__((weak)) void HCD_HS_SOF_Callback(HCD_HS_HandleTypeDef *hhcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hhcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the HCD_HS_SOF_Callback could be implemented in the user file + */ +} + +/** + * @brief Connection Event callback. + * @param hhcd HCD handle + * @retval None + */ +void __attribute__((weak)) HCD_HS_Connect_Callback(HCD_HS_HandleTypeDef *hhcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hhcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the HCD_HS_Connect_Callback could be implemented in the user file + */ +} + +/** + * @brief Disconnection Event callback. + * @param hhcd HCD handle + * @retval None + */ +void __attribute__((weak)) HCD_HS_Disconnect_Callback(HCD_HS_HandleTypeDef *hhcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hhcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the HCD_HS_Disconnect_Callback could be implemented in the user file + */ +} + +/** + * @brief Port Enabled Event callback. + * @param hhcd HCD handle + * @retval None + */ +void __attribute__((weak)) HCD_HS_PortEnabled_Callback(HCD_HS_HandleTypeDef *hhcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hhcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the HCD_HS_Disconnect_Callback could be implemented in the user file + */ +} + +/** + * @brief Port Disabled Event callback. + * @param hhcd HCD handle + * @retval None + */ +void __attribute__((weak)) HCD_HS_PortDisabled_Callback(HCD_HS_HandleTypeDef *hhcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hhcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the HCD_HS_Disconnect_Callback could be implemented in the user file + */ +} + + +/** + * @brief Notify URB state change callback. + * @param hhcd HCD handle + * @param chnum Channel number. + * This parameter can be a value from 1 to 15 + * @param urb_state: + * This parameter can be one of these values: + * URB_IDLE/ + * URB_DONE/ + * URB_NOTREADY/ + * URB_NYET/ + * URB_ERROR/ + * URB_STALL/ + * @retval None + */ +void __attribute__((weak)) HCD_HS_HC_NotifyURBChange_Callback(HCD_HS_HandleTypeDef *hhcd, uint8_t chnum, HCD_HS_URBStateTypeDef urb_state) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hhcd); + UNUSED(chnum); + UNUSED(urb_state); + + /* NOTE : This function should not be modified, when the callback is needed, + the HCD_HS_HC_NotifyURBChange_Callback could be implemented in the user file + */ +} + + +/** + * @} + */ + +/** @defgroup HCD_Exported_Functions_Group3 Peripheral Control functions + * @brief Management functions + * +@verbatim + =============================================================================== + ##### Peripheral Control functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to control the HCD data + transfers. + +@endverbatim + * @{ + */ + +/** + * @brief Start the host driver. + * @param hhcd HCD handle + * @retval USB_HS status + */ +USB_HS_StatusTypeDef HCD_HS_Start(HCD_HS_HandleTypeDef *hhcd) +{ + __USB_HS_LOCK(hhcd); + /* Enable port power */ + USB_HS_DriveVbus(1U); + + /* Enable global interrupt */ + __HCD_HS_ENABLE(); + __USB_HS_UNLOCK(hhcd); + + return USB_HS_OK; +} + +/** + * @brief Stop the host driver. + * @param hhcd HCD handle + * @retval USB_HS status + */ + +USB_HS_StatusTypeDef HCD_HS_Stop(HCD_HS_HandleTypeDef *hhcd) +{ + __USB_HS_LOCK(hhcd); + (void)USB_HS_StopHost(); + __USB_HS_UNLOCK(hhcd); + + return USB_HS_OK; +} + +/** + * @brief Reset the host port. + * @param hhcd HCD handle + * @retval none + */ +void HCD_HS_ResetPort(void) +{ + USB_HS_ResetPort(); +} + +/** + * @} + */ + +/** @defgroup HCD_Exported_Functions_Group4 Peripheral State functions + * @brief Peripheral State functions + * +@verbatim + =============================================================================== + ##### Peripheral State functions ##### + =============================================================================== + [..] + This subsection permits to get in run-time the status of the peripheral + and the data flow. + +@endverbatim + * @{ + */ + +/** + * @brief Return the HCD handle state. + * @param hhcd HCD handle + * @retval HCD state + */ +HCD_HS_StateTypeDef HCD_HS_GetState(HCD_HS_HandleTypeDef *hhcd) +{ + return hhcd->State; +} + +/** + * @brief Return URB state for a channel. + * @param hhcd HCD handle + * @param chnum Channel number. + * This parameter can be a value from 1 to 15 + * @retval URB state. + * This parameter can be one of these values: + * URB_IDLE + * URB_DONE + * URB_NOTREADY + * URB_NYET + * URB_ERROR + * URB_STALL + */ +HCD_HS_URBStateTypeDef HCD_HS_HC_GetURBState(HCD_HS_HandleTypeDef *hhcd, uint8_t chnum) +{ + return hhcd->hc[chnum].urb_state; +} + + +/** + * @brief Return the last host transfer size. + * @param hhcd HCD handle + * @param chnum Channel number. + * This parameter can be a value from 1 to 15 + * @retval last transfer size in byte + */ +uint32_t HCD_HS_HC_GetXferCount(HCD_HS_HandleTypeDef *hhcd, uint8_t chnum) +{ + return hhcd->hc[chnum].xfer_count; +} + +/** + * @brief Return the Host Channel state. + * @param hhcd HCD handle + * @param chnum Channel number. + * This parameter can be a value from 1 to 15 + * @retval Host channel state + * This parameter can be one of these values: + * HC_IDLE/ + * HC_XFRC/ + * HC_HALTED/ + * HC_NYET/ + * HC_NAK/ + * HC_STALL/ + * HC_XACTERR/ + * HC_BBLERR/ + * HC_DATATGLERR + */ +HCD_HS_HCStateTypeDef HCD_HS_HC_GetState(HCD_HS_HandleTypeDef *hhcd, uint8_t chnum) +{ + return hhcd->hc[chnum].state; +} + +/** + * @brief Return the current Host frame number. + * @param hhcd HCD handle + * @retval Current Host frame number + */ +uint32_t HCD_HS_GetCurrentFrame() +{ + return (USB_HS_GetCurrentFrame()); +} + +/** + * @brief Return the Host enumeration speed. + * @param hhcd HCD handle + * @retval Enumeration speed + */ +uint32_t HCD_HS_GetCurrentSpeed() +{ + return (USB_HS_GetHostSpeed()); +} + +/** + * @brief Set host channel Hub information + * @param hhcd HCD handle + * @param ch_num Channel number. + * This parameter can be a value from 1 to 15 + * @param addr Hub address + * @param PortNbr Hub port number + * @retval none + */ +void HCD_HS_HC_SetHubInfo(HCD_HS_HandleTypeDef *hhcd, uint8_t ch_num, uint8_t addr, uint8_t PortNbr) +{ + uint32_t HostCoreSpeed = USB_HS_GetHostSpeed(); + + /* LS/FS device plugged to HS HUB */ + if ((hhcd->hc[ch_num].speed != HCD_DEVICE_SPEED_HIGH) && (HostCoreSpeed == HPRT0_PRTSPD_HIGH_SPEED)) + { + hhcd->hc[ch_num].do_ssplit = 1U; + + if ((hhcd->hc[ch_num].ep_type == EP_TYPE_CTRL) && (hhcd->hc[ch_num].ep_is_in != 0U)) + { + hhcd->hc[ch_num].toggle_in = 1U; + } + } + + hhcd->hc[ch_num].hub_addr = addr; + hhcd->hc[ch_num].hub_port_nbr = PortNbr; + +} + +/** + * @brief Clear host channel Hub information + * @param hhcd HCD handle + * @param ch_num Channel number. + * This parameter can be a value from 1 to 15 + * @retval none + */ +void HCD_HS_HC_ClearHubInfo(HCD_HS_HandleTypeDef *hhcd, uint8_t ch_num) +{ + + hhcd->hc[ch_num].do_ssplit = 0U; + hhcd->hc[ch_num].do_csplit = 0U; + hhcd->hc[ch_num].hub_addr = 0U; + hhcd->hc[ch_num].hub_port_nbr = 0U; + +} + + +/** + * @} + */ + +/** + * @} + */ + +/** @addtogroup HCD_Private_Functions + * @{ + */ +/** + * @brief Handle Host Channel IN interrupt requests. + * @param hhcd HCD handle + * @param chnum Channel number. + * This parameter can be a value from 1 to 15 + * @retval none + */ +static void HCD_HS_HC_IN_IRQHandler(HCD_HS_HandleTypeDef *hhcd, uint8_t chnum) +{ + uint32_t tmpreg; + + if (__HCD_HS_GET_CH_FLAG(chnum, OTG_HS_HCINT_AHBERR)) + { + __HCD_HS_CLEAR_HC_INT(chnum, OTG_HS_HCINT_AHBERR); + hhcd->hc[chnum].state = HC_XACTERR; + USB_HS_HC_Halt(chnum); + } + else if (__HCD_HS_GET_CH_FLAG(chnum, OTG_HS_HCINT_BBERR)) + { + __HCD_HS_CLEAR_HC_INT(chnum, OTG_HS_HCINT_BBERR); + hhcd->hc[chnum].state = HC_BBLERR; + USB_HS_HC_Halt(chnum); + } + else if (__HCD_HS_GET_CH_FLAG(chnum, OTG_HS_HCINT_STALL)) + { + __HCD_HS_CLEAR_HC_INT(chnum, OTG_HS_HCINT_STALL); + hhcd->hc[chnum].state = HC_STALL; + USB_HS_HC_Halt(chnum); + } + else if (__HCD_HS_GET_CH_FLAG(chnum, OTG_HS_HCINT_DTERR)) + { + __HCD_HS_CLEAR_HC_INT(chnum, OTG_HS_HCINT_DTERR); + hhcd->hc[chnum].state = HC_DATATGLERR; + USB_HS_HC_Halt(chnum); + } + else if (__HCD_HS_GET_CH_FLAG(chnum, OTG_HS_HCINT_TXERR)) + { + __HCD_HS_CLEAR_HC_INT(chnum, OTG_HS_HCINT_TXERR); + hhcd->hc[chnum].state = HC_XACTERR; + USB_HS_HC_Halt(chnum); + } + else + { + /* ... */ + } + + if (__HCD_HS_GET_CH_FLAG(chnum, OTG_HS_HCINT_FRMOR)) + { + USB_HS_HC_Halt(chnum); + __HCD_HS_CLEAR_HC_INT(chnum, OTG_HS_HCINT_FRMOR); + } + else if (__HCD_HS_GET_CH_FLAG(chnum, OTG_HS_HCINT_XFRC)) + { + /* clear any pending ACK IT */ + __HCD_HS_CLEAR_HC_INT(chnum, OTG_HS_HCINT_ACK); + + if (hhcd->hc[chnum].do_csplit == 1U) + { + hhcd->hc[chnum].do_csplit = 0U; + __HCD_HS_CLEAR_HC_CSPLT(chnum); + } + + if (hhcd->Init.dma_enable != 0U) + { + hhcd->hc[chnum].xfer_count = hhcd->hc[chnum].XferSize - (USB_HS_HC(chnum)->HCTSIZ & OTG_HS_HCTSIZ_XFRSIZ); + } + + hhcd->hc[chnum].state = HC_XFRC; + hhcd->hc[chnum].ErrCnt = 0U; + __HCD_HS_CLEAR_HC_INT(chnum, OTG_HS_HCINT_XFRC); + + if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL) || + (hhcd->hc[chnum].ep_type == EP_TYPE_BULK)) + { + USB_HS_HC_Halt(chnum); + __HCD_HS_CLEAR_HC_INT(chnum, OTG_HS_HCINT_NAK); + } + else if ((hhcd->hc[chnum].ep_type == EP_TYPE_INTR) || + (hhcd->hc[chnum].ep_type == EP_TYPE_ISOC)) + { + USB_HS_HC(chnum)->HCCHAR |= OTG_HS_HCCHAR_ODDFRM; + hhcd->hc[chnum].urb_state = URB_DONE; + + HCD_HS_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state); + } + + else + { + /* ... */ + } + + if (hhcd->Init.dma_enable == 1U) + { + if ((((hhcd->hc[chnum].xfer_count + hhcd->hc[chnum].max_packet -1U) / hhcd->hc[chnum].max_packet) & 1U) != 0U) + { + hhcd->hc[chnum].toggle_in ^= 1U; + } + } + else + { + hhcd->hc[chnum].toggle_in ^= 1U; + } + } + + else if (__HCD_HS_GET_CH_FLAG(chnum, OTG_HS_HCINT_ACK)) + { + __HCD_HS_CLEAR_HC_INT(chnum, OTG_HS_HCINT_ACK); + if (hhcd->hc[chnum].do_ssplit == 1U) + { + hhcd->hc[chnum].do_csplit = 1U; + hhcd->hc[chnum].state = HC_ACK; + + USB_HS_HC_Halt(chnum); + } + } + + else if (__HCD_HS_GET_CH_FLAG(chnum, OTG_HS_HCINT_CHH)) + { + __HCD_HS_CLEAR_HC_INT(chnum, OTG_HS_HCINT_CHH); + + if (hhcd->hc[chnum].state == HC_XFRC) + { + hhcd->hc[chnum].state = HC_HALTED; + hhcd->hc[chnum].urb_state = URB_DONE; + } + else if (hhcd->hc[chnum].state == HC_STALL) + { + hhcd->hc[chnum].state = HC_HALTED; + hhcd->hc[chnum].urb_state = URB_STALL; + } + else if ((hhcd->hc[chnum].state == HC_XACTERR) || + (hhcd->hc[chnum].state == HC_DATATGLERR)) + { + hhcd->hc[chnum].state = HC_HALTED; + hhcd->hc[chnum].ErrCnt++; + if (hhcd->hc[chnum].ErrCnt > 2U) + { + hhcd->hc[chnum].ErrCnt = 0U; + if (hhcd->hc[chnum].do_ssplit == 1U) + { + hhcd->hc[chnum].do_csplit = 0U; + hhcd->hc[chnum].ep_ss_schedule = 0U; + __HCD_HS_CLEAR_HC_CSPLT(chnum); + } + hhcd->hc[chnum].urb_state = URB_ERROR; + } + else + { + hhcd->hc[chnum].urb_state = URB_NOTREADY; + if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL) || + (hhcd->hc[chnum].ep_type == EP_TYPE_BULK)) + { + /* re-activate the channel */ + tmpreg = USB_HS_HC(chnum)->HCCHAR; + tmpreg &= ~OTG_HS_HCCHAR_CHDIS; + tmpreg |= OTG_HS_HCCHAR_CHENA; + USB_HS_HC(chnum)->HCCHAR = tmpreg; + } + } + } + else if (hhcd->hc[chnum].state == HC_NYET) + { + hhcd->hc[chnum].state = HC_HALTED; + if (hhcd->hc[chnum].do_csplit == 1U) + { + if (hhcd->hc[chnum].ep_type == EP_TYPE_INTR) + { + hhcd->hc[chnum].NyetErrCnt++; + if (hhcd->hc[chnum].NyetErrCnt > 2U) + { + hhcd->hc[chnum].NyetErrCnt = 0U; + hhcd->hc[chnum].do_csplit = 0U; + + if (hhcd->hc[chnum].ErrCnt < 3U) + { + hhcd->hc[chnum].ep_ss_schedule = 1U; + } + __HCD_HS_CLEAR_HC_CSPLT(chnum); + hhcd->hc[chnum].urb_state = URB_ERROR; + } + else + { + hhcd->hc[chnum].urb_state = URB_NOTREADY; + } + } + else + { + hhcd->hc[chnum].urb_state = URB_NOTREADY; + } + + if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL) || + (hhcd->hc[chnum].ep_type == EP_TYPE_BULK)) + { + /* re-activate the channel */ + tmpreg = USB_HS_HC(chnum)->HCCHAR; + tmpreg &= ~OTG_HS_HCCHAR_CHDIS; + tmpreg |= OTG_HS_HCCHAR_CHENA; + USB_HS_HC(chnum)->HCCHAR = tmpreg; + } + } + } + else if (hhcd->hc[chnum].state == HC_ACK) + { + hhcd->hc[chnum].state = HC_HALTED; + if (hhcd->hc[chnum].do_csplit == 1U) + { + hhcd->hc[chnum].urb_state = URB_NOTREADY; + + /* Set Complete split and re-active the channel */ + USB_HS_HC(chnum)->HCSPLT |= OTG_HS_HCSPLT_COMPLSPLT; + USB_HS_HC(chnum)->HCINTMSK |= OTG_HS_HCINTMSK_NYETM; + USB_HS_HC(chnum)->HCINTMSK &= ~OTG_HS_HCINTMSK_ACKM; + + if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL) || + (hhcd->hc[chnum].ep_type == EP_TYPE_BULK)) + { + /* re-activate the channel */ + tmpreg = USB_HS_HC(chnum)->HCCHAR; + tmpreg &= ~OTG_HS_HCCHAR_CHDIS; + tmpreg |= OTG_HS_HCCHAR_CHENA; + USB_HS_HC(chnum)->HCCHAR = tmpreg; + } + } + } + + else if (hhcd->hc[chnum].state == HC_NAK) + { + hhcd->hc[chnum].state = HC_HALTED; + hhcd->hc[chnum].urb_state = URB_NOTREADY; + + if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL) || + (hhcd->hc[chnum].ep_type == EP_TYPE_BULK)) + { + /* re-activate the channel */ + tmpreg = USB_HS_HC(chnum)->HCCHAR; + tmpreg &= ~OTG_HS_HCCHAR_CHDIS; + tmpreg |= OTG_HS_HCCHAR_CHENA; + USB_HS_HC(chnum)->HCCHAR = tmpreg; + } + } + else if (hhcd->hc[chnum].state == HC_BBLERR) + { + hhcd->hc[chnum].state = HC_HALTED; + hhcd->hc[chnum].ErrCnt++; + hhcd->hc[chnum].urb_state = URB_ERROR; + } + else + { + if (hhcd->hc[chnum].state == HC_HALTED) + { + return; + } + } + + HCD_HS_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state); + } + + else if (__HCD_HS_GET_CH_FLAG(chnum, OTG_HS_HCINT_NAK)) + { + if (hhcd->hc[chnum].ep_type == EP_TYPE_INTR) + { + hhcd->hc[chnum].ErrCnt = 0U; + hhcd->hc[chnum].state = HC_NAK; + USB_HS_HC_Halt(chnum); + } + else if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL) || + (hhcd->hc[chnum].ep_type == EP_TYPE_BULK)) + { + hhcd->hc[chnum].ErrCnt = 0U; + + if ((hhcd->Init.dma_enable == 0U) || (hhcd->hc[chnum].do_csplit == 1U)) + { + hhcd->hc[chnum].state = HC_NAK; + USB_HS_HC_Halt(chnum); + } + } + else + { + /*...*/ + } + + if (hhcd->hc[chnum].do_csplit == 1U) + { + hhcd->hc[chnum].do_csplit = 0U; + __HCD_HS_CLEAR_HC_CSPLT(chnum); + __HCD_HS_UNMASK_ACK_HC_INT(chnum); + } + __HCD_HS_CLEAR_HC_INT(chnum, OTG_HS_HCINT_NAK); + } + else + { + /*...*/ + } + +} + +/** + * @brief Handle Host Channel OUT interrupt requests. + * @param hhcd HCD handle + * @param chnum Channel number. + * This parameter can be a value from 1 to 15 + * @retval none + */ +static void HCD_HS_HC_OUT_IRQHandler(HCD_HS_HandleTypeDef *hhcd, uint8_t chnum) +{ + uint32_t tmpreg; + uint32_t num_packets; + + if (__HCD_HS_GET_CH_FLAG(chnum, OTG_HS_HCINT_AHBERR)) + { + __HCD_HS_CLEAR_HC_INT(chnum, OTG_HS_HCINT_AHBERR); + hhcd->hc[chnum].state = HC_XACTERR; + USB_HS_HC_Halt(chnum); + } + else if (__HCD_HS_GET_CH_FLAG(chnum, OTG_HS_HCINT_ACK)) + { + __HCD_HS_CLEAR_HC_INT(chnum, OTG_HS_HCINT_ACK); + if (hhcd->hc[chnum].do_ping == 1U) + { + hhcd->hc[chnum].do_ping = 0U; + hhcd->hc[chnum].urb_state = URB_NOTREADY; + hhcd->hc[chnum].state = HC_ACK; + USB_HS_HC_Halt(chnum); + } + + if ((hhcd->hc[chnum].do_ssplit == 1U) && (hhcd->hc[chnum].do_csplit == 0U)) + { + if (hhcd->hc[chnum].ep_type != EP_TYPE_ISOC) + { + hhcd->hc[chnum].do_csplit = 1U; + } + hhcd->hc[chnum].state = HC_ACK; + USB_HS_HC_Halt(chnum); + + /* reset error_count */ + hhcd->hc[chnum].ErrCnt = 0U; + } + } + else if (__HCD_HS_GET_CH_FLAG(chnum, OTG_HS_HCINT_FRMOR)) + { + __HCD_HS_CLEAR_HC_INT(chnum, OTG_HS_HCINT_FRMOR); + USB_HS_HC_Halt(chnum); + } + else if (__HCD_HS_GET_CH_FLAG(chnum, OTG_HS_HCINT_XFRC)) + { + hhcd->hc[chnum].ErrCnt = 0U; + + /* transaction completed with NYET state, update do ping state */ + if (__HCD_HS_GET_CH_FLAG(chnum, OTG_HS_HCINT_NYET)) + { + hhcd->hc[chnum].do_ping = 1U; + __HCD_HS_CLEAR_HC_INT(chnum, OTG_HS_HCINT_NYET); + } + if (hhcd->hc[chnum].do_csplit != 0U) + { + hhcd->hc[chnum].do_csplit = 0U; + __HCD_HS_CLEAR_HC_CSPLT(chnum); + } + + /* clear any pending IT */ + __HCD_HS_CLEAR_HC_INT(chnum, OTG_HS_HCINT_XFRC); + hhcd->hc[chnum].state = HC_XFRC; + USB_HS_HC_Halt(chnum); + } + else if (__HCD_HS_GET_CH_FLAG(chnum, OTG_HS_HCINT_NYET)) + { + hhcd->hc[chnum].state = HC_NYET; + + if (hhcd->hc[chnum].do_ssplit == 0U) + { + hhcd->hc[chnum].do_ping = 1U; + } + + hhcd->hc[chnum].ErrCnt = 0U; + USB_HS_HC_Halt(chnum); + /* clear any pending IT */ + __HCD_HS_CLEAR_HC_INT(chnum, OTG_HS_HCINT_NYET); + } + + else if (__HCD_HS_GET_CH_FLAG(chnum, OTG_HS_HCINT_STALL)) + { + __HCD_HS_CLEAR_HC_INT(chnum, OTG_HS_HCINT_STALL); + hhcd->hc[chnum].state = HC_STALL; + USB_HS_HC_Halt(chnum); + } + else if (__HCD_HS_GET_CH_FLAG(chnum, OTG_HS_HCINT_NAK)) + { + hhcd->hc[chnum].ErrCnt = 0U; + hhcd->hc[chnum].state = HC_NAK; + + if (hhcd->hc[chnum].do_ping == 0U) + { + if (hhcd->hc[chnum].speed == HCD_DEVICE_SPEED_HIGH) + { + hhcd->hc[chnum].do_ping = 1U; + } + } + + USB_HS_HC_Halt(chnum); + __HCD_HS_CLEAR_HC_INT(chnum, OTG_HS_HCINT_NAK); + } + else if (__HCD_HS_GET_CH_FLAG(chnum, OTG_HS_HCINT_TXERR)) + { + if (hhcd->Init.dma_enable == 0U) + { + hhcd->hc[chnum].state = HC_XACTERR; + USB_HS_HC_Halt(chnum); + } + else + { + hhcd->hc[chnum].ErrCnt++; + if (hhcd->hc[chnum].ErrCnt > 2U) + { + hhcd->hc[chnum].urb_state = URB_ERROR; + + HCD_HS_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state); + } + else + { + hhcd->hc[chnum].urb_state = URB_NOTREADY; + + /* Re-activate the channel */ + tmpreg = USB_HS_HC(chnum)->HCCHAR; + tmpreg &= ~OTG_HS_HCCHAR_CHDIS; + tmpreg |= OTG_HS_HCCHAR_CHENA; + USB_HS_HC(chnum)->HCCHAR = tmpreg; + } + } + __HCD_HS_CLEAR_HC_INT(chnum, OTG_HS_HCINT_TXERR); + } + + else if (__HCD_HS_GET_CH_FLAG(chnum, OTG_HS_HCINT_DTERR)) + { + hhcd->hc[chnum].state = HC_DATATGLERR; + USB_HS_HC_Halt(chnum); + __HCD_HS_CLEAR_HC_INT(chnum, OTG_HS_HCINT_DTERR); + } + else if (__HCD_HS_GET_CH_FLAG(chnum, OTG_HS_HCINT_CHH)) + { + __HCD_HS_CLEAR_HC_INT(chnum, OTG_HS_HCINT_CHH); + + if (hhcd->hc[chnum].state == HC_XFRC) + { + hhcd->hc[chnum].state = HC_HALTED; + hhcd->hc[chnum].urb_state = URB_DONE; + + if ((hhcd->hc[chnum].ep_type == EP_TYPE_BULK) || + (hhcd->hc[chnum].ep_type == EP_TYPE_INTR)) + { + if (hhcd->Init.dma_enable == 0U) + { + hhcd->hc[chnum].toggle_out ^= 1U; + } + if ((hhcd->Init.dma_enable == 1U) && (hhcd->hc[chnum].xfer_len > 0U)) + { + num_packets = (hhcd->hc[chnum].xfer_len + hhcd->hc[chnum].max_packet - 1U) / hhcd->hc[chnum].max_packet; + if ((num_packets & 1U) != 0U) + { + hhcd->hc[chnum].toggle_out ^= 1U; + } + } + } + } + else if (hhcd->hc[chnum].state == HC_ACK) + { + hhcd->hc[chnum].state = HC_HALTED; + if (hhcd->hc[chnum].do_csplit == 1U) + { + hhcd->hc[chnum].urb_state = URB_NOTREADY; + } + } + else if (hhcd->hc[chnum].state == HC_NAK) + { + hhcd->hc[chnum].state = HC_HALTED; + hhcd->hc[chnum].urb_state = URB_NOTREADY; + + if (hhcd->hc[chnum].do_csplit == 1U) + { + hhcd->hc[chnum].do_csplit = 0U; + __HCD_HS_CLEAR_HC_CSPLT(chnum); + } + } + else if (hhcd->hc[chnum].state == HC_NYET) + { + hhcd->hc[chnum].state = HC_HALTED; + hhcd->hc[chnum].urb_state = URB_NOTREADY; + } + else if (hhcd->hc[chnum].state == HC_STALL) + { + hhcd->hc[chnum].state = HC_HALTED; + hhcd->hc[chnum].urb_state = URB_STALL; + } + else if ((hhcd->hc[chnum].state == HC_XACTERR) || + (hhcd->hc[chnum].state == HC_DATATGLERR)) + { + hhcd->hc[chnum].state = HC_HALTED; + hhcd->hc[chnum].ErrCnt++; + if (hhcd->hc[chnum].ErrCnt > 2U) + { + hhcd->hc[chnum].ErrCnt = 0U; + hhcd->hc[chnum].urb_state = URB_ERROR; + } + else + { + hhcd->hc[chnum].urb_state = URB_NOTREADY; + /* re-activate the channel */ + tmpreg = USB_HS_HC(chnum)->HCCHAR; + tmpreg &= ~OTG_HS_HCCHAR_CHDIS; + tmpreg |= OTG_HS_HCCHAR_CHENA; + USB_HS_HC(chnum)->HCCHAR = tmpreg; + } + } + else + { + return; + } + + HCD_HS_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state); + + } + + else + { + return; + } +} + +/** + * @brief Handle Rx Queue Level interrupt requests. + * @param hhcd HCD handle + * @retval none + */ +static void HCD_HS_RXQLVL_IRQHandler(HCD_HS_HandleTypeDef *hhcd) +{ + uint32_t pktsts; + uint32_t pktcnt; + uint32_t GrxstspReg; + uint32_t xferSizePktCnt; + uint32_t tmpreg; + uint32_t chnum; + + GrxstspReg = USB_HS->GRXSTSP; + chnum = GrxstspReg & OTG_HS_GRXSTSP_CHNUM; + pktsts = (GrxstspReg & OTG_HS_GRXSTSP_PKTSTS) >> 17; + pktcnt = (GrxstspReg & OTG_HS_GRXSTSP_BCNT) >> 4; + + switch (pktsts) + { + case GRXSTS_PKTSTS_IN: + /* Read the data into the host buffer. */ + if ((pktcnt > 0U) && (hhcd->hc[chnum].xfer_buff != (void *)0)) + { + if ((hhcd->hc[chnum].xfer_count + pktcnt) <= hhcd->hc[chnum].xfer_len) + { + USB_HS_ReadPacket(hhcd->hc[chnum].xfer_buff, (uint16_t)pktcnt); + + /* manage multiple Xfer */ + hhcd->hc[chnum].xfer_buff += pktcnt; + hhcd->hc[chnum].xfer_count += pktcnt; + + /* get transfer size packet count */ + xferSizePktCnt = (USB_HS_HC(chnum)->HCTSIZ & OTG_HS_HCTSIZ_PKTCNT) >> 19; + + if ((hhcd->hc[chnum].max_packet == pktcnt) && (xferSizePktCnt > 0U)) + { + /* re-activate the channel when more packets are expected */ + tmpreg = USB_HS_HC(chnum)->HCCHAR; + tmpreg &= ~OTG_HS_HCCHAR_CHDIS; + tmpreg |= OTG_HS_HCCHAR_CHENA; + USB_HS_HC(chnum)->HCCHAR = tmpreg; + hhcd->hc[chnum].toggle_in ^= 1U; + } + } + else + { + hhcd->hc[chnum].urb_state = URB_ERROR; + } + } + break; + + case GRXSTS_PKTSTS_DATA_TOGGLE_ERR: + break; + + case GRXSTS_PKTSTS_IN_XFER_COMP: + case GRXSTS_PKTSTS_CH_HALTED: + default: + break; + } +} + +/** + * @brief Handle Host Port interrupt requests. + * @param hhcd HCD handle + * @retval None + */ +static void HCD_HS_Port_IRQHandler(HCD_HS_HandleTypeDef *hhcd) +{ + __IO uint32_t hprt0; + __IO uint32_t hprt0_dup; + + /* Handle Host Port Interrupts */ + hprt0 = USB_HS_HPRT0; + hprt0_dup = USB_HS_HPRT0; + + hprt0_dup &= ~(OTG_HS_HPRT_PENA | OTG_HS_HPRT_PCDET | \ + OTG_HS_HPRT_PENCHNG | OTG_HS_HPRT_POCCHNG); + + /* Check whether Port Connect detected */ + if ((hprt0 & OTG_HS_HPRT_PCDET) == OTG_HS_HPRT_PCDET) + { + if ((hprt0 & OTG_HS_HPRT_PCSTS) == OTG_HS_HPRT_PCSTS) + { + + HCD_HS_Connect_Callback(hhcd); + } + hprt0_dup |= OTG_HS_HPRT_PCDET; + } + + /* Check whether Port Enable Changed */ + if ((hprt0 & OTG_HS_HPRT_PENCHNG) == OTG_HS_HPRT_PENCHNG) + { + hprt0_dup |= OTG_HS_HPRT_PENCHNG; + + if ((hprt0 & OTG_HS_HPRT_PENA) == OTG_HS_HPRT_PENA) + { + if((hprt0 & OTG_HS_HPRT_PSPD) == (HPRT0_PRTSPD_HIGH_SPEED<<17)) + { + USB_HS_HOST->HFIR = 0x1D4C;//HFIR_60_MHZ; + } + HCD_HS_PortEnabled_Callback(hhcd); + } + else + { + + HCD_HS_PortDisabled_Callback(hhcd); + } + } + + /* Check for an overcurrent */ + if ((hprt0 & OTG_HS_HPRT_POCCHNG) == OTG_HS_HPRT_POCCHNG) + { + hprt0_dup |= OTG_HS_HPRT_POCCHNG; + } + + /* Clear Port Interrupts */ + USB_HS_HPRT0 = hprt0_dup; +} + +/** + * @} + */ + + +#endif /* defined (USB_OTG_HS) */ +#endif /* HCD_MODULE_ENABLED */ + diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_i2c.c b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_i2c.c new file mode 100644 index 00000000000..33dc5f94c45 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_i2c.c @@ -0,0 +1,1320 @@ +/** + ****************************************************************************** + * @file ft32f4xx_i2c.c + * @author FMD AE + * @brief This file provides firmware functions to manage the following + * functionalities of the Inter-Integrated circuit (I2C): + * + Initialization and Configuration + * + Communications handling + * + SMBUS management + * + I2C registers management + * + Data transfers management + * + DMA transfers management + * + Interrupts and flags management + * @version V1.0.0 + * @date 2025-03-31 + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx_i2c.h" +#include "ft32f4xx_rcc.h" + + + +#define CR1_CLEAR_MASK ((uint32_t)0x00CDE0FF) /*I2C_AnalogFilter)); + assert_param(IS_I2C_DIGITAL_FILTER(I2C_InitStruct->I2C_DigitalFilter)); + assert_param(IS_I2C_NoStretch(I2C_InitStruct->I2C_NoStretchMode)); + assert_param(IS_I2C_MODE(I2C_InitStruct->I2C_Mode)); + assert_param(IS_I2C_OWN_ADDRESS1(I2C_InitStruct->I2C_OwnAddress1)); + assert_param(IS_I2C_ACK(I2C_InitStruct->I2C_Ack)); + assert_param(IS_I2C_ACKNOWLEDGE_ADDRESS(I2C_InitStruct->I2C_AcknowledgedAddress)); + + /* Disable I2Cx Peripheral */ + I2Cx->CR1 &= (uint32_t)~((uint32_t)I2C_CR1_PE); + + /*---------------------------- I2Cx FILTERS Configuration ------------------*/ + /* Get the I2Cx CR1 value */ + tmpreg = I2Cx->CR1; + /* Clear I2Cx CR1 register */ + tmpreg &= CR1_CLEAR_MASK; + /* Configure I2Cx: analog and digital filter */ + /* Set ANFOFF bit according to I2C_AnalogFilter value */ + /* Set DFN bits according to I2C_DigitalFilter value */ + tmpreg |= (uint32_t)I2C_InitStruct->I2C_AnalogFilter | (I2C_InitStruct->I2C_DigitalFilter << 8); + + /*---------------------------- I2Cx Nostretch Configuration ----------------*/ + /* Set NOSTRETCH bit according to I2C_NoStretchMode value */ + tmpreg |= (uint32_t)I2C_InitStruct->I2C_NoStretchMode; + + /* Write to I2Cx CR1 */ + I2Cx->CR1 = tmpreg; + + /*---------------------------- I2Cx TIMING Configuration -------------------*/ + /* Configure I2Cx: Timing */ + /* Set TIMINGR bits according to I2C_Timing */ + /* Write to I2Cx TIMING */ + I2Cx->TIMINGR = I2C_InitStruct->I2C_Timing & TIMING_CLEAR_MASK; + + /* Enable I2Cx Peripheral */ + I2Cx->CR1 |= I2C_CR1_PE; + + /*---------------------------- I2Cx OAR1 Configuration ---------------------*/ + /* Clear tmpreg local variable */ + tmpreg = 0; + /* Clear OAR1 register */ + I2Cx->OAR1 = (uint32_t)tmpreg; + /* Clear OAR2 register */ + I2Cx->OAR2 = (uint32_t)tmpreg; + /* Configure I2Cx: Own Address1 and acknowledged address */ + /* Set OA1MODE bit according to I2C_AcknowledgedAddress value */ + /* Set OA1 bits according to I2C_OwnAddress1 value */ + tmpreg = (uint32_t)((uint32_t)I2C_InitStruct->I2C_AcknowledgedAddress | \ + (uint32_t)I2C_InitStruct->I2C_OwnAddress1); + /* Write to I2Cx OAR1 */ + I2Cx->OAR1 = tmpreg; + /* Enable Own Address1 acknowledgement */ + I2Cx->OAR1 |= I2C_OAR1_OA1EN; + + /*---------------------------- I2Cx MODE Configuration ---------------------*/ + /* Configure I2Cx: mode */ + /* Set SMBDEN and SMBHEN bits according to I2C_Mode value */ + tmpreg = I2C_InitStruct->I2C_Mode; + /* Write to I2Cx CR1 */ + I2Cx->CR1 |= tmpreg; + + /*---------------------------- I2Cx ACK Configuration ----------------------*/ + /* Get the I2Cx CR2 value */ + tmpreg = I2Cx->CR2; + /* Clear I2Cx CR2 register */ + tmpreg &= CR2_CLEAR_MASK; + /* Configure I2Cx: acknowledgement */ + /* Set NACK bit according to I2C_Ack value */ + tmpreg |= I2C_InitStruct->I2C_Ack; + /* Write to I2Cx CR2 */ + I2Cx->CR2 = tmpreg; +} + +/** + * @brief Fills each I2C_InitStruct member with its default value. + * @param I2C_InitStruct: pointer to an I2C_InitTypeDef structure which will be initialized. + * @retval None + */ +void I2C_StructInit(I2C_InitTypeDef* I2C_InitStruct) +{ + /*---------------- Reset I2C init structure parameters values --------------*/ + /* Initialize the I2C_Timing member */ + I2C_InitStruct->I2C_Timing = 0; + /* Initialize the I2C_AnalogFilter member */ + I2C_InitStruct->I2C_AnalogFilter = I2C_AnalogFilter_Enable; + /* Initialize the I2C_DigitalFilter member */ + I2C_InitStruct->I2C_DigitalFilter = 0; + /* Initialize the I2C_NoStretchMode member */ + I2C_InitStruct->I2C_NoStretchMode = I2C_NoStretch_Disable; + /* Initialize the I2C_Mode member */ + I2C_InitStruct->I2C_Mode = I2C_Mode_I2C; + /* Initialize the I2C_OwnAddress1 member */ + I2C_InitStruct->I2C_OwnAddress1 = 0; + /* Initialize the I2C_Ack member */ + I2C_InitStruct->I2C_Ack = I2C_Ack_Disable; + /* Initialize the I2C_AcknowledgedAddress member */ + I2C_InitStruct->I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; +} + +/** + * @brief Enables or disables the specified I2C peripheral. + * @param I2Cx: where x can be 1 or 2 or 3 to select the I2C peripheral. + * @param NewState: new state of the I2Cx peripheral. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_Cmd(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the selected I2C peripheral */ + I2Cx->CR1 |= I2C_CR1_PE; + } + else + { + /* Disable the selected I2C peripheral */ + I2Cx->CR1 &= (uint32_t)~((uint32_t)I2C_CR1_PE); + } +} + +/** + * @brief Enables or disables the specified I2C software reset. + * @param I2Cx: where x can be 1 or 2 or 3 to select the I2C peripheral. + * @retval None + */ +void I2C_SoftwareResetCmd(I2C_TypeDef* I2Cx) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + + /* Disable peripheral */ + I2Cx->CR1 &= (uint32_t)~((uint32_t)I2C_CR1_PE); + + /* Perform a dummy read to delay the disable of peripheral for minimum + 3 APB clock cycles to perform the software reset functionality */ + *(__IO uint32_t *)(uint32_t)I2Cx; + + /* Enable peripheral */ + I2Cx->CR1 |= I2C_CR1_PE; +} + +/** + * @brief Enables or disables the specified I2C interrupts. + * @param I2Cx: where x can be 1 or 2 or 3 to select the I2C peripheral. + * @param I2C_IT: specifies the I2C interrupts sources to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg I2C_IT_ERRI: Error interrupt mask + * @arg I2C_IT_TCI: Transfer Complete interrupt mask + * @arg I2C_IT_STOPI: Stop Detection interrupt mask + * @arg I2C_IT_NACKI: Not Acknowledge received interrupt mask + * @arg I2C_IT_ADDRI: Address Match interrupt mask + * @arg I2C_IT_RXI: RX interrupt mask + * @arg I2C_IT_TXI: TX interrupt mask + * @param NewState: new state of the specified I2C interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_ITConfig(I2C_TypeDef* I2Cx, uint32_t I2C_IT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + assert_param(IS_I2C_CONFIG_IT(I2C_IT)); + + if (NewState != DISABLE) + { + /* Enable the selected I2C interrupts */ + I2Cx->CR1 |= I2C_IT; + } + else + { + /* Disable the selected I2C interrupts */ + I2Cx->CR1 &= (uint32_t)~((uint32_t)I2C_IT); + } +} + +/** + * @brief Enables or disables the I2C Clock stretching. + * @param I2Cx: where x can be 1 or 2 or 3 to select the I2C peripheral. + * @param NewState: new state of the I2Cx Clock stretching. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_StretchClockCmd(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable clock stretching */ + I2Cx->CR1 &= (uint32_t)~((uint32_t)I2C_CR1_NOSTRETCH); + } + else + { + /* Disable clock stretching */ + I2Cx->CR1 |= I2C_CR1_NOSTRETCH; + } +} + +/** + * @brief Enables or disables the I2C own address 2. + * @param I2Cx: where x can be 1 or 2 or 3 to select the I2C peripheral. + * @param NewState: new state of the I2C own address 2. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_DualAddressCmd(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable own address 2 */ + I2Cx->OAR2 |= I2C_OAR2_OA2EN; + } + else + { + /* Disable own address 2 */ + I2Cx->OAR2 &= (uint32_t)~((uint32_t)I2C_OAR2_OA2EN); + } +} + +/** + * @brief Configures the I2C slave own address 2 and mask. + * @param I2Cx: where x can be 1 or 2 or 3 to select the I2C peripheral. + * @param Address: specifies the slave address to be programmed. + * @param Mask: specifies own address 2 mask to be programmed. + * This parameter can be one of the following values: + * @arg I2C_OA2_NoMask: no mask. + * @arg I2C_OA2_Mask01: OA2[1] is masked and don't care. + * @arg I2C_OA2_Mask02: OA2[2:1] are masked and don't care. + * @arg I2C_OA2_Mask03: OA2[3:1] are masked and don't care. + * @arg I2C_OA2_Mask04: OA2[4:1] are masked and don't care. + * @arg I2C_OA2_Mask05: OA2[5:1] are masked and don't care. + * @arg I2C_OA2_Mask06: OA2[6:1] are masked and don't care. + * @arg I2C_OA2_Mask07: OA2[7:1] are masked and don't care. + * @retval None + */ +void I2C_OwnAddress2Config(I2C_TypeDef* I2Cx, uint16_t Address, uint8_t Mask) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_OWN_ADDRESS2(Address)); + assert_param(IS_I2C_OWN_ADDRESS2_MASK(Mask)); + + /* Get the old register value */ + tmpreg = I2Cx->OAR2; + + /* Reset I2Cx OA2 bit [7:1] and OA2MSK bit [1:0] */ + tmpreg &= (uint32_t)~((uint32_t)(I2C_OAR2_OA2 | I2C_OAR2_OA2MSK)); + + /* Set I2Cx SADD */ + tmpreg |= (uint32_t)(((uint32_t)Address & I2C_OAR2_OA2) | \ + (((uint32_t)Mask << 8) & I2C_OAR2_OA2MSK)) ; + + /* Store the new register value */ + I2Cx->OAR2 = tmpreg; +} + +/** + * @brief Enables or disables the I2C general call mode. + * @param I2Cx: where x can be 1 or 2 or 3 to select the I2C peripheral. + * @param NewState: new state of the I2C general call mode. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_GeneralCallCmd(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable general call mode */ + I2Cx->CR1 |= I2C_CR1_GCEN; + } + else + { + /* Disable general call mode */ + I2Cx->CR1 &= (uint32_t)~((uint32_t)I2C_CR1_GCEN); + } +} + +/** + * @brief Enables or disables the I2C slave byte control. + * @param I2Cx: where x can be 1 or 2 or 3 to select the I2C peripheral. + * @param NewState: new state of the I2C slave byte control. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_SlaveByteControlCmd(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable slave byte control */ + I2Cx->CR1 |= I2C_CR1_SBC; + } + else + { + /* Disable slave byte control */ + I2Cx->CR1 &= (uint32_t)~((uint32_t)I2C_CR1_SBC); + } +} + +/** + * @brief Configures the slave address to be transmitted after start generation. + * @param I2Cx: where x can be 1 or 2 or 3 to select the I2C peripheral. + * @param Address: specifies the slave address to be programmed. + * @note This function should be called before generating start condition. + * @retval None + */ +void I2C_SlaveAddressConfig(I2C_TypeDef* I2Cx, uint16_t Address) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_SLAVE_ADDRESS(Address)); + + /* Get the old register value */ + tmpreg = I2Cx->CR2; + + /* Reset I2Cx SADD bit [9:0] */ + tmpreg &= (uint32_t)~((uint32_t)I2C_CR2_SADD); + + /* Set I2Cx SADD */ + tmpreg |= (uint32_t)((uint32_t)Address & I2C_CR2_SADD); + + /* Store the new register value */ + I2Cx->CR2 = tmpreg; +} + +/** + * @brief Enables or disables the I2C 10-bit addressing mode for the master. + * @param I2Cx: where x can be 1 or 2 or 3 to select the I2C peripheral. + * @param NewState: new state of the I2C 10-bit addressing mode. + * This parameter can be: ENABLE or DISABLE. + * @note This function should be called before generating start condition. + * @retval None + */ +void I2C_10BitAddressingModeCmd(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable 10-bit addressing mode */ + I2Cx->CR2 |= I2C_CR2_ADD10; + } + else + { + /* Disable 10-bit addressing mode */ + I2Cx->CR2 &= (uint32_t)~((uint32_t)I2C_CR2_ADD10); + } +} + +/** + * @} + */ + + +/** + * @brief Enables or disables the I2C automatic end mode (stop condition is + * automatically sent when nbytes data are transferred). + * @param I2Cx: where x can be 1 or 2 or 3 to select the I2C peripheral. + * @param NewState: new state of the I2C automatic end mode. + * This parameter can be: ENABLE or DISABLE. + * @note This function has effect if Reload mode is disabled. + * @retval None + */ +void I2C_AutoEndCmd(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable Auto end mode */ + I2Cx->CR2 |= I2C_CR2_AUTOEND; + } + else + { + /* Disable Auto end mode */ + I2Cx->CR2 &= (uint32_t)~((uint32_t)I2C_CR2_AUTOEND); + } +} + +/** + * @brief Enables or disables the I2C nbytes reload mode. + * @param I2Cx: where x can be 1 or 2 or 3 to select the I2C peripheral. + * @param NewState: new state of the nbytes reload mode. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_ReloadCmd(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable Auto Reload mode */ + I2Cx->CR2 |= I2C_CR2_RELOAD; + } + else + { + /* Disable Auto Reload mode */ + I2Cx->CR2 &= (uint32_t)~((uint32_t)I2C_CR2_RELOAD); + } +} + +/** + * @brief Configures the number of bytes to be transmitted/received. + * @param I2Cx: where x can be 1 or 2 or 3 to select the I2C peripheral. + * @param Number_Bytes: specifies the number of bytes to be programmed. + * @retval None + */ +void I2C_NumberOfBytesConfig(I2C_TypeDef* I2Cx, uint8_t Number_Bytes) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + + /* Get the old register value */ + tmpreg = I2Cx->CR2; + + /* Reset I2Cx Nbytes bit [7:0] */ + tmpreg &= (uint32_t)~((uint32_t)I2C_CR2_NBYTES); + + /* Set I2Cx Nbytes */ + tmpreg |= (uint32_t)(((uint32_t)Number_Bytes << 16) & I2C_CR2_NBYTES); + + /* Store the new register value */ + I2Cx->CR2 = tmpreg; +} + +/** + * @brief Configures the type of transfer request for the master. + * @param I2Cx: where x can be 1 or 2 or 3 to select the I2C peripheral. + * @param I2C_Direction: specifies the transfer request direction to be programmed. + * This parameter can be one of the following values: + * @arg I2C_Direction_Transmitter: Master request a write transfer + * @arg I2C_Direction_Receiver: Master request a read transfer + * @retval None + */ +void I2C_MasterRequestConfig(I2C_TypeDef* I2Cx, uint16_t I2C_Direction) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_DIRECTION(I2C_Direction)); + + /* Test on the direction to set/reset the read/write bit */ + if (I2C_Direction == I2C_Direction_Transmitter) + { + /* Request a write Transfer */ + I2Cx->CR2 &= (uint32_t)~((uint32_t)I2C_CR2_RD_WRN); + } + else + { + /* Request a read Transfer */ + I2Cx->CR2 |= I2C_CR2_RD_WRN; + } +} + +/** + * @brief Generates I2Cx communication START condition. + * @param I2Cx: where x can be 1 or 2 or 3 to select the I2C peripheral. + * @param NewState: new state of the I2C START condition generation. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_GenerateSTART(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Generate a START condition */ + I2Cx->CR2 |= I2C_CR2_START; + } + else + { + /* Disable the START condition generation */ + I2Cx->CR2 &= (uint32_t)~((uint32_t)I2C_CR2_START); + } +} + +/** + * @brief Generates I2Cx communication STOP condition. + * @param I2Cx: where x can be 1 or 2 or 3 to select the I2C peripheral. + * @param NewState: new state of the I2C STOP condition generation. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_GenerateSTOP(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Generate a STOP condition */ + I2Cx->CR2 |= I2C_CR2_STOP; + } + else + { + /* Disable the STOP condition generation */ + I2Cx->CR2 &= (uint32_t)~((uint32_t)I2C_CR2_STOP); + } +} + +/** + * @brief Enables or disables the I2C 10-bit header only mode with read direction. + * @param I2Cx: where x can be 1 or 2 or 3 to select the I2C peripheral. + * @param NewState: new state of the I2C 10-bit header only mode. + * This parameter can be: ENABLE or DISABLE. + * @note This mode can be used only when switching from master transmitter mode + * to master receiver mode. + * @retval None + */ +void I2C_10BitAddressHeaderCmd(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable 10-bit header only mode */ + I2Cx->CR2 |= I2C_CR2_HEAD10R; + } + else + { + /* Disable 10-bit header only mode */ + I2Cx->CR2 &= (uint32_t)~((uint32_t)I2C_CR2_HEAD10R); + } +} + +/** + * @brief Generates I2C communication Acknowledge. + * @param I2Cx: where x can be 1 or 2 or 3 to select the I2C peripheral. + * @param NewState: new state of the Acknowledge. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_AcknowledgeConfig(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable ACK generation */ + I2Cx->CR2 &= (uint32_t)~((uint32_t)I2C_CR2_NACK); + } + else + { + /* Enable NACK generation */ + I2Cx->CR2 |= I2C_CR2_NACK; + } +} + +/** + * @brief Returns the I2C slave matched address . + * @param I2Cx: where x can be 1 or 2 or 3 to select the I2C peripheral. + * @retval The value of the slave matched address . + */ +uint8_t I2C_GetAddressMatched(I2C_TypeDef* I2Cx) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + + /* Return the slave matched address in the SR1 register */ + return (uint8_t)(((uint32_t)I2Cx->ISR & I2C_ISR_ADDCODE) >> 16) ; +} + +/** + * @brief Returns the I2C slave received request. + * @param I2Cx: where x can be 1 or 2 or 3 to select the I2C peripheral. + * @retval The value of the received request. + */ +uint16_t I2C_GetTransferDirection(I2C_TypeDef* I2Cx) +{ + uint32_t tmpreg = 0; + uint16_t direction = 0; + + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + + /* Return the slave matched address in the SR1 register */ + tmpreg = (uint32_t)(I2Cx->ISR & I2C_ISR_DIR); + + /* If write transfer is requested */ + if (tmpreg == 0) + { + /* write transfer is requested */ + direction = I2C_Direction_Transmitter; + } + else + { + /* Read transfer is requested */ + direction = I2C_Direction_Receiver; + } + return direction; +} + +/** + * @brief Generate I2C TXIS event. + * @param I2Cx: where x can be 1 or 2 or 3 to select the I2C peripheral. + * @param NewState: new state of I2C TXIS event generation. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_GenerateTXIS(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Genarate I2C TXIS event */ + I2Cx->ISR |= I2C_ISR_TXIS; + } + else + { + /* No effect */ + I2Cx->ISR &= (uint32_t)~((uint32_t)I2C_ISR_TXIS); + } +} + +/** + * @brief Generate I2C TXE event. + * @param I2Cx: where x can be 1 or 2 or 3 to select the I2C peripheral. + * @param NewState: new state of I2C TXE event generation. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_GenerateTXE(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Genarate I2C TXE event */ + I2Cx->ISR |= I2C_ISR_TXE; + } + else + { + /* No effect */ + I2Cx->ISR &= (uint32_t)~((uint32_t)I2C_ISR_TXE); + } +} + +/** + * @brief Handles I2Cx communication when starting transfer or during transfer (TC or TCR flag are set). + * @param I2Cx: where x can be 1 or 2 or 3 to select the I2C peripheral. + * @param Address: specifies the slave address to be programmed. + * @param Number_Bytes: specifies the number of bytes to be programmed. + * This parameter must be a value between 0 and 255. + * @param ReloadEndMode: new state of the I2C START condition generation. + * This parameter can be one of the following values: + * @arg I2C_Reload_Mode: Enable Reload mode . + * @arg I2C_AutoEnd_Mode: Enable Automatic end mode. + * @arg I2C_SoftEnd_Mode: Enable Software end mode. + * @param StartStopMode: new state of the I2C START condition generation. + * This parameter can be one of the following values: + * @arg I2C_No_StartStop: Don't Generate stop and start condition. + * @arg I2C_Generate_Stop: Generate stop condition (Number_Bytes should be set to 0). + * @arg I2C_Generate_Start_Read: Generate Restart for read request. + * @arg I2C_Generate_Start_Write: Generate Restart for write request. + * @retval None + */ +void I2C_TransferHandling(I2C_TypeDef* I2Cx, uint16_t Address, uint8_t Number_Bytes, uint32_t ReloadEndMode, uint32_t StartStopMode) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_SLAVE_ADDRESS(Address)); + assert_param(IS_RELOAD_END_MODE(ReloadEndMode)); + assert_param(IS_START_STOP_MODE(StartStopMode)); + + /* Get the CR2 register value */ + tmpreg = I2Cx->CR2; + + /* clear tmpreg specific bits */ + tmpreg &= (uint32_t)~((uint32_t)(I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | I2C_CR2_RD_WRN | I2C_CR2_START | I2C_CR2_STOP)); + + /* update tmpreg */ + tmpreg |= (uint32_t)(((uint32_t)Address & I2C_CR2_SADD) | (((uint32_t)Number_Bytes << 16) & I2C_CR2_NBYTES) | \ + (uint32_t)ReloadEndMode | (uint32_t)StartStopMode); + + /* update CR2 register */ + I2Cx->CR2 = tmpreg; +} + +/** + * @} + */ + +/** + * @brief Enables or disables I2C SMBus alert. + * @param I2Cx: where x can be 1 or 2 or 3 to select the I2C peripheral. + * @param NewState: new state of the I2Cx SMBus alert. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_SMBusAlertCmd(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable SMBus alert */ + I2Cx->CR1 |= I2C_CR1_ALERTEN; + } + else + { + /* Disable SMBus alert */ + I2Cx->CR1 &= (uint32_t)~((uint32_t)I2C_CR1_ALERTEN); + } +} + +/** + * @brief Enables or disables I2C Clock Timeout (SCL Timeout detection). + * @param I2Cx: where x can be 1 or 2 or 3 to select the I2C peripheral. + * @param NewState: new state of the I2Cx clock Timeout. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_ClockTimeoutCmd(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable Clock Timeout */ + I2Cx->TIMEOUTR |= I2C_TIMEOUTR_TIMOUTEN; + } + else + { + /* Disable Clock Timeout */ + I2Cx->TIMEOUTR &= (uint32_t)~((uint32_t)I2C_TIMEOUTR_TIMOUTEN); + } +} + +/** + * @brief Enables or disables I2C Extended Clock Timeout (SCL cumulative Timeout detection). + * @param I2Cx: where x can be 1 or 2 or 3 to select the I2C peripheral. + * @param NewState: new state of the I2Cx Extended clock Timeout. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_ExtendedClockTimeoutCmd(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable Clock Timeout */ + I2Cx->TIMEOUTR |= I2C_TIMEOUTR_TEXTEN; + } + else + { + /* Disable Clock Timeout */ + I2Cx->TIMEOUTR &= (uint32_t)~((uint32_t)I2C_TIMEOUTR_TEXTEN); + } +} + +/** + * @brief Enables or disables I2C Idle Clock Timeout (Bus idle SCL and SDA + * high detection). + * @param I2Cx: where x can be 1 or 2 or 3 to select the I2C peripheral. + * @param NewState: new state of the I2Cx Idle clock Timeout. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_IdleClockTimeoutCmd(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable Clock Timeout */ + I2Cx->TIMEOUTR |= I2C_TIMEOUTR_TIDLE; + } + else + { + /* Disable Clock Timeout */ + I2Cx->TIMEOUTR &= (uint32_t)~((uint32_t)I2C_TIMEOUTR_TIDLE); + } +} + +/** + * @brief Configures the I2C Bus Timeout A (SCL Timeout when TIDLE = 0 or Bus + * idle SCL and SDA high when TIDLE = 1). + * @param I2Cx: where x can be 1 or 2 or 3 to select the I2C peripheral. + * @param Timeout: specifies the TimeoutA to be programmed. + * @retval None + */ +void I2C_TimeoutAConfig(I2C_TypeDef* I2Cx, uint16_t Timeout) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_TIMEOUT(Timeout)); + + /* Get the old register value */ + tmpreg = I2Cx->TIMEOUTR; + + /* Reset I2Cx TIMEOUTA bit [11:0] */ + tmpreg &= (uint32_t)~((uint32_t)I2C_TIMEOUTR_TIMEOUTA); + + /* Set I2Cx TIMEOUTA */ + tmpreg |= (uint32_t)((uint32_t)Timeout & I2C_TIMEOUTR_TIMEOUTA) ; + + /* Store the new register value */ + I2Cx->TIMEOUTR = tmpreg; +} + +/** + * @brief Configures the I2C Bus Timeout B (SCL cumulative Timeout). + * @param I2Cx: where x can be 1 or 2 or 3 to select the I2C peripheral. + * @param Timeout: specifies the TimeoutB to be programmed. + * @retval None + */ +void I2C_TimeoutBConfig(I2C_TypeDef* I2Cx, uint16_t Timeout) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_TIMEOUT(Timeout)); + + /* Get the old register value */ + tmpreg = I2Cx->TIMEOUTR; + + /* Reset I2Cx TIMEOUTB bit [11:0] */ + tmpreg &= (uint32_t)~((uint32_t)I2C_TIMEOUTR_TIMEOUTB); + + /* Set I2Cx TIMEOUTB */ + tmpreg |= (uint32_t)(((uint32_t)Timeout << 16) & I2C_TIMEOUTR_TIMEOUTB) ; + + /* Store the new register value */ + I2Cx->TIMEOUTR = tmpreg; +} + +/** + * @brief Enables or disables I2C PEC calculation. + * @param I2Cx: where x can be 1 or 2 or 3 to select the I2C peripheral. + * @param NewState: new state of the I2Cx PEC calculation. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_CalculatePEC(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable PEC calculation */ + I2Cx->CR1 |= I2C_CR1_PECEN; + } + else + { + /* Disable PEC calculation */ + I2Cx->CR1 &= (uint32_t)~((uint32_t)I2C_CR1_PECEN); + } +} + +/** + * @brief Enables or disables I2C PEC transmission/reception request. + * @param I2Cx: where x can be 1 or 2 or 3 to select the I2C peripheral. + * @param NewState: new state of the I2Cx PEC request. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_PECRequestCmd(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable PEC transmission/reception request */ + I2Cx->CR2 |= I2C_CR2_PECBYTE; + } + else + { + /* Disable PEC transmission/reception request */ + I2Cx->CR2 &= (uint32_t)~((uint32_t)I2C_CR2_PECBYTE); + } +} + +/** + * @brief Returns the I2C PEC. + * @param I2Cx: where x can be 1 or 2 or 3 to select the I2C peripheral. + * @retval The value of the PEC . + */ +uint8_t I2C_GetPEC(I2C_TypeDef* I2Cx) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + + /* Return the slave matched address in the SR1 register */ + return (uint8_t)((uint32_t)I2Cx->PECR & I2C_PECR_PEC); +} + +/** + * @} + */ + + + +/** +* @brief Reads the specified I2C register and returns its value. +* @param I2Cx: where x can be 1 or 2 or 3 to select the I2C peripheral. +* @param I2C_Register: specifies the register to read. +* This parameter can be one of the following values: +* @arg I2C_Register_CR1: CR1 register. +* @arg I2C_Register_CR2: CR2 register. +* @arg I2C_Register_OAR1: OAR1 register. +* @arg I2C_Register_OAR2: OAR2 register. +* @arg I2C_Register_TIMINGR: TIMING register. +* @arg I2C_Register_TIMEOUTR: TIMEOUTR register. +* @arg I2C_Register_ISR: ISR register. +* @arg I2C_Register_ICR: ICR register. +* @arg I2C_Register_PECR: PECR register. +* @arg I2C_Register_RXDR: RXDR register. +* @arg I2C_Register_TXDR: TXDR register. +* @retval The value of the read register. +*/ +uint32_t I2C_ReadRegister(I2C_TypeDef* I2Cx, uint8_t I2C_Register) +{ + __IO uint32_t tmp = 0; + + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_REGISTER(I2C_Register)); + + tmp = (uint32_t)I2Cx; + tmp += I2C_Register; + + /* Return the selected register value */ + return (*(__IO uint32_t *) tmp); +} + +/** + * @} + */ + +/** + * @brief Sends a data byte through the I2Cx peripheral. + * @param I2Cx: where x can be 1 or 2 or 3 to select the I2C peripheral. + * @param Data: Byte to be transmitted.. + * @retval None + */ +void I2C_SendData(I2C_TypeDef* I2Cx, uint8_t Data) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + + /* Write in the DR register the data to be sent */ + I2Cx->TXDR = (uint8_t)Data; +} + +/** + * @brief Returns the most recent received data by the I2Cx peripheral. + * @param I2Cx: where x can be 1 or 2 or 3 to select the I2C peripheral. + * @retval The value of the received data. + */ +uint8_t I2C_ReceiveData(I2C_TypeDef* I2Cx) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + + /* Return the data in the DR register */ + return (uint8_t)I2Cx->RXDR; +} + +/** + * @} + */ + +/** + * @brief Enables or disables the I2C DMA interface. + * @param I2Cx: where x can be 1 or 2 or 3 to select the I2C peripheral. + * @param I2C_DMAReq: specifies the I2C DMA transfer request to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg I2C_DMAReq_Tx: Tx DMA transfer request + * @arg I2C_DMAReq_Rx: Rx DMA transfer request + * @param NewState: new state of the selected I2C DMA transfer request. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_DMACmd(I2C_TypeDef* I2Cx, uint32_t I2C_DMAReq, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + assert_param(IS_I2C_DMA_REQ(I2C_DMAReq)); + + if (NewState != DISABLE) + { + /* Enable the selected I2C DMA requests */ + I2Cx->CR1 |= I2C_DMAReq; + } + else + { + /* Disable the selected I2C DMA requests */ + I2Cx->CR1 &= (uint32_t)~I2C_DMAReq; + } +} +/** + * @} + */ +/** + * @brief Checks whether the specified I2C flag is set or not. + * @param I2Cx: where x can be 1 or 2 or 3 to select the I2C peripheral. + * @param I2C_FLAG: specifies the flag to check. + * This parameter can be one of the following values: + * @arg I2C_FLAG_TXE: Transmit data register empty + * @arg I2C_FLAG_TXIS: Transmit interrupt status + * @arg I2C_FLAG_RXNE: Receive data register not empty + * @arg I2C_FLAG_ADDR: Address matched (slave mode) + * @arg I2C_FLAG_NACKF: NACK received flag + * @arg I2C_FLAG_STOPF: STOP detection flag + * @arg I2C_FLAG_TC: Transfer complete (master mode) + * @arg I2C_FLAG_TCR: Transfer complete reload + * @arg I2C_FLAG_BERR: Bus error + * @arg I2C_FLAG_ARLO: Arbitration lost + * @arg I2C_FLAG_OVR: Overrun/Underrun + * @arg I2C_FLAG_PECERR: PEC error in reception + * @arg I2C_FLAG_TIMEOUT: Timeout or Tlow detection flag + * @arg I2C_FLAG_ALERT: SMBus Alert + * @arg I2C_FLAG_BUSY: Bus busy + * @retval The new state of I2C_FLAG (SET or RESET). + */ +FlagStatus I2C_GetFlagStatus(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG) +{ + uint32_t tmpreg = 0; + FlagStatus bitstatus = RESET; + + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_GET_FLAG(I2C_FLAG)); + + /* Get the ISR register value */ + tmpreg = I2Cx->ISR; + + /* Get flag status */ + tmpreg &= I2C_FLAG; + + if (tmpreg != 0) + { + /* I2C_FLAG is set */ + bitstatus = SET; + } + else + { + /* I2C_FLAG is reset */ + bitstatus = RESET; + } + return bitstatus; +} + +/** + * @brief Clears the I2Cx's pending flags. + * @param I2Cx: where x can be 1 or 2 or 3 to select the I2C peripheral. + * @param I2C_FLAG: specifies the flag to clear. + * This parameter can be any combination of the following values: + * @arg I2C_FLAG_ADDR: Address matched (slave mode) + * @arg I2C_FLAG_NACKF: NACK received flag + * @arg I2C_FLAG_STOPF: STOP detection flag + * @arg I2C_FLAG_BERR: Bus error + * @arg I2C_FLAG_ARLO: Arbitration lost + * @arg I2C_FLAG_OVR: Overrun/Underrun + * @arg I2C_FLAG_PECERR: PEC error in reception + * @arg I2C_FLAG_TIMEOUT: Timeout or Tlow detection flag + * @arg I2C_FLAG_ALERT: SMBus Alert + * @retval None + */ +void I2C_ClearFlag(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_CLEAR_FLAG(I2C_FLAG)); + + /* Clear the selected flag */ + I2Cx->ICR = I2C_FLAG; +} + +/** + * @brief Checks whether the specified I2C interrupt has occurred or not. + * @param I2Cx: where x can be 1 or 2 or 3 to select the I2C peripheral. + * @param I2C_IT: specifies the interrupt source to check. + * This parameter can be one of the following values: + * @arg I2C_IT_TXIS: Transmit interrupt status + * @arg I2C_IT_RXNE: Receive data register not empty + * @arg I2C_IT_ADDR: Address matched (slave mode) + * @arg I2C_IT_NACKF: NACK received flag + * @arg I2C_IT_STOPF: STOP detection flag + * @arg I2C_IT_TC: Transfer complete (master mode) + * @arg I2C_IT_TCR: Transfer complete reload + * @arg I2C_IT_BERR: Bus error + * @arg I2C_IT_ARLO: Arbitration lost + * @arg I2C_IT_OVR: Overrun/Underrun + * @arg I2C_IT_PECERR: PEC error in reception + * @arg I2C_IT_TIMEOUT: Timeout or Tlow detection flag + * @arg I2C_IT_ALERT: SMBus Alert + * @retval The new state of I2C_IT (SET or RESET). + */ +ITStatus I2C_GetITStatus(I2C_TypeDef* I2Cx, uint32_t I2C_IT) +{ + uint32_t tmpreg = 0; + ITStatus bitstatus = RESET; + uint32_t enablestatus = 0; + + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_GET_IT(I2C_IT)); + + /* Check if the interrupt source is enabled or not */ + /* If Error interrupt */ + if ((uint32_t)(I2C_IT & ERROR_IT_MASK)) + { + enablestatus = (uint32_t)((I2C_CR1_ERRIE) & (I2Cx->CR1)); + } + /* If TC interrupt */ + else if ((uint32_t)(I2C_IT & TC_IT_MASK)) + { + enablestatus = (uint32_t)((I2C_CR1_TCIE) & (I2Cx->CR1)); + } + else + { + enablestatus = (uint32_t)((I2C_IT) & (I2Cx->CR1)); + } + + /* Get the ISR register value */ + tmpreg = I2Cx->ISR; + + /* Get flag status */ + tmpreg &= I2C_IT; + + /* Check the status of the specified I2C flag */ + if ((tmpreg != RESET) && enablestatus) + { + /* I2C_IT is set */ + bitstatus = SET; + } + else + { + /* I2C_IT is reset */ + bitstatus = RESET; + } + + /* Return the I2C_IT status */ + return bitstatus; +} + +/** + * @brief Clears the I2Cx's interrupt pending bits. + * @param I2Cx: where x can be 1 or 2 or 3 to select the I2C peripheral. + * @param I2C_IT: specifies the interrupt pending bit to clear. + * This parameter can be any combination of the following values: + * @arg I2C_IT_ADDR: Address matched (slave mode) + * @arg I2C_IT_NACKF: NACK received flag + * @arg I2C_IT_STOPF: STOP detection flag + * @arg I2C_IT_BERR: Bus error + * @arg I2C_IT_ARLO: Arbitration lost + * @arg I2C_IT_OVR: Overrun/Underrun + * @arg I2C_IT_PECERR: PEC error in reception + * @arg I2C_IT_TIMEOUT: Timeout or Tlow detection flag + * @arg I2C_IT_ALERT: SMBus Alert + * @retval None. + */ +void I2C_ClearITPendingBit(I2C_TypeDef* I2Cx, uint32_t I2C_IT) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_CLEAR_IT(I2C_IT)); + + /* Clear the selected flag */ + I2Cx->ICR = I2C_IT; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT FMD *****END OF FILE**********************/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_i2s.c b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_i2s.c new file mode 100644 index 00000000000..8c2e7e99500 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_i2s.c @@ -0,0 +1,1626 @@ +/** + ****************************************************************************** + * @file ft32f4xx_i2s.c + * @author FMD AE + * @brief This file provides firmware functions to manage the following + * functionalities of the Inter-IC Sound (I2S): + * + Initialization and Configuration + * + Communications management + * + I2S registers management + * + Data transfers management + * + Interrupts management + * @version V1.0.0 + * @date 2025-03-31 + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx_i2s.h" +#include "ft32f4xx_rcc.h" + +/** @defgroup I2S I2S + * @brief I2S module driver + * @{ + */ + +/** @defgroup I2S_Exported_Functions I2S Exported Functions + * @{ + */ + +/** + * @brief Deinitializes the I2Sx peripheral registers to their default reset values. + * @param I2Sx: where x can be 2 or 3 to select the I2S peripheral. + * @retval None + */ +void I2S_DeInit(I2S_TypeDef* I2Sx) +{ + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + + if (I2Sx == I2S2) + { + /* Enable I2S2 reset state */ + RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2S2, ENABLE); + /* Release I2S2 from reset state */ + RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2S2, DISABLE); + } + else + { + /* Enable I2S3 reset state */ + RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2S3, ENABLE); + /* Release I2S3 from reset state */ + RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2S3, DISABLE); + } +} + + +/** + * @brief Initializes the I2Sx peripheral according to the specified + * parameters in the I2S_InitStruct. + * @param I2Sx: where x can be 2 or 3 to select the I2S peripheral. + * @param I2S_InitStruct: pointer to a I2S_InitTypeDef structure that + * contains the configuration information for the specified I2S peripheral. + * @retval None + */ +void I2S_Init(I2S_TypeDef* I2Sx, I2S_InitTypeDef* I2S_InitStruct) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + assert_param(IS_I2S_CH0_CONFIG(I2S_InitStruct->I2S_Channel0)); + assert_param(IS_I2S_CH1_CONFIG(I2S_InitStruct->I2S_Channel1)); + assert_param(IS_I2S_MASTERSLAVE_STATE(I2S_InitStruct->I2S_TranMasterSlaveConfig)); + assert_param(IS_I2S_SAMPLE_RATE(I2S_InitStruct->I2S_TranSampleRate)); + assert_param(IS_I2S_SAMPLE_RATE(I2S_InitStruct->I2S_RecSampleRate)); + assert_param(IS_I2S_RESOLUTION(I2S_InitStruct->I2S_TranSampleResolution)); + assert_param(IS_I2S_RESOLUTION(I2S_InitStruct->I2S_RecSampleResolution)); + assert_param(IS_I2S_FIFO_THRESHOLD(I2S_InitStruct->I2S_TFIFOAEmptyThreshold)); + assert_param(IS_I2S_FIFO_THRESHOLD(I2S_InitStruct->I2S_TFIFOAFullThreshold)); + assert_param(IS_I2S_FIFO_THRESHOLD(I2S_InitStruct->I2S_RFIFOAEmptyThreshold)); + assert_param(IS_I2S_FIFO_THRESHOLD(I2S_InitStruct->I2S_RFIFOAFullThreshold)); + assert_param(IS_I2S_STANDARD(I2S_InitStruct->I2S_Standard)); + + /* Software reset I2S special function register + * Software reset I2S TX FIFO + * Software reset I2S RX FIFO + * Software reset I2S TX control unit + * Software reset I2S RX control unit + * Software reset I2S channel 0 + * Software reset I2S channel 1 */ + I2Sx->CTRL &= (uint32_t)~(((uint32_t)I2S_CTRL_SFRRST) | + ((uint32_t)I2S_CTRL_TFIFORST) | ((uint32_t)I2S_CTRL_RFIFORST) | + ((uint32_t)I2S_CTRL_TSYNCRST) | ((uint32_t)I2S_CTRL_RSYNCRST) | + ((uint32_t)I2S_CTRL_I2SEN0) | ((uint32_t)I2S_CTRL_I2SEN1)); + + /*---------------------------- I2Sx Channel0 Configuration ------------------*/ + /* Configure I2Sx channel : enable or disable, transmitter or receiver */ + /* Set I2SEN0 bit according to I2S_Channel0 value */ + /* Set TRCFG0 bits according to I2S_Channel0 value */ + if (I2S_InitStruct->I2S_Channel0 == I2S_Ch0_Disable) + { + I2Sx->CTRL &= (uint32_t)~((uint32_t)I2S_CTRL_I2SEN0); + } + else if (I2S_InitStruct->I2S_Channel0 == I2S_Ch0_Transmitter) + { + I2Sx->CTRL |= I2S_CTRL_TRCFG0; + } + else if (I2S_InitStruct->I2S_Channel0 == I2S_Ch0_Receiver) + { + I2Sx->CTRL &= (uint32_t)~((uint32_t)I2S_CTRL_TRCFG0); + } + + /*---------------------------- I2Sx Channel1 Configuration ------------------*/ + /* Configure I2Sx channel : enable or disable, transmitter or receiver */ + /* Set I2SEN1 bit according to I2S_Channel1 value */ + /* Set TRCFG1 bit according to I2S_Channel1 value */ + if (I2S_InitStruct->I2S_Channel1 == I2S_Ch1_Disable) + { + I2Sx->CTRL &= (uint32_t)~((uint32_t)I2S_CTRL_I2SEN1); + } + else if (I2S_InitStruct->I2S_Channel1 == I2S_Ch1_Transmitter) + { + I2Sx->CTRL |= I2S_CTRL_TRCFG1; + } + else if (I2S_InitStruct->I2S_Channel1 == I2S_Ch1_Receiver) + { + I2Sx->CTRL &= (uint32_t)~((uint32_t)I2S_CTRL_TRCFG1); + } + + /*-------------------- I2Sx transmitter master or slave configuration --------------*/ + /* Set TMS bit according to I2S_TranMasterSlaveConfig value*/ + if (I2S_InitStruct->I2S_TranMasterSlaveConfig != I2S_SLAVE) + { + /* Set I2S transmitter synchronizing unit to master */ + I2Sx->CTRL |= I2S_CTRL_TMS; + } + else + { + /* Set I2S transmitter synchronizing unit to slave */ + I2Sx->CTRL &= (uint32_t)~((uint32_t)I2S_CTRL_TMS); + } + + /*-------------------- I2Sx receiver master or slave configuration --------------*/ + /* Set RMS bit according to I2S_RecMasterSlaveConfig value*/ + if (I2S_InitStruct->I2S_RecMasterSlaveConfig != I2S_SLAVE) + { + /* Set I2S receiver synchronizing unit to master */ + I2Sx->CTRL |= I2S_CTRL_RMS; + } + else + { + /* Set I2S receiver synchronizing unit to slave */ + I2Sx->CTRL &= (uint32_t)~((uint32_t)I2S_CTRL_RMS); + } + + /*-------------- I2Sx tansmitter sample rate configuration -----------------*/ + /* Set TSAMPLERATE bits according to I2S_TranSampleRate values */ + I2Sx->SRR |= I2S_InitStruct->I2S_TranSampleRate; + /*-------------- I2Sx transmitter sample resolution configuration ----------*/ + /* Set TRESOLUTION bits according to I2S_TranSampleResolution values */ + I2Sx->SRR |= (I2S_InitStruct->I2S_TranSampleResolution << 11); + /*-------------- I2Sx receiver sample rate configuration -------------------*/ + /* Set RSAMPLERATE bits according to I2S_RecSampleRate values */ + I2Sx->SRR |= (I2S_InitStruct->I2S_RecSampleRate << 16); + /*-------------- I2Sx receiver sample resolution configuration -------------*/ + /* Set RRESOLUTION bits according to I2S_RecSampleResolution values */ + I2Sx->SRR |= (I2S_InitStruct->I2S_RecSampleResolution << 27); + + /*----------I2S transmit FIFO almost empty threshold configuration ---------*/ + /* Set TAEMPTYTHRESHOLD bits according to I2S_TFIFOAEmptyThreshold values*/ + I2Sx->TFIFO_CTRL |= (I2S_InitStruct->I2S_TFIFOAEmptyThreshold); + /*----------I2S transmit FIFO almost full threshold configuration ---------*/ + /* Get the old register value */ + tmpreg = I2Sx->TFIFO_CTRL; + /* Reset I2Sx TAFULLTHRESHOLD bit [2:0] */ + tmpreg &= (uint32_t)~((uint32_t)I2S_TFIFO_CTRL_TAFULLTHRESHOLD); + /* Set TAFULLTHRESHOLD bits according to I2S_TFIFOAFullThreshold values*/ + tmpreg |= (uint32_t)(((uint32_t)I2S_InitStruct->I2S_TFIFOAFullThreshold << 16) & + I2S_TFIFO_CTRL_TAFULLTHRESHOLD); + /* Store the new register value */ + I2Sx->TFIFO_CTRL = tmpreg; + + + /*----------I2S receive FIFO almost empty threshold configuration ---------*/ + /* Set RAEMPTYTHRESHOLD bits according to I2S_RFIFOAEmptyThreshold values*/ + I2Sx->RFIFO_CTRL |= (I2S_InitStruct->I2S_RFIFOAEmptyThreshold << 16); + /*----------I2S receive FIFO almost full threshold configuration ---------*/ + /* Get the old register value */ + tmpreg = I2Sx->RFIFO_CTRL; + /* Reset I2Sx RAFULLTHRESHOLD bit [2:0] */ + tmpreg &= (uint32_t)~((uint32_t)I2S_RFIFO_CTRL_RAFULLTHRESHOLD); + /* Set RAFULLTHRESHOLD bits according to I2S_RFIFOAFullThreshold values*/ + tmpreg |= (uint32_t)(((uint32_t)I2S_InitStruct->I2S_RFIFOAFullThreshold << 16) & + I2S_RFIFO_CTRL_RAFULLTHRESHOLD); + /* Store the new register value */ + I2Sx->RFIFO_CTRL = tmpreg; + + /*------------------I2S standard configuration------------------------------*/ + /* Set DEV_CONF registers according to I2S_STANDARD values */ + I2Sx->DEV_CONF = I2S_InitStruct->I2S_Standard; +} + + +/** + * @brief Fills each I2S_InitStruct member with its default value. + * @param I2S_InitStruct: pointer to an I2S_InitTypeDef structure which will be initialized. + * @retval None + */ +void I2S_StructInit(I2S_InitTypeDef* I2S_InitStruct) +{ + /*---------------- Reset I2S init structure parameters values --------------*/ + /* Initialize the I2S_Channel0 member */ + I2S_InitStruct->I2S_Channel0 = 0; + /* Initialize the I2S_Channel1 member */ + I2S_InitStruct->I2S_Channel1 = 0; + + /* Initialize the I2S_TranMasterSlaveConfig member */ + I2S_InitStruct->I2S_TranMasterSlaveConfig = 0; + /* Initialize the I2S_RecMasterSlaveConfig member */ + I2S_InitStruct->I2S_RecMasterSlaveConfig = 0; + + /* Initialize the I2S_TranSampleRate member */ + I2S_InitStruct->I2S_TranSampleRate = 0; + /* Initialize the I2S_TranSampleResolution member */ + I2S_InitStruct->I2S_TranSampleResolution = 0; + /* Initialize the I2S_RecSampleRate member */ + I2S_InitStruct->I2S_RecSampleRate = 0; + /* Initialize the I2S_RecSampleResolution member */ + I2S_InitStruct->I2S_RecSampleResolution = 0; + + /* Initialize the I2S_TFIFOAEmptyThreshold member */ + I2S_InitStruct->I2S_TFIFOAEmptyThreshold = 0; + /* Initialize the I2S_TFIFOAFullThreshold member */ + I2S_InitStruct->I2S_TFIFOAFullThreshold = 7; + /* Initialize the I2S_RFIFOAEmptyThreshold member */ + I2S_InitStruct->I2S_RFIFOAEmptyThreshold = 0; + /* Initialize the I2S_RFIFOAFullThreshold member */ + I2S_InitStruct->I2S_RFIFOAFullThreshold = 7; + + /* Initialize the I2S_Standard member */ + I2S_InitStruct->I2S_Standard = 0; +} + +/** + * @brief Enables or disables I2S channel + * @param I2Sx: where x can be 2 or 3 to select the I2S peripheral. + * @param CHy: I2S channel y select, where y can be 0 or 1 to select the I2S channel + * This parameter can be any combination of the following values: + * @arg I2S_CH0: I2S channel 0 select + * @arg I2S_CH1: I2S channel 1 select + * @param NewState: new state of the I2Sx channel 0/1. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2S_ChannelConfig(I2S_TypeDef* I2Sx, uint32_t CHy, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + assert_param(IS_I2S_CHANNEL_SEL(CHy)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable channel y */ + I2Sx->CTRL |= CHy; + } + else + { + /* Disable channel y */ + I2Sx->CTRL &= (uint32_t)~((uint32_t)CHy); + } +} + + +/** + * @brief I2S channel 0/1 transmitter or receiver config + * @param I2Sx: where x can be 2 or 3 to select the I2S peripheral. + * @param CHy_TRANREC: I2S channel y transmitter or receiver config, + * where y can be 0 or 1 to select the I2S channel. + * This parameter can be any combination of the following values: + * @arg I2S_CH0_TRANREC: I2S channel 0 is transmitter or receiver + * @arg I2S_CH1_TRANREC: I2S channel 1 is transmitter or receiver + * @param I2S_TranRec: transmitter or receiver of the I2Sx channel 0/1. + * This parameter can be one of the following values: + * @arg I2S_TRANSMITTER: I2S channel y is transmitter + * @arg I2S_RECEIVER : I2S channel y is receiver + * @retval None + */ +void I2S_ChannelTranRecConfig(I2S_TypeDef* I2Sx, uint32_t CHy_TRANREC, uint32_t I2S_TranRec) +{ + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + assert_param(IS_I2S_CHANNEL_TRANREC(CHy_TRANREC)); + assert_param(IS_I2S_TRANREC_STATE(I2S_TranRec)); + + if (I2S_TranRec != I2S_RECEIVER) + { + /* Set channel y to transmitter */ + I2Sx->CTRL |= CHy_TRANREC; + } + else + { + /* Set channel y to receiver */ + I2Sx->CTRL &= (uint32_t)~((uint32_t)CHy_TRANREC); + } +} + + +/** + * @brief Enables or disables the Loop-back test for I2S channel 0/1 + * @param I2Sx: where x can be 2 or 3 to select the I2S peripheral. + * @param NewState: new state of the I2Sx channel 0/1 Loop-back test. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2S_LoopBackCmd(I2S_TypeDef* I2Sx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable Loop-Back test mode */ + I2Sx->CTRL |= I2S_CTRL_LOOPBACK01; + } + else + { + /* Disable Loop-Back test mode */ + I2Sx->CTRL &= (uint32_t)~((uint32_t)I2S_CTRL_LOOPBACK01); + } +} + + +/** + * @brief Software reset I2S special function register. + * @param I2Sx: where x can be 2 or 3 to select the I2S peripheral. + * @retval None + */ +void I2S_SFRResetCmd(I2S_TypeDef* I2Sx) +{ + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + + /* Reset SFR */ + I2Sx->CTRL &= (uint32_t)~((uint32_t)I2S_CTRL_SFRRST); +} + + +/** + * @brief Configures I2S transmitter synchronizing unit as the master or slave + * @param I2Sx: where x can be 2 or 3 to select the I2S peripheral. + * @param I2S_MS: master or slave of the I2Sx transmitter synchronizing unit. + * This parameter can be one of the following values: + * @arg I2S_MASTER: I2S transmitter synchronizing unit is master. + * @arg I2S_SLAVE : I2S transmitter synchronizing unit is slave. + * @retval None + */ +void I2S_TranMasterSlaveConfig(I2S_TypeDef* I2Sx, uint32_t I2S_MS) +{ + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + assert_param(IS_I2S_MASTERSLAVE_STATE(I2S_MS)); + + if (I2S_MS != I2S_SLAVE) + { + /* Set I2S transmitter synchronizing unit to master */ + I2Sx->CTRL |= I2S_CTRL_TMS; + } + else + { + /* Set I2S transmitter synchronizing unit to slave */ + I2Sx->CTRL &= (uint32_t)~((uint32_t)I2S_CTRL_TMS); + } +} + + +/** + * @brief Configures I2S receiver synchronizing unit as the master or slave + * @param I2Sx: where x can be 2 or 3 to select the I2S peripheral. + * @param I2S_MS: master or slave of the I2Sx receiver synchronizing unit. + * This parameter can be one of the following values: + * @arg I2S_MASTER: I2S receiver synchronizing unit is master. + * @arg I2S_SLAVE : I2S receiver synchronizing unit is slave. + * @retval None + */ +void I2S_RecMasterSlaveConfig(I2S_TypeDef* I2Sx, uint32_t I2S_MS) +{ + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + assert_param(IS_I2S_MASTERSLAVE_STATE(I2S_MS)); + + if (I2S_MS != I2S_SLAVE) + { + /* Set I2S receiver synchronizing unit to master */ + I2Sx->CTRL |= I2S_CTRL_RMS; + } + else + { + /* Set I2S receiver synchronizing unit to slave */ + I2Sx->CTRL &= (uint32_t)~((uint32_t)I2S_CTRL_RMS); + } +} + + +/** + * @brief Software reset I2S transmit FIFO. + * @param I2Sx: where x can be 2 or 3 to select the I2S peripheral. + * @retval None + */ +void I2S_TFIFOResetCmd(I2S_TypeDef* I2Sx) +{ + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + + /* Reset transmit FIFO */ + I2Sx->CTRL &= (uint32_t)~((uint32_t)I2S_CTRL_TFIFORST); +} + + +/** + * @brief Software reset I2S receive FIFO. + * @param I2Sx: where x can be 2 or 3 to select the I2S peripheral. + * @retval None + */ +void I2S_RFIFOResetCmd(I2S_TypeDef* I2Sx) +{ + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + + /* Reset receive FIFO */ + I2Sx->CTRL &= (uint32_t)~((uint32_t)I2S_CTRL_RFIFORST); +} + + +/** + * @brief Software reset I2S transmitter synchronizing unit. + * @param I2Sx: where x can be 2 or 3 to select the I2S peripheral. + * @param NewState: new state of the I2Sx transmitter synchronizing unit software reset. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2S_TranSyncResetCmd(I2S_TypeDef* I2Sx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + /* Reset transmitter synchronizing unit */ + if (NewState != DISABLE) + { + /* Enable software reset transmitter synchronizing unit */ + I2Sx->CTRL &= (uint32_t)~((uint32_t)I2S_CTRL_TSYNCRST); + } + else + { + /* Disable software reset transmitter synchronizing unit */ + I2Sx->CTRL |= I2S_CTRL_TSYNCRST; + } +} + + +/** + * @brief Software reset I2S Receiver synchronizing unit. + * @param I2Sx: where x can be 2 or 3 to select the I2S peripheral. + * @param NewState: new state of the I2Sx receiver synchronizing unit software reset. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2S_RecSyncResetCmd(I2S_TypeDef* I2Sx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable software reset receiver synchronizing unit */ + I2Sx->CTRL &= (uint32_t)~((uint32_t)I2S_CTRL_RSYNCRST); + } + else + { + /* Disable software reset receiver synchronizing unit */ + I2Sx->CTRL |= I2S_CTRL_RSYNCRST; + } +} + +/** + * @brief Enables or disables the Loop-back test for I2S transmitter + * synchronizing unit. + * @param I2Sx: where x can be 2 or 3 to select the I2S peripheral. + * @param NewState: new state of the I2Sx transmitter synchronizing unit + * loop-back test. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2S_TranSyncLoopBackCmd(I2S_TypeDef* I2Sx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable Loop-back test for I2S transmitter synchronizing unit */ + I2Sx->CTRL |= I2S_CTRL_TSYNCLOOPBACK; + } + else + { + /* Disable Loop-back test for I2S transmitter synchronizing unit */ + I2Sx->CTRL &= (uint32_t)~((uint32_t)I2S_CTRL_TSYNCLOOPBACK); + } +} + + +/** + * @brief Enables or disables the Loop-back test for I2S receiver + * synchronizing unit. + * @param I2Sx: where x can be 2 or 3 to select the I2S peripheral. + * @param NewState: new state of the I2Sx receiver synchronizing unit + * loop-back test. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2S_RecSyncLoopBackCmd(I2S_TypeDef* I2Sx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable Loop-back test for I2S receiver synchronizing unit*/ + I2Sx->CTRL |= I2S_CTRL_RSYNCLOOPBACK; + } + else + { + /* Disable Loop-back test for I2S receiver synchronizing unit */ + I2Sx->CTRL &= (uint32_t)~((uint32_t)I2S_CTRL_RSYNCLOOPBACK); + } +} + + +/** + * @brief Configures the transmitter sample rate. + * @param I2Sx: where x can be 2 or 3 to select the I2S peripheral. + * @param SAMPLE_RATE specifies the sample rate to be programmed. + * @retval None + */ +void I2S_TranSampleRateConfig(I2S_TypeDef* I2Sx, uint16_t SAMPLE_RATE) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + assert_param(IS_I2S_SAMPLE_RATE(SAMPLE_RATE)); + + /* Get the old register value */ + tmpreg = I2Sx->SRR; + + /* Reset I2Sx TSAMPLERATE bit [10:0] */ + tmpreg &= (uint32_t)~((uint32_t)I2S_SRR_TSAMPLERATE); + + /* Set I2Sx TSAMPLERATE */ + tmpreg |= (uint32_t)((uint32_t)SAMPLE_RATE & I2S_SRR_TSAMPLERATE); + + /* Store the new register value */ + I2Sx->SRR = tmpreg; +} + + +/** + * @brief Configures the transmitter sample resolution. + * @param I2Sx: where x can be 2 or 3 to select the I2S peripheral. + * @param RESOLUTION specifies the sample resolution to be programmed. + * @retval None + */ +void I2S_TranSampleResolutionConfig(I2S_TypeDef* I2Sx, uint8_t RESOLUTION) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + assert_param(IS_I2S_RESOLUTION(RESOLUTION)); + + /* Get the old register value */ + tmpreg = I2Sx->SRR; + + /* Reset I2Sx TRESOLUTION bit [10:0] */ + tmpreg &= (uint32_t)~((uint32_t)I2S_SRR_TRESOLUTION); + + /* Set I2Sx TRESOLUTION */ + tmpreg |= (uint32_t)(((uint32_t)RESOLUTION << 11) & I2S_SRR_TRESOLUTION); + + /* Store the new register value */ + I2Sx->SRR = tmpreg; +} + + +/** + * @brief Configures the receiver sample rate. + * @param I2Sx: where x can be 2 or 3 to select the I2S peripheral. + * @param SAMPLE_RATE specifies the sample rate to be programmed. + * @retval None + */ +void I2S_RecSampleRateConfig(I2S_TypeDef* I2Sx, uint16_t SAMPLE_RATE) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + assert_param(IS_I2S_SAMPLE_RATE(SAMPLE_RATE)); + + /* Get the old register value */ + tmpreg = I2Sx->SRR; + + /* Reset I2Sx RSAMPLERATE bit [10:0] */ + tmpreg &= (uint32_t)~((uint32_t)I2S_SRR_RSAMPLERATE); + + /* Set I2Sx RSAMPLERATE */ + tmpreg |= (uint32_t)(((uint32_t)SAMPLE_RATE << 16) & I2S_SRR_RSAMPLERATE); + + /* Store the new register value */ + I2Sx->SRR = tmpreg; +} + + +/** + * @brief Configures the receiver sample resolution. + * @param I2Sx: where x can be 2 or 3 to select the I2S peripheral. + * @param RESOLUTION specifies the sample resolution to be programmed. + * @retval None + */ +void I2S_RecSampleResolutionConfig(I2S_TypeDef* I2Sx, uint8_t RESOLUTION) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + assert_param(IS_I2S_RESOLUTION(RESOLUTION)); + + /* Get the old register value */ + tmpreg = I2Sx->SRR; + + /* Reset I2Sx RRESOLUTION bit [10:0] */ + tmpreg &= (uint32_t)~((uint32_t)I2S_SRR_RRESOLUTION); + + /* Set I2Sx RRESOLUTION */ + tmpreg |= (uint32_t)(((uint32_t)RESOLUTION << 27) & I2S_SRR_RRESOLUTION); + + /* Store the new register value */ + I2Sx->SRR = tmpreg; +} + + +/** + * @brief Enables or disables I2S channel 0/1 clock + * @param I2Sx: where x can be 2 or 3 to select the I2S peripheral. + * @param CHy_CLOCK: I2S channel y clock strobe, where y can be 0 or 1 + * to select the I2S channel. + * This parameter can be any combination of the following values: + * @arg I2S_CH0_CLOCK_STROBE: I2S channel 0 clock strobe + * @arg I2S_CH1_CLOCK_STROBE: I2S channel 1 clock strobe + * @param NewState: new state of the I2Sx channel 0/1 clock. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2S_ChannelClockConfig(I2S_TypeDef* I2Sx, uint32_t CHy_CLOCK, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + assert_param(IS_I2S_CHANNEL_CLOCK_STROBE(CHy_CLOCK)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable channel y clock */ + I2Sx->CID_CTRL &= (uint32_t)~((uint32_t)CHy_CLOCK); + } + else + { + /* Disable channel y clock */ + I2Sx->CID_CTRL |= CHy_CLOCK; + } +} + + +/** + * @brief Enables or disables I2S transmitter synchronizing unit clock + * @param I2Sx: where x can be 2 or 3 to select the I2S peripheral. + * @param NewState: new state of the I2Sx transmitter synchronizing unit clock. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2S_TranSyncUnitCmd(I2S_TypeDef* I2Sx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable transmitter synchronizing unit clock*/ + I2Sx->CID_CTRL &= (uint32_t)~((uint32_t)I2S_CID_CTRL_STROBETS); + } + else + { + /* Disable transmitter synchronizing unit clock */ + I2Sx->CID_CTRL |= I2S_CID_CTRL_STROBETS; + } +} + + +/** + * @brief Enables or disables I2S receiver synchronizing unit clock + * @param I2Sx: where x can be 2 or 3 to select the I2S peripheral. + * @param NewState: new state of the I2Sx receiver synchronizing unit clock. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2S_RecSyncUnitCmd(I2S_TypeDef* I2Sx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable receiver synchronizing unit clock*/ + I2Sx->CID_CTRL &= (uint32_t)~((uint32_t)I2S_CID_CTRL_STROBERS); + } + else + { + /* Disable receiver synchronizing unit clock */ + I2Sx->CID_CTRL |= I2S_CID_CTRL_STROBERS; + } +} + + +/** + * @brief Returns the I2S transmit FIFO level status. + * @param I2Sx: where x can be 2 or 3 to select the I2S peripheral. + * @retval The value of the I2S transmit FIFO level status. + */ +uint8_t I2S_GetTranFIFOLevel(I2S_TypeDef* I2Sx) +{ + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + + /* Return the I2S transmit FIFO level status */ + return (uint8_t)((uint32_t)I2Sx->TFIFO_STAT & I2S_TFIFO_STAT_TLEVEL) ; +} + + +/** + * @brief Returns the I2S receive FIFO level status. + * @param I2Sx: where x can be 2 or 3 to select the I2S peripheral. + * @retval The value of the I2S receive FIFO level status. + */ +uint8_t I2S_GetRecFIFOLevel(I2S_TypeDef* I2Sx) +{ + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + + /* Return the I2S receive FIFO level status */ + return (uint8_t)((uint32_t)I2Sx->RFIFO_STAT & I2S_RFIFO_STAT_RLEVEL) ; +} + + +/** + * @brief Configures the threshold for almost empty flag in I2S transmit fifo. + * @param I2Sx: where x can be 2 or 3 to select the I2S peripheral. + * @param FIFO_Threshold specifies the fifo threshold to be programmed. + * @retval None + */ +void I2S_TFIFOAEmptyThresholdConfig(I2S_TypeDef* I2Sx, uint8_t FIFO_Threshold) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + assert_param(IS_I2S_FIFO_THRESHOLD(FIFO_Threshold)); + + /* Get the old register value */ + tmpreg = I2Sx->TFIFO_CTRL; + + /* Reset I2Sx TAEMPTYTHRESHOLD bit [2:0] */ + tmpreg &= (uint32_t)~((uint32_t)I2S_TFIFO_CTRL_TAEMPTYTHRESHOLD); + + /* Set I2Sx TAEMPTYTHRESHOLD */ + tmpreg |= (uint32_t)((uint32_t)FIFO_Threshold & I2S_TFIFO_CTRL_TAEMPTYTHRESHOLD); + + /* Store the new register value */ + I2Sx->TFIFO_CTRL = tmpreg; +} + + +/** + * @brief Configures the threshold for almost full flag in I2S transmit fifo. + * @param I2Sx: where x can be 2 or 3 to select the I2S peripheral. + * @param FIFO_Threshold specifies the fifo threshold to be programmed. + * @retval None + */ +void I2S_TFIFOAFullThresholdConfig(I2S_TypeDef* I2Sx, uint8_t FIFO_Threshold) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + assert_param(IS_I2S_FIFO_THRESHOLD(FIFO_Threshold)); + + /* Get the old register value */ + tmpreg = I2Sx->TFIFO_CTRL; + + /* Reset I2Sx TAFULLTHRESHOLD bit [2:0] */ + tmpreg &= (uint32_t)~((uint32_t)I2S_TFIFO_CTRL_TAFULLTHRESHOLD); + + /* Set I2Sx TAFULLTHRESHOLD */ + tmpreg |= (uint32_t)(((uint32_t)FIFO_Threshold << 16) & I2S_TFIFO_CTRL_TAFULLTHRESHOLD); + + /* Store the new register value */ + I2Sx->TFIFO_CTRL = tmpreg; +} + + +/** + * @brief Configures the threshold for almost empty flag in I2S receive fifo. + * @param I2Sx: where x can be 2 or 3 to select the I2S peripheral. + * @param FIFO_Threshold specifies the fifo threshold to be programmed. + * @retval None + */ +void I2S_RFIFOAEmptyThresholdConfig(I2S_TypeDef* I2Sx, uint8_t FIFO_Threshold) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + assert_param(IS_I2S_FIFO_THRESHOLD(FIFO_Threshold)); + + /* Get the old register value */ + tmpreg = I2Sx->RFIFO_CTRL; + + /* Reset I2Sx RAEMPTYTHRESHOLD bit [2:0] */ + tmpreg &= (uint32_t)~((uint32_t)I2S_RFIFO_CTRL_RAEMPTYTHRESHOLD); + + /* Set I2Sx RAEMPTYTHRESHOLD */ + tmpreg |= (uint32_t)((uint32_t)FIFO_Threshold & I2S_RFIFO_CTRL_RAEMPTYTHRESHOLD); + + /* Store the new register value */ + I2Sx->RFIFO_CTRL = tmpreg; +} + + +/** + * @brief Configures the threshold for almost full flag in I2S receive fifo. + * @param I2Sx: where x can be 2 or 3 to select the I2S peripheral. + * @param FIFO_Threshold specifies the fifo threshold to be programmed. + * @retval None + */ +void I2S_RFIFOAFullThresholdConfig(I2S_TypeDef* I2Sx, uint8_t FIFO_Threshold) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + assert_param(IS_I2S_FIFO_THRESHOLD(FIFO_Threshold)); + + /* Get the old register value */ + tmpreg = I2Sx->RFIFO_CTRL; + + /* Reset I2Sx RAFULLTHRESHOLD bit [2:0] */ + tmpreg &= (uint32_t)~((uint32_t)I2S_RFIFO_CTRL_RAFULLTHRESHOLD); + + /* Set I2Sx RAFULLTHRESHOLD */ + tmpreg |= (uint32_t)(((uint32_t)FIFO_Threshold << 16) & I2S_RFIFO_CTRL_RAFULLTHRESHOLD); + + /* Store the new register value */ + I2Sx->RFIFO_CTRL = tmpreg; +} + + +/** + * @brief Configures the I2S standard. + * @param I2Sx: where x can be 2 or 3 to select the I2S peripheral. + * @param STANDARD specifies the standard to be followed in I2S transmittion. + * This parameter can be one of the following values: + * @arg I2S_Philips : I2S Philips mode + * @arg I2S_Right_Justified: I2S Right-Justified mode + * @arg I2S_Left_Justified : I2S Left-Justified mode + * @arg I2S_DSP : I2S DSP mode + * @retval None + */ +void I2S_StandardConfig(I2S_TypeDef* I2Sx, uint32_t Standard) +{ + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + assert_param(IS_I2S_STANDARD(Standard)); + + /* Store the new register value */ + I2Sx->DEV_CONF = Standard; +} + + +/** + * @brief Configures I2S continuous serial clock active edge for transmission. + * @param I2Sx: where x can be 2 or 3 to select the I2S peripheral. + * @param I2S_SCK_Polar specifies the active edge of I2S SCK signals. + * This parameter can be one of the following values: + * @arg I2S_SCK_POLAR_RISE: Seriral clock active edge is rising edge. + * @arg I2S_SCK_POLAR_FALL: Seriral clock active edge is falling edge. + * @retval None + */ +void I2S_TranSckPolarConfig(I2S_TypeDef* I2Sx, uint8_t I2S_SCK_Polar) +{ + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + assert_param(IS_I2S_SCK_POLAR(I2S_SCK_Polar)); + + if (I2S_SCK_Polar != I2S_SCK_POLAR_RISE) + { + /* Set I2S serial clock active edge for transmission to falling edge */ + I2Sx->DEV_CONF |= I2S_DEV_CONF_TRANSCKPOLAR; + } + else + { + /* Set I2S serial clock active edge for transmission to rising edge */ + I2Sx->DEV_CONF &= (uint32_t)~((uint32_t)I2S_DEV_CONF_TRANSCKPOLAR); + } +} + + +/** + * @brief Configures I2S continuous serial clock active edge for reception. + * @param I2Sx: where x can be 2 or 3 to select the I2S peripheral. + * @param I2S_SCK_Polar specifies the active edge of I2S SCK signals. + * This parameter can be one of the following values: + * @arg I2S_SCK_POLAR_RISE: Seriral clock active edge is rising edge. + * @arg I2S_SCK_POLAR_FALL: Seriral clock active edge is falling edge. + * @retval None + */ +void I2S_RecSckPolarConfig(I2S_TypeDef* I2Sx, uint8_t I2S_SCK_Polar) +{ + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + assert_param(IS_I2S_SCK_POLAR(I2S_SCK_Polar)); + + if (I2S_SCK_Polar != I2S_SCK_POLAR_RISE) + { + /* Set I2S serial clock active edge for receprion to falling edge */ + I2Sx->DEV_CONF |= I2S_DEV_CONF_RECSCKPOLAR; + } + else + { + /* Set I2S serial clock active edge for reception to rising edge */ + I2Sx->DEV_CONF &= (uint32_t)~((uint32_t)I2S_DEV_CONF_RECSCKPOLAR); + } +} + + +/** + * @brief Configures I2S word select signal polarity selection for transmission. + * @param I2Sx: where x can be 2 or 3 to select the I2S peripheral. + * @param I2S_WS_Polar specifies the polarity of I2S WS signals. + * This parameter can be one of the following values: + * @arg I2S_WS_POLAR_0: the level of WS signal for the transmitted + * left channel data sample is '0' and the level of WS signal + * for the transmitted right channel data sample is '1'. + * @arg I2S_WS_POLAR_1: the level of WS signal for the transmitted + * left channel data sample is '1' and the level of WS signal + * for the transmitted right channel data sample is '0'. + * @retval None + */ +void I2S_TranWSPolarConfig(I2S_TypeDef* I2Sx, uint8_t I2S_WS_Polar) +{ + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + assert_param(IS_I2S_WS_POLAR(I2S_WS_Polar)); + + if (I2S_WS_Polar != I2S_WS_POLAR_0) + { + /* Set I2S WS signal polarity for transmission to 1 */ + I2Sx->DEV_CONF |= I2S_DEV_CONF_TRANWSPOLAR; + } + else + { + /* Set I2S WS signal polarity for transmission to 0 */ + I2Sx->DEV_CONF &= (uint32_t)~((uint32_t)I2S_DEV_CONF_TRANWSPOLAR); + } +} + + +/** + * @brief Configures I2S word select signal polarity selection for reception. + * @param I2Sx: where x can be 2 or 3 to select the I2S peripheral. + * @param I2S_WS_Polar specifies the polarity of I2S WS signals. + * This parameter can be one of the following values: + * @arg I2S_WS_POLAR_0: the level of WS signal for the received + * left channel data sample is '0' and the level of WS signal + * for the received right channel data sample is '1'. + * @arg I2S_WS_POLAR_1: the level of WS signal for the received + * left channel data sample is '1' and the level of WS signal + * for the received right channel data sample is '0'. + * @retval None + */ +void I2S_RecWSPolarConfig(I2S_TypeDef* I2Sx, uint8_t I2S_WS_Polar) +{ + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + assert_param(IS_I2S_WS_POLAR(I2S_WS_Polar)); + + if (I2S_WS_Polar != I2S_WS_POLAR_0) + { + /* Set I2S WS signal polarity for reception to 1 */ + I2Sx->DEV_CONF |= I2S_DEV_CONF_RECWSPOLAR; + } + else + { + /* Set I2S WS signal polarity for reception to 0 */ + I2Sx->DEV_CONF &= (uint32_t)~((uint32_t)I2S_DEV_CONF_RECWSPOLAR); + } +} + + +/** + * @brief Configures alignment of the transmitted digital data sample at the APB bus. + * @param I2Sx: where x can be 2 or 3 to select the I2S peripheral. + * @param I2S_ALIGN specifies the alignment of the digital data sample. + * This parameter can be one of the following values: + * @arg I2S_ALIGN_MSB: the MSB side alignment of the resolution-width + * data sample. + * @arg I2S_ALIGN_LSB: the MSB side alignment of the resolution-width + * data sample. + * @retval None + */ +void I2S_TranAPBAlignConfig(I2S_TypeDef* I2Sx, uint8_t I2S_Align) +{ + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + assert_param(IS_I2S_ALIGNMENT(I2S_Align)); + + if (I2S_Align != I2S_ALIGN_LSB) + { + /* Set the MSB side alignment the resolution-width transmitted + * digital data sample at the APB bus */ + I2Sx->DEV_CONF |= I2S_DEV_CONF_TRANAPBALIGNLR; + } + else + { + /* Set the LSB side alignment the resolution-width transmitted + * digital data sample at the APB bus */ + I2Sx->DEV_CONF &= (uint32_t)~((uint32_t)I2S_DEV_CONF_TRANAPBALIGNLR); + } +} + + +/** + * @brief Configures alignment of the received digital data sample at the APB bus. + * @param I2Sx: where x can be 2 or 3 to select the I2S peripheral. + * @param I2S_ALIGN specifies the alignment of the digital data sample. + * This parameter can be one of the following values: + * @arg I2S_ALIGN_MSB: the MSB side alignment of the resolution-width + * data sample. + * @arg I2S_ALIGN_LSB: the MSB side alignment of the resolution-width + * data sample. + * @retval None + */ +void I2S_RecAPBAlignConfig(I2S_TypeDef* I2Sx, uint8_t I2S_Align) +{ + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + assert_param(IS_I2S_ALIGNMENT(I2S_Align)); + + if (I2S_Align != I2S_ALIGN_LSB) + { + /* Set the MSB side alignment the resolution-width received + * digital data sample at the APB bus */ + I2Sx->DEV_CONF |= I2S_DEV_CONF_RECAPBALIGNLR; + } + else + { + /* Set the LSB side alignment the resolution-width received + * digital data sample at the APB bus */ + I2Sx->DEV_CONF &= (uint32_t)~((uint32_t)I2S_DEV_CONF_RECAPBALIGNLR); + } +} + + +/** + * @brief Configures alignment of the transmitted digital data sample at the + * I2S serial data line. + * @param I2Sx: where x can be 2 or 3 to select the I2S peripheral. + * @param I2S_ALIGN specifies the alignment of the digital data sample. + * This parameter can be one of the following values: + * @arg I2S_ALIGN_MSB: the MSB side alignment of the resolution-width + * data sample. + * @arg I2S_ALIGN_LSB: the MSB side alignment of the resolution-width + * data sample. + * @retval None + */ +void I2S_TranI2SAlignConfig(I2S_TypeDef* I2Sx, uint8_t I2S_Align) +{ + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + assert_param(IS_I2S_ALIGNMENT(I2S_Align)); + + if (I2S_Align != I2S_ALIGN_LSB) + { + /* Set the MSB side alignment the resolution-width transmitted + * digital data sample at the I2S serial data line */ + I2Sx->DEV_CONF |= I2S_DEV_CONF_TRANI2SALIGNLR; + } + else + { + /* Set the LSB side alignment the resolution-width transmitted + * digital data sample at the I2S serial data line */ + I2Sx->DEV_CONF &= (uint32_t)~((uint32_t)I2S_DEV_CONF_TRANI2SALIGNLR); + } +} + + +/** + * @brief Configures alignment of the received digital data sample at the + * I2S serial data line. + * @param I2Sx: where x can be 2 or 3 to select the I2S peripheral. + * @param I2S_ALIGN specifies the alignment of the digital data sample. + * This parameter can be one of the following values: + * @arg I2S_ALIGN_MSB: the MSB side alignment of the resolution-width + * data sample. + * @arg I2S_ALIGN_LSB: the MSB side alignment of the resolution-width + * data sample. + * @retval None + */ +void I2S_RecI2SAlignConfig(I2S_TypeDef* I2Sx, uint8_t I2S_Align) +{ + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + assert_param(IS_I2S_ALIGNMENT(I2S_Align)); + + if (I2S_Align != I2S_ALIGN_LSB) + { + /* Set the MSB side alignment the resolution-width received + * digital data sample at the I2S serial data line */ + I2Sx->DEV_CONF |= I2S_DEV_CONF_RECI2SALIGNLR; + } + else + { + /* Set the LSB side alignment the resolution-width received + * digital data sample at the I2S serial data line */ + I2Sx->DEV_CONF &= (uint32_t)~((uint32_t)I2S_DEV_CONF_RECI2SALIGNLR); + } +} + + +/** + * @brief Configures the transmitted valid data delay at the I2S SD + * output line afte the WS line edge + * @param I2Sx: where x can be 2 or 3 to select the I2S peripheral. + * @param I2S_Tran_data_WS_del specifies the the transmitted valid data delay at + * the I2S SD output line afte the WS line edge + * This parameter can be one of the following values: + * @arg I2S_TRAN_DATA_WS_DEL_0: The serial data for transmission are + * updated on the second rising/falling edge of the clock signal + * after the WS signal change. + * @arg I2S_TRAN_DATA_WS_DEL_1: The serial data for transmission are + * updated on the first rising/falling edge of the clock signal + * after the WS signal change. + * @retval None + */ +void I2S_TranDataWSDelConfig(I2S_TypeDef* I2Sx, uint8_t I2S_Tran_Data_WS_Del) +{ + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + assert_param(IS_I2S_TRAN_DATA_WS_DEL(I2S_Tran_Data_WS_Del)); + + if (I2S_Tran_Data_WS_Del != I2S_TRAN_DATA_WS_DEL_0) + { + /* Set the serial data for transmission are updated on the + * first rising/falling edge of the clock signal after the + * WS signal change */ + I2Sx->DEV_CONF |= I2S_DEV_CONF_TRANDATAWSDEL; + } + else + { + /* Set the serial data for transmission are updated on the + * second rising/falling edge of the clock signal after the + * WS signal change */ + I2Sx->DEV_CONF &= (uint32_t)~((uint32_t)I2S_DEV_CONF_TRANDATAWSDEL); + } +} + + +/** + * @brief Configures the received valid data delay at the I2S SD + * input line afte the WS line edge + * @param I2Sx: where x can be 2 or 3 to select the I2S peripheral. + * @param I2S_Rec_Data_WS_Del specifies the the received valid data delay at + * the I2S SD output line afte the WS line edge + * This parameter can be one of the following values: + * @arg I2S_REC_DATA_WS_DEL_0: The received serial data are updated + * on the thired rising/falling edge of the clock signal + * after the WS signal change. + * @arg I2S_REC_DATA_WS_DEL_1: The received serial data are updated + * on the second rising/falling edge of the clock signal + * after the WS signal change. + * @retval None + */ +void I2S_RecDataWSDelConfig(I2S_TypeDef* I2Sx, uint8_t I2S_Rec_Data_WS_Del) +{ + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + assert_param(IS_I2S_REC_DATA_WS_DEL(I2S_Rec_Data_WS_Del)); + + if (I2S_Rec_Data_WS_Del != I2S_REC_DATA_WS_DEL_0) + { + /* Set the received serial data are updated on the + * second rising/falling edge of the clock signal after the + * WS signal change */ + I2Sx->DEV_CONF |= I2S_DEV_CONF_RECDATAWSDEL; + } + else + { + /* Set the received serial data are updated on the + * third rising/falling edge of the clock signal after the + * WS signal change */ + I2Sx->DEV_CONF &= (uint32_t)~((uint32_t)I2S_DEV_CONF_RECDATAWSDEL); + } +} + + +/** + * @brief Configures the I2S WS signal format for the transmitter unit. + * @param I2Sx: where x can be 2 or 3 to select the I2S peripheral. + * @param I2S_WS_Format: I2Sx WS signal format. + * This parameter can be one of the following values: + * @arg I2S_WS_PHILIPS: WS signal format specific to the standard + * Philips I2S interface. + * @arg I2S_WS_DSP : WS signal format specific to the DSP audio + * interface mode. + * @retval None + */ + +void I2S_TranWSFormatConfig(I2S_TypeDef* I2Sx, uint8_t I2S_WS_Format) +{ + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + assert_param(IS_I2S_WS_FORMAT(I2S_WS_Format)); + + if (I2S_WS_Format != I2S_WS_PHILIPS) + { + /* Set I2S WS signal format to the DSP audio interface mode + * for the transmitter unit */ + I2Sx->DEV_CONF |= I2S_DEV_CONF_TRANWSDSPMODE; + } + else + { + /* Set I2S WS signal format to the standard Philips I2S interface + * for the transmitter unit */ + I2Sx->DEV_CONF &= (uint32_t)~((uint32_t)I2S_DEV_CONF_TRANWSDSPMODE); + } +} + + +/** + * @brief Configures the I2S WS signal format for the receiver unit. + * @param I2Sx: where x can be 2 or 3 to select the I2S peripheral. + * @param I2S_WS_Format: I2Sx WS signal format. + * This parameter can be one of the following values: + * @arg I2S_WS_PHILIPS: WS signal format specific to the standard + * Philips I2S interface. + * @arg I2S_WS_DSP : WS signal format specific to the DSP audio + * interface mode. + * @retval None + */ + +void I2S_RecWSFormatConfig(I2S_TypeDef* I2Sx, uint8_t I2S_WS_Format) +{ + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + assert_param(IS_I2S_WS_FORMAT(I2S_WS_Format)); + + if (I2S_WS_Format != I2S_WS_PHILIPS) + { + /* Set I2S WS signal format to the DSP audio interface mode + * for the receiver unit */ + I2Sx->DEV_CONF |= I2S_DEV_CONF_RECWSDSPMODE; + } + else + { + /* Set I2S WS signal format to the standard Philips I2S interface + * for the receiver unit */ + I2Sx->DEV_CONF &= (uint32_t)~((uint32_t)I2S_DEV_CONF_RECWSDSPMODE); + } +} + + +/** + * @brief Reads the specified I2S register and returns its value. + * @param I2Sx: where x can be 2 or 3 to select the I2S peripheral. + * @param I2S_Register: specifies the register to read. + * This parameter can be one of the following values: + * @arg I2S_Register_CTRL : CTRL register + * @arg I2S_Register_INTR_STAT : INTR_STAT register + * @arg I2S_Register_SRR : SRR register + * @arg I2S_Register_CID_CTRL : CID_CTRL register + * @arg I2S_Register_TFIFO_STAT: TFIFO_STAT register + * @arg I2S_Register_RFIFO_STAT: RFIFO_STAT register + * @arg I2S_Register_TFIFO_CTRL: TFIFO_CTRL register + * @arg I2S_Register_RFIFO_CTRL: RFIFO_CTRL register + * @arg I2S_Register_DEV_CONF : DEV_CONF register + * @arg I2S_Register_POLL_STAT : POLL_STAT register + * @retval The value of the read register. + */ + +uint32_t I2S_ReadRegister(I2S_TypeDef* I2Sx, uint8_t I2S_Register) +{ + __IO uint32_t tmp = 0; + + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + assert_param(IS_I2S_REGISTER(I2S_Register)); + + tmp = (uint32_t)I2Sx; + tmp += I2S_Register; + + /* Return the selected register value */ + return (*(__IO uint32_t *) tmp); +} + + +/** + * @brief Transmit a data byte through the I2Sx peripheral. + * @param I2Sx: where x can be 2 or 3 to select the I2S peripheral. + * @param Data: Byte to be transmitted.. + * @retval None + */ +void I2S_SendData(I2S_TypeDef* I2Sx, uint32_t Data) +{ + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + + /* Write in the FIFO the data to be sent */ + I2Sx->FIFO = (uint32_t)Data; +} + +/** + * @brief Returns the most recent received data by the I2Sx peripheral. + * @param I2Sx: where x can be 2 or 3 to select the I2S peripheral. + * @retval The value of the received data. + */ +uint32_t I2S_ReceiveData(I2S_TypeDef* I2Sx) +{ + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + + /* Return the data in the DR register */ + return (uint32_t)I2Sx->FIFO; +} + + +/** + * @brief Enables or disables all the I2S interrupts mask request. + * @param I2Sx: where x can be 2 or 3 to select the I2S peripheral. + * @param NewState: new state of all the I2Sx interrupts request. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2S_AllITMaskCmd(I2S_TypeDef* I2Sx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable all the I2S interrupts request mask*/ + I2Sx->CID_CTRL |= I2S_CID_CTRL_INTREQMASK; + } + else + { + /* I2S interrupts request individual maks*/ + I2Sx->CID_CTRL &= (uint32_t)~((uint32_t)I2S_CID_CTRL_INTREQMASK); + } +} + + +/** + * @brief Enables or disables the specified I2S FIFO interrupts. + * @param I2Sx: where x can be 2 or 3 to select the I2S peripheral. + * @param I2S_IT_Mask: specifies the I2S interrupts sources to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg I2S_TFIFOEMPTY_MASK : Transmit fifo empty flag mask + * @arg I2S_TFIFOAEMPTY_MASK: Transmit fifo almost empty flag mask + * @arg I2S_TFIFOFULL_MASK : Transmit fifo full flag mask + * @arg I2S_TFIFOAFULL_MASK : Transmit fifo almost full flag mask + * @arg I2S_RFIFOEMPTY_MASK : Receive fifo empty flag mask + * @arg I2S_RFIFOAEMPTY_MASK: Receive fifo almost empty flag mask + * @arg I2S_RFIFOFULL_MASK : Receive fifo full flag mask + * @arg I2S_RFIFOAFULL_MASK : Receive fifo almost full flag mask + * @param NewState: new state of the specified I2Sx FIFO interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2S_FIFOITConfig(I2S_TypeDef* I2Sx, uint32_t I2S_IT_Mask, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + assert_param(IS_I2S_FIFO_IT_MASK(I2S_IT_Mask)); + + if (NewState != DISABLE) + { + /* Enable the selected I2S FIFO interrupts */ + I2Sx->CID_CTRL |= I2S_IT_Mask; + } + else + { + /* Disable the selected I2S FIFO interrupts */ + I2Sx->CID_CTRL &= (uint32_t)~((uint32_t)I2S_IT_Mask); + } +} + +/** + * @brief Enables or disables the specified I2S channel 0/1 data + * underrun/overrun interrupts. + * @param I2Sx: where x can be 2 or 3 to select the I2S peripheral. + * @param I2S_IT_Mask: specifies the I2S interrupts sources to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg I2S_0_MASK: I2S channel 0 data underrun/overrun interrupts mask + * @arg I2S_1_MASK: I2S channel 1 data underrun/overrun interrupts mask + * @param NewState: new state of the specified I2Sx channel 0/1 + * data underrun/overrun interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2S_DataITConfig(I2S_TypeDef* I2Sx, uint32_t I2S_IT_Mask, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + assert_param(IS_I2S_DATA_IT_MASK(I2S_IT_Mask)); + + if (NewState != DISABLE) + { + /* Enable the selected I2S channel 0/1 data underrun/overrun interrupts */ + I2Sx->CID_CTRL |= I2S_IT_Mask; + } + else + { + /* Disable the selected I2S channel 0/1 data underrun/overrun interrupts */ + I2Sx->CID_CTRL &= (uint32_t)~((uint32_t)I2S_IT_Mask); + } +} + + +/** + * @brief Checks whether the specified I2S interrupt has occurred or not. + * @param I2Sx: where x can be 2 or 3 to select the I2S peripheral. + * @param I2S_IT: specifies the interrupt source to check. + * This parameter can be one of the following values: + * @arg I2S_IT_TDATAUNDERR: Transmitter data underrun event + * @arg I2S_IT_RDATAOVRERR: Receiver data overrun error + * @arg I2S_IT_TFIFOEMPTY : Transmit fifo empty flag + * @arg I2S_IT_TFIFOAEMPTY: Transmit fifo almost empty flag + * @arg I2S_IT_TFIFOFULL : Transmit fifo full flag + * @arg I2S_IT_TFIFOAFULL : Transmit fifo almost full flag + * @arg I2S_IT_RFIFOEMPTY : Receive fifo empty flag + * @arg I2S_IT_RFIFOAEMPTY: Receive fifo almost empty flag + * @arg I2S_IT_RFIFOFULL : Receive fifo full flag + * @arg I2S_IT_RFIFOAFULL : Receive fifo almost full flag + * @retval The new state of I2S_IT (SET or RESET). + */ +ITStatus I2S_GetITStatus(I2S_TypeDef* I2Sx, uint32_t I2S_IT) +{ + uint32_t tmpreg = 0; + ITStatus bitstatus = RESET; + + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + assert_param(IS_I2S_GET_IT(I2S_IT)); + + /* Get the INTR_STAT register value */ + tmpreg = I2Sx->INTR_STAT; + + /* Get flag status */ + tmpreg &= I2S_IT; + + /* Check the status of the specified I2S flag */ + if (tmpreg != RESET) + { + /* I2S_IT is set */ + bitstatus = SET; + } + else + { + /* I2S_IT is reset */ + bitstatus = RESET; + } + + /* Return the I2S_IT status */ + return bitstatus; +} + + +/** + * @brief Clears the I2Sx's interrupt pending bits. + * @param I2Sx: where x can be 2 or 3 to select the I2S peripheral. + * @param I2S_IT: specifies the interrupt pending bit to clear. + * This parameter can be any combination of the following values: + * @arg I2S_IT_TDATAUNDERR: Transmitter data underrun event + * @arg I2S_IT_RDATAOVRERR: Receiver data overrun error + * @arg I2S_IT_TFIFOEMPTY : Transmit fifo empty flag + * @arg I2S_IT_TFIFOAEMPTY: Transmit fifo almost empty flag + * @arg I2S_IT_TFIFOFULL : Transmit fifo full flag + * @arg I2S_IT_TFIFOAFULL : Transmit fifo almost full flag + * @arg I2S_IT_RFIFOEMPTY : Receive fifo empty flag + * @arg I2S_IT_RFIFOAEMPTY: Receive fifo almost empty flag + * @arg I2S_IT_RFIFOFULL : Receive fifo full flag + * @arg I2S_IT_RFIFOAFULL : Receive fifo almost full flag + * @retval The new state of I2S_IT (SET or RESET). + */ +void I2S_ClearITPendingBit(I2S_TypeDef* I2Sx, uint32_t I2S_IT) +{ + uint32_t tmpreg = 0; + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + assert_param(IS_I2S_CLEAR_IT(I2S_IT)); + + /* Clear the selected flag */ + if ((I2S_IT & I2S_IT_RDATAOVRERR) == I2S_IT_RDATAOVRERR) + { + I2Sx->INTR_STAT &= (uint32_t)~((uint32_t)I2S_IT); + } + else + { + tmpreg = I2Sx->INTR_STAT; + tmpreg &= (uint32_t)~((uint32_t)I2S_IT); + tmpreg |= I2S_IT_RDATAOVRERR; + I2Sx->INTR_STAT = tmpreg; + } +} + + +/** + * @brief Returns the channel code of the transmitter that caused underrun event. + * @param I2Sx: where x can be 2 or 3 to select the I2S peripheral. + * @retval The channel code of the transmitter that caused underrun event, + * it can be channel 0 or channel 1. + */ +uint8_t I2S_GetUnderrunCode(I2S_TypeDef* I2Sx) +{ + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + + /* Return the channel code of the transmitter that caused underrun event + * in INTR_STAT register */ + return (uint8_t)((uint32_t)I2Sx->INTR_STAT & I2S_INTR_STAT_UNDERRCODE); +} + + +/** + * @brief Returns the channel code of the receiver that caused overrun error. + * @param I2Sx: where x can be 2 or 3 to select the I2S peripheral. + * @retval the channel code of the receiver that caused overrun error, + * it can be channel 0 or channel 1. + */ +uint8_t I2S_GetOverrunCode(I2S_TypeDef* I2Sx) +{ + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + + /* Return the channel code of the receiver that caused overrun error + * in INTR_STAT register */ + return (uint8_t)((uint32_t)I2Sx->INTR_STAT & I2S_INTR_STAT_OVRERRCODE); +} + + +/** + * @brief Returns the I2S polling status. + * @param I2Sx: where x can be 2 or 3 to select the I2S peripheral. + * @param I2S_Stat: specifies the I2S current FIFO or data status to check + * This parameter can be one of the following values: + * @arg I2S_STAT_TFIFOEMPTY : Transmit fifo empty flag + * @arg I2S_STAT_TFIFOAEMPTY: Transmit fifo almost flag + * @arg I2S_STAT_TXUNDERRUN : Transmitter data underrun + * @arg I2S_STAT_RFIFOFULL : Receive fifo full flag + * @arg I2S_STAT_RFIFOAFULL : Receive fifo almost full flag + * @arg I2S_STAT_RXOVERRUN : Receiver data overrun + * @retval The new state of I2S_STAT (SET or RESET). + */ +FlagStatus I2S_GetPollStatus(I2S_TypeDef* I2Sx, uint32_t I2S_Stat) +{ + uint32_t tmpreg = 0; + FlagStatus bitstatus = RESET; + + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + assert_param(IS_I2S_GET_STAT(I2S_Stat)); + + /* Get the POLL_STAT register value */ + tmpreg = I2Sx->POLL_STAT; + + /* Get flag status */ + tmpreg &= I2S_Stat; + + if (tmpreg != 0) + { + /* I2S_Stat is set */ + bitstatus = SET; + } + else + { + /* I2S_Stat is reset */ + bitstatus = RESET; + } + return bitstatus; +} + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT FMD *****END OF FILE**********************/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_iwdg.c b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_iwdg.c new file mode 100644 index 00000000000..471d3f03479 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_iwdg.c @@ -0,0 +1,167 @@ +/** + ****************************************************************************** + * @file ft32f4xx_iwdg.c + * @author FMD AE + * @brief This file provides firmware functions to manage the following + * functionalities of the Independent watchdog (IWDG) peripheral: + * + Prescaler and Counter configuration + * + IWDG activation + * + Flag management + * @version V1.0.0 + * @data 2025-03-05 + ****************************************************************************** + */ +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx_iwdg.h" + +/* ---------------------- IWDG registers bit mask ----------------------------*/ +/* KR register bit mask */ +#define KR_KEY_RELOAD ((uint16_t)0xAAAA) +#define KR_KEY_ENABLE ((uint16_t)0xCCCC) + + +/** + * @brief Enables or disables write access to IWDG_PR and IWDG_RLR registers. + * @param IWDG_WriteAccess: new state of write access to IWDG_PR and IWDG_RLR registers. + * This parameter can be one of the following values: + * @arg IWDG_WriteAccess_Enable: Enable write access to IWDG_PR and IWDG_RLR registers + * @arg IWDG_WriteAccess_Disable: Disable write access to IWDG_PR and IWDG_RLR registers + * @retval None + */ +void IWDG_WriteAccessCmd(uint16_t IWDG_WriteAccess) +{ + /* Check the parameters */ + assert_param(IS_IWDG_WRITE_ACCESS(IWDG_WriteAccess)); + IWDG->KR = IWDG_WriteAccess; +} + +/** + * @brief Sets IWDG Prescaler value. + * @param IWDG_Prescaler: specifies the IWDG Prescaler value. + * This parameter can be one of the following values: + * @arg IWDG_Prescaler_4: IWDG prescaler set to 4 + * @arg IWDG_Prescaler_8: IWDG prescaler set to 8 + * @arg IWDG_Prescaler_16: IWDG prescaler set to 16 + * @arg IWDG_Prescaler_32: IWDG prescaler set to 32 + * @arg IWDG_Prescaler_64: IWDG prescaler set to 64 + * @arg IWDG_Prescaler_128: IWDG prescaler set to 128 + * @arg IWDG_Prescaler_256: IWDG prescaler set to 256 + * @retval None + */ +void IWDG_SetPrescaler(uint8_t IWDG_Prescaler) +{ + /* Check the parameters */ + assert_param(IS_IWDG_PRESCALER(IWDG_Prescaler)); + IWDG->PR = IWDG_Prescaler; +} + +/** + * @brief Sets IWDG Reload value. + * @param Reload: specifies the IWDG Reload value. + * This parameter must be a number between 0 and 0x0FFF. + * @retval None + */ +void IWDG_SetReload(uint16_t Reload) +{ + /* Check the parameters */ + assert_param(IS_IWDG_RELOAD(Reload)); + IWDG->RLR = Reload; +} + +/** + * @brief Reloads IWDG counter with value defined in the reload register + * (write access to IWDG_PR and IWDG_RLR registers disabled). + * @param None + * @retval None + */ +void IWDG_ReloadCounter(void) +{ + IWDG->KR = KR_KEY_RELOAD; +} + + +/** + * @brief Sets the IWDG window value. + * @param WindowValue: specifies the window value to be compared to the downcounter. + * @retval None + */ +void IWDG_SetWindowValue(uint16_t WindowValue) +{ + /* Check the parameters */ + assert_param(IS_IWDG_WINDOW_VALUE(WindowValue)); + IWDG->WINR = WindowValue; +} + +/** + * @} + */ + +/** @defgroup IWDG_Group2 IWDG activation function + * @brief IWDG activation function + * +@verbatim + ============================================================================== + ##### IWDG activation function ##### + ============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Enables IWDG (write access to IWDG_PR and IWDG_RLR registers disabled). + * @param None + * @retval None + */ +void IWDG_Enable(void) +{ + IWDG->KR = KR_KEY_ENABLE; +} + +/** + * @} + */ + +/** + * @brief Checks whether the specified IWDG flag is set or not. + * @param IWDG_FLAG: specifies the flag to check. + * This parameter can be one of the following values: + * @arg IWDG_FLAG_PVU: Prescaler Value Update on going + * @arg IWDG_FLAG_RVU: Reload Value Update on going + * @arg IWDG_FLAG_WVU: Counter Window Value Update on going + * @retval The new state of IWDG_FLAG (SET or RESET). + */ +FlagStatus IWDG_GetFlagStatus(uint16_t IWDG_FLAG) +{ + FlagStatus bitstatus = RESET; + /* Check the parameters */ + assert_param(IS_IWDG_FLAG(IWDG_FLAG)); + if ((IWDG->SR & IWDG_FLAG) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + /* Return the flag status */ + return bitstatus; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_lptim.c b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_lptim.c new file mode 100644 index 00000000000..930bb1b2947 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_lptim.c @@ -0,0 +1,673 @@ +/** + ****************************************************************************** + * @file ft32f4xx_lptim.c + * @author FMD AE + * @brief This file provides firmware functions to manage the following + * functionalities of the Serial peripheral interface (LPTIM): + * + Initialization and Configuration + * + Read CNT/ARR/CMP Register functions + * + Write ARR/CMP Register functions + * + PWM Mode Start/Stop + * + Onepulse Mode Start/Stop + * + Setonce Mode Start/Stop + * + Encoder Mode Start/Stop + * + Timeout Mode Start/Stop + * + Counter Mode Start/Stop + * + CNT reset management + * + Interrupts and flags management + * @version V1.0.0 + * @data 2025-03-31 + ****************************************************************************** + */ +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx_lptim.h" +#include "ft32f4xx_rcc.h" + +/* LPTIM registers Masks */ +#define CFGR_CLEAR_MASK ((uint32_t)0x20ebeedf) +//#define SPI_CTRLR0_CLEAR_MASK ((uint32_t)0x0c03033f) + + +/* Private function prototypes -----------------------------------------------*/ +void LPTIM_Start_Continuous(void); +void LPTIM_Start_Single(void); +void LPTIM_Disable(void); +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup LPTIM_Exported_Functions_Group1 Initialization/de-initialization functions + * @brief Initialization and Configuration functions. + * +@verbatim + ============================================================================== + ##### Initialization and de-initialization functions ##### + ============================================================================== + [..] This section provides functions allowing to: + (+) Initialize the LPTIM according to the specified parameters in the + LPTIM_InitTypeDef and initialize the associated handle. + (+) DeInitialize the LPTIM peripheral. + +@endverbatim + * @{ + */ + + +/** + * @brief Deinitializes the LPTIM peripheral registers to their default + * reset values. + */ +void LPTIM_DeInit(void) +{ + + /* Enable LPTIM reset state */ + RCC_APB2PeriphResetCmd(RCC_APB2Periph_LPTIM, ENABLE); + /* Release LPTIM from reset state */ + RCC_APB2PeriphResetCmd(RCC_APB2Periph_LPTIM, DISABLE); +} + +/** + * @brief Fills each LPTIM_InitStruct member with its default value. + * @param LPTIM_InitStruct: pointer to a LPTIM_InitTypeDef structure which will be initialized. + * @retval None + */ +void LPTIM_StructInit(LPTIM_InitTypeDef *LPTIM_InitStruct) +{ + /*--------------- Reset LPTIM init structure parameters values -----------------*/ + /* Initialize the LPTIM clock source member */ + LPTIM_InitStruct->Source = LPTIM_CLOCKSOURCE_APBCLOCK_LPOSC; + /* Initialize the LPTIM clock prescaler member */ + LPTIM_InitStruct->Prescaler = LPTIM_PRESCALER_DIV1; + /* Initialize the LPTIM polarity of the active edge member */ + LPTIM_InitStruct->Polarity = LPTIM_CLOCKPOLARITY_RISING; + /* Initialize the LPTIM Clock_SampleTime member */ + LPTIM_InitStruct->Clock_SampleTime = LPTIM_CLOCKSAMPLETIME_DIRECTTRANSITION; + /* Initialize the LPTIM Trigger_Source member */ + LPTIM_InitStruct->Trigger_Source = LPTIM_TRIGSOURCE_0; + /* Initialize the LPTIM Trigegr_ActiveEdge member */ + LPTIM_InitStruct->Trigegr_ActiveEdge = LPTIM_SOFTWARE; + /* Initialize the LPTIM Trigg_SampleTime member */ + LPTIM_InitStruct->Trigg_SampleTime = LPTIM_TRIGSAMPLETIME_DIRECTTRANSITION; + /* Initialize the LPTIM OutputPolarity member */ + LPTIM_InitStruct->OutputPolarity = LPTIM_OUTPUTPOLARITY_HIGH; + /* Initialize the LPTIM UpdateMode member */ + LPTIM_InitStruct->UpdateMode = LPTIM_UPDATE_IMMEDIATE; + /*Initialize the LPTIM CounterSource member*/ + LPTIM_InitStruct->CounterSource = LPTIM_COUNTERSOURCE_INTERNAL; + /*Initialize the LPTIM Input1Source member*/ + LPTIM_InitStruct->Input1Source = LPTIM_INPUT1SOURCE_GPIO; + /*Initialize the LPTIM Input2Source member*/ + LPTIM_InitStruct->Input2Source = LPTIM_INPUT2SOURCE_GPIO; + +} + +/** + * @brief Initializes the LPTIM peripheral according to the specified + * parameters in the LPTIM_InitStruct. + * @param LPTIM_InitStruct: pointer to a LPTIM_InitTypeDef structure that + * contains the configuration information for the specified LPTIM peripheral. + * @retval None + */ +void LPTIM_Init(LPTIM_InitTypeDef *LPTIM_InitStruct) +{ + uint32_t tmpreg = 0; + + /* Check the LPTIM parameters */ + assert_param(IS_LPTIM_CLOCK_SOURCE(LPTIM_InitStruct->Source)); + assert_param(IS_LPTIM_CLOCK_PRESCALER(LPTIM_InitStruct->Prescaler)); + assert_param(IS_LPTIM_CLOCK_POLARITY(LPTIM_InitStruct->Polarity)); + assert_param(IS_LPTIM_CLOCK_SAMPLE_TIME(LPTIM_InitStruct->Clock_SampleTime)); + assert_param(IS_LPTIM_TRG_SOURCE(LPTIM_InitStruct->Trigger_Source)); + assert_param(IS_LPTIM_EXT_TRG_POLARITY(LPTIM_InitStruct->Trigegr_ActiveEdge)); + assert_param(IS_LPTIM_TRIG_SAMPLE_TIME(LPTIM_InitStruct->Trigg_SampleTime)); + assert_param(IS_LPTIM_OUTPUT_POLARITY(LPTIM_InitStruct->OutputPolarity)); + assert_param(IS_LPTIM_UPDATE_MODE(LPTIM_InitStruct->UpdateMode)); + assert_param(IS_LPTIM_COUNTER_SOURCE(LPTIM_InitStruct->CounterSource)); + assert_param(IS_LPTIM_INPUT1_SOURCE(LPTIM_InitStruct->Input1Source)); + assert_param(IS_LPTIM_INPUT2_SOURCE(LPTIM_InitStruct->Input2Source)); + + /*---------------------------- LPTIM CFGR Configuration ------------------------*/ + /* Get the LPTIM CFGR value */ + tmpreg = LPTIM->CFGR; + /* Clear TRIGSEL[3:0],COUNTMODE.PRELOAD,WAVPOL,TRIGEN[1:0],PRESC[2:0],TRGFLT,CKFLT,CKPOL,CKSEL bits */ + tmpreg &= ~CFGR_CLEAR_MASK; + /* Configure LPTIM CFGR register*/ + tmpreg |= (uint32_t)((uint32_t)LPTIM_InitStruct->Source | LPTIM_InitStruct->Prescaler | + LPTIM_InitStruct->Polarity | LPTIM_InitStruct->Clock_SampleTime | + LPTIM_InitStruct->Trigger_Source | LPTIM_InitStruct->Trigegr_ActiveEdge | + LPTIM_InitStruct->Trigg_SampleTime | LPTIM_InitStruct->OutputPolarity | + LPTIM_InitStruct->CounterSource); + /* Write to LPTIM CFGR */ + LPTIM->CFGR = tmpreg; + + /*-------------------------LPTIM OR Configuration -----------------------*/ + /* Clear OR register */ + tmpreg = 0; + /* Configure LPTIM IN1[2:0], IN2[2:0] */ + tmpreg |= (uint32_t)((uint32_t)(LPTIM_InitStruct->Input1Source) | LPTIM_InitStruct->Input2Source); + /* Write to LPTIM OR */ + LPTIM->OR = tmpreg; + +} + +/** + * @} + */ + + +/** @defgroup LPTIM_Exported_Functions_Group2 LPTIM Start-Stop operation functions + * @brief Start-Stop operation functions. + * +@verbatim + ============================================================================== + ##### LPTIM Start Stop operation functions ##### + ============================================================================== + [..] This section provides functions allowing to: + (+) Start the PWM mode. + (+) Stop the PWM mode. + (+) Start the One pulse mode. + (+) Stop the One pulse mode. + (+) Start the Set once mode. + (+) Stop the Set once mode. + (+) Start the Encoder mode. + (+) Stop the Encoder mode. + (+) Start the Timeout mode. + (+) Stop the Timeout mode. + (+) Start the Counter mode. + (+) Stop the Counter mode. + + +@endverbatim + * @{ + */ + +/** + * @brief Start the LPTIM PWM generation. + * @param Period Specifies the Autoreload value. + * This parameter must be a value between 0x0000 and 0xFFFF. + * @param Pulse Specifies the compare value. + * This parameter must be a value between 0x0000 and 0xFFFF. + */ + +void LPTIM_PWM_Start(uint32_t Period, uint32_t Pulse) +{ + /* Check the parameters */ + assert_param(IS_LPTIM_PERIOD(Period)); + assert_param(IS_LPTIM_PULSE(Pulse)); + + /* Reset WAVE bit to set PWM mode */ + LPTIM->CFGR &= ~LPTIM_CFGR_WAVE; + + /* Enable the Peripheral */ + LPTIM->CR |= LPTIM_CR_ENABLE; + + /* Write the ARR register value*/ + LPTIM_Write_ARRRegister(Period); + + /* Write the CMP register value*/ + LPTIM_Write_CMPRegister(Pulse); + + /* Start timer in continuous mode */ + LPTIM_Start_Continuous(); + +} + +/** + * @brief Stop the LPTIM PWM generation. + */ +void LPTIM_PWM_Stop(void) +{ + /* Disable the Peripheral */ + LPTIM_Disable(); +} +/** + * @brief Start the LPTIM One pulse generation. + * @param Period Specifies the Autoreload value. + * This parameter must be a value between 0x0000 and 0xFFFF. + * @param Pulse Specifies the compare value. + * This parameter must be a value between 0x0000 and 0xFFFF. + */ +void LPTIM_OnePulse_Start(uint32_t Period, uint32_t Pulse) +{ + + /* Check the parameters */ + assert_param(IS_LPTIM_PERIOD(Period)); + assert_param(IS_LPTIM_PULSE(Pulse)); + + /* Reset WAVE bit to set one pulse mode */ + LPTIM->CFGR &= ~LPTIM_CFGR_WAVE; + + /* Enable the Peripheral */ + LPTIM->CR |= LPTIM_CR_ENABLE; + + /* Write the ARR register value*/ + LPTIM_Write_ARRRegister(Period); + + /* Write the CMP register value*/ + LPTIM_Write_CMPRegister(Pulse); + + /* Start timer in single mode */ + LPTIM_Start_Single(); + +} + +/** + * @brief Stop the LPTIM OnePulse generation. + */ +void LPTIM_OnePulse_Stop(void) +{ + /* Disable the Peripheral */ + LPTIM_Disable(); +} + +/** + * @brief Start the LPTIM in Set once mode. + * @param Period Specifies the Autoreload value. + * This parameter must be a value between 0x0000 and 0xFFFF. + * @param Pulse Specifies the compare value. + * This parameter must be a value between 0x0000 and 0xFFFF. + */ +void LPTIM_SetOnce_Start(uint32_t Period, uint32_t Pulse) +{ + + /* Check the parameters */ + assert_param(IS_LPTIM_PERIOD(Period)); + assert_param(IS_LPTIM_PULSE(Pulse)); + + /* Set WAVE bit to enable the set once mode */ + LPTIM->CFGR |= LPTIM_CFGR_WAVE; + + /* Enable the Peripheral */ + LPTIM->CR |= LPTIM_CR_ENABLE; + + /* Write the ARR register value*/ + LPTIM_Write_ARRRegister(Period); + + /* Write the CMP register value*/ + LPTIM_Write_CMPRegister(Pulse); + + /* Start timer in single mode */ + LPTIM_Start_Single(); + +} + +/** + * @brief Stop the LPTIM SetOnce generation. + */ +void LPTIM_SetOnce_Stop(void) +{ + /* Disable the Peripheral */ + LPTIM_Disable(); +} + + +/** + * @brief Start the Encoder interface. + * @param Period Specifies the Autoreload value. + * This parameter must be a value between 0x0000 and 0xFFFF. + */ +void LPTIM_Encoder_Start(uint32_t Period) +{ + + /* Check the parameters */ + assert_param(IS_LPTIM_PERIOD(Period)); + + /* Set ENC bit to enable the encoder interface */ + LPTIM->CFGR |= LPTIM_CFGR_ENC; + + LPTIM_Counter_Start(Period); + ///* Enable the Peripheral */ + //LPTIM->CR |= LPTIM_CR_ENABLE; + + ///* Write the ARR register value*/ + //LPTIM_Write_ARRRegister(Period); + + ///* Start timer in continuous mode */ + //LPTIM_Start_Continuous(); + +} + + +/** + * @brief Stop the LPTIM Encoder generation. + */ +void LPTIM_Encoder_Stop(void) +{ + /* Disable the Peripheral */ + LPTIM_Disable(); + /* Reset ENC bit to disable the encoder function */ + LPTIM->CFGR &= ~LPTIM_CFGR_ENC; +} + + +void LPTIM_TimeOut_Start(uint32_t Period, uint32_t Timeout) +{ + + /* Check the parameters */ + assert_param(IS_LPTIM_PERIOD(Period)); + assert_param(IS_LPTIM_PULSE(Timeout)); + + /* Set TIMOUT bit to enable the timeout function */ + LPTIM->CFGR |= LPTIM_CFGR_TIMOUT; + + /* Enable the Peripheral */ + LPTIM->CR |= LPTIM_CR_ENABLE; + + /* Write the ARR register value*/ + LPTIM_Write_ARRRegister(Period); + + /* Write the CMP register value*/ + LPTIM_Write_CMPRegister(Timeout); + + /* Start timer in continuous mode */ + LPTIM_Start_Continuous(); + +} + +/** + * @brief Stop the LPTIM TimeOut generation. + */ +void LPTIM_TimeOut_Stop(void) +{ + /* Disable the Peripheral */ + LPTIM_Disable(); + + /* Reset TIMOUT bit to disable the timeout function */ + LPTIM->CFGR &= ~LPTIM_CFGR_TIMOUT; +} + +/** + * @brief Start the Counter mode. + * @param Period Specifies the Autoreload value. + * This parameter must be a value between 0x0000 and 0xFFFF. + */ +void LPTIM_Counter_Start(uint32_t Period) +{ + /* Check the parameters */ + assert_param(IS_LPTIM_PERIOD(Period)); + + /* If clock source is not ULPTIM clock and counter source is external, then it must not be prescaled */ + if ((LPTIM->CFGR & (LPTIM_CFGR_CKSEL | LPTIM_CFGR_COUNTMODE)) == LPTIM_CFGR_COUNTMODE) + { + /* Check if clock is prescaled */ + /* Set clock prescaler to 0 */ + LPTIM->CFGR &= ~LPTIM_CFGR_PRESC; + } + + /* Enable the Peripheral */ + LPTIM->CR |= LPTIM_CR_ENABLE; + + /* Write the ARR register value*/ + LPTIM_Write_ARRRegister(Period); + + /* Start timer in continuous mode */ + LPTIM_Start_Continuous(); + +} + +/** + * @brief Stop the LPTIM Counter generation. + */ +void LPTIM_Counter_Stop(void) +{ + /* Disable the Peripheral */ + LPTIM_Disable(); + +} + +void LPTIM_Disable(void) +{ + uint32_t tmpclksource = 0; + uint32_t tmpIER; + uint32_t tmpCFGR; + uint32_t tmpCMP; + uint32_t tmpARR; + uint32_t tmpOR; + + //__disable_irq(); + + /*********** Save LPTIM Config ***********/ + /* Save LPTIM source clock */ + tmpclksource = (RCC->CCIPR & RCC_CCIPR_LPTIMSEL); + + /* Save LPTIM configuration registers */ + tmpIER = LPTIM->IER; + tmpCFGR = LPTIM->CFGR; + tmpCMP = LPTIM->CMP; + tmpARR = LPTIM->ARR; + tmpOR = LPTIM->OR; + + /*********** Reset LPTIM ***********/ + RCC_APB2PeriphResetCmd(RCC_APB2PeriphRst_LPTIM, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2PeriphRst_LPTIM, DISABLE); + + /*********** Restore LPTIM Config ***********/ + /* Force LPTIM source kernel clock from APB */ + RCC_LPTIMCLKConfig(RCC_LPTIMCLK_PCLK); + + /* Restore CMP register (LPTIM should be enabled first) */ + LPTIM->CR |= LPTIM_CR_ENABLE; + LPTIM_Write_CMPRegister(tmpCMP); + + /* Restore ARR register (LPTIM should be enabled first) */ + LPTIM->CR |= LPTIM_CR_ENABLE; + LPTIM_Write_ARRRegister(tmpARR); + + /* Restore LPTIM source kernel clock */ + RCC_LPTIMCLKConfig(tmpclksource); + + /* Restore configuration registers (LPTIM should be disabled first) */ + LPTIM->CR &= ~(LPTIM_CR_ENABLE); + LPTIM->IER = tmpIER; + LPTIM->CFGR = tmpCFGR; + LPTIM->OR = tmpOR; + + //__enable_irq(); + +} +/** + * @} + */ + + +/** @defgroup LPTIM_Exported_Functions_Group3 LPTIM Read operation functions + * @brief Read operation functions. + * +@verbatim + ============================================================================== + ##### LPTIM Read/Write operation functions ##### + ============================================================================== +[..] This section provides LPTIM Reading functions. + (+) Read the counter value. + (+) Read the period (Auto-reload) value. + (+) Read the pulse (Compare)value. + (+) Write the period (Auto-reload) value. + (+) Write the pulse (Compare)value. +@endverbatim + * @{ + */ + +/** + * @brief Return the current counter value. + * @retval Counter value. + */ + +uint32_t LPTIM_ReadCounter(void) +{ + return (LPTIM->CNT); +} + +/** + * @brief Return the current Autoreload (Period) value. + * @retval Autoreload value. + */ + +uint32_t LPTIM_ReadAutoReload(void) +{ + return (LPTIM->ARR); +} + +/** + * @brief Return the current Compare (Pulse) value. + * @retval Compare value. + */ + +uint32_t LPTIM_ReadCompare(void) +{ + return (LPTIM->CMP); +} + +/** + * @brief LPTimer Write ARR register + * @param Period the ARR value + */ + +void LPTIM_Write_ARRRegister(uint32_t Period) +{ + /* Clear ARROK flag */ + LPTIM->ICR = LPTIM_ICR_ARROKCF ; + + /* Load the period value in the autoreload register*/ + LPTIM->ARR = Period ; + + /* Wait for the completion of the write operation to the LPTIM_ARR register */ + while (LPTIM_GetStatus(LPTIM_ISR_ARROK) != LPTIM_ISR_ARROK); +} + +/** + * @brief LPTimer Write CMP register + * @param Pulse the CMP value + */ + +void LPTIM_Write_CMPRegister(uint32_t Pulse) +{ + /* Clear CMPOK flag */ + LPTIM->ICR = LPTIM_ICR_CMPOKCF ; + + /* Load the pulse value in the compare register*/ + LPTIM->CMP = Pulse ; + + /* Wait for the completion of the write operation to the LPTIM_CMP register */ + while (LPTIM_GetStatus(LPTIM_ISR_CMPOK) != LPTIM_ISR_CMPOK); +} + +/** + * @brief Enables or disables LPTIM PRELOAD bit + * @param NewState: new state of the PRELOAD bit. + * This parameter can be: ENABLE or DISABLE. + */ +void LPTIM_Preload_Config(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Set PRELOAD bit*/ + LPTIM->CFGR |= LPTIM_CFGR_PRELOAD ; + } + else + { + /* Clear PRELOAD bit*/ + LPTIM->CFGR &= ~LPTIM_CFGR_PRELOAD ; + } +} +/** + * @} + */ + + +/** + * @brief LPTimer Start in Continuous mode + */ +void LPTIM_Start_Continuous(void) +{ + /* Set CNTSTRT bits*/ + LPTIM->CR |= LPTIM_CR_CNTSTRT ; +} + +/** + * @brief LPTimer Start in single mode + */ +void LPTIM_Start_Single(void) +{ + /* Set SNGSTRT bits*/ + LPTIM->CR |= LPTIM_CR_SNGSTRT ; +} + +/** + * @brief Enables or disables LPTIM reset cnt after read cnt + * @param NewState: new state of the RSTARE bits. + * This parameter can be: ENABLE or DISABLE. + */ +void LPTIM_RSTARE(FunctionalState NewState) +{ + + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Set RSTARE bits*/ + LPTIM->CR |= LPTIM_CR_RSTARE ; + } + else + { + /* Clear RSTARE bits*/ + LPTIM->CR &= ~LPTIM_CR_RSTARE ; + } +} + +void LPTIM_COUNTRST(void) +{ + + /* Set COUNTRST bits*/ + LPTIM->CR |= LPTIM_CR_COUNTRST ; + +} +/** + * @brief LPTimer interrupt enable + * @param LPTIM_IT The lptim interrupt enable + * @param NewState: new state of the LPTIM interrupts. + * This parameter can be: ENABLE or DISABLE. + */ +void LPTIM_ITConfig(uint32_t LPTIM_IT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Set the IT enable bits*/ + LPTIM->IER |= LPTIM_IT ; + } + else + { + /* Disable the IT enable bits*/ + LPTIM->IER &= ~LPTIM_IT ; + } +} + +/** + * @brief LPTimer Wait for flag set + * @param LPTIM_SR_FLAG The lptim flag + */ +uint32_t LPTIM_GetStatus(uint32_t LPTIM_ISR_FLAG) +{ + /* Get the QSPI status */ + return (uint32_t)(LPTIM->ISR & LPTIM_ISR_FLAG); + +} + +/** + * @brief LPTimer clear interrupt flag + * @param flag The lptim interrupt clear bit + */ +void LPTIM_ClearFlag(uint32_t flag) +{ + /* Write ICR register to clear ISR bits*/ + LPTIM->ICR = flag ; +} +/** + * @} + */ + +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_misc.c b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_misc.c new file mode 100644 index 00000000000..7c6385834c6 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_misc.c @@ -0,0 +1,256 @@ +/** + ****************************************************************************** + * @file ft32f4xx_misc.c + * @author FMD AE + * @brief This file provides all the miscellaneous firmware functions (add-on + * to CMSIS functions). + * @version V1.0.0 + * @data 2025-07-01 + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx_misc.h" + +/** @defgroup MISC + * @brief MISC driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +#define AIRCR_VECTKEY_MASK ((uint32_t)0x05FA0000) + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup MISC_Private_Functions + * @{ + */ + +/** + * @brief Configures the priority grouping: pre-emption priority and subpriority. + * @param NVIC_PriorityGroup: specifies the priority grouping bits length. + * This parameter can be one of the following values: + * @arg NVIC_PriorityGroup_0: 0 bits for pre-emption priority + * 4 bits for subpriority + * @arg NVIC_PriorityGroup_1: 1 bits 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 bits for subpriority + * @arg NVIC_PriorityGroup_4: 4 bits for pre-emption priority + * 0 bits 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 NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup) +{ + /* Check the parameters */ + assert_param(IS_NVIC_PRIORITY_GROUP(NVIC_PriorityGroup)); + + /* Set the PRIGROUP[10:8] bits according to NVIC_PriorityGroup value */ + SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup; +} + +/** + * @brief Initializes the NVIC peripheral according to the specified + * parameters in the NVIC_InitStruct. + * @note To configure interrupts priority correctly, the NVIC_PriorityGroupConfig() + * function should be called before. + * @param NVIC_InitStruct: pointer to a NVIC_InitTypeDef structure that contains + * the configuration information for the specified NVIC peripheral. + * @retval None + */ +void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct) +{ + uint8_t tmppriority = 0x00, tmppre = 0x00, tmpsub = 0x0F; + + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NVIC_InitStruct->NVIC_IRQChannelCmd)); + assert_param(IS_NVIC_PREEMPTION_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority)); + assert_param(IS_NVIC_SUB_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelSubPriority)); + + if (NVIC_InitStruct->NVIC_IRQChannelCmd != DISABLE) + { + /* Compute the Corresponding IRQ Priority --------------------------------*/ + tmppriority = (0x700 - ((SCB->AIRCR) & (uint32_t)0x700)) >> 0x08; + tmppre = (0x4 - tmppriority); + tmpsub = tmpsub >> tmppriority; + + tmppriority = NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority << tmppre; + tmppriority |= (uint8_t)(NVIC_InitStruct->NVIC_IRQChannelSubPriority & tmpsub); + + tmppriority = tmppriority << 0x04; + + NVIC->IP[NVIC_InitStruct->NVIC_IRQChannel] = tmppriority; + + /* Enable the Selected IRQ Channels --------------------------------------*/ + NVIC->ISER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] = + (uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F); + } + else + { + /* Disable the Selected IRQ Channels -------------------------------------*/ + NVIC->ICER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] = + (uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F); + } +} + +/** + * @brief Sets the vector table location and Offset. + * @param NVIC_VectTab: specifies if the vector table is in RAM or FLASH memory. + * This parameter can be one of the following values: + * @arg NVIC_VectTab_RAM: Vector Table in internal SRAM. + * @arg NVIC_VectTab_FLASH: Vector Table in internal FLASH. + * @param Offset: Vector Table base offset field. This value must be a multiple of 0x200. + * @retval None + */ +void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset) +{ + /* Check the parameters */ + assert_param(IS_NVIC_VECTTAB(NVIC_VectTab)); + assert_param(IS_NVIC_OFFSET(Offset)); + + SCB->VTOR = NVIC_VectTab | (Offset & (uint32_t)0x1FFFFF80); +} + +/** + * @brief Selects the condition for the system to enter low power mode. + * @param LowPowerMode: Specifies the new mode for the system to enter low power mode. + * This parameter can be one of the following values: + * @arg NVIC_LP_SEVONPEND: Low Power SEV on Pend. + * @arg NVIC_LP_SLEEPDEEP: Low Power DEEPSLEEP request. + * @arg NVIC_LP_SLEEPONEXIT: Low Power Sleep on Exit. + * @param NewState: new state of LP condition. This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void NVIC_SystemLPConfig(uint8_t LowPowerMode, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_NVIC_LP(LowPowerMode)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + SCB->SCR |= LowPowerMode; + } + else + { + SCB->SCR &= (uint32_t)(~(uint32_t)LowPowerMode); + } +} + + +/* Systick initial ---------------------------------------------------------- */ + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/** @addtogroup Private_Variables + * @{ + */ +//__IO uint32_t uwTick; +//uint32_t uwTickPrio = (1UL << 4U); /* Invalid PRIO */ +//TickFreqTypeDef uwTickFreq = TICK_FREQ_DEFAULT; /* 1KHz */ +///** +// * @} +// */ + +//uint32_t SystemCoreClocktik = 210000000; /*SYSTEM clock frequece */ + +//#define TICK_INT_PRIORITY (0x0FU) /*!< tick interrupt priority */ + + +///** +// * @brief Initializes the System Timer and its its interrupt,and statrs the System Tick Timer. +// * 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 SYSTICK_Config(uint32_t TicksNumb) +//{ +// return SysTick_Config(TicksNumb); +//} + +///** +// * @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 In the default implementation, SysTick timer is the source of time base. +// * It is used to generate interrupts at regular time intervals. +// * 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 void __attribute__((weak)) to be overwritten in case of other +// * implementation in user file. +// * @param TickPriority Tick interrupt priority. +// * @retval staus: +// */ +//void InitTick(uint32_t TickPriority,uint32_t SubPriority) +//{ +// uint32_t prioritygroup = 0x00U; + +// prioritygroup = NVIC_GetPriorityGrouping(); + +// /* Configure the SysTick to have interrupt in 1ms time basis*/ +// if (SYSTICK_Config(SystemCoreClocktik / (1000U / uwTickFreq)) > 0U) +// { +// return; +// } + +// /* Configure the SysTick IRQ priority */ +// if (TickPriority < (1UL << 4U)) +// { +// NVIC_SetPriority(SysTick_IRQn, NVIC_EncodePriority(prioritygroup, TickPriority, SubPriority)); +// uwTickPrio = TickPriority; +// } +// else +// { +// return; +// } + +// return; +//} + +///** +// * @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 void __attribute__((weak)) to be overwritten in case of other +// * implementations in user file. +// * @retval None +// */ +//void IncTick(void) +//{ +// uwTick += uwTickFreq; +//} + +///** +// * @brief Provides a tick value in millisecond. +// * @note This function is declared as void __attribute__((weak)) to be overwritten in case of other +// * implementations in user file. +// * @retval tick value +// */ +//uint32_t GetTick(void) +//{ +// return uwTick; +//} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_opamp.c b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_opamp.c new file mode 100644 index 00000000000..fb88a274510 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_opamp.c @@ -0,0 +1,483 @@ +/** + ****************************************************************************** + * @file ft32f1xx_opa.c + * @author FMD xzhang + * @brief This file provides firmware functions to manage the following + * functionalities of the comparators (OPA1 OPA2 OPA3) peripheral + * applicable + * @version V1.0.0 + * @data 2025-03-31 + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx_opamp.h" +#include "ft32f4xx_rcc.h" + + +/** + * @brief Initializes the OPA peripheral according to the specified parameters + * in OPA_InitStruct + * @note If the selected opamp is locked, initialization can't be performed. + * To unlock the configuration, perform a system reset. + * @note To correctly run this function, the OPA_Cali() function must be called before. + * @param OPAMP_Selection: the selected comparator. + * This parameter can be one of the following values: + * @arg OPAMP_1: OPAMP1 selected + * @arg OPAMP_2: OPAMP2 selected + * @arg OPAMP_3: OPAMP3 selected + * @param OPA_InitStruct: pointer to an OPA_InitTypeDef structure that contains + * the configuration information for the specified OPA peripheral. + * @retval None + */ +void OPA_Init(OPA_InitTypeDef* OPA_InitStruct, uint32_t OPAMP_Selection) +{ + uint32_t tmpreg1 = 0; + uint32_t tmpreg2 = 0; + + /* Check the parameters */ + assert_param(IS_OPAX_PERIPH(OPAMP_Selection)); + assert_param(IS_OPA_VIP_SEL(OPA_InitStruct -> OPA_VPSEL)); + assert_param(IS_OPA_VIM_SEL(OPA_InitStruct -> OPA_VMSEL)); + assert_param(IS_OPA_VIPS_SEL(OPA_InitStruct -> OPA_VPSSEL)); + assert_param(IS_OPA_VIMS_SEL(OPA_InitStruct -> OPA_VMSSEL)); + assert_param(IS_OPAX_TIM8_EN(OPA_InitStruct -> T8_CM)); + assert_param(IS_OPAX_TIM1_EN(OPA_InitStruct -> T1_CM)); + assert_param(IS_OPAX_OPAHSM(OPA_InitStruct -> OPAHSM)); + assert_param(IS_OPAX_OPINTOEN(OPA_InitStruct -> OPINTOEN)); + assert_param(IS_OPAX_O2PADSEL(OPA_InitStruct -> O2PADSEL)); + assert_param(IS_OPA_PGAGAIN(OPA_InitStruct -> OPA_PGAGAIN)); + + /*!< Configure : OPA_VPSEL OPA_VMSEL OPAHSM OPINTOEN O2PADSEL OPA_PGAGAIN*/ + tmpreg1 = (uint32_t)(OPA_InitStruct -> OPA_VPSEL | OPA_InitStruct -> OPA_VMSEL | OPA_InitStruct -> OPAHSM | OPA_InitStruct -> OPINTOEN | OPA_InitStruct -> O2PADSEL | OPA_InitStruct -> OPA_PGAGAIN); + + /*!< Configure : OPA_VPSSEL OPA_VMSSEL T8_CM T1_CM*/ + tmpreg2 = (uint32_t)(OPA_InitStruct -> OPA_VPSSEL | OPA_InitStruct -> OPA_VMSSEL | OPA_InitStruct ->T8_CM | OPA_InitStruct -> T1_CM); + + if (OPAMP_Selection == OPAMP_1) //config opamp1 + { + /*!< Write to COMP_CSR register */ + COMP_OPAM_DAC ->OPAMP1_CSR = tmpreg1; + COMP_OPAM_DAC ->OPAMP1_TCMR = tmpreg2; + } + else if (OPAMP_Selection == OPAMP_2) //config opamp2 + { + /*!< Write to COMP_CSR register */ + COMP_OPAM_DAC ->OPAMP2_CSR = tmpreg1; + COMP_OPAM_DAC ->OPAMP2_TCMR = tmpreg2; + } + else if (OPAMP_Selection == OPAMP_3) //config opamp3 + { + /*!< Write to COMP_CSR register */ + COMP_OPAM_DAC ->OPAMP3_CSR = tmpreg1; + COMP_OPAM_DAC ->OPAMP3_TCMR = tmpreg2; + } +} + + +/** + * @brief Deinitializes OPA peripheral registers to their default reset values. + * @note Deinitialization can't be performed if the OPA configuration is locked. + * To unlock the configuration, perform a system reset. + * @param OPAx: the selected comparator. + * This parameter can be one of the following values: + * @arg OPAMP_1: OPAMP1 selected + * @arg OPAMP_2: OPAMP2 selected + * @arg OPAMP_3: OPAMP3 selected + * @retval None + */ +void OPA_DeInit(uint32_t OPAMP_Selection) +{ + /* Check the parameters */ + assert_param(IS_OPAX_PERIPH(OPAMP_Selection)); + + if (OPAMP_Selection == OPAMP_1) + { + /*!< Set OPA_CSR register to reset value */ + COMP_OPAM_DAC ->OPAMP1_CSR = ((uint32_t)0x00000000); + COMP_OPAM_DAC ->OPAMP1_TCMR = ((uint32_t)0x00000000); + } + else if (OPAMP_Selection == OPAMP_2) + { + COMP_OPAM_DAC ->OPAMP2_CSR = ((uint32_t)0x00000000); + COMP_OPAM_DAC ->OPAMP2_TCMR = ((uint32_t)0x00000000); + } + else if (OPAMP_Selection == OPAMP_3) + { + COMP_OPAM_DAC ->OPAMP3_CSR = ((uint32_t)0x00000000); + COMP_OPAM_DAC ->OPAMP3_TCMR = ((uint32_t)0x00000000); + } + +} + + +/** + * @brief Enable or disable the OPA peripheral. + * @note If the selected opamp is locked, enable/disable can't be performed. + * To unlock the configuration, perform a system reset. + * @param OPAMP_Selection: the selected comparator. + * This parameter can be one of the following values: + * @arg OPAMP_1: OPAMP1 selected + * @arg OPAMP_2: OPAMP2 selected + * @arg OPAMP_3: OPAMP3 selected + * @param NewState: new state of the OPA peripheral. + * This parameter can be: ENABLE or DISABLE. + * @note When disabled, the opamp doesn't perform comparison and the + * output level is low. + * @retval None + */ +void OPA_Cmd(uint32_t OPAMP_Selection, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_OPAX_PERIPH(OPAMP_Selection)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + if (OPAMP_Selection == OPAMP_1) + /* Enable the selected OPA peripheral */ + COMP_OPAM_DAC ->OPAMP1_CSR |= OPAMP1_CSR_OPAEN; + else if (OPAMP_Selection == OPAMP_2) + /* Enable the selected OPA peripheral */ + COMP_OPAM_DAC ->OPAMP2_CSR |= OPAMP2_CSR_OPAEN; + else if (OPAMP_Selection == OPAMP_3) + /* Enable the selected OPA peripheral */ + COMP_OPAM_DAC ->OPAMP3_CSR |= OPAMP3_CSR_OPAEN; + } + else + { + if (OPAMP_Selection == OPAMP_1) + /* Disable the selected OPA peripheral */ + COMP_OPAM_DAC ->OPAMP1_CSR &= ~OPAMP1_CSR_OPAEN; + else if (OPAMP_Selection == OPAMP_2) + /* Disable the selected OPA peripheral */ + COMP_OPAM_DAC ->OPAMP2_CSR &= ~OPAMP2_CSR_OPAEN; + else if (OPAMP_Selection == OPAMP_3) + /* Disable the selected OPA peripheral */ + COMP_OPAM_DAC ->OPAMP3_CSR &= ~OPAMP3_CSR_OPAEN; + } +} + + + +/** + * @brief Calibration OPAMPx 's NMOS or PMOS. + * @note If you want to Calibration OPAMP ,recommend to use OPA_DeInit() firstly. + * @note Every TRIMOFFSETN/P change need delay 200 us + * @note Trim NMOS switch to PMOS need delay 500 us at least ,in this Function is 600us + * @param OPAMP_Selection: the selected comparator. + * This parameter can be one of the following values: + * @arg OPAMP_1: OPAMP1 selected + * @arg OPAMP_2: OPAMP2 selected + * @arg OPAMP_3: OPAMP3 selected + * @retval NONE + */ +volatile uint32_t flag; +volatile uint32_t flag_n; +volatile uint32_t flag_p; +volatile uint32_t nmos_cnt = 0; +volatile uint32_t pmos_cnt = 0; + +void OPAMP_Calibration(uint32_t OPAMP_Selection) +{ + uint32_t next_nmos_cnt; + uint32_t next_pmos_cnt; + uint32_t apbclock; + /*This is TIM's ARR value is calculate automaticly according to sysclk by users set */ + uint32_t ARR_value; + + RCC_ClocksTypeDef RCC_ClocksStatus; + + RCC_GetClocksFreq(&RCC_ClocksStatus); + + apbclock = RCC_ClocksStatus.PCLK_Frequency ; + + if ((RCC->CFGR & 0x400) == 0x400) //if PPRE1[10] bit is 1 + ARR_value = (apbclock >> 2) / 625; //==(200*time freq)/1000000, tim freq=2 * apbclock; + else + ARR_value = (apbclock >> 3) / 625; //==(200*apbclock)/1000000; + + + /*Open TIMER6 clk */ + RCC->APB1ENR |= RCC_APB1ENR_TIM6EN; + /*set 50us as calibration delay by TIMER6 */ + NVIC_EnableIRQ(TIM6_DAC_IRQn); + TIM6 -> DIER |= TIM_DIER_UIE ; + TIM6 -> ARR = ARR_value ; //delay: 200us ;0xc80 =200000ns/T(freq clk) Now apb1clk is 16MHZ + TIM6 -> CR2 |= TIM_CR2_MMS_1 ; + TIM6 -> CR1 |= TIM_CR1_CEN ; + /* ==========================select OPAMP1==========================*/ + if (OPAMP_Selection == OPAMP_1) + { + /*-------------------calibration NMOS------------------*/ + /*make sure enable opamp1*/ + COMP_OPAM_DAC -> OPAMP1_CSR |= OPAMP1_CSR_OPAEN ; + /*enable cal trim*/ + COMP_OPAM_DAC -> OPAMP1_CSR |= OPAMP1_CSR_USERTRIM ; + /*cal sel NMOS*/ + COMP_OPAM_DAC -> OPAMP1_CSR |= OPAMP1_CSR_CALSEL_0 | OPAMP1_CSR_CALSEL_1; + /*vpsel =101*/ + COMP_OPAM_DAC -> OPAMP1_CSR |= OPAMP1_CSR_VP_SEL_2 | OPAMP1_CSR_VP_SEL_0; + + /*if nmos_cnt = 31,jump out cal NMOS*/ + while (((COMP_OPAM_DAC -> OPAMP1_CSR) & OPAMP1_CSR_TRIMOFFSETN_Msk) != OPAMP1_CSR_TRIMOFFSETN_Msk) + { + /*wait calout value become 0 */ + while ((COMP_OPAM_DAC -> OPAMP1_CSR & OPAMP1_CSR_CALOUT) == 0x40000000) + { + if (nmos_cnt >= 0x1f) + { + /*NMOS max value is 31 */ + nmos_cnt = 0x1f; + break; + } + else + { + /*wait 50us flag*/ + while (flag_n == 1) + { + next_nmos_cnt = (nmos_cnt << 24) | 0xe0ffffff; + /*updata TRIMOFFSETN value in OPAMP1_CSR and keep other bit*/ + COMP_OPAM_DAC -> OPAMP1_CSR = next_nmos_cnt & (0x1f000000 | (COMP_OPAM_DAC -> OPAMP1_CSR)); + nmos_cnt ++; + flag_n = 0; + } + } + } + break; + } + /*wait 600us*/ + for (int num = 0; num < 3; num++) + { + flag = 1; + while (flag == 1); //wait 50us + } + /*-----------------calibration PMOS-----------------*/ + /*cal sel PMOS*/ + COMP_OPAM_DAC -> OPAMP1_CSR &= ~OPAMP1_CSR_CALSEL_1 ; + /*if pmos_cnt = 31,jump out cal PMOS*/ + while (((COMP_OPAM_DAC -> OPAMP1_CSR) & OPAMP1_CSR_TRIMOFFSETP_Msk) != OPAMP1_CSR_TRIMOFFSETP_Msk) + { + while ((COMP_OPAM_DAC -> OPAMP1_CSR & OPAMP1_CSR_CALOUT) == 0x40000000) + { + if (pmos_cnt >= 0x20) + { + pmos_cnt = 0x1f; + break; + } + else + { + /*wait 50us flag*/ + while (flag_p == 1) + { + next_pmos_cnt = (pmos_cnt << 19) | 0xff07ffff; + /*updata TRIMOFFSETN value in OPAMP1_CSR and keep other bit*/ + COMP_OPAM_DAC -> OPAMP1_CSR = next_pmos_cnt & (0x00f80000 | (COMP_OPAM_DAC -> OPAMP1_CSR)); + pmos_cnt ++; + flag_p = 0; + } + } + } + break; + } + flag = 1; + while (flag == 1); //50us + COMP_OPAM_DAC -> OPAMP1_CSR &= ~OPAMP1_CSR_CALSEL_0 + & ~OPAMP1_CSR_USERTRIM + & ~OPAMP1_CSR_VP_SEL_2 //vp_sel:000 + & ~OPAMP1_CSR_VP_SEL_0; + }//end opamp1 + + + /* =============================select OPAMP2==========================*/ + else if (OPAMP_Selection == OPAMP_2) + { + /*-------------------calibration NMOS------------------*/ + /*make sure enable OPAMP2*/ + COMP_OPAM_DAC -> OPAMP2_CSR |= OPAMP2_CSR_OPAEN ; + /*enable cal trim*/ + COMP_OPAM_DAC -> OPAMP2_CSR |= OPAMP2_CSR_USERTRIM ; + /*cal sel NMOS*/ + COMP_OPAM_DAC -> OPAMP2_CSR |= OPAMP2_CSR_CALSEL_0 | OPAMP2_CSR_CALSEL_1; + /*vpsel =101*/ + COMP_OPAM_DAC -> OPAMP2_CSR |= OPAMP2_CSR_VP_SEL_2 | OPAMP2_CSR_VP_SEL_0; + /*if nmos_cnt = 31,jump out cal NMOS*/ + while (((COMP_OPAM_DAC -> OPAMP2_CSR) & OPAMP2_CSR_TRIMOFFSETN_Msk) != OPAMP2_CSR_TRIMOFFSETN_Msk) + { + /*wait calout value become 0 */ + while ((COMP_OPAM_DAC -> OPAMP2_CSR & OPAMP2_CSR_CALOUT) == 0x40000000) + { + if (nmos_cnt >= 0x1f) + { + /*NMOS max value is 31 */ + nmos_cnt = 0x1f; + break; + } + else + { + /*wait 50us flag*/ + while (flag_n == 1) + { + next_nmos_cnt = (nmos_cnt << 24) | 0xe0ffffff; + /*updata TRIMOFFSETN value in OPAMP2_CSR and keep other bit*/ + COMP_OPAM_DAC -> OPAMP2_CSR = next_nmos_cnt & (0x1f000000 | (COMP_OPAM_DAC -> OPAMP2_CSR)); + nmos_cnt ++; + flag_n = 0; + } + } + } + break; + } + /*wait 600us*/ + for (int num = 0; num < 3; num++) + { + flag = 1; + while (flag == 1); + } + /*-----------------calibration PMOS-----------------*/ + /*cal sel PMOS*/ + COMP_OPAM_DAC -> OPAMP2_CSR &= ~OPAMP2_CSR_CALSEL_1 ; + /*if pmos_cnt = 31,jump out cal PMOS*/ + while (((COMP_OPAM_DAC -> OPAMP2_CSR) & OPAMP2_CSR_TRIMOFFSETP_Msk) != OPAMP2_CSR_TRIMOFFSETP_Msk) + { + while ((COMP_OPAM_DAC -> OPAMP2_CSR & OPAMP2_CSR_CALOUT) == 0x40000000) + { + if (pmos_cnt >= 0x20) + { + pmos_cnt = 0x1f; + break; + } + else + { + /*wait 50us flag*/ + while (flag_p == 1) + { + next_pmos_cnt = (pmos_cnt << 19) | 0xff07ffff; + /*updata TRIMOFFSETN value in OPAMP2_CSR and keep other bit*/ + COMP_OPAM_DAC -> OPAMP2_CSR = next_pmos_cnt & (0x00f80000 | (COMP_OPAM_DAC -> OPAMP2_CSR)); + pmos_cnt ++; + flag_p = 0; + } + } + } + break; + } + flag = 1; + while (flag == 1); //50us + COMP_OPAM_DAC -> OPAMP2_CSR &= ~OPAMP2_CSR_CALSEL_0 + & ~OPAMP2_CSR_USERTRIM + & ~OPAMP2_CSR_VP_SEL_2 //vp_sel:000 + & ~OPAMP2_CSR_VP_SEL_0; + }//end OPAMP2 + + /*================================= select OPAMP3===============================*/ + else if (OPAMP_Selection == OPAMP_3) + { + /*-------------------calibration NMOS------------------*/ + /*make sure enable OPAMP3*/ + COMP_OPAM_DAC -> OPAMP3_CSR |= OPAMP3_CSR_OPAEN ; + /*enable cal trim*/ + COMP_OPAM_DAC -> OPAMP3_CSR |= OPAMP3_CSR_USERTRIM ; + /*cal sel NMOS*/ + COMP_OPAM_DAC -> OPAMP3_CSR |= OPAMP3_CSR_CALSEL_0 | OPAMP3_CSR_CALSEL_1; + /*vpsel =101*/ + COMP_OPAM_DAC -> OPAMP3_CSR |= OPAMP3_CSR_VP_SEL_2 | OPAMP3_CSR_VP_SEL_0; + + /*if nmos_cnt = 31,jump out cal NMOS*/ + while (((COMP_OPAM_DAC -> OPAMP3_CSR) & OPAMP3_CSR_TRIMOFFSETN_Msk) != OPAMP3_CSR_TRIMOFFSETN_Msk) + { + /*wait calout value become 0 */ + while ((COMP_OPAM_DAC -> OPAMP3_CSR & OPAMP3_CSR_CALOUT) == 0x40000000) + { + if (nmos_cnt >= 0x1f) + { + /*NMOS max value is 31 */ + nmos_cnt = 0x1f; + break; + } + else + { + /*wait 50us flag*/ + while (flag_n == 1) + { + next_nmos_cnt = (nmos_cnt << 24) | 0xe0ffffff; + /*updata TRIMOFFSETN value in OPAMP3_CSR and keep other bit*/ + COMP_OPAM_DAC -> OPAMP3_CSR = next_nmos_cnt & (0x1f000000 | (COMP_OPAM_DAC -> OPAMP3_CSR)); + nmos_cnt ++; + flag_n = 0; + } + } + } + break; + } + /*wait 600us*/ + for (int num = 0; num < 3; num++) + { + flag = 1; + while (flag == 1); //wait 50us + } + /*-----------------calibration PMOS-----------------*/ + /*cal sel PMOS*/ + COMP_OPAM_DAC -> OPAMP3_CSR &= ~OPAMP3_CSR_CALSEL_1 ; + /*if pmos_cnt = 31,jump out cal PMOS*/ + while (((COMP_OPAM_DAC -> OPAMP3_CSR) & OPAMP3_CSR_TRIMOFFSETP_Msk) != OPAMP3_CSR_TRIMOFFSETP_Msk) + { + while ((COMP_OPAM_DAC -> OPAMP3_CSR & OPAMP3_CSR_CALOUT) == 0x40000000) + { + if (pmos_cnt >= 0x20) + { + pmos_cnt = 0x1f; + break; + } + else + { + /*wait 50us flag*/ + while (flag_p == 1) + { + next_pmos_cnt = (pmos_cnt << 19) | 0xff07ffff; + /*updata TRIMOFFSETN value in OPAMP3_CSR and keep other bit*/ + COMP_OPAM_DAC -> OPAMP3_CSR = next_pmos_cnt & (0x00f80000 | (COMP_OPAM_DAC -> OPAMP3_CSR)); + pmos_cnt ++; + flag_p = 0; + } + } + } + break; + } + flag = 1; + while (flag == 1); //50us + COMP_OPAM_DAC -> OPAMP3_CSR &= ~OPAMP3_CSR_CALSEL_0 + & ~OPAMP3_CSR_USERTRIM + & ~OPAMP3_CSR_VP_SEL_2 //vp_sel:000 + & ~OPAMP3_CSR_VP_SEL_0; + }//end OPAMP3 + +} + +void TIM6_DAC_Handler(void) +{ + flag = 0; + flag_n = 1; + flag_p = 1; + + TIM6 -> SR &= ~TIM_SR_UIF; +} + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_pcd_ex_hs.c b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_pcd_ex_hs.c new file mode 100644 index 00000000000..2eeba1af063 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_pcd_ex_hs.c @@ -0,0 +1,112 @@ +/** + ****************************************************************************** + * @file ft32f4xx_pcd_ex_hs.c + * @author FMD XA + * @brief This file provides firmware functions to manage the following + * functionalities of the USB Peripheral Controller: + * + Extended features functions + * @version V1.0.0 + * @data 2025-04-01 + */ +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx.h" +#include "ft32f4xx_rcc.h" + + +/** @addtogroup FT32F4xx_DRIVER + * @{ + */ + +#ifdef PCD_MODULE_ENABLED +#if defined (USB_OTG_HS) +/** @defgroup PCD_HS PCD + * @brief PCD HS module driver + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ + + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup PCDEx_HS_Exported_Functions PCDEx Exported Functions + * @{ + */ + +/** @defgroup PCDEx_HS_Exported_Functions_Group1 Peripheral Control functions + * @brief PCDEx control functions + * +@verbatim + =============================================================================== + ##### Extended features functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Update FIFO configuration +@endverbatim + * @{ + */ +#if defined (USB_OTG_HS) +/** + * @brief Set Tx FIFO + * @param fifo The number of Tx fifo + * @param size Fifo size + * @retval none + */ +void PCDEx_HS_SetTxFiFo(uint8_t fifo, uint16_t size) +{ + uint8_t i; + uint32_t Tx_Offset; + + /* TXn min size = 16 words. (n : Transmit FIFO index) + When a TxFIFO is not used, the Configuration should be as follows: + case 1 : n > m and Txn is not used (n,m : Transmit FIFO indexes) + --> Txm can use the space allocated for Txn. + case2 : n < m and Txn is not used (n,m : Transmit FIFO indexes) + --> Txn should be configured with the minimum space of 16 words + The FIFO is used optimally when used TxFIFOs are allocated in the top + of the FIFO.Ex: use EP1 and EP2 as IN instead of EP1 and EP3 as IN ones. + When DMA is used 3n * FIFO locations should be reserved for internal DMA registers */ + + Tx_Offset = USB_HS->GRXFSIZ; + + if (fifo == 0U) + { + USB_HS->DIEPTXF0_HNPTXFSIZ = ((uint32_t)size << 16) | Tx_Offset; + } + else + { + Tx_Offset += (USB_HS->DIEPTXF0_HNPTXFSIZ) >> 16; + for (i = 0U; i < (fifo - 1U); i++) + { + Tx_Offset += (USB_HS->DIEPTXF[i] >> 16); + } + + /* Multiply Tx_Size by 2 to get higher performance */ + USB_HS->DIEPTXF[fifo - 1U] = ((uint32_t)size << 16) | Tx_Offset; + } + +} + +/** + * @brief Set Rx FIFO + * @param size Size of Rx fifo + * @retval none + */ +void PCDEx_HS_SetRxFiFo(uint16_t size) +{ + USB_HS->GRXFSIZ = size; + +} +#endif /* defined (USB_OTG_HS) */ + +/** + * @} + */ + + +#endif /* defined (USB_OTG_HS) */ +#endif /* PCD_MODULE_ENABLED */ + diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_pcd_fs.c b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_pcd_fs.c new file mode 100644 index 00000000000..1d29cf9ec36 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_pcd_fs.c @@ -0,0 +1,1413 @@ +/** + ****************************************************************************** + * @file ft32f4xx_pcd_fs.c + * @author FMD XA + * @brief This file provides firmware functions to manage the following + * functionalities of the USB Peripheral Controller: + * + Initialization/de-initialization functions + * + Peripheral Control functions + * + Peripheral State functions + * @version V1.0.0 + * @data 2025-05-30 + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + (#)Declare a PCD_FS_HandleTypeDef handle structure, for example: + PCD_FS_HandleTypeDef hpcd; + + (#)Fill parameters of Init structure in PCD handle + + (#)Call PCD_FS_Init() API to initialize the PCD peripheral (Core, Host core, ...) + + (#)Initialize the PCD low level resources through the PCD_FS_MspInit() API: + (##) Enable the PCD/USB Low Level interface clock using the following macros + (##) Initialize the related GPIO clocks + (##) Configure PCD NVIC interrupt + + (#)Associate the Upper USB Host stack to the PCD Driver: + (##) hpcd.pData = pdev; + + (#)Enable PCD transmission and reception: + (##) PCD_FS_Start(); + + @endverbatim + */ +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx.h" +#include "ft32f4xx_pcd_fs.h" +#include "ft32f4xx_rcc.h" +#include "usbd_core.h" + +/** @addtogroup FT32F4xx_DRIVER + * @{ + */ + +#ifdef PCD_FS_MODULE_ENABLED +#if defined (USB_OTG_FS) +/** @defgroup PCD_FS PCD + * @brief PCD FS module driver + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/** @defgroup PCD_FS_Private_Macros PCD Private Functions + * @{ + */ +#define PCD_MIN(a,b) (((a) < (b)) ? (a) : (b)) +#define PCD_MAX(a,b) (((a) > (b)) ? (a) : (b)) +/** + * @{ + */ + +/** @defgroup PCD_FS_Private_Functions PCD Private Functions + * @{ + */ + +static USB_FS_StatusTypeDef PCD_FS_WriteEmptyTxFifo(PCD_FS_HandleTypeDef *hpcd, uint8_t epnum); +static void PCD_FS_EP_OutXferComplete_int(PCD_FS_HandleTypeDef *hpcd, uint8_t epnum); +static void PCD_FS_EP_OutSetupPacket_int(PCD_FS_HandleTypeDef *hpcd, uint8_t epnum); +/** + * @{ + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup PCD_FS_Exported_Functions PCD Exported Functions + * @{ + */ + +/** @defgroup PCD_FS_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + ##### Initialization and de-initialization functions ##### + =============================================================================== + [..] This section provides functions allowing to: + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the PCD according to the specified + * parameters in the PCD_InitTypeDef and initialize the associated handle. + * @param hpcd PCD handle + * @retval USB_FS status + */ +USB_FS_StatusTypeDef PCD_FS_Init(PCD_FS_HandleTypeDef *hpcd) +{ + + uint8_t i; + + /* Check the PCD handle allocation */ + if (hpcd == NULL) + { + return USB_FS_ERROR; + } + + if (hpcd->State == PCD_FS_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hpcd->Lock = USB_FS_UNLOCKED; + + /* Init the low level hardware : GPIO, CLOCK, NVIC... */ + PCD_FS_MspInit(hpcd); + } + + hpcd->State = PCD_FS_STATE_BUSY; + + /* Disable the Interrupts */ + USB_FS_SetUSBInt(0U); + USB_FS_SetEPInt(0U); + /*Init the Core (common init.) */ +// if (USB_FS_CoreInit() != USB_FS_OK) +// { +// hpcd->State = PCD_FS_STATE_ERROR; +// return USB_FS_ERROR; +// } + + /* Init endpoints structures */ + for (i = 0U; i < hpcd->Init.endpoints; i++) + { + /* Init ep structure */ + hpcd->IN_ep[i].is_in = 1U; + hpcd->IN_ep[i].num = i; + hpcd->IN_ep[i].tx_fifo_num = i; + /* Control until ep is activated */ + hpcd->IN_ep[i].type = EP_TYPE_CTRL; + hpcd->IN_ep[i].maxpacket = 0U; + hpcd->IN_ep[i].xfer_buff = 0U; + hpcd->IN_ep[i].xfer_len = 0U; + } + + for (i = 0U; i < hpcd->Init.endpoints; i++) + { + hpcd->OUT_ep[i].is_in = 0U; + hpcd->OUT_ep[i].num = i; + /* Control until ep is activated */ + hpcd->OUT_ep[i].type = EP_TYPE_CTRL; + hpcd->OUT_ep[i].maxpacket = 0U; + hpcd->OUT_ep[i].xfer_buff = 0U; + hpcd->OUT_ep[i].xfer_len = 0U; + } + + /* Init Device */ + if (USB_FS_DevInit(hpcd->Init) != USB_FS_OK) + { + hpcd->State = PCD_FS_STATE_ERROR; + return USB_FS_ERROR; + } + + hpcd->USB_Address = 0U; + hpcd->State = PCD_FS_STATE_READY; + hpcd->ctrl_state = CTRL_SETUP_P; +// USB_FS_DrvSess(0U); + + return USB_FS_OK; +} + +/** + * @brief DeInitializes the PCD peripheral. + * @param hpcd PCD handle + * @retval USB_FS status + */ +USB_FS_StatusTypeDef PCD_FS_DeInit(PCD_FS_HandleTypeDef *hpcd) +{ + uint32_t i; + /* Check the PCD handle allocation */ + if (hpcd == NULL) + { + return USB_FS_ERROR; + } + + hpcd->State = PCD_FS_STATE_BUSY; + + /* Stop Device */ + USB_FS_SetUSBInt(0U); + USB_FS_SetEPInt(0U); + + if (USB_FS_RstEP0Regs() != USB_FS_OK) + { + return USB_FS_ERROR; + } + for (i = 1U; i < hpcd->Init.endpoints; i++) + { + if (USB_FS_RstEPRegs(i) != USB_FS_OK) + { + return USB_FS_ERROR; + } + } + /* DeInit the low level hardware: CLOCK, NVIC.*/ + PCD_FS_MspDeInit(hpcd); + + hpcd->State = PCD_FS_STATE_RESET; + + return USB_FS_OK; +} + +/** + * @brief set iso mode. + * @param hpcd PCD handle + * @retval none + */ +void PCD_FS_SetISO(uint8_t ep_num, uint8_t state) +{ + USB_FS_IndexSel(ep_num); + if (state != 0U) + { + USB_FS->TXCSR2 |= OTG_FS_TXCSR2_ISO ; + USB_FS->RXCSR2 |= OTG_FS_RXCSR2_ISO ; + } + else + { + USB_FS->TXCSR2 &= ~OTG_FS_TXCSR2_ISO ; + USB_FS->RXCSR2 &= ~OTG_FS_RXCSR2_ISO ; + } +} + +/** + * @brief set maxpacket. + * @param hpcd PCD handle + * @retval none + */ +void PCD_FS_SetMaxPkt(uint8_t ep_num, uint16_t size) +{ + uint16_t maxpkt; + maxpkt = (size + 7U) / 8U ; + USB_FS_IndexSel(ep_num); + + USB_FS->TXMAXP = maxpkt; + USB_FS->RXMAXP = maxpkt; +} + +/** + * @brief Initializes the PCD MSP. + * @param hpcd PCD handle + * @retval None + */ +void __attribute__((weak)) PCD_FS_MspInit(PCD_FS_HandleTypeDef *hpcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the PCD_FS_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitializes PCD MSP. + * @param hpcd PCD handle + * @retval None + */ +void __attribute__((weak)) PCD_FS_MspDeInit(PCD_FS_HandleTypeDef *hpcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the PCD_FS_MspDeInit could be implemented in the user file + */ +} + + +/** + * @} + */ + +/** @defgroup PCD_Exported_Functions_Group2 Input and Output operation functions + * @brief Data transfers functions + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to manage the PCD data + transfers. + +@endverbatim + * @{ + */ + +/** + * @brief Start the USB device + * @param hpcd PCD handle + * @retval USB_FS status + */ +USB_FS_StatusTypeDef PCD_FS_Start(PCD_FS_HandleTypeDef *hpcd) +{ + __USB_FS_LOCK(hpcd); + +// USB_FS_SetUSBInt(OTG_FS_INTRUSBE_SOFINTE | OTG_FS_INTRUSBE_RSTINTE | +// OTG_FS_INTRUSBE_DISCINTE | OTG_FS_INTRUSBE_SREQINTE | +// OTG_FS_INTRUSBE_VERRINTE); + + USB_FS_DrvSess(1U); + + __USB_FS_UNLOCK(hpcd); + + return USB_FS_OK; +} + +/** + * @brief Stop the USB device. + * @param hpcd PCD handle + * @retval USB_FS status + */ +USB_FS_StatusTypeDef PCD_FS_Stop(PCD_FS_HandleTypeDef *hpcd) +{ + uint32_t i; + __USB_FS_LOCK(hpcd); + + USB_FS_SetUSBInt(0U); + + USB_FS_DrvSess(0U); + if (USB_FS_FlushEp0Fifo() != USB_FS_OK) + { + return USB_FS_ERROR; + } + for (i = 1U; i < hpcd->Init.endpoints; i++) + { + if (USB_FS_FlushTxFifo(i) != USB_FS_OK) + { + return USB_FS_ERROR; + } + if (USB_FS_FlushRxFifo(i) != USB_FS_OK) + { + return USB_FS_ERROR; + } + } + __USB_FS_UNLOCK(hpcd); + + return USB_FS_OK; +} + +#if defined (USB_OTG_FS) +/** + * @brief Handles PCD interrupt request. + * @param hpcd PCD handle + * @retval none + */ +void PCD_FS_IRQHandler(PCD_FS_HandleTypeDef *hpcd) +{ + uint32_t i; + uint32_t ep_intr; + uint32_t epint; + uint32_t epnum; + uint32_t fifoemptymsk; + uint32_t RegVal; + uint32_t reg_int; + uint32_t tx_int; + uint32_t rx_int; + uint8_t reg_power; + + reg_int = USB_FS_ReadInterrupts(); + /* ensure that we are in device mode */ + if ((USB_FS_GetMode() & USB_OTG_MODE_DEVICE) == USB_OTG_MODE_DEVICE) + { + /* avoid spurious interrupt */ + if (reg_int == 0U) + { + return; + } + + /* store current frame number */ + hpcd->FrameNumber = USB_FS_GetCurrentFrame(); + + /* Handle vbus error Interrupts */ + if ((reg_int & 0xFFU) != 0U) + { + if ((reg_int & OTG_FS_INTRUSB_VERRINT) == OTG_FS_INTRUSB_VERRINT) + { + PCD_FS_VBusErrCallback(hpcd); + } + + /* Handle session request Interrupts */ + if ((reg_int & OTG_FS_INTRUSB_SREQINT) == OTG_FS_INTRUSB_SREQINT) + { + PCD_FS_SessionCallback(hpcd); + } + + /* Handle Host Disconnect Interrupts */ + if ((reg_int & OTG_FS_INTRUSB_DISCINT) == OTG_FS_INTRUSB_DISCINT) + { + /* Handle Host Port Disconnect Interrupt */ + PCD_FS_DisconnectCallback(hpcd); + } + + /* Handle Host Connect Interrupts */ +// if ((reg_int & OTG_FS_INTRUSB_CONNINT) == OTG_FS_INTRUSB_CONNINT) +// { +// /* Handle Host Port Connect Interrupt */ +// PCD_FS_ConnectCallback(hpcd); +// } + + /* Handle Host SOF Interrupt */ + if ((reg_int & OTG_FS_INTRUSB_SOFINT) == OTG_FS_INTRUSB_SOFINT) + { + PCD_FS_SOFCallback(hpcd); + } + /* Handle Host reset Interrupt */ + if ((reg_int & OTG_FS_INTRUSB_RSTINT) == OTG_FS_INTRUSB_RSTINT) + { + USB_FS->CSR0 |= (OTG_FS_CSR0_SSETUPEND | OTG_FS_CSR0_SRXPKTRDY); + USB_FS_RstEP0Regs(); + for (i = 1U; i < hpcd->Init.endpoints; i++) + { + USB_FS->TXCSR1 = 0U; + USB_FS->RXCSR1 = 0U; + (void)USB_FS_ReadInterrupts(); + USB_FS_RstEPRegs(i); + } + + USB_FS_SetEPInt(0x0FU); + + USB_FS_SetAddress(0U); + + PCD_FS_ResetCallback(hpcd); + } + /* Handle resume Interrupt */ + if ((reg_int & OTG_FS_INTRUSB_RESINT) == OTG_FS_INTRUSB_RESINT) + { + PCD_FS_ResumeCallback(hpcd); + } + /* Handle suspend Interrupt */ + if ((reg_int & OTG_FS_INTRUSB_SUSPINT) == OTG_FS_INTRUSB_SUSPINT) + { + reg_power = USB_FS_GetPower(); + if ((reg_power & OTG_FS_POWER_SUSPEND) != 0U) + { + PCD_FS_SuspendCallback(hpcd); + } + } + } + /* Handle EP0 endpoint Interrupt */ + tx_int = ((reg_int >> 8) & 0xFU); + if ((tx_int & OTG_FS_INTRTX1_EP0INF) == OTG_FS_INTRTX1_EP0INF) + { + (void)USB_FS_IndexSel(0U); + USBD_SET_ADDR(hpcd->pData); + PCD_FS_EP0_IRQHandler(hpcd); + } + + /* Handle Tx endpoint Interrupt */ + if (((reg_int >> 8) & 0xEU) != 0U) + { + for (i = 1U; i < hpcd->Init.endpoints; i++) + { + if (((tx_int >> i) & 0x01U) != 0U) + { + (void)USB_FS_IndexSel((uint8_t)i); + PCD_FS_TXEP_IRQHandler(hpcd, (uint8_t)i); + } + } + } + + /* Handle Rx endpoint Interrupt */ + if (((reg_int >> 16) & 0xFU) != 0U) + { + rx_int = ((reg_int >> 16) & 0xFU); + for (i = 1U; i < hpcd->Init.endpoints; i++) + { + if (((rx_int >> i) & 0x01U) != 0U) + { + (void)USB_FS_IndexSel((uint8_t)i); + PCD_FS_RXEP_IRQHandler(hpcd, (uint8_t)i); + } + } + } + } +} + +/** + * @brief Handles PCD Wakeup interrupt request. + * @param hpcd PCD handle + * @retval none status + */ +void PCD_FS_WKUP_IRQHandler(void) +{ + /* Clear EXTI pending Bit */ + __USB_OTG_FS_WAKEUP_EXTI_CLEAR_FLAG(); +} +#endif /* defined (USB_OTG_FS) */ + + +/** + * @brief Data OUT stage callback. + * @param hpcd PCD handle + * @param epnum endpoint number + * @retval None + */ +//void __attribute__((weak)) PCD_FS_DataOutStageCallback(PCD_FS_HandleTypeDef *hpcd, uint8_t epnum) +//{ +// /* Prevent unused argument(s) compilation warning */ +// UNUSED(hpcd); +// UNUSED(epnum); +// +// /* NOTE : This function should not be modified, when the callback is needed, +// the PCD_FS_DataOutStageCallback could be implemented in the user file +// */ +//} +// +///** +// * @brief Data IN stage callback +// * @param hpcd PCD handle +// * @param epnum endpoint number +// * @retval None +// */ +//void __attribute__((weak)) PCD_FS_DataInStageCallback(PCD_FS_HandleTypeDef *hpcd, uint8_t epnum) +//{ +// /* Prevent unused argument(s) compilation warning */ +// UNUSED(hpcd); +// UNUSED(epnum); +// +// /* NOTE : This function should not be modified, when the callback is needed, +// the PCD_FS_DataInStageCallback could be implemented in the user file +// */ +//} +///** +// * @brief Setup stage callback +// * @param hpcd PCD handle +// * @retval None +// */ +//void __attribute__((weak)) PCD_FS_SetupStageCallback(PCD_FS_HandleTypeDef *hpcd) +//{ +// /* Prevent unused argument(s) compilation warning */ +// UNUSED(hpcd); +// +// /* NOTE : This function should not be modified, when the callback is needed, +// the PCD_FS_SetupStageCallback could be implemented in the user file +// */ +//} +// +///** +// * @brief USB Start Of Frame callback. +// * @param hpcd PCD handle +// * @retval None +// */ +//void __attribute__((weak)) PCD_FS_SOFCallback(PCD_FS_HandleTypeDef *hpcd) +//{ +// /* Prevent unused argument(s) compilation warning */ +// UNUSED(hpcd); +// +// /* NOTE : This function should not be modified, when the callback is needed, +// the PCD_FS_SOFCallback could be implemented in the user file +// */ +//} + +/** + * @brief USB Start Of Frame callback. + * @param hpcd PCD handle + * @retval None + */ +void __attribute__((weak)) PCD_FS_SessionCallback(PCD_FS_HandleTypeDef *hpcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the PCD_FS_SOFCallback could be implemented in the user file + */ +} + +/** + * @brief USB Start Of Frame callback. + * @param hpcd PCD handle + * @retval None + */ +void __attribute__((weak)) PCD_FS_VBusErrCallback(PCD_FS_HandleTypeDef *hpcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the PCD_FS_SOFCallback could be implemented in the user file + */ +} + +/** + * @brief USB Start Of Frame callback. + * @param hpcd PCD handle + * @retval None + */ +void __attribute__((weak)) PCD_FS_OVERRUNCallback(PCD_FS_HandleTypeDef *hpcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the PCD_FS_SOFCallback could be implemented in the user file + */ +} + +/** + * @brief USB Start Of Frame callback. + * @param hpcd PCD handle + * @retval None + */ +void __attribute__((weak)) PCD_FS_UNDERRUNCallback(PCD_FS_HandleTypeDef *hpcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the PCD_FS_SOFCallback could be implemented in the user file + */ +} + +/** + * @brief USB Start Of Frame callback. + * @param hpcd PCD handle + * @retval None + */ +void __attribute__((weak)) PCD_FS_DERRCallback(PCD_FS_HandleTypeDef *hpcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the PCD_FS_SOFCallback could be implemented in the user file + */ +} +/** + * @brief USB Reset callback. + * @param hpcd PCD handle + * @retval None + */ +//void __attribute__((weak)) PCD_FS_ResetCallback(PCD_FS_HandleTypeDef *hpcd) +//{ +// /* Prevent unused argument(s) compilation warning */ +// UNUSED(hpcd); +// +// /* NOTE : This function should not be modified, when the callback is needed, +// the PCD_FS_ResetCallback could be implemented in the user file +// */ +//} +// +///** +// * @brief Suspend event callback. +// * @param hpcd PCD handle +// * @retval None +// */ +//void __attribute__((weak)) PCD_FS_SuspendCallback(PCD_FS_HandleTypeDef *hpcd) +//{ +// /* Prevent unused argument(s) compilation warning */ +// UNUSED(hpcd); +// +// /* NOTE : This function should not be modified, when the callback is needed, +// the PCD_SuspendCallback could be implemented in the user file +// */ +//} +// +///** +// * @brief Resume event callback. +// * @param hpcd PCD handle +// * @retval None +// */ +//void __attribute__((weak)) PCD_FS_ResumeCallback(PCD_FS_HandleTypeDef *hpcd) +//{ +// /* Prevent unused argument(s) compilation warning */ +// UNUSED(hpcd); +// +// /* NOTE : This function should not be modified, when the callback is needed, +// the PCD_FS_ResumeCallback could be implemented in the user file +// */ +//} +// +// +///** +// * @brief Connection event callback. +// * @param hpcd PCD handle +// * @retval None +// */ +//void __attribute__((weak)) PCD_FS_ConnectCallback(PCD_FS_HandleTypeDef *hpcd) +//{ +// /* Prevent unused argument(s) compilation warning */ +// UNUSED(hpcd); +// +// /* NOTE : This function should not be modified, when the callback is needed, +// the PCD_FS_ConnectCallback could be implemented in the user file +// */ +//} +// +///** +// * @brief Disconnection event callback. +// * @param hpcd PCD handle +// * @retval None +// */ +//void __attribute__((weak)) PCD_FS_DisconnectCallback(PCD_FS_HandleTypeDef *hpcd) +//{ +// /* Prevent unused argument(s) compilation warning */ +// UNUSED(hpcd); +// +// /* NOTE : This function should not be modified, when the callback is needed, +// the PCD_FS_DisconnectCallback could be implemented in the user file +// */ +//} + +/** + * @} + */ + +/** @defgroup PCD_Exported_Functions_Group3 Peripheral Control functions + * @brief management functions + * +@verbatim + =============================================================================== + ##### Peripheral Control functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to control the PCD data + transfers. + +@endverbatim + * @{ + */ + +///** +// * @brief Connect the USB device +// * @param hpcd PCD handle +// * @retval USB_FS status +// */ +//USB_FS_StatusTypeDef PCD_FS_DevConnect(PCD_FS_HandleTypeDef *hpcd) +//{ +// __USB_FS_LOCK(hpcd); +// +// USB_FS_DevConnect(); +// __USB_FS_UNLOCK(hpcd); +// +// return USB_FS_OK; +//} + +/** + * @brief Disconnect the USB device. + * @param hpcd PCD handle + * @retval USB_FS status + */ +USB_FS_StatusTypeDef PCD_FS_DevDisconnect(PCD_FS_HandleTypeDef *hpcd) +{ + __USB_FS_LOCK(hpcd); + + USB_FS_DrvSess(0U); + __USB_FS_UNLOCK(hpcd); + + return USB_FS_OK; +} + +/** + * @brief Set the USB Device address. + * @param hpcd PCD handle + * @param address new device address + * @retval USB_FS status + */ +USB_FS_StatusTypeDef PCD_FS_SetAddress(PCD_FS_HandleTypeDef *hpcd, uint8_t address) +{ + __USB_FS_LOCK(hpcd); + hpcd->USB_Address = address; + USB_FS_SetAddress(address); + __USB_FS_UNLOCK(hpcd); + + return USB_FS_OK; +} +/** + * @brief Open and configure an endpoint. + * @param hpcd PCD handle + * @param ep_addr endpoint address + * @param ep_mps endpoint max packet size + * @param ep_type endpoint type + * @retval USB_FS status + */ +USB_FS_StatusTypeDef PCD_FS_EP_Open(PCD_FS_HandleTypeDef *hpcd, uint8_t ep_addr, + uint16_t ep_mps, uint8_t ep_type) +{ + USB_FS_StatusTypeDef ret = USB_FS_OK; + PCD_FS_EPTypeDef *ep; + + if ((ep_addr & 0x80U) == 0x80U) + { + ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; + ep->is_in = 1U; + } + else + { + ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK]; + ep->is_in = 0U; + } + + ep->num = ep_addr & EP_ADDR_MSK; + ep->maxpacket = ep_mps; + ep->type = ep_type; + + if (ep->is_in != 0U) + { + /* Assign a Tx FIFO */ + ep->tx_fifo_num = ep->num; + } + /* Set initial data PID. */ + if (ep_type == EP_TYPE_BULK) + { + ep->data_pid_start = 0U; + } + + __USB_FS_LOCK(hpcd); + if (ep->num != 0U) + { + USB_FS_Enable_DEP(ep); + } + __USB_FS_UNLOCK(hpcd); + + return ret; +} + +/** + * @brief Deactivate an endpoint. + * @param hpcd PCD handle + * @param ep_addr endpoint address + * @retval USB_FS status + */ +USB_FS_StatusTypeDef PCD_FS_EP_Close(PCD_FS_HandleTypeDef *hpcd, uint8_t ep_addr) +{ + PCD_FS_EPTypeDef *ep; + + if ((ep_addr & 0x80U) == 0x80U) + { + ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; + ep->is_in = 1U; + } + else + { + ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK]; + ep->is_in = 0U; + } + ep->num = ep_addr & EP_ADDR_MSK; + + __USB_FS_LOCK(hpcd); + if (USB_FS_SendStall(ep) != USB_FS_OK) + { + return USB_FS_ERROR; + } + __USB_FS_UNLOCK(hpcd); + return USB_FS_OK; +} + + +/** + * @brief Receive an amount of data. + * @param hpcd PCD handle + * @param ep_addr endpoint address + * @param pBuf pointer to the reception buffer + * @param len amount of data to be received + * @retval none + */ +void PCD_FS_EP_Receive(PCD_FS_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len) +{ + PCD_FS_EPTypeDef *ep; + + ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK]; + + /*setup and start the Xfer */ + ep->xfer_buff = pBuf; + ep->xfer_len = len; + ep->xfer_count = 0U; + ep->is_in = 0U; + ep->num = ep_addr & EP_ADDR_MSK; + if (ep->num != 0U) + { + USB_FS_DEPStartXfer(ep); + } + else + { + USB_FS_DEP0StartXfer(ep); + } +} + +/** + * @brief Get Received Data Size + * @param hpcd PCD handle + * @param ep_addr endpoint address + * @retval Data Size + */ +uint32_t PCD_FS_EP_GetRxCount(const PCD_FS_HandleTypeDef *hpcd, uint8_t ep_addr) +{ + return hpcd->OUT_ep[ep_addr & EP_ADDR_MSK].xfer_count; +} +/** + * @brief Send an amount of data + * @param hpcd PCD handle + * @param ep_addr endpoint address + * @param pBuf pointer to the transmission buffer + * @param len amount of data to be sent + * @retval none + */ +void PCD_FS_EP_Transmit(PCD_FS_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len) +{ + PCD_FS_EPTypeDef *ep; + + ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; + + /*setup and start the Xfer */ + ep->xfer_buff = pBuf; + ep->xfer_len = len; + ep->xfer_count = 0U; + ep->is_in = 1U; + ep->num = ep_addr & EP_ADDR_MSK; + ep->is_stall = 0U; + + if (ep->num != 0U) + { + USB_FS_DEPStartXfer(ep); + } + else + { + USB_FS_DEP0StartXfer(ep); + } +} + +/** + * @brief Set a STALL condition over an endpoint + * @param hpcd PCD handle + * @param ep_addr endpoint address + * @retval USB_FS status + */ +USB_FS_StatusTypeDef PCD_FS_EP_SetStall(PCD_FS_HandleTypeDef *hpcd, uint8_t ep_addr) +{ + PCD_FS_EPTypeDef *ep; + + if (((uint32_t)ep_addr & EP_ADDR_MSK) > hpcd->Init.endpoints) + { + return USB_FS_ERROR; + } + + if ((0x80U & ep_addr) == 0x80U) + { + ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; + ep->is_in = 1U; + } + else + { + ep = &hpcd->OUT_ep[ep_addr]; + ep->is_in = 0U; + } + + ep->is_stall = 1U; + ep->num = ep_addr & EP_ADDR_MSK; + + __USB_FS_LOCK(hpcd); + + USB_FS_SendStall(ep); + + if ((ep_addr & EP_ADDR_MSK) == 0U) + { + (void)USB_FS_DEP0StartXfer(ep); + } + + __USB_FS_UNLOCK(hpcd); + + return USB_FS_OK; +} + +/** + * @brief Clear a STALL condition over in an endpoint + * @param hpcd PCD handle + * @param ep_addr endpoint address + * @retval USB_FS status + */ +USB_FS_StatusTypeDef PCD_FS_EP_ClrStall(PCD_FS_HandleTypeDef *hpcd, uint8_t ep_addr) +{ + PCD_FS_EPTypeDef *ep; + + if (((uint32_t)ep_addr & 0x0FU) > hpcd->Init.endpoints) + { + return USB_FS_ERROR; + } + + if ((0x80U & ep_addr) == 0x80U) + { + ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; + ep->is_in = 1U; + } + else + { + ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK]; + ep->is_in = 0U; + } + + ep->is_stall = 0U; + ep->num = ep_addr & EP_ADDR_MSK; + + __USB_FS_LOCK(hpcd); + USB_FS_ClrStall(ep); + __USB_FS_UNLOCK(hpcd); + + return USB_FS_OK; +} + +/** + * + * @brief Abort an USB EP transaction + * @param hpcd PCD handle + * @param ep_addr endpoint address + * @retval USB_FS status + */ +USB_FS_StatusTypeDef PCD_FS_EP_Abort(PCD_FS_HandleTypeDef *hpcd, uint8_t ep_addr) +{ + USB_FS_StatusTypeDef ret; + PCD_FS_EPTypeDef *ep; + + if ((0x80U & ep_addr) == 0x80U) + { + ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; + } + else + { + ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK]; + } + + /* Stop Xfer */ + if (ep->num == 0U) + { + ret = USB_FS_RstEP0Regs(); + } + else + { + ret = USB_FS_RstEPRegs(ep->num); + } + + return ret; +} + +/** + * @brief Flush an endpoint + * @param hpcd PCD handle + * @param ep_addr endpoint address + * @retval USB_FS status + */ +USB_FS_StatusTypeDef PCD_FS_EP_Flush(PCD_FS_HandleTypeDef *hpcd, uint8_t ep_addr) +{ + __USB_FS_LOCK(hpcd); + + if ((ep_addr & 0x80U) == 0x80U) + { + (void)USB_FS_FlushTxFifo((uint32_t)ep_addr & EP_ADDR_MSK); + } + else + { + (void)USB_FS_FlushRxFifo((uint32_t)ep_addr & EP_ADDR_MSK); + } + + __USB_FS_UNLOCK(hpcd); + + return USB_FS_OK; +} + +/** + * @brief Activate remote wakeup signalling + * @param hpcd PCD handle + * @retval none + */ +void PCD_FS_ActivateRemoteWakeup(void) +{ + USB_FS_Activate_Resume(); +} + +/** + * @brief De-activate remote wakeup signalling. + * @param hpcd PCD handle + * @retval none + */ +void PCD_FS_DeActivateRemoteWakeup(void) +{ + USB_FS_DeActivate_Resume(); +} + +/** + * @} + */ + +/** @defgroup PCD_Exported_Functions_Group4 Peripheral State functions + * @brief Peripheral State functions + * +@verbatim + =============================================================================== + ##### Peripheral State functions ##### + =============================================================================== + [..] + This subsection permits to get in run-time the status of the peripheral + and the data flow. + +@endverbatim + * @{ + */ + +/** + * @brief Return the PCD handle state. + * @param hpcd PCD handle + * @retval hpcd state + */ +PCD_FS_StateTypeDef PCD_FS_GetState(PCD_FS_HandleTypeDef const *hpcd) +{ + return hpcd->State; +} + +/** + * @} + */ + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @addtogroup PCD_Private_Functions + * @{ + */ + +#if defined (USB_OTG_FS) + + +/** + * @brief Check FIFO for the next packet to be loaded. + * @param hpcd PCD handle + * @param epnum endpoint number + * @retval USB_FS status + */ +static USB_FS_StatusTypeDef PCD_FS_WriteEmptyTxFifo(PCD_FS_HandleTypeDef *hpcd, uint8_t epnum) +{ + PCD_FS_EPTypeDef *ep; + uint32_t len; + + ep = &hpcd->IN_ep[epnum]; + + if (ep->xfer_count > ep->xfer_len) + { + return USB_FS_ERROR; + } + + len = ep->xfer_len - ep->xfer_count; + + if (len > ep->maxpacket) + { + len = ep->maxpacket; + } + + while (((USB_FS->TXCSR1 & OTG_FS_TXCSR1_FIFONE) == 0U) & + (ep->xfer_count < ep->xfer_len) & (ep->xfer_len != 0U)) + { + /* Write the FIFO */ + len = ep->xfer_len - ep->xfer_count; + + if (len > ep->maxpacket) + { + len = ep->maxpacket; + } + + USB_FS_FIFOWrite(ep->xfer_buff, (uint8_t)epnum, (uint16_t)len); + + ep->xfer_buff += len; + ep->xfer_count += len; + } + + return USB_FS_OK; +} + +/** + * @brief process EP OUT transfer complete interrupt. + * @param hpcd PCD handle + * @param epnum endpoint number + * @retval none + * */ +void PCD_FS_EP0_IRQHandler(PCD_FS_HandleTypeDef *hpcd) +{ + USB_OTG_FS_DEPTypeDef *ep; + uint8_t tmpreg; + uint8_t bytecount; + tmpreg = USB_FS->CSR0; + + if ((tmpreg & OTG_FS_CSR0_RXPKTRDY) == OTG_FS_CSR0_RXPKTRDY) + { + bytecount = USB_FS_Read_Count0(); + ep = &hpcd->OUT_ep[0U]; + + if (hpcd->ctrl_state == CTRL_SETUP_P) + { + hpcd->ctrl_state = CTRL_DATA; + USB_FS_FIFORead((uint8_t *)hpcd->Setup, 0U, bytecount); + USB_FS->CSR0 |= OTG_FS_CSR0_SRXPKTRDY; + PCD_FS_SetupStageCallback(hpcd); + } + else + { + USB_FS_FIFORead(ep->xfer_buff, 0U, bytecount); + + ep->xfer_buff += bytecount; + ep->xfer_count += bytecount; + + USB_FS->CSR0 |= OTG_FS_CSR0_SRXPKTRDY; + + if (ep->xfer_count >= ep->xfer_len || bytecount < ep->maxpacket) + { + hpcd->ctrl_state = CTRL_SETUP_P; + PCD_FS_DataOutStageCallback(hpcd, 0U); + } + } + } + else if (tmpreg != 0U) + { + if ((tmpreg & OTG_FS_CSR0_SETUPEND) == OTG_FS_CSR0_SETUPEND) + { + USB_FS->CSR0 |= OTG_FS_CSR0_SSETUPEND; + USB_FS_FlushEp0Fifo(); + } + if ((tmpreg & OTG_FS_CSR0_STSTALL) == OTG_FS_CSR0_STSTALL) + { + hpcd->ctrl_state = CTRL_SETUP_P; + USB_FS_FlushEp0Fifo(); /* flush fifo to halt transcation*/ + USB_FS->CSR0 &= (~(OTG_FS_CSR0_STSTALL | OTG_FS_CSR0_SDSTALL)); + } + } + else + { + PCD_FS_DataInStageCallback(hpcd, 0U); /* for packet split */ + hpcd->ctrl_state = CTRL_SETUP_P;/*...*/ + } + +} + +/** + * @brief process EP OUT transfer complete interrupt. + * @param hpcd PCD handle + * @param epnum endpoint number + * @retval none + * */ +void PCD_FS_TXEP_IRQHandler(PCD_FS_HandleTypeDef *hpcd, uint32_t epnum) +{ + uint8_t tmpreg; + uint32_t num_packets; + + tmpreg = USB_FS->TXCSR1; + + if ((tmpreg & OTG_FS_TXCSR1_FIFONE) == 0U) + { + USB_FS_FlushTxFifo(epnum); + } + + if ((tmpreg & OTG_FS_TXCSR1_STSTALL) == OTG_FS_TXCSR1_STSTALL) + { + (void)USB_FS_FlushTxFifo(epnum); /* flush fifo to halt transcation*/ + USB_FS->TXCSR1 &= (~OTG_FS_TXCSR1_STSTALL); + } + else if ((tmpreg & OTG_FS_TXCSR1_UNDERRUN) == OTG_FS_TXCSR1_UNDERRUN) + { + USB_FS->TXCSR1 &= (~OTG_FS_TXCSR1_UNDERRUN); + PCD_FS_UNDERRUNCallback(hpcd); + } + else + { + PCD_FS_DataInStageCallback(hpcd, (uint8_t)epnum); + } +} + +/** + * @brief process EP OUT transfer complete interrupt. + * @param hpcd PCD handle + * @param epnum endpoint number + * @retval none + * */ +void PCD_FS_RXEP_IRQHandler(PCD_FS_HandleTypeDef *hpcd, uint32_t epnum) +{ + uint8_t tmpreg; + uint16_t byte_count; + uint32_t num_packets; + PCD_FS_EPTypeDef *ep; + + tmpreg = USB_FS->RXCSR1; + + if (((tmpreg & OTG_FS_RXCSR1_FIFOF) == OTG_FS_RXCSR1_FIFOF) & + ((tmpreg & OTG_FS_RXCSR1_RXPKTRDY) != OTG_FS_RXCSR1_RXPKTRDY)) + { + byte_count = USB_FS_Read_RxCount(); + USB_FS_FIFORead(ep->xfer_buff, epnum, byte_count); + // PCD_FS_FIFOFULLCallback(hpcd); + } + + if ((tmpreg & OTG_FS_RXCSR1_STSTALL) == OTG_FS_RXCSR1_STSTALL) + { + (void)USB_FS_FlushRxFifo(epnum); /* flush fifo to halt transcation*/ + USB_FS->RXCSR1 &= (~OTG_FS_RXCSR1_STSTALL); + } + else if ((tmpreg & OTG_FS_RXCSR1_OVERRUN) == OTG_FS_RXCSR1_OVERRUN) + { + USB_FS->RXCSR1 &= (~OTG_FS_RXCSR1_OVERRUN); + PCD_FS_OVERRUNCallback(hpcd); + } + else if ((tmpreg & OTG_FS_RXCSR1_RXPKTRDY) == OTG_FS_RXCSR1_RXPKTRDY) + { + if ((tmpreg & OTG_FS_RXCSR1_DERR) == OTG_FS_RXCSR1_DERR) + { + PCD_FS_DERRCallback(hpcd); + } + else + { + byte_count = USB_FS_Read_RxCount(); + USB_FS_FIFORead(ep->xfer_buff, epnum, byte_count); +// PCD_FS_DataInStageCallback(hpcd, (uint8_t)epnum, byte_count); + USB_FS->RXCSR1 &= (~OTG_FS_RXCSR1_RXPKTRDY); + } + } +} + + +#endif /* defined (USB_OTG_FS) */ + + +/** + * @brief Set Tx FIFO + * @param fifo The number of Tx fifo + * @param size Fifo size + * @retval none + */ +void PCD_FS_SetTxFiFo(uint8_t fifo, uint16_t size, uint8_t dpb) +{ + uint8_t i; + uint32_t Tx_Offset; + uint8_t fifo_size; + uint8_t dpb_cfg; + + dpb_cfg = dpb << 4 ; + /* TXn min size = 16 words. (n : Transmit FIFO index) + When a TxFIFO is not used, the Configuration should be as follows: + case 1 : n > m and Txn is not used (n,m : Transmit FIFO indexes) + --> Txm can use the space allocated for Txn. + case2 : n < m and Txn is not used (n,m : Transmit FIFO indexes) + --> Txn should be configured with the minimum space of 16 words + The FIFO is used optimally when used TxFIFOs are allocated in the top + of the FIFO.Ex: use EP1 and EP2 as IN instead of EP1 and EP3 as IN ones. + */ + + Tx_Offset = 0x08; + if (fifo == 0U) + { + return; + } + else + { + for (i = 1U; i < fifo; i++) + { + USB_FS_IndexSel(i); + fifo_size = USB_FS->TXFIFO2 >> 5 ; + Tx_Offset += (0x01U << fifo_size); + } + USB_FS_IndexSel(fifo); + USB_FS->TXFIFO1 = Tx_Offset; + USB_FS->TXFIFO2 = ((usb_log2((size + 7U) / 8U) << 5) | dpb_cfg); + } +} + +/** + * @brief Set Rx FIFO + * @param size Size of Rx fifo + * @retval none + */ +void PCD_FS_SetRxFiFo(uint8_t fifo, uint16_t size, uint8_t dpb) +{ + uint8_t i; + uint32_t Rx_Offset; + uint8_t fifo_size; + uint8_t dpb_cfg; + + dpb_cfg = dpb << 4 ; + Rx_Offset = 0x08; + + if (fifo == 0U) + { + return; + } + else + { + for (i = 1U; i < fifo; i++) + { + USB_FS_IndexSel(i); + fifo_size = USB_FS->RXFIFO2 >> 5 ; + Rx_Offset += (0x01U << fifo_size); + } + USB_FS_IndexSel(fifo); + USB_FS->RXFIFO1 = Rx_Offset; + USB_FS->RXFIFO2 = ((usb_log2((size + 7U) / 8U) << 5) | dpb_cfg); + } +} + +/** + * @} + */ + + +#endif /* defined (USB_OTG_FS) */ +#endif /* PCD_FS_MODULE_ENABLED */ + diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_pcd_hs.c b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_pcd_hs.c new file mode 100644 index 00000000000..3ad3449bbcf --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_pcd_hs.c @@ -0,0 +1,1438 @@ +/** + ****************************************************************************** + * @file ft32f4xx_pcd_hs.c + * @author FMD XA + * @brief This file provides firmware functions to manage the following + * functionalities of the USB Peripheral Controller: + * + Initialization/de-initialization functions + * + Peripheral Control functions + * + Peripheral State functions + * @version V1.0.0 + * @data 2025-03-26 + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + (#)Declare a PCD_HS_HandleTypeDef handle structure, for example: + PCD_HS_HandleTypeDef hpcd; + + (#)Fill parameters of Init structure in PCD handle + + (#)Call PCD_HS_Init() API to initialize the PCD peripheral (Core, Host core, ...) + + (#)Initialize the PCD low level resources through the PCD_HS_MspInit() API: + (##) Enable the PCD/USB Low Level interface clock using the following macros + (##) Initialize the related GPIO clocks + (##) Configure PCD NVIC interrupt + + (#)Associate the Upper USB Host stack to the PCD Driver: + (##) hpcd.pData = pdev; + + (#)Enable PCD transmission and reception: + (##) PCD_HS_Start(); + + @endverbatim + */ +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx.h" +#include "ft32f4xx_rcc.h" +#include "ft32f4xx_pcd_hs.h" + +/** @addtogroup FT32F4xx_DRIVER + * @{ + */ + +#ifdef PCD_MODULE_ENABLED +#if defined (USB_OTG_HS) +/** @defgroup PCD_HS PCD + * @brief PCD HS module driver + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/** @defgroup PCD_HS_Private_Macros PCD Private Functions + * @{ + */ +#define PCD_MIN(a,b) (((a) < (b)) ? (a) : (b)) +#define PCD_MAX(a,b) (((a) > (b)) ? (a) : (b)) +/** + * @{ + */ + +/** @defgroup PCD_HS_Private_Functions PCD Private Functions + * @{ + */ + +static USB_HS_StatusTypeDef PCD_HS_WriteEmptyTxFifo(PCD_HS_HandleTypeDef *hpcd, uint32_t epnum); +static void PCD_HS_EP_OutXfrComplete_int(PCD_HS_HandleTypeDef *hpcd, uint32_t epnum); +static void PCD_HS_EP_OutSetupPacket_int(PCD_HS_HandleTypeDef *hpcd, uint32_t epnum); +/** + * @{ + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup PCD_HS_Exported_Functions PCD Exported Functions + * @{ + */ + +/** @defgroup PCD_HS_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + ##### Initialization and de-initialization functions ##### + =============================================================================== + [..] This section provides functions allowing to: + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the PCD according to the specified + * parameters in the PCD_InitTypeDef and initialize the associated handle. + * @param hpcd PCD handle + * @retval USB_HS status + */ +USB_HS_StatusTypeDef PCD_HS_Init(PCD_HS_HandleTypeDef *hpcd) +{ + + uint8_t i; + + /* Check the PCD handle allocation */ + if (hpcd == NULL) + { + return USB_HS_ERROR; + } + + if (hpcd->State == PCD_HS_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hpcd->Lock = USB_HS_UNLOCKED; + + /* Init the low level hardware : GPIO, CLOCK, NVIC... */ + PCD_HS_MspInit(hpcd); + } + + hpcd->State = PCD_HS_STATE_BUSY; + + /* Disable the Interrupts */ + __PCD_HS_DISABLE(); + + /*Init the Core (common init.) */ + if (USB_HS_CoreInit(hpcd->Init) != USB_HS_OK) + { + hpcd->State = PCD_HS_STATE_ERROR; + return USB_HS_ERROR; + } + + /* Init endpoints structures */ + for (i = 0U; i < hpcd->Init.dev_endpoints; i++) + { + /* Init ep structure */ + hpcd->IN_ep[i].is_in = 1U; + hpcd->IN_ep[i].num = i; + hpcd->IN_ep[i].tx_fifo_num = i; + /* Control until ep is activated */ + hpcd->IN_ep[i].type = EP_TYPE_CTRL; + hpcd->IN_ep[i].maxpacket = 0U; + hpcd->IN_ep[i].xfer_buff = 0U; + hpcd->IN_ep[i].xfer_len = 0U; + } + + for (i = 0U; i < hpcd->Init.dev_endpoints; i++) + { + hpcd->OUT_ep[i].is_in = 0U; + hpcd->OUT_ep[i].num = i; + /* Control until ep is activated */ + hpcd->OUT_ep[i].type = EP_TYPE_CTRL; + hpcd->OUT_ep[i].maxpacket = 0U; + hpcd->OUT_ep[i].xfer_buff = 0U; + hpcd->OUT_ep[i].xfer_len = 0U; + } + + /* Init Device */ + if (USB_HS_DevInit(hpcd->Init) != USB_HS_OK) + { + hpcd->State = PCD_HS_STATE_ERROR; + return USB_HS_ERROR; + } + + hpcd->USB_Address = 0U; + hpcd->State = PCD_HS_STATE_READY; + + USB_HS_DevDisconnect(); + + return USB_HS_OK; +} + +/** + * @brief DeInitializes the PCD peripheral. + * @param hpcd PCD handle + * @retval USB_HS status + */ +USB_HS_StatusTypeDef PCD_HS_DeInit(PCD_HS_HandleTypeDef *hpcd) +{ + /* Check the PCD handle allocation */ + if (hpcd == NULL) + { + return USB_HS_ERROR; + } + + hpcd->State = PCD_HS_STATE_BUSY; + + /* Stop Device */ + if (USB_HS_StopDevice() != USB_HS_OK) + { + return USB_HS_ERROR; + } + + /* DeInit the low level hardware: CLOCK, NVIC.*/ + PCD_HS_MspDeInit(hpcd); + + hpcd->State = PCD_HS_STATE_RESET; + + return USB_HS_OK; +} + +/** + * @brief Initializes the PCD MSP. + * @param hpcd PCD handle + * @retval None + */ +void __attribute__((weak)) PCD_HS_MspInit(PCD_HS_HandleTypeDef *hpcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the PCD_HS_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitializes PCD MSP. + * @param hpcd PCD handle + * @retval None + */ +void __attribute__((weak)) PCD_HS_MspDeInit(PCD_HS_HandleTypeDef *hpcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the PCD_HS_MspDeInit could be implemented in the user file + */ +} + + +/** + * @} + */ + +/** @defgroup PCD_Exported_Functions_Group2 Input and Output operation functions + * @brief Data transfers functions + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to manage the PCD data + transfers. + +@endverbatim + * @{ + */ + +/** + * @brief Start the USB device + * @param hpcd PCD handle + * @retval USB_HS status + */ +USB_HS_StatusTypeDef PCD_HS_Start(PCD_HS_HandleTypeDef *hpcd) +{ + __USB_HS_LOCK(hpcd); + __PCD_HS_ENABLE(); + + USB_HS_DevConnect(); + __USB_HS_UNLOCK(hpcd); + + return USB_HS_OK; +} + +/** + * @brief Stop the USB device. + * @param hpcd PCD handle + * @retval USB_HS status + */ +USB_HS_StatusTypeDef PCD_HS_Stop(PCD_HS_HandleTypeDef *hpcd) +{ + __USB_HS_LOCK(hpcd); + __PCD_HS_DISABLE(); + + USB_HS_DevDisconnect(); + + (void)USB_HS_FlushTxFifo(0x10U); + + __USB_HS_UNLOCK(hpcd); + + return USB_HS_OK; +} + +#if defined (USB_OTG_HS) +/** + * @brief Handles PCD interrupt request. + * @param hpcd PCD handle + * @retval none + */ +void PCD_HS_IRQHandler(PCD_HS_HandleTypeDef *hpcd) +{ + USB_OTG_HS_EPTypeDef *ep; + RCC_ClocksTypeDef RCC_ClocksStatus; + uint32_t AHBCLK; + uint32_t i; + uint32_t ep_intr; + uint32_t epint; + uint32_t epnum; + uint32_t fifoemptymsk; + uint32_t RegVal; + + /* ensure that we are in device mode */ + if (USB_HS_GetMode() == USB_OTG_MODE_DEVICE) + { + /* avoid spurious interrupt */ + if (__PCD_HS_IS_INVALID_INTERRUPT()) + { + return; + } + + /* store current frame number */ + hpcd->FrameNumber = (USB_HS_DEVICE->DSTS & OTG_HS_DSTS_FNSOF_Msk) >> OTG_HS_DSTS_FNSOF_Pos; + + if (__PCD_HS_GET_FLAG(OTG_HS_GINTSTS_MMIS)) + { + /* incorrect mode, acknowledge the interrupt */ + __PCD_HS_CLEAR_FLAG(OTG_HS_GINTSTS_MMIS); + } + + /* Handle RxQLevel Interrupt */ + if (__PCD_HS_GET_FLAG(OTG_HS_GINTSTS_RXFLVL)) + { + USB_HS_MASK_INTERRUPT(OTG_HS_GINTSTS_RXFLVL); + + RegVal = USB_HS->GRXSTSP; + + ep = &hpcd->OUT_ep[RegVal & OTG_HS_GRXSTSP_EPNUM]; + + if (((RegVal & OTG_HS_GRXSTSP_PKTSTS) >> 17) == STS_DATA_UPDT) + { + if ((RegVal & OTG_HS_GRXSTSP_BCNT) != 0U) + { + (void)USB_HS_ReadPacket(ep->xfer_buff, (uint16_t)((RegVal & OTG_HS_GRXSTSP_BCNT) >> 4)); + + ep->xfer_buff += (RegVal & OTG_HS_GRXSTSP_BCNT) >> 4; + ep->xfer_count += (RegVal & OTG_HS_GRXSTSP_BCNT) >> 4; + } + } + else if (((RegVal & OTG_HS_GRXSTSP_PKTSTS) >> 17) == STS_SETUP_UPDT) + { + (void)USB_HS_ReadPacket((uint8_t *)hpcd->Setup, 8U); + ep->xfer_count += (RegVal & OTG_HS_GRXSTSP_BCNT) >> 4; + } + else + { + /* ... */ + } + USB_HS_UNMASK_INTERRUPT(OTG_HS_GINTSTS_RXFLVL); + } + /* USB_HS->GINTSTS OEPINT(OUT POINT)*/ + if (__PCD_HS_GET_FLAG(OTG_HS_GINTSTS_OEPINT)) + { + epnum = 0U; + + /* Read in the device interrupt bits */ + ep_intr = USB_HS_ReadDevAllOutEpInterrupt(); + + while (ep_intr != 0U) + { + if ((ep_intr & 0x1U) != 0U) + { + epint = USB_HS_ReadDevOutEPInterrupt((uint8_t)epnum); +// if(epnum == 0)USBD_SET_ADDR_Callback(hpcd); + if ((epint & OTG_HS_DOEPINT_XFRC) == OTG_HS_DOEPINT_XFRC) + { + CLEAR_OUT_EP_INTR(epnum, OTG_HS_DOEPINT_XFRC); + (void)PCD_HS_EP_OutXfrComplete_int(hpcd, epnum); + } + + if ((epint & OTG_HS_DOEPINT_STUPD) == OTG_HS_DOEPINT_STUPD) + { + CLEAR_OUT_EP_INTR(epnum, OTG_HS_DOEPINT_STUPD); + /* Class B setup phase done for previous decoded setup */ + (void)PCD_HS_EP_OutSetupPacket_int(hpcd, epnum); + } + + if ((epint & OTG_HS_DOEPINT_OTKNEPDIS) ==OTG_HS_DOEPINT_OTKNEPDIS) + { + CLEAR_OUT_EP_INTR(epnum, OTG_HS_DOEPINT_OTKNEPDIS); + } + + /* Clear OUT Endpoint disable interrupt */ + if ((epint & OTG_HS_DOEPINT_EPDISD) == OTG_HS_DOEPINT_EPDISD) + { + if ((USB_HS->GINTSTS & OTG_HS_GINTSTS_GONAKEFF) == OTG_HS_GINTSTS_GONAKEFF) + { + USB_HS_DEVICE->DCTL |= OTG_HS_DCTL_CGONAK ; + } + + ep = &hpcd->OUT_ep[epnum]; + if (ep->is_iso_incomplete == 1U) + { + ep->is_iso_incomplete = 0U; + + PCD_HS_ISOOUTIncompleteCallback(hpcd, (uint8_t)epnum); + } + CLEAR_OUT_EP_INTR(epnum, OTG_HS_DOEPINT_EPDISD); + } + + /* Clear Status Phase Received interrupt */ + if ((epint & OTG_HS_DOEPINT_OTEPSPR) == OTG_HS_DOEPINT_OTEPSPR) + { + CLEAR_OUT_EP_INTR(epnum, OTG_HS_DOEPINT_OTEPSPR); + } + + /* Clear OUT NAK interrupt */ + if ((epint & OTG_HS_DOEPINT_NAKINT) == OTG_HS_DOEPINT_NAKINT) + { + CLEAR_OUT_EP_INTR(epnum, OTG_HS_DOEPINT_NAKINT); + } + } + epnum++; + ep_intr >>= 1U; + } + } + + if (__PCD_HS_GET_FLAG(OTG_HS_GINTSTS_IEPINT)) + { + /* Read in the device interrupt bits */ + ep_intr = USB_HS_ReadDevAllInEpInterrupt(); + + epnum = 0U; + + while (ep_intr != 0U) + { + if ((ep_intr & 0x1U) != 0U) /* In ITR */ + { + epint = USB_HS_ReadDevInEPInterrupt((uint8_t)epnum); + + if ((epint & OTG_HS_DIEPINT_XFRC) == OTG_HS_DIEPINT_XFRC) + { + fifoemptymsk = (uint32_t)(0x1UL << (epnum & EP_ADDR_MSK)); + USB_HS_DEVICE->DIEPEMPMSK &= ~fifoemptymsk; + + CLEAR_IN_EP_INTR(epnum, OTG_HS_DIEPINT_XFRC); + + PCD_HS_DataInStageCallback(hpcd, (uint8_t)epnum); + } + if ((epint & OTG_HS_DIEPINT_TOC) == OTG_HS_DIEPINT_TOC) + { + CLEAR_IN_EP_INTR(epnum, OTG_HS_DIEPINT_TOC); + } + if ((epint & OTG_HS_DIEPINT_ITTXFE) == OTG_HS_DIEPINT_ITTXFE) + { + CLEAR_IN_EP_INTR(epnum, OTG_HS_DIEPINT_ITTXFE); + } + if ((epint & OTG_HS_DIEPINT_INEPNE) == OTG_HS_DIEPINT_INEPNE) + { + CLEAR_IN_EP_INTR(epnum, OTG_HS_DIEPINT_INEPNE); + } + if ((epint & OTG_HS_DIEPINT_EPDISD) == OTG_HS_DIEPINT_EPDISD) + { + (void)USB_HS_FlushTxFifo(epnum); + + ep = &hpcd->IN_ep[epnum]; + if (ep->is_iso_incomplete == 1U) + { + ep->is_iso_incomplete = 0U; + + PCD_HS_ISOINIncompleteCallback(hpcd, (uint8_t)epnum); + } + + CLEAR_IN_EP_INTR(epnum, OTG_HS_DIEPINT_EPDISD); + } + if ((epint & OTG_HS_DIEPINT_TXFE) == OTG_HS_DIEPINT_TXFE) + { + (void)PCD_HS_WriteEmptyTxFifo(hpcd, epnum); + } + } + epnum++; + ep_intr >>= 1U; + } + } + + /* Handle Resume Interrupt */ + if (__PCD_HS_GET_FLAG(OTG_HS_GINTSTS_WKUPINT)) + { + /* Clear the Remote Wake-up Signaling */ + USB_HS_DEVICE->DCTL &= ~OTG_HS_DCTL_RWUSIG; + + PCD_HS_ResumeCallback(hpcd); + + __PCD_HS_CLEAR_FLAG(OTG_HS_GINTSTS_WKUPINT); + } + + /* Handle Suspend Interrupt */ + if (__PCD_HS_GET_FLAG(OTG_HS_GINTSTS_USBSUSP)) + { + if ((USB_HS_DEVICE->DSTS & OTG_HS_DSTS_SUSPSTS) == OTG_HS_DSTS_SUSPSTS) + { + +// PCD_HS_SuspendCallback(hpcd); + } + __PCD_HS_CLEAR_FLAG(OTG_HS_GINTSTS_USBSUSP); + } + /* Handle Reset Interrupt */ + if (__PCD_HS_GET_FLAG(OTG_HS_GINTSTS_USBRST)) + { + USB_HS_DEVICE->DCTL &= ~OTG_HS_DCTL_RWUSIG; + (void)USB_HS_FlushTxFifo(0x10U); + + for (i = 0U; i < hpcd->Init.dev_endpoints; i++) + { + USB_HS_INEP(i)->DIEPINT = 0xFB7FU; + USB_HS_INEP(i)->DIEPCTL &= ~OTG_HS_DIEPCTL_STALL; + USB_HS_OUTEP(i)->DOEPINT = 0xFB7FU; + USB_HS_OUTEP(i)->DOEPCTL &= ~OTG_HS_DOEPCTL_STALL; + USB_HS_OUTEP(i)->DOEPCTL |= OTG_HS_DOEPCTL_SNAK; + } + USB_HS_DEVICE->DAINTMSK |= 0x10001U; + + if (hpcd->Init.use_dedicated_ep1 != 0U) + { + USB_HS_DEVICE->DOUTEP1MSK |= OTG_HS_DOEPMSK_STUPM | + OTG_HS_DOEPMSK_XFRCM | + OTG_HS_DOEPMSK_EPDM; + + USB_HS_DEVICE->DINEP1MSK |= OTG_HS_DIEPMSK_TOM | + OTG_HS_DIEPMSK_XFRCM | + OTG_HS_DIEPMSK_EPDM; + } + else + { + USB_HS_DEVICE->DOEPMSK |= OTG_HS_DOEPMSK_STUPM | + OTG_HS_DOEPMSK_XFRCM | + OTG_HS_DOEPMSK_EPDM | + OTG_HS_DOEPMSK_OTEPSPRM | + OTG_HS_DOEPMSK_NAKM; + + USB_HS_DEVICE->DIEPMSK |= OTG_HS_DIEPMSK_TOM | + OTG_HS_DIEPMSK_XFRCM | + OTG_HS_DIEPMSK_EPDM ; + } + + /* Set Default Address to 0 */ + USB_HS_DEVICE->DCFG &= ~OTG_HS_DCFG_DAD; + + /* setup EP0 to receive SETUP packets */ + (void)USB_HS_EP0_OutStart((uint8_t)hpcd->Init.dma_enable, (uint8_t *)hpcd->Setup); + + __PCD_HS_CLEAR_FLAG(OTG_HS_GINTSTS_USBRST); + } + + /* Handle Enumeration done Interrupt */ + if (__PCD_HS_GET_FLAG(OTG_HS_GINTSTS_ENUMDNE)) + { + (void)USB_HS_ActivateSetup(); + hpcd->Init.speed = USB_HS_GetDevSpeed(); + + /* Set USB Turnaround time */ + /* RCC_GetClocksFreq wait for update */ + RCC_GetClocksFreq(&RCC_ClocksStatus); + AHBCLK = RCC_ClocksStatus.HCLK_Frequency; + (void)USB_HS_SetTurnaroundTime(AHBCLK, (uint8_t)hpcd->Init.speed); + + PCD_HS_ResetCallback(hpcd); + + __PCD_HS_CLEAR_FLAG(OTG_HS_GINTSTS_ENUMDNE); + } + + /* Handle SOF Interrupt */ + if (__PCD_HS_GET_FLAG(OTG_HS_GINTSTS_SOF)) + { + PCD_HS_SOFCallback(hpcd); + + __PCD_HS_CLEAR_FLAG(OTG_HS_GINTSTS_SOF); + } + + /* Handle Global OUT NAK effective Interrupt */ + if (__PCD_HS_GET_FLAG(OTG_HS_GINTSTS_GONAKEFF)) + { + USB_HS->GINTMSK &= ~OTG_HS_GINTMSK_GONAKEFM; + for (epnum = 1U; epnum < hpcd->Init.dev_endpoints; epnum++) + { + if (hpcd->OUT_ep[epnum].is_iso_incomplete == 1U) + { + /* abort current transaction and disable the EP */ + (void)PCD_HS_EP_Abort(hpcd, (uint8_t)epnum); + } + } + } + /* Handle Incomplete ISO IN Interrupt */ + if (__PCD_HS_GET_FLAG(OTG_HS_GINTSTS_IISOIXFR)) + { + for (epnum = 1U; epnum < hpcd->Init.dev_endpoints; epnum++) + { + RegVal = USB_HS_INEP(epnum)->DIEPCTL; + + if ((hpcd->IN_ep[epnum].type == EP_TYPE_ISOC) & ((RegVal & OTG_HS_DIEPCTL_EPENA) == OTG_HS_DIEPCTL_EPENA)) + { + hpcd->IN_ep[epnum].is_iso_incomplete = 1U; + + /* Abort current transaction and disable the EP */ + (void)PCD_HS_EP_Abort(hpcd, (uint8_t)(epnum | 0x80U)); + } + } + + __PCD_HS_CLEAR_FLAG(OTG_HS_GINTSTS_IISOIXFR); + } + + /* Handle Incomplete ISO OUT Interrupt */ + if (__PCD_HS_GET_FLAG(OTG_HS_GINTSTS_IPXFR_INCOMPISOOUT)) + { + for (epnum = 1U; epnum < hpcd->Init.dev_endpoints; epnum++) + { + RegVal = USB_HS_OUTEP(epnum)->DOEPCTL; + + if ((hpcd->OUT_ep[epnum].type == EP_TYPE_ISOC) & ((RegVal & OTG_HS_DOEPCTL_EPENA) == OTG_HS_DIEPCTL_EPENA) + & (((RegVal & (0x1U << 16U)) >> 16U) == (hpcd->FrameNumber & 0x1U))) + { + hpcd->OUT_ep[epnum].is_iso_incomplete = 1U; + USB_HS->GINTMSK |= OTG_HS_GINTMSK_GONAKEFM; + + if ((USB_HS->GINTSTS & OTG_HS_GINTSTS_GONAKEFF) == 0U) + { + USB_HS_DEVICE->DCTL |= OTG_HS_DCTL_SGONAK; + break; + } + } + } + + __PCD_HS_CLEAR_FLAG(OTG_HS_GINTSTS_IPXFR_INCOMPISOOUT); + } + + /* Handle Connection event Interrupt */ + if (__PCD_HS_GET_FLAG(OTG_HS_GINTSTS_SRQINT)) + { + PCD_HS_ConnectCallback(hpcd); + + __PCD_HS_CLEAR_FLAG(OTG_HS_GINTSTS_SRQINT); + } + + /* Handle Disconnection event Interrupt */ + if (__PCD_HS_GET_FLAG(OTG_HS_GINTSTS_OTGINT)) + { + RegVal = USB_HS->GOTGINT; + + if ((RegVal & OTG_HS_GOTGINT_SEDET) == OTG_HS_GOTGINT_SEDET) + { + + PCD_HS_DisconnectCallback(hpcd); + } + USB_HS->GOTGINT |= RegVal; + } + } +} + +/** + * @brief Handles PCD Wakeup interrupt request. + * @param hpcd PCD handle + * @retval none status + */ +void PCD_HS_WKUP_IRQHandler() +{ + /* Clear EXTI pending Bit */ + __USB_OTG_HS_WAKEUP_EXTI_CLEAR_FLAG(); +} +#endif /* defined (USB_OTG_HS) */ + + +/** + * @brief Data OUT stage callback. + * @param hpcd PCD handle + * @param epnum endpoint number + * @retval None + */ +void __attribute__((weak)) PCD_HS_DataOutStageCallback(PCD_HS_HandleTypeDef *hpcd, uint8_t epnum) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + UNUSED(epnum); + + /* NOTE : This function should not be modified, when the callback is needed, + the PCD_HS_DataOutStageCallback could be implemented in the user file + */ +} + +/** + * @brief Data IN stage callback + * @param hpcd PCD handle + * @param epnum endpoint number + * @retval None + */ +void __attribute__((weak)) PCD_HS_DataInStageCallback(PCD_HS_HandleTypeDef *hpcd, uint8_t epnum) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + UNUSED(epnum); + + /* NOTE : This function should not be modified, when the callback is needed, + the PCD_HS_DataInStageCallback could be implemented in the user file + */ +} +/** + * @brief Setup stage callback + * @param hpcd PCD handle + * @retval None + */ +void __attribute__((weak)) PCD_HS_SetupStageCallback(PCD_HS_HandleTypeDef *hpcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the PCD_HS_SetupStageCallback could be implemented in the user file + */ +} + +/** + * @brief USB Start Of Frame callback. + * @param hpcd PCD handle + * @retval None + */ +void __attribute__((weak)) PCD_HS_SOFCallback(PCD_HS_HandleTypeDef *hpcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the PCD_HS_SOFCallback could be implemented in the user file + */ +} + +/** + * @brief USB Reset callback. + * @param hpcd PCD handle + * @retval None + */ +void __attribute__((weak)) PCD_HS_ResetCallback(PCD_HS_HandleTypeDef *hpcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the PCD_HS_ResetCallback could be implemented in the user file + */ +} +void __attribute__((weak)) USBD_SET_ADDR_Callback(PCD_HS_HandleTypeDef *hpcd) +{ + UNUSED(hpcd); +} +/** + * @brief Suspend event callback. + * @param hpcd PCD handle + * @retval None + */ +void __attribute__((weak)) PCD_HS_SuspendCallback(PCD_HS_HandleTypeDef *hpcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the PCD_SuspendCallback could be implemented in the user file + */ +} + +/** + * @brief Resume event callback. + * @param hpcd PCD handle + * @retval None + */ +void __attribute__((weak)) PCD_HS_ResumeCallback(PCD_HS_HandleTypeDef *hpcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the PCD_HS_ResumeCallback could be implemented in the user file + */ +} + +/** + * @brief Incomplete ISO OUT callback. + * @param hpcd PCD handle + * @param epnum endpoint number + * @retval None + */ +void __attribute__((weak)) PCD_HS_ISOOUTIncompleteCallback(PCD_HS_HandleTypeDef *hpcd, uint8_t epnum) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + UNUSED(epnum); + + /* NOTE : This function should not be modified, when the callback is needed, + the PCD_HS_ISOOUTIncompleteCallback could be implemented in the user file + */ +} + +/** + * @brief Incomplete ISO IN callback. + * @param hpcd PCD handle + * @param epnum endpoint number + * @retval None + */ +void __attribute__((weak)) PCD_HS_ISOINIncompleteCallback(PCD_HS_HandleTypeDef *hpcd, uint8_t epnum) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + UNUSED(epnum); + + /* NOTE : This function should not be modified, when the callback is needed, + the PCD_HS_ISOINIncompleteCallback could be implemented in the user file + */ +} + +/** + * @brief Connection event callback. + * @param hpcd PCD handle + * @retval None + */ +void __attribute__((weak)) PCD_HS_ConnectCallback(PCD_HS_HandleTypeDef *hpcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the PCD_HS_ConnectCallback could be implemented in the user file + */ +} + +/** + * @brief Disconnection event callback. + * @param hpcd PCD handle + * @retval None + */ +void __attribute__((weak)) PCD_HS_DisconnectCallback(PCD_HS_HandleTypeDef *hpcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the PCD_HS_DisconnectCallback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup PCD_Exported_Functions_Group3 Peripheral Control functions + * @brief management functions + * +@verbatim + =============================================================================== + ##### Peripheral Control functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to control the PCD data + transfers. + +@endverbatim + * @{ + */ + +/** + * @brief Connect the USB device + * @param hpcd PCD handle + * @retval USB_HS status + */ +USB_HS_StatusTypeDef PCD_HS_DevConnect(PCD_HS_HandleTypeDef *hpcd) +{ + __USB_HS_LOCK(hpcd); + + USB_HS_DevConnect(); + __USB_HS_UNLOCK(hpcd); + + return USB_HS_OK; +} + +/** + * @brief Disconnect the USB device. + * @param hpcd PCD handle + * @retval USB_HS status + */ +USB_HS_StatusTypeDef PCD_HS_DevDisconnect(PCD_HS_HandleTypeDef *hpcd) +{ + __USB_HS_LOCK(hpcd); + + USB_HS_DevDisconnect(); + __USB_HS_UNLOCK(hpcd); + + return USB_HS_OK; +} + +/** + * @brief Set the USB Device address. + * @param hpcd PCD handle + * @param address new device address + * @retval USB_HS status + */ +USB_HS_StatusTypeDef PCD_HS_SetAddress(PCD_HS_HandleTypeDef *hpcd, uint8_t address) +{ + __USB_HS_LOCK(hpcd); + hpcd->USB_Address = address; + USB_HS_SetDevAddress(address); + __USB_HS_UNLOCK(hpcd); + + return USB_HS_OK; +} +/** + * @brief Open and configure an endpoint. + * @param hpcd PCD handle + * @param ep_addr endpoint address + * @param ep_mps endpoint max packet size + * @param ep_type endpoint type + * @retval USB_HS status + */ +USB_HS_StatusTypeDef PCD_HS_EP_Open(PCD_HS_HandleTypeDef *hpcd, uint8_t ep_addr, + uint16_t ep_mps, uint8_t ep_type) +{ + USB_HS_StatusTypeDef ret = USB_HS_OK; + PCD_HS_EPTypeDef *ep; + + if ((ep_addr & 0x80U) == 0x80U) + { + ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; + ep->is_in = 1U; + } + else + { + ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK]; + ep->is_in = 0U; + } + + ep->num = ep_addr & EP_ADDR_MSK; + ep->maxpacket = ep_mps; + ep->type = ep_type; + + if (ep->is_in != 0U) + { + /* Assign a Tx FIFO */ + ep->tx_fifo_num = ep->num; + } + /* Set initial data PID. */ + if (ep_type == EP_TYPE_BULK) + { + ep->data_pid_start = 0U; + } + + __USB_HS_LOCK(hpcd); + USB_HS_ActivateEndpoint(ep); + __USB_HS_UNLOCK(hpcd); + + return ret; +} + +/** + * @brief Deactivate an endpoint. + * @param hpcd PCD handle + * @param ep_addr endpoint address + * @retval USB_HS status + */ +USB_HS_StatusTypeDef PCD_HS_EP_Close(PCD_HS_HandleTypeDef *hpcd, uint8_t ep_addr) +{ + PCD_HS_EPTypeDef *ep; + + if ((ep_addr & 0x80U) == 0x80U) + { + ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; + ep->is_in = 1U; + } + else + { + ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK]; + ep->is_in = 0U; + } + ep->num = ep_addr & EP_ADDR_MSK; + + __USB_HS_LOCK(hpcd); + USB_HS_DeactivateEndpoint(ep); + __USB_HS_UNLOCK(hpcd); + return USB_HS_OK; +} + + +/** + * @brief Receive an amount of data. + * @param hpcd PCD handle + * @param ep_addr endpoint address + * @param pBuf pointer to the reception buffer + * @param len amount of data to be received + * @retval none + */ +void PCD_HS_EP_Receive(PCD_HS_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len) +{ + PCD_HS_EPTypeDef *ep; + + ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK]; + + /*setup and start the Xfer */ + ep->xfer_buff = pBuf; + ep->xfer_len = len; + ep->xfer_count = 0U; + ep->is_in = 0U; + ep->num = ep_addr & EP_ADDR_MSK; + + if (hpcd->Init.dma_enable == 1U) + { + ep->dma_addr = (uint32_t)pBuf; + } + + USB_HS_EPStartXfer(ep, (uint8_t)hpcd->Init.dma_enable); + +} + +/** + * @brief Get Received Data Size + * @param hpcd PCD handle + * @param ep_addr endpoint address + * @retval Data Size + */ +uint32_t PCD_HS_EP_GetRxCount(PCD_HS_HandleTypeDef const *hpcd, uint8_t ep_addr) +{ + return hpcd->OUT_ep[ep_addr & EP_ADDR_MSK].xfer_count; +} +/** + * @brief Send an amount of data + * @param hpcd PCD handle + * @param ep_addr endpoint address + * @param pBuf pointer to the transmission buffer + * @param len amount of data to be sent + * @retval none + */ +void PCD_HS_EP_Transmit(PCD_HS_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len) +{ + PCD_HS_EPTypeDef *ep; + + ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; + + /*setup and start the Xfer */ + ep->xfer_buff = pBuf; + ep->xfer_len = len; + ep->xfer_count = 0U; + ep->is_in = 1U; + ep->num = ep_addr & EP_ADDR_MSK; + + if ((ep_addr & EP_ADDR_MSK) == 1U) + { + ep->dma_addr = (uint32_t)pBuf; + } + + USB_HS_EPStartXfer(ep, (uint8_t)hpcd->Init.dma_enable); + +} + +/** + * @brief Set a STALL condition over an endpoint + * @param hpcd PCD handle + * @param ep_addr endpoint address + * @retval USB_HS status + */ +USB_HS_StatusTypeDef PCD_HS_EP_SetStall(PCD_HS_HandleTypeDef *hpcd, uint8_t ep_addr) +{ + PCD_HS_EPTypeDef *ep; + + if (((uint32_t)ep_addr & EP_ADDR_MSK) > hpcd->Init.dev_endpoints) + { + return USB_HS_ERROR; + } + + if ((0x80U & ep_addr) == 0x80U) + { + ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; + ep->is_in = 1U; + } + else + { + ep = &hpcd->OUT_ep[ep_addr]; + ep->is_in = 0U; + } + + ep->is_stall = 1U; + ep->num = ep_addr & EP_ADDR_MSK; + + __USB_HS_LOCK(hpcd); + + USB_HS_EPSetStall(ep); + + if ((ep_addr & EP_ADDR_MSK) == 0U) + { + (void)USB_HS_EP0_OutStart((uint8_t)hpcd->Init.dma_enable, (uint8_t *)hpcd->Setup); + } + + __USB_HS_UNLOCK(hpcd); + + return USB_HS_OK; +} + +/** + * @brief Clear a STALL condition over in an endpoint + * @param hpcd PCD handle + * @param ep_addr endpoint address + * @retval USB_HS status + */ +USB_HS_StatusTypeDef PCD_HS_EP_ClrStall(PCD_HS_HandleTypeDef *hpcd, uint8_t ep_addr) +{ + PCD_HS_EPTypeDef *ep; + + if (((uint32_t)ep_addr & 0x0FU) > hpcd->Init.dev_endpoints) + { + return USB_HS_ERROR; + } + + if ((0x80U & ep_addr) == 0x80U) + { + ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; + ep->is_in = 1U; + } + else + { + ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK]; + ep->is_in = 0U; + } + + ep->is_stall = 0U; + ep->num = ep_addr & EP_ADDR_MSK; + + __USB_HS_LOCK(hpcd); + USB_HS_EPClearStall(ep); + __USB_HS_UNLOCK(hpcd); + + return USB_HS_OK; +} + +/** + * + * @brief Abort an USB EP transaction + * @param hpcd PCD handle + * @param ep_addr endpoint address + * @retval USB_HS status + */ +USB_HS_StatusTypeDef PCD_HS_EP_Abort(PCD_HS_HandleTypeDef *hpcd, uint8_t ep_addr) +{ + USB_HS_StatusTypeDef ret; + PCD_HS_EPTypeDef *ep; + + if ((0x80U & ep_addr) == 0x80U) + { + ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; + } + else + { + ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK]; + } + + /* Stop Xfer */ + ret = USB_HS_EPStopXfer(ep); + + return ret; +} + +/** + * @brief Flush an endpoint + * @param hpcd PCD handle + * @param ep_addr endpoint address + * @retval USB_HS status + */ +USB_HS_StatusTypeDef PCD_HS_EP_Flush(PCD_HS_HandleTypeDef *hpcd, uint8_t ep_addr) +{ + __USB_HS_LOCK(hpcd); + + if ((ep_addr & 0x80U) == 0x80U) + { + (void)USB_HS_FlushTxFifo((uint32_t)ep_addr & EP_ADDR_MSK); + } + else + { + (void)USB_HS_FlushRxFifo(); + } + + __USB_HS_UNLOCK(hpcd); + + return USB_HS_OK; +} + +/** + * @brief Activate remote wakeup signalling + * @param hpcd PCD handle + * @retval none + */ +void PCD_HS_ActivateRemoteWakeup() +{ + USB_HS_ActivateRemoteWakeup(); +} + +/** + * @brief De-activate remote wakeup signalling. + * @param hpcd PCD handle + * @retval none + */ +void PCD_HS_DeActivateRemoteWakeup() +{ + USB_HS_DeActivateRemoteWakeup(); +} + +/** + * @} + */ + +/** @defgroup PCD_Exported_Functions_Group4 Peripheral State functions + * @brief Peripheral State functions + * +@verbatim + =============================================================================== + ##### Peripheral State functions ##### + =============================================================================== + [..] + This subsection permits to get in run-time the status of the peripheral + and the data flow. + +@endverbatim + * @{ + */ + +/** + * @brief Return the PCD handle state. + * @param hpcd PCD handle + * @retval hpcd state + */ +PCD_HS_StateTypeDef PCD_HS_GetState(PCD_HS_HandleTypeDef const *hpcd) +{ + return hpcd->State; +} + +/** + * @} + */ + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @addtogroup PCD_Private_Functions + * @{ + */ +#if defined (USB_OTG_HS) + +/** + * @brief Set the USB Device high speed test mode + * @param hpcd PCD handle + * @param testmode USB Device high speed testmode + * @retval none + */ +void PCD_HS_SetTestMode(uint8_t testmode) +{ + switch (testmode) + { + case TEST_J: + case TEST_K: + case TEST_SE0_NAK: + case TEST_PACKET: + case TEST_FORCE_EN: + USB_HS_DEVICE->DCTL |= (uint32_t)testmode << 4; + break; + + default: + break; + + } +} +#endif /* defined (USB_OTG_HS) */ + + +#if defined (USB_OTG_HS) + + +/** + * @brief Check FIFO for the next packet to be loaded. + * @param hpcd PCD handle + * @param epnum endpoint number + * @retval USBH status + */ +static USB_HS_StatusTypeDef PCD_HS_WriteEmptyTxFifo(PCD_HS_HandleTypeDef *hpcd, uint32_t epnum) +{ + USB_OTG_HS_EPTypeDef *ep; + uint32_t len; + uint32_t len32b; + uint32_t fifoemptymsk; + + ep = &hpcd->IN_ep[epnum]; + + if (ep->xfer_count > ep->xfer_len) + { + return USB_HS_ERROR; + } + + len = ep->xfer_len - ep->xfer_count; + + if (len > ep->maxpacket) + { + len = ep->maxpacket; + } + + len32b = (len + 3U) / 4U; + + while (((USB_HS_INEP(epnum)->DTXFSTS & OTG_HS_DTXFSTS_INEPTFSAV) >= len32b) & + (ep->xfer_count < ep->xfer_len) & (ep->xfer_len != 0U)) + { + /* Write the FIFO */ + len = ep->xfer_len - ep->xfer_count; + + if (len > ep->maxpacket) + { + len = ep->maxpacket; + } + len32b = (len + 3U) / 4U; + + USB_HS_WritePacket(ep->xfer_buff, (uint8_t)epnum, (uint16_t)len, (uint8_t)hpcd->Init.dma_enable); + + ep->xfer_buff += len; + ep->xfer_count += len; + } + + if (ep->xfer_len <= ep->xfer_count) + { + fifoemptymsk = (uint32_t)(0x1UL << (epnum & EP_ADDR_MSK)); + USB_HS_DEVICE->DIEPEMPMSK &= ~fifoemptymsk; + } + + return USB_HS_OK; +} + + +/** + * @brief process EP OUT transfer complete interrupt. + * @param hpcd PCD handle + * @param epnum endpoint number + * @retval none + * */ +void PCD_HS_EP_OutXfrComplete_int(PCD_HS_HandleTypeDef *hpcd, uint32_t epnum) +{ + USB_OTG_HS_EPTypeDef *ep; + uint32_t DoepintReg = USB_HS_OUTEP(epnum)->DOEPINT; + + if (hpcd->Init.dma_enable == 1U) + { + if ((DoepintReg & OTG_HS_DOEPINT_STUPD) == OTG_HS_DOEPINT_STUPD) /* Class C */ + { + /* StupPktRcvd = 1 this is a setup packet */ + if((DoepintReg & OTG_HS_DOEPINT_STPKRE) == OTG_HS_DOEPINT_STPKRE) + { + CLEAR_OUT_EP_INTR(epnum, OTG_HS_DOEPINT_STPKRE); + } + } + else if ((DoepintReg & OTG_HS_DOEPINT_OTEPSPR) == OTG_HS_DOEPINT_OTEPSPR) + { + CLEAR_OUT_EP_INTR(epnum, OTG_HS_DOEPINT_OTEPSPR); + } + else if ((DoepintReg & (OTG_HS_DOEPINT_STUPD | OTG_HS_DOEPINT_OTEPSPR)) == 0U) + { + /* StupPktRcvd = 1 this is a setup packet */ + if((DoepintReg & OTG_HS_DOEPINT_STPKRE) == OTG_HS_DOEPINT_STPKRE) + { + CLEAR_OUT_EP_INTR(epnum, OTG_HS_DOEPINT_STPKRE); + } + else + { + ep = &hpcd->OUT_ep[epnum]; + /* out data packet received over EP */ + ep->xfer_count = ep->xfer_size - (USB_HS_OUTEP(epnum)->DOEPTSIZ & OTG_HS_DOEPTSIZ_XFRSIZ) ; + + if (epnum == 0U) + { + if (ep->xfer_len == 0U) + { + /* this is ZLP, so prepare EP0 for next setup */ + (void)USB_HS_EP0_OutStart(1U, (uint8_t *)hpcd->Setup); + } + else + { + ep->xfer_buff += ep->xfer_count; + } + } + + PCD_HS_DataOutStageCallback(hpcd, (uint8_t)epnum); + } + } + else + { + /*...*/ + } + } + else + { + /* StupPktRcvd = 1 this is a setup packet */ + if ((DoepintReg & OTG_HS_DOEPINT_STPKRE) == OTG_HS_DOEPINT_STPKRE) + { + CLEAR_OUT_EP_INTR(epnum, OTG_HS_DOEPINT_STPKRE); + } + else + { + if ((DoepintReg & OTG_HS_DOEPINT_OTEPSPR) == OTG_HS_DOEPINT_OTEPSPR) + { + CLEAR_OUT_EP_INTR(epnum, OTG_HS_DOEPINT_OTEPSPR); + } + + PCD_HS_DataOutStageCallback(hpcd, (uint8_t)epnum); + } + + } + +} + + +/** + * @brief process EP OUT setup packet received interrupt. + * @param hpcd PCD handle + * @param epnum endpoint number + * @retval none + */ +static void PCD_HS_EP_OutSetupPacket_int(PCD_HS_HandleTypeDef *hpcd, uint32_t epnum) +{ + uint32_t DoepintReg = USB_HS_OUTEP(epnum)->DOEPINT; + + if ((DoepintReg & OTG_HS_DOEPINT_STPKRE) == OTG_HS_DOEPINT_STPKRE) + { + CLEAR_OUT_EP_INTR(epnum, OTG_HS_DOEPINT_STPKRE); + } + + /* Inform the upper layer that a setup packet is available */ + PCD_HS_SetupStageCallback(hpcd); + +} +#endif /* defined (USB_OTG_HS) */ + +/** + * @} + */ + + +#endif /* defined (USB_OTG_HS) */ +#endif /* PCD_MODULE_ENABLED */ + diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_pwr.c b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_pwr.c new file mode 100644 index 00000000000..ab45da17394 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_pwr.c @@ -0,0 +1,575 @@ +/** + ****************************************************************************** + * @file ft32f4xx_pwr.c + * @author Rwang + * @brief This file provides firmware functions to manage the following + * functionalities of the Power Controller (PWR) peripheral: + * + Backup Domain Access + * + PVD configuration + * + WakeUp pins configuration + * + Low Power modes configuration + * + Flags management + * + Vbat charge configuration + * @version V1.0.0 + * @data 2025-03-24 + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx_pwr.h" +#include "ft32f4xx_rcc.h" + + +/* ------------------ PWR registers bit mask ------------------------ */ + +/* CR register bit mask */ +#define CR_VBRS_MASK ((uint32_t)0x00080000) +#define CR_VOS_MASK ((uint32_t)0x00006000) +#define CR_PLSR_MASK ((uint32_t)0x00000E00) +#define CR_PLSF_MASK ((uint32_t)0x000001C0) +#define SCB_SCR_SLEEPONEXIT ((uint32_t)0x00000002) +#define SCB_SCR_SLEEPDEEP ((uint32_t)0x00000004) + + + +/** + * @brief Deinitializes the PWR peripheral registers to their default reset values. + * @param None + * @retval None + */ +void PWR_DeInit(void) +{ + RCC_APB1PeriphResetCmd(RCC_APB1Periph_PWR, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_PWR, DISABLE); +} +/** + * @} + */ + + +/** + * @brief Enables or disables vbat charge + * @note Vbat will be charge by external resistance + * @param NewState: new state of the access to the Backup domain registers. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void PWR_VbatCharge(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the Vbat charge */ + PWR->CR |= PWR_CR_VBE; + } + else + { + /* Disable the Vbat Charge*/ + PWR->CR &= ~PWR_CR_VBE; + } +} +/** + * @} + */ + + +/** + * @brief Configures the Vbat Charge Resistance. + * @param PWR_VbatRes: specifies the Vbat Resistance detection + * This parameter can be one of the following values: + * @arg PWR_Vbat_Charge_5k + * @arg PWR_Vbat_Charge_1point5k + * @note Refer to the electrical characteristics of your device datasheet for + * more details about the voltage threshold corresponding to each + * detection level. + * @retval None + */ +void PWR_VbatResConfig(uint32_t PWR_VbatRes) +{ + /* Check the parameters */ + assert_param(IS_PWR_VBAT_RES(PWR_VbatRes)); + + /* Set Vbrs and Vbrs bit according to PWR_VbatRes value */ + if (PWR_VbatRes == PWR_Vbat_Charge_5k) + { + PWR->CR &= ~PWR_CR_VBRS; + } + else + { + PWR->CR |= PWR_CR_VBRS; + } +} +/** + * @} + */ + + +/** + * @brief Configures the Main Voltage Regulator. + * @param PWR_VOSLevel: specifies the Main Voltage Regulator detection + * This parameter can be one of the following values: + * @arg PWR_VosLevel_0 + * @arg PWR_VosLevel_1 + * @arg PWR_VosLevel_2 + * @arg PWR_VosLevel_3 + * @note Refer to the electrical characteristics of your device datasheet for + * more details about the voltage threshold corresponding to each + * detection level. + * @retval None + */ +void PWR_VosLevelConfig(uint32_t PWR_VosLevel) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_PWR_VOS_LEVEL(PWR_VosLevel)); + + tmpreg = PWR->CR; + + /* Clear vos bits */ + tmpreg &= ~CR_VOS_MASK; + + /* Set vos and vos bits according to PWR_VosLevel value */ + tmpreg |= PWR_VosLevel; + + /* Store the new value */ + PWR->CR = tmpreg; +} +/** + * @} + */ + + +/** + * @brief Enables or disables access to the Backup domain registers. + * @note If the HSE divided by 32 is used as the RTC clock, the + * Backup Domain Access should be kept enabled. + * @param NewState: new state of the access to the Backup domain registers. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void PWR_BackupAccessCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the Backup Domain Access */ + PWR->CR |= PWR_CR_DBP; + } + else + { + /* Disable the Backup Domain Access */ + PWR->CR &= ~PWR_CR_DBP; + } +} +/** + * @} + */ + + +/** + * @brief Enables or disables the Power Voltage Detector(PVD). + * @param NewState: new state of the PVD. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void PWR_PVDEnable(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the PVD */ + PWR->CR |= PWR_CR_PVDE; + } + else + { + /* Disable the PVD */ + PWR->CR &= ~PWR_CR_PVDE; + } +} +/** + * @} + */ + + +/** + * @brief Configures the rise voltage threshold detected by the Power Voltage Detector(PVD). + * @param PWR_PVDRLevel: specifies the PVD rise detection level + * This parameter can be one of the following values: + * @arg PWR_PVDRLevel_0 + * @arg PWR_PVDRLevel_1 + * @arg PWR_PVDRLevel_2 + * @arg PWR_PVDRLevel_3 + * @arg PWR_PVDRLevel_4 + * @arg PWR_PVDRLevel_5 + * @arg PWR_PVDRLevel_6 + * @arg PWR_PVDRLevel_7 + * @note Refer to the electrical characteristics of your device datasheet for + * more details about the voltage threshold corresponding to each + * detection rise level. + * @retval None + */ +void PWR_PVDRLevelConfig(uint32_t PWR_PVDRLevel) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_PWR_PVDR_LEVEL(PWR_PVDRLevel)); + + tmpreg = PWR->CR; + + /* Clear PVDR bits */ + tmpreg &= ~CR_PLSR_MASK; + + /* Set PVDR and PVDR bits according to PWR_PVDRLevel value */ + tmpreg |= PWR_PVDRLevel; + + /* Store the new value */ + PWR->CR = tmpreg; +} +/** + * @} + */ + + +/** + * @brief Configures the fall voltage threshold detected by the Power Voltage Detector(PVD). + * @param PWR_PVDRLevel: specifies the PVD fall detection level + * This parameter can be one of the following values: + * @arg PWR_PVDFLevel_0 + * @arg PWR_PVDFLevel_1 + * @arg PWR_PVDFLevel_2 + * @arg PWR_PVDFLevel_3 + * @arg PWR_PVDFLevel_4 + * @arg PWR_PVDFLevel_5 + * @arg PWR_PVDFLevel_6 + * @arg PWR_PVDFLevel_7 + * @note Refer to the electrical characteristics of your device datasheet for + * more details about the voltage threshold corresponding to each + * detection fall level. + * @retval None + */ +void PWR_PVDFLevelConfig(uint32_t PWR_PVDFLevel) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_PWR_PVDF_LEVEL(PWR_PVDFLevel)); + + tmpreg = PWR->CR; + + /* Clear PVDF bits */ + tmpreg &= ~CR_PLSF_MASK; + + /* Set PVDF and PVDF bits according to PWR_PVDFLevel value */ + tmpreg |= PWR_PVDFLevel; + + /* Store the new value */ + PWR->CR = tmpreg; +} +/** + * @} + */ + + +/** + * @brief Enables or Disable the Power Off Reset in standby(Pdroff). + * @param NewState: new state of the Pdroff. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void PWR_PdroffEnable(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Disable the PDR in standby*/ + PWR->CR |= PWR_CR_PDROFF; + } + else + { + /* Enable the PVD in standby*/ + PWR->CR &= ~PWR_CR_PDROFF; + } +} +/** + * @} + */ + + +/** + * @brief Enables or disables the WakeUp Pin functionality. + * @param PWR_WakeUpPin: specifies the WakeUpPin. + * This parameter can be one of the following values + * @arg PWR_WakeUpPin_1 + * @arg PWR_WakeUpPin_2 + * @arg PWR_WakeUpPin_3 + * @param NewState: new state of the WakeUp Pin functionality. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void PWR_WakeUpPinCmd(uint32_t PWR_WakeUpPin, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_PWR_WAKEUP_PIN(PWR_WakeUpPin)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the EWUPx pin */ + PWR->CSR |= PWR_WakeUpPin; + } + else + { + /* Disable the EWUPx pin */ + PWR->CSR &= ~PWR_WakeUpPin; + } +} +/** + * @} + */ + + +/** + * @brief Enables or Disable the Backup Regulator Enable(BRE). + * @param NewState: new state of the Bre. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void PWR_BreEnable(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the Backup Regulator*/ + PWR->CSR |= PWR_CSR_BRE; + } + else + { + /* Disable the Backup Regulator*/ + PWR->CSR &= ~PWR_CSR_BRE; + } +} +/** + * @} + */ + + +/** + * @brief Enters Sleep mode. + * @note In Sleep mode, all I/O pins keep the same state as in Run mode. + * @param PWR_SLEEPEntry: specifies if SLEEP mode in entered with WFI or WFE 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 + * @arg PWR_SleepEntry_SLEEPONEXIT: enter SLEEP mode while mcu exit the lowest priority interrupt + * @retval None + */ +void PWR_EnterSleepMode(uint8_t PWR_SleepEntry) +{ + /* Check the parameters */ + assert_param(IS_PWR_SLEEP_ENTRY(PWR_SleepEntry)); + + /* Clear SLEEPDEEP bit of Cortex-M0 System Control Register */ + SCB->SCR &= ~SCB_SCR_SLEEPDEEP; + + /* Select SLEEP mode entry */ + if (PWR_SleepEntry == PWR_SleepEntry_WFI) + { + /* Request Wait For Interrupt */ + __WFI(); + } + else if (PWR_SleepEntry == PWR_SleepEntry_WFE) + { + /* Request Wait For Event */ + __SEV(); + __WFE(); + __WFE(); + } + else if (PWR_SleepEntry == PWR_SleepEntry_SLEEPONEXIT) + { + /* Set SLEEP on exit bit of Cortex-M0 System Control Register */ + SCB->SCR |= SCB_SCR_SLEEPONEXIT; + } +} + +/** + * @brief Enters STOP mode. + * @note In Stop mode, all I/O pins keep the same state as in Run mode. + * @note When exiting Stop mode by issuing an interrupt or a wakeup event, + * the HSI RC oscillator is selected as system clock. + * @note When the voltage regulator operates in low power mode, an additional + * startup delay is incurred when waking up from Stop mode. + * By keeping the internal regulator ON during Stop mode, the consumption + * is higher although the startup time is reduced. + * @param PWR_Regulator: specifies the regulator state in STOP mode. + * This parameter can be one of the following values: + * @arg PWR_Regulator_ON: STOP mode with regulator ON + * @arg PWR_Regulator_LowPower: STOP mode with regulator in low power mode + * @param PWR_STOPEntry: specifies if STOP mode in entered with WFI or WFE 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 + * @retval None + */ +void PWR_EnterStopMode(uint32_t PWR_Regulator, uint8_t PWR_StopEntry) +{ + /* Check the parameters */ + assert_param(IS_PWR_REGULATOR(PWR_Regulator)); + assert_param(IS_PWR_STOP_ENTRY(PWR_StopEntry)); + + /* Select Regulator status in stop mode */ + if (PWR_Regulator == PWR_Regulator_ON) + { + /* Clear LPDS bit make Regulator open in stop mode */ + PWR->CR &= ~PWR_CR_LPDS; + } + else if (PWR_Regulator == PWR_Regulator_LowPower) + { + /* Set LPDS bit make Regulator Lowerpower in stop mode */ + PWR->CR |= PWR_CR_LPDS; + } + + /* Select STOP mode entry */ + if (PWR_StopEntry == PWR_StopEntry_WFI) + { + /* Set SLEEPDEEP bit of Cortex System Control Register */ + SCB->SCR |= SCB_SCR_SLEEPDEEP; + /* Request Wait For Interrupt */ + __WFI(); + } + else if (PWR_StopEntry == PWR_StopEntry_WFE) + { + /* Set SLEEPDEEP bit of Cortex System Control Register */ + SCB->SCR |= SCB_SCR_SLEEPDEEP; + /* Request Wait For Event */ + __SEV(); + __WFE(); + __WFE(); + } +} + +/** + * @brief Enters STANDBY mode. + * @note In Standby mode, all I/O pins are high impedance except for: + * - Reset pad (still available) + * - RTC_AF1 pin (PC13) if configured for Wakeup pin 2 (WKUP2), tamper, + * time-stamp, RTC Alarm out, or RTC clock calibration out. + * - WKUP pin 1 (PA0) if enabled. + * @param PWR_StandbyEntry: specifies if STOP mode in entered with WFI or WFE instruction. + * This parameter can be one of the following values: + * @arg PWR_StandbyEntry_WFI: enter STANDBY mode with WFI instruction + * @arg PWR_StandbyEntry_WFE: enter STANDBY mode with WFE instruction + * @note The Wakeup flag (WUF) need to be cleared at application level before to call this function + * @param None + * @retval None + */ +void PWR_EnterStandbyMode(uint8_t PWR_StandbyEntry) +{ + assert_param(IS_PWR_STANDBY_ENTRY(PWR_StandbyEntry)); + + /* Select STANDBY mode */ + PWR->CR |= PWR_CR_PDDS; + + /* Set SLEEPDEEP bit of Cortex-M0 System Control Register */ + SCB->SCR |= SCB_SCR_SLEEPDEEP; + + /* Select Standby mode entry */ + if (PWR_StandbyEntry == PWR_StandbyEntry_WFI) + { + /* Request Wait For Interrupt */ + __WFI(); + } + else if (PWR_StandbyEntry == PWR_StandbyEntry_WFE) + { + /* Request Wait For Event */ + __SEV(); + __WFE(); + __WFE(); + } +} +/** + * @} + */ + +/** + * @brief Checks whether the specified PWR flag is set or not. + * @param PWR_FLAG: specifies the flag to check. + * This parameter can be one of the following values: + * @arg PWR_FLAG_WU: Wake Up flag. This flag indicates that a wakeup + * event was received from the WKUP pin or from the RTC alarm + * (Alarm A or Alarm B), RTC Tamper event or RTC TimeStamp event + * @arg PWR_FLAG_SB: StandBy flag. This flag indicates that the + * system was resumed from Standby mode + * @arg PWR_FLAG_PVDO: PVD Output. This flag is valid only if PVD + * is enabled by the PWR_PVDEnable() function. + * @arg PWR_FLAG_BRR: Backup regulator ready. This flag is valid + * only if BRE is enabled by the PWR_BreEnable() function. + * @arg PWR_FLAG_VREFINTRDY: Internal Voltage Reference Ready flag + * This flag indicates the state of the internal voltage + * reference, VREFINT. + * @retval The new state of PWR_FLAG (SET or RESET). + */ +FlagStatus PWR_GetFlagStatus(uint32_t PWR_FLAG) +{ + FlagStatus bitstatus = RESET; + + /* Check the parameters */ + assert_param(IS_PWR_GET_FLAG(PWR_FLAG)); + + if ((PWR->CSR & PWR_FLAG) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + /* Return the flag status */ + return bitstatus; +} +/** + * @} + */ + + +/** + * @brief Clears the PWR's pending flags. + * @param PWR_FLAG: specifies the flag to clear. + * This parameter can be one of the following values: + * @arg PWR_FLAG_CWU: Wake Up flag + * @arg PWR_FLAG_CSB: StandBy flag + * @retval None + */ +void PWR_ClearFlag(uint32_t PWR_FLAG) +{ + /* Check the parameters */ + assert_param(IS_PWR_CLEAR_FLAG(PWR_FLAG)); + + if (PWR_FLAG == PWR_FLAG_CWU) + { + /*clear wkup flag*/ + PWR->CR |= PWR_FLAG_CWU; + } + else if (PWR_FLAG == PWR_FLAG_CWU) + { + /*clare standby flag*/ + PWR->CR |= PWR_FLAG_CSB; + } +} +/** + * @} + */ + + +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_qspi.c b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_qspi.c new file mode 100644 index 00000000000..b42c1181952 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_qspi.c @@ -0,0 +1,1047 @@ +/** + ****************************************************************************** + * @file ft32f4xx_qspi.c + * @author FMD AE + * @brief This file provides firmware functions to manage the following + * functionalities of the Serial peripheral interface (QSPI): + * + Initialization and Configuration + * + Data transfers functions + * + DMA transfers management + * + XIP transfer management + * + XIP transfer management + * + Interrupts and flags management + * @version V1.0.0 + * @data 2025-03-06 + ****************************************************************************** + */ +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx_qspi.h" +#include "ft32f4xx_rcc.h" + +/* QSPI registers Masks */ +#define CTRLR0_CLEAR_MASK ((uint32_t)0x00c04fc0) +#define SPI_CTRLR0_CLEAR_MASK ((uint32_t)0x0c03033f) +/** + * @brief Deinitializes the QSPI peripheral registers to their default + * reset values. + */ +void QSPI_DeInit(void) +{ + + /* Enable QSPI reset state */ + RCC_AHB3PeriphResetCmd(RCC_AHB3Periph_QSPI, ENABLE); + /* Release QSPI from reset state */ + RCC_AHB3PeriphResetCmd(RCC_AHB3Periph_QSPI, DISABLE); +} + +/** + * @brief Fills each QSPI_InitStruct member with its default value. + * @param QSPI_InitStruct: pointer to a QSPI_InitTypeDef structure which will be initialized. + * @retval None + */ +void QSPI_StructInit(QSPI_InitTypeDef *QSPI_InitStruct) +{ + /*--------------- Reset QSPI init structure parameters values -----------------*/ + /* Initialize the QSPI_Protocol member */ + QSPI_InitStruct->QSPI_Protocol = QSPI_PROTOCOL_SPI; + /* Initialize the QSPI_Direction member */ + QSPI_InitStruct->QSPI_Direction = QSPI_DIRECTION_Tx_ONLY; + /* Initialize the QSPI_SSTE member */ + QSPI_InitStruct->QSPI_SSTE = QSPI_SSTE_TOGGLE_DIS; + /* Initialize the QSPI_DataSize member */ + QSPI_InitStruct->QSPI_DataSize = QSPI_DATASIZE_8B; + /* Initialize the QSPI_SCPOL member */ + QSPI_InitStruct->QSPI_SCPOL = QSPI_SCPOL_LOW; + /* Initialize the QSPI_SCPHA member */ + QSPI_InitStruct->QSPI_SCPHA = QSPI_SCPHA_1EDGE; + /* Initialize the QSPI_SER member */ + QSPI_InitStruct->QSPI_SER = QSPI_NCS0; + /* Initialize the QSPI_Chio select min time member */ + QSPI_InitStruct->QSPI_CS_MIN_HIGH = 0; + /*Initialize the DataMode member*/ + QSPI_InitStruct->QSPI_DataMode = QSPI_STANDARD; + +} + + +/** + * @brief Initializes the QSPI peripheral according to the specified + * parameters in the QSPI_InitStruct. + * @param QSPI_InitStruct: pointer to a QSPI_InitTypeDef structure that + * contains the configuration information for the specified QSPI peripheral. + * Br: specifies the baundrate. Br can be the value between 0x0~0x7FFF. + * @retval None + */ +void QSPI_Init(QSPI_InitTypeDef *QSPI_InitStruct, uint16_t Br) +{ + uint32_t tmpreg = 0; + + /* Check the QSPI parameters */ + assert_param(IS_QSPI_PROPTOCOL(QSPI_InitStruct->QSPI_Protocol)); + assert_param(IS_QSPI_DIRECTION_MODE(QSPI_InitStruct->QSPI_Direction)); + assert_param(IS_QSPI_SSTE(QSPI_InitStruct->QSPI_SSTE)); + assert_param(IS_QSPI_DATA_SIZE(QSPI_InitStruct->QSPI_DataSize)); + assert_param(IS_QSPI_SCPOL(QSPI_InitStruct->QSPI_SCPOL)); + assert_param(IS_QSPI_SCPHA(QSPI_InitStruct->QSPI_SCPHA)); + assert_param(IS_QSPI_SER_SEL(QSPI_InitStruct->QSPI_SER)); + assert_param(IS_QSPI_DATA_MODE(QSPI_InitStruct->QSPI_DataMode)); + + /*---------------------------- QSPI CTRLR0 Configuration ------------------------*/ + /* Get the QSPI CTRLR0 value */ + tmpreg = QSPI->CTRLR0; + /* Clear CLK_LOOP_EN,SPI_FRF,SSTE,SRL,TMOD,SCPOL,SCPHA,FRF,DFS bits */ + tmpreg &= ~CTRLR0_CLEAR_MASK; + /* Configure QSPI: Protocol,Direction,SSTE,DataSize,SCPOL,SCPHA,SER,SRL*/ + /* Set SPI_FRF bits according to QSPI_Protocol value,select SPI/SSP/MICROWIRE proptocol */ + /* Set TMOD bit according to QSPI_Direction values,include txrx tx rx*/ + /* Set SSTE bit according to QSPI_SSTE value */ + /* Set SCPOL bit according to QSPI_SCPOL value */ + /* Set SCPHA bit according to QSPI_SCPHA value */ + + /* Set DataSize according to QSPI_DataSize value,DataSize value must >= 'h11*/ + tmpreg = (uint32_t)((uint32_t)QSPI_InitStruct->QSPI_DataSize); + tmpreg |= (uint32_t)((uint32_t)QSPI_InitStruct->QSPI_Protocol | QSPI_InitStruct->QSPI_Direction | + QSPI_InitStruct->QSPI_SSTE | QSPI_InitStruct->QSPI_SCPOL | + QSPI_InitStruct->QSPI_SCPHA | QSPI_InitStruct->QSPI_SER | + QSPI_InitStruct->QSPI_DataMode); + /* Write to QSPI CTRLR0 */ + QSPI->CTRLR0 = tmpreg; + + /*-------------------------QSPI SER Configuration -----------------------*/ + /* Get the QSPI SER value */ + tmpreg = QSPI->SER; + /* Clear SER[1:0] bits */ + tmpreg &= (uint32_t)~QSPI_SER_SER; + /* Configure QSPI: NCSx select */ + tmpreg |= (uint32_t)(QSPI_InitStruct->QSPI_SER); + /* Write to QSPI SER */ + QSPI->SER = tmpreg; + + /*---------------------------- QSPI BAUDR Configuration --------------------*/ + /* Clear SCKDV[14:0] */ + QSPI->BAUDR = 0; + QSPI->BAUDR = Br << 1; + + /*---------------------------- QSPI SPI_CTRLR1 Configuration ------------------------*/ + /* Get the QSPI SPI_CTRLR1 value */ + tmpreg = QSPI->SPI_CTRLR1; + /* Clear CS_MIN_HIGH bit */ + tmpreg &= ~0xf0000; + /* Configure CS_MIN_HIGH bit */ + tmpreg |= (uint32_t)((uint32_t)QSPI_InitStruct->QSPI_CS_MIN_HIGH) ; + /* Write to QSPI SPI_CTRLR1 */ + QSPI->SPI_CTRLR1 = tmpreg << 16; +} + +/** + * @brief Initializes the QSPI peripheral according to the specified + * parameters in the QSPI_CommandStruct. + * @param QSPI_CommandStruct: pointer to a QSPI_CommandTypeDef structure that + * contains the configuration information for the specified QSPI peripheral. + * @retval None + */ + +/** + * @brief Enables or disables the Testing Mode for QSPI. + * @retval None + */ + +void QSPI_TestMode_Enable(FunctionalState NewState) +{ + + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable test mode */ + QSPI->CTRLR0 |= QSPI_TESTING_MODE ; + } + else + { + /* Disable test mode*/ + QSPI->CTRLR0 &= ~QSPI_TESTING_MODE ; + } +} + +/** + * @brief Config MicroWire Mode for QSPI. + * @param MHS: specifies the MICROWIRE handshake enable or disable. + * This parameter can be any combination of the following values: + * @arg QSPI_MICROHAND_DIS: handshake disable; + * @arg QSPI_MICROHAND_EN: handshake enable; + * MDD: specifies the MICROWIRE transfer direction. + * This parameter can be any combination of the following values: + * @arg QSPI_MICRODIR_Rx: receive data; + * @arg QSPI_MICRODIR_Tx: transmit data; + * MWMOD: specifies the MICROWIRE transfer mode. + * This parameter can be any combination of the following values: + * @arg QSPI_MICROTRANS_NSEQ: nosequence transfer; + * @arg QSPI_MICROTRANS_SEQ: sequence trnsfer; + * FrameSize: specifies the control frame size. + * This parameter can be any combination of the following values: + * @arg QSPI_CFS_1B: cfs 1 bit; + * @arg QSPI_CFS_2B: cfs 2 bit; + * ...... ...... + * @arg QSPI_CFS_15B: cfs 15 bit; + * @arg QSPI_CFS_16B: cfs 16 bit; + + * @retval None + */ + +void QSPI_MicroWireMode_Config(uint32_t MHS, uint32_t MDD, uint32_t MWMOD, uint32_t FrameSize, FunctionalState NewState) +{ + + uint32_t tmpreg = 0; + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Get the QSPI MWCR value */ + tmpreg = QSPI->MWCR; + /* Clear the MWMOD,MDD,MHS*/ + tmpreg &= ~0x7; + /* Set the MWMOD,MDD,MHS*/ + tmpreg |= MHS | MDD | MWMOD; + /* Write the QSPI MWCR register*/ + QSPI->MWCR = tmpreg ; + + /* Get the QSPI CTRLR0 value */ + tmpreg = QSPI->CTRLR0 ; + /* Clear the CFS,FRF value */ + tmpreg &= ~(0xf << 16 | QSPI_CTRLR0_FRF); + /*Set the CFS,FRF bits */ + tmpreg |= (FrameSize | QSPI_PROTOCOL_MICROWIRE); + /* Write the CFS,FRF bits in CTRLR0 */ + QSPI->CTRLR0 |= tmpreg ; + } + else + { + /* Disable the MICROWIRE mode for the selected QSPI peripheral */ + QSPI->CTRLR0 &= ~QSPI_CTRLR0_FRF ; + } +} + +/** + * @brief Enables or disables the specified QSPI peripheral. + * @param NewState: new state of the QSPI peripheral. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void QSPI_EnCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected QSPI peripheral */ + QSPI->SSIENR |= QSPI_SSIENR_SSIC_EN; + } + else + { + /* Disable the selected QSPI peripheral */ + QSPI->SSIENR &= ~QSPI_SSIENR_SSIC_EN; + } +} + +/** + * @brief Enables or disables the TI Mode. + * + * @note This function can be called only after the QSPI_Init() function has + * been called. + * + * @param NewState: new state of the selected QSPI TI communication mode. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void QSPI_TIModeCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the TI mode for the selected QSPI peripheral */ + QSPI->CTRLR0 &= (uint32_t)~((uint32_t)QSPI_CTRLR0_FRF); + QSPI->CTRLR0 |= (QSPI_CTRLR0_FRF & 1 << 6); + } + else + { + /* Disable the TI mode for the selected QSPI peripheral */ + QSPI->CTRLR0 &= (uint32_t)~((uint32_t)QSPI_CTRLR0_FRF); + } +} +/** + * @brief Configures the data size for the selected QSPI. + * @param QSPI_DataSize: specifies the QSPI data size. + * For the QSPI peripheral this parameter can be one of the following values: + * @arg QSPI_DATASIZE_4B: Set data size to 4 bits + * @arg QSPI_DATASIZE_5B: Set data size to 5 bits + * @arg QSPI_DATASIZE_6B: Set data size to 6 bits + * ...... ...... + * @arg QSPI_DATASIZE_30B: Set data size to 30 bits + * @arg QSPI_DATASIZE_31B: Set data size to 31 bits + * @arg QSPI_DATASIZE_32B: Set data size to 32 bits + * @retval None + */ +void QSPI_DataSizeConfig(uint16_t QSPI_DataSize) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_QSPI_DATA_SIZE(QSPI_DataSize)); + if (QSPI_DataSize >= 3) + { + /* Read the CTRLR0 register */ + tmpreg = QSPI->CTRLR0; + /* Clear DFD[4:0] bits */ + tmpreg &= ~0x1f; + /* Set new DS[3:0] bits value */ + tmpreg = QSPI_DataSize | tmpreg; + QSPI->CTRLR0 = tmpreg; + } + else + { + // printf("ERROR ! QSPI DATA SIZE CAN NOT BE LESS THAN 4BITS!!! \n"); + } +} + +/** + * @brief Configures the number of data frames. + * @param QSPI_NDF: specifies the NDF value. + * @retval None + */ +void QSPI_DataNumberConfig(uint32_t QSPI_NDF) +{ + /* Check the parameters */ + assert_param(IS_QSPI_DATANUMBER(QSPI_NDF)); + + /* Set new NDF bits value */ + QSPI->CTRLR1 = QSPI_NDF ; +} +/** + * @brief Configures the FIFO reception threshold for the selected QSPI. + * @param QSPI_RxFIFOThreshold: specifies the FIFO reception threshold. + * @retval None + */ +void QSPI_RxFIFOThresholdConfig(uint16_t QSPI_RxFIFOThreshold) +{ + /* Check the parameters */ + assert_param(IS_QSPI_RX_FIFO_THRESHOLD(QSPI_RxFIFOThreshold)); + + /* Clear RFT bit */ + QSPI->RXFTLR &= ~QSPI_RXFTLR_RFT; + + /* Set new RFT bit value */ + QSPI->RXFTLR |= QSPI_RxFIFOThreshold; +} + +/** + * @brief Configures the FIFO transmition threshold for the selected QSPI. + * @param QSPI_TxFIFOThreshold: specifies the FIFO transmition threshold. + * @param QSPI_TxFIFOStart: specifies the FIFO transfer start interrupt level. + * @retval None + */ +void QSPI_TxFIFOThresholdConfig(uint16_t QSPI_TxFIFOStart, uint16_t QSPI_TxFIFOThreshold) +{ + /* Check the parameters */ + assert_param(IS_QSPI_TX_FIFO_THRESHOLD(QSPI_TxFIFOThreshold)); + assert_param(IS_QSPI_TX_FIFO_STARTLEVEL(QSPI_TxFIFOStart)); + + /* Clear TXFTHR TFT bit */ + QSPI->TXFTLR &= ~(QSPI_TXFTLR_TFT | QSPI_TXFTLR_TXFTHR); + + /* Set new TXFTHR TFT bit value */ + QSPI->TXFTLR |= (QSPI_TxFIFOStart << 16 | QSPI_TxFIFOThreshold); +} + +/** + * @brief Enables or disables the slave select toggle mode. + * @note This bits only can be set when SCPH = 0. + * @param NewState: new state of the NSS pulse management mode. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void QSPI_SSTEModeCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the NSS pulse management mode */ + QSPI->CTRLR0 |= QSPI_CTRLR0_SSTE; + } + else + { + /* Disable the NSS pulse management mode */ + QSPI->CTRLR0 &= ~QSPI_CTRLR0_SSTE; + } +} + +/** + * @} + */ +/** + * @brief Transmits a Data through the QSPI peripheral. + * @param Data: Data to be transmitted. + * @retval None + */ +void QSPI_SendData(uint32_t Data) +{ + + QSPI->DR[0] = (uint32_t)Data; +} + +/** + * @brief Returns the most recent received data by the QSPI peripheral. + * @retval The value of the received data. + */ +uint32_t QSPI_ReceiveData(void) +{ + uint32_t qspixbase = 0x00; + + qspixbase = (uint32_t)QSPI; + qspixbase += 0x60; + + return *(__IO uint32_t *) qspixbase; +} + +/** + * @brief Config the QSPI SPI frame format. + * @param LINE: specifies the QSPI line numbers. + * This parameter can be any combination of the following values: + * @arg QSPI_STANDARD: single line; + * @arg QSPI_DUAL: dual line; + * @arg QSPI_QUAD: quad line. + * @retval None + */ +void QSPI_LineCfg(uint32_t LINE) +{ + /* Check the parameters */ + assert_param(IS_QSPI_DATA_MODE(LINE)); + + /* Clear the SPI_FRF bits*/ + QSPI->CTRLR0 &= ~QSPI_CTRLR0_SPI_FRF ; + /* Set the SPI_FRF bits*/ + QSPI->CTRLR0 |= LINE; +} + +/** + * @brief Config the QSPI transfer mode. + * @param TRANS: specifies the QSPI transfer mode. + * This parameter can be any combination of the following values: + * @arg QSPI_DIRECTION_Tx_AND_Rx: txrx mode; + * @arg QSPI_DIRECTION_Tx_ONLY: tx only mode; + * @arg QSPI_DIRECTION_Rx_ONLY: rx only mode; + * @arg QSPI_DIRECTION_EEPROM_READ: eeprom read mode. + * @retval None + */ + +void QSPI_TransMode(uint32_t TRANS) +{ + /* Check the parameters */ + assert_param(IS_QSPI_DIRECTION_MODE(TRANS)); + + /* Clear the TMOD bits*/ + QSPI->CTRLR0 &= ~QSPI_CTRLR0_TMOD ; + /* Set the TMOD bits*/ + QSPI->CTRLR0 |= TRANS ; +} + +/** + * @brief Config QSPI waitcycles. + * @param NUMBER: specifies the QSPI number of waitcycles. + * This parameter can be less than 0x1f: + * @retval None + */ +void QSPI_WaitCyclesConfig(uint32_t NUMBER) +{ + + /* Check the parameters */ + assert_param(IS_QSPI_WAITCYCLES(NUMBER)); + + /* Clear the WAIT_CYCLES bits*/ + QSPI->SPI_CTRLR0 &= ~QSPI_SPI_CTRLR0_WAIT_CYCLES; + /* Set the WAIT_CYCLES bits*/ + QSPI->SPI_CTRLR0 |= NUMBER << 11 ; + +} + +/** + * @brief Config QSPI waitcycles. + * @param TRANSTYPE: specifies the number of instruction and addr phase lane. + * This parameter can be any combination of the following values: + * @arg QSPI_TRANSTYPE_STAND : both instruction and addr work in standard mode + * @arg QSPI_TRANSTYPE_MIX : instruction works in standard,addr works in the SPI mode selected in the SPI_FRF filed + * @arg QSPI_TRANSTYPE_FRF : both instruction and addr work in the SPI mode selected in the SPI_FRF filed + * @retval None + */ +void QSPI_TransTypeConfig(uint32_t TRANSTYPE) +{ + + /* Check the parameters */ + assert_param(IS_QSPI_TRANSTYPE(TRANSTYPE)); + + /* Clear the TRANS_TYPE bits*/ + QSPI->SPI_CTRLR0 &= ~QSPI_SPI_CTRLR0_TRANS_TYPE; + /* Set the TRANS_TYPE bits*/ + QSPI->SPI_CTRLR0 |= TRANSTYPE ; + +} + +/** + * @} + */ +/** + * @brief Enables or disables the QSPI DMA interface. + * @param QSPI_MAReq: specifies the QSPI DMA transfer request to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg QSPI_DMAReq_Tx: Tx buffer DMA transfer request + * @arg QSPI_DMAReq_Rx: Rx buffer DMA transfer request + * @param NewState: new state of the selected QSPI DMA transfer request. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void QSPI_DMACmd(uint32_t QSPI_DMAReq, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + assert_param(IS_QSPI_DMA_REQ(QSPI_DMAReq)); + + if (NewState != DISABLE) + { + /* Enable the selected QSPI DMA requests */ + QSPI->DMACR |= QSPI_DMAReq; + } + else + { + /* Disable the selected QSPI DMA requests */ + QSPI->DMACR &= (uint32_t)~QSPI_DMAReq; + } +} + +/** + * @brief Config the DMA Tx data level. + * @param QSPI_DMATxDLevel: specifies the QSPI DMA Tx data level. + * This parameter can be less than 0xF. + * @retval None + */ + +void QSPI_DMA_Tx_DATALEVELCmd(uint32_t QSPI_DMATxDLevel) +{ + /* Check the parameters */ + assert_param(IS_QSPI_DMA_TX_DATA_LEVEL(QSPI_DMATxDLevel)); + + /* Config the QSPI DMA Txdata level */ + QSPI->DMATDLR = QSPI_DMATxDLevel; + +} + +/** + * @brief Config the DMA Rx data level. + * @param QSPI_DMARxDLevel: specifies the QSPI DMA Rx data level. + * This parameter can be less than 0xF. + * @retval None + */ + +void QSPI_DMA_Rx_DATALEVELCmd(uint32_t QSPI_DMARxDLevel) +{ + /* Check the parameters */ + assert_param(IS_QSPI_DMA_RX_DATA_LEVEL(QSPI_DMARxDLevel)); + + /* Config the QSPI DMA Rxdata level */ + QSPI->DMARDLR = QSPI_DMARxDLevel; + +} + + +/** + * @} + */ + +/** + * @brief Enables or disables the QSPI XIP instruction phase. + * @param NewState: new state of the selected QSPI instruction phase. + * This parameter can be: ENABLE or DISABLE. + * INST_L specifies the QSPI instruction phase length. + * This parameter can be one of the following values: + * QSPI_INSTRUCTION_0B: instruction 0 bits. + * QSPI_INSTRUCTION_4B: instruction 4 bits. + * QSPI_INSTRUCTION_8B: instruction 8 bits. + * QSPI_INSTRUCTION_16B: instruction 16 bits. + * @note Write SPI_CTRLR0 register must clear SSIENR bit. + * Normal mode instruction enable: INST_L != 0. + * XIP mode enable: (INST_L != 0) && (XIP_INST_EN == 1) + * @retval None + */ +void QSPI_XIP_INSTCmd(uint32_t INSTRUCTION_L, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + assert_param(IS_QSPI_XIP_INST(QSPI_INSTCfg)); + + if (NewState != DISABLE) + { + /* Clear the INST_L*/ + QSPI->SPI_CTRLR0 &= ~QSPI_SPI_CTRLR0_INST_L ; + /* Config instruction length and enable*/ + QSPI->SPI_CTRLR0 |= INSTRUCTION_L | QSPI_SPI_CTRLR0_XIP_INST_EN; + + } + else + { + /* Clear INST_L and XIP_INST_EN bits*/ + QSPI->SPI_CTRLR0 &= ~(QSPI_SPI_CTRLR0_INST_L | QSPI_SPI_CTRLR0_XIP_INST_EN); + } +} + + +/** + * @brief Config the QSPI XIP instruction opcode. + * @param QSPI_XIP_INSTCfg: specifies the QSPI XIP mode instruction . + * This parameter can be less than 0xFFFF. + * @retval None + */ + +void QSPI_XIP_INST_Config(uint32_t QSPI_XIP_INSTCfg) +{ + /* Set mode bit phase*/ + QSPI->XIP_INCR_INST = QSPI_XIP_INSTCfg ; +} + +/** + * @brief Enables or disables the QSPI ADDR phase. + * @note Write SPI_CTRLR0 register must clear SSIENR bit. + * ADDR_L specifies the QSPI addr phase length. + * This parameter can be one of the following values: + * QSPI_ADDRESS_0B: addr length 0 bits. + * QSPI_ADDRESS_4B: addr length 4 bits. + * ...... ...... + * QSPI_ADDRESS_56B: addr length 56 bits. + * QSPI_ADDRESS_60B: addr length 60 bits. + * @retval None + */ +void QSPI_ADDRCfg(uint32_t ADDR_L) +{ + /* Check the parameters */ + assert_param(IS_QSPI_ADDRESSSIZE(ADDR_L)); + + /* Clear ADDR_L bits*/ + QSPI->SPI_CTRLR0 &= ~QSPI_SPI_CTRLR0_ADDR_L; + /* Config ADDR_L bits*/ + QSPI->SPI_CTRLR0 |= ADDR_L; +} + +/** + * @brief Enables or disables the QSPI XIP mode bits . + * @param NewState: new state of the QSPI mode bits phase. + * This parameter can be: ENABLE or DISABLE. + * MODEBITS: specifies the QSPI XIP mode bits . + * This parameter can be less than 0xFFFF. + * MD_SIZE: specifies the QSPI mode bits length. + * This parameter can be one of the following values: + * QSPI_MODEBITS_2B: modebits length equal to 2 bits. + * QSPI_MODEBITS_4B: modebits length equal to 4 bits. + * QSPI_MODEBITS_8B: modebits length equal to 8 bits. + * QSPI_MODEBITS_16B: modebits length equal to 16 bits. + * @retval None + */ + +void QSPI_XIP_ModeBitsCmd(uint32_t MODEBITS, uint32_t MD_SIZE, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + assert_param(IS_QSPI_MODEBITSSIZE(MD_SIZE)); + assert_param(IS_QSPI_XIP_MODEBITS(MODEBITS)); + + if (NewState != DISABLE) + { + /* Clear XIP_MBL bits*/ + QSPI->SPI_CTRLR0 &= ~QSPI_SPI_CTRLR0_XIP_MBL ; + /* Set XIP_MD_BIT_EN , XIP_MBL bits*/ + QSPI->SPI_CTRLR0 |= QSPI_SPI_CTRLR0_XIP_MD_BIT_EN | MD_SIZE; + /* Config XIP mode bits*/ + QSPI->XIP_MODE_BITS = MODEBITS; + } + else + { + /* Clear XIP_MD_BIT_EN bit*/ + QSPI->SPI_CTRLR0 &= ~QSPI_SPI_CTRLR0_XIP_MD_BIT_EN ; + } +} + + +/** + * @brief Enables or disables the QSPI data/addr phase ddr mode . + * @param NewState: new state of the QSPI data/addr phase ddr mode. + * This parameter can be: ENABLE or DISABLE. + * Ddr_TXD: specifies the DDR mode driveing edge of transmit data. + * This parameter can be less than 0xFF. + * @retval None + */ + +void QSPI_Ddrcmd(uint32_t Ddr_TXD, FunctionalState NewState) +{ + + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + assert_param(IS_QSPI_DDR_DRIVE_EDGE(Ddr_TXD)); + if (NewState != DISABLE) + { + /* Set the SPI_DDR_EN bit*/ + QSPI->SPI_CTRLR0 |= QSPI_SPI_CTRLR0_SPI_DDR_EN ; + /* Set the TDE bit*/ + QSPI->DDR_DRIVE_EDGE = Ddr_TXD ; + } + else + { + /* Clear the SPI_DDR_EN bit*/ + QSPI->SPI_CTRLR0 &= ~QSPI_SPI_CTRLR0_SPI_DDR_EN ; + /* Clear the TDE bit*/ + QSPI->DDR_DRIVE_EDGE = 0 ; + } + +} + +/** + * @brief Enables or disables the QSPI instruction phase ddr mode . + * @param NewState: new state of the QSPI instruction phase ddr mode. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ + +void QSPI_InstDdrcmd(FunctionalState NewState) +{ + + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Set the INST_DDR_EN bit*/ + QSPI->SPI_CTRLR0 |= QSPI_SPI_CTRLR0_INST_DDR_EN ; + } + else + { + /* Clear the INST_DDR_EN bit*/ + QSPI->SPI_CTRLR0 &= ~QSPI_SPI_CTRLR0_INST_DDR_EN ; + } + +} + +/** + * @brief Enables or disables the QSPI XIP continous transfer . + * @param NewState: new state of the QSPI XIP continous transfer. + * This parameter can be: ENABLE or DISABLE. + * TIMOUT: specifies the XIP time out value in terms of hclk. + * This parameter can be less than 0xFF. + * @retval None + */ + +void QSPI_XIP_ContinuousCmd(uint32_t TIMOUT, FunctionalState NewState) +{ + + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + assert_param(IS_QSPI_XIP_TIMOUT(TIMOUT)); + + if (NewState != DISABLE) + { + /* Set the SSIC_XIP_CONT_XFER_EN bit*/ + QSPI->SPI_CTRLR0 |= QSPI_SPI_CTRLR0_SSIC_XIP_CONT_XFER_EN; + /* Set the XIP_CNT_TIME_OUT */ + QSPI->XIP_CNT_TIME_OUT = TIMOUT ; + } + else + { + /* Clear the SSIC_XIP_CONT_XFER_EN bit*/ + QSPI->SPI_CTRLR0 &= ~QSPI_SPI_CTRLR0_SSIC_XIP_CONT_XFER_EN; + } +} + + +/** + * @brief Enables or disables the QSPI XIP DFS Fix . + * @param NewState: new state of the QSPI XIP DFS fix. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ + +void QSPI_XIP_DFSHCCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Set the XIP_DFS_HC bit*/ + QSPI->SPI_CTRLR0 |= QSPI_SPI_CTRLR0_XIP_DFS_HC; + } + else + { + /* Clear the XIP_DFS_HC bit*/ + QSPI->SPI_CTRLR0 &= ~QSPI_SPI_CTRLR0_XIP_DFS_HC; + } + +} +/** + * @brief Enables or disables the QSPI CLK_LOOP_BACK MODE . + * @param NewState: new state of the QSPI clk loop back mode. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ + +void QSPI_CLK_LOOPCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Set the CLK_LOOP_EN bit*/ + QSPI->CTRLR0 |= QSPI_CTRLR0_CLK_LOOP_EN; + } + else + { + /* Clear the CLK_LOOP_EN bit*/ + QSPI->CTRLR0 &= ~QSPI_CTRLR0_CLK_LOOP_EN; + } + +} +/** + * @brief Config the rx sample delay mode . + * @param SE:specifies the receive data sample edge + * This parameter can be one of the following value: + * @arg QSPI_SAMPLE_NEGEDGE: sample negedge; + * @arg QSPI_SAMPLE_POSEDGE: sample posgedge; + * RSD:specifies the receive data sample delay. + * This parameter can be less than 0xFF . + * @retval None + */ +void QSPI_RX_SAMPLEDLYConfig(uint32_t SE, uint32_t RSD) +{ + + /* Check the parameters */ + assert_param(IS_QSPI_SAMPLE_DLY_EDGE(SE)); + assert_param(IS_QSPI_SAMPLE_DLY(RSD)); + + /* Clear SE and RSD bits*/ + QSPI->RX_SAMPLE_DELAY = 0; + /* Set SE and RSD bits*/ + QSPI->RX_SAMPLE_DELAY = (SE | RSD) ; +} + + +/** + * @brief Enables or disables the QSPI read data strobe mode. + * @param RXDS_VL_EN :specifies enable or disable variable latency mode. + * This parameter can be one of the following value: + * @arg QSPI_VARIABLE_LATEN_DIS: disable variable latency mode; + * @arg QSPI_VARIABLE_LATEN_EN: enable variable latency mode; + * @param NewState: new state of the QSPI read data strobe mod. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void QSPI_RXDSConfig(uint32_t RXDS_VL_EN, FunctionalState NewState) +{ + + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + assert_param(IS_QSPI_VL_EN(RXDS_VL_EN)); + + if (NewState != DISABLE) + { + /* Clear the RXDS_VL_EN,SPI_RXDS_EN bit*/ + QSPI->SPI_CTRLR0 &= ~(QSPI_SPI_CTRLR0_SPI_RXDS_EN | QSPI_SPI_CTRLR0_RXDS_VL_EN); + /* Set the RXDS_VL_EN,SPI_RXDS_EN bit*/ + QSPI->SPI_CTRLR0 |= QSPI_SPI_CTRLR0_SPI_RXDS_EN | RXDS_VL_EN ; + } + else + { + /* Clear the SPI_RXDS_EN bit*/ + QSPI->SPI_CTRLR0 &= ~QSPI_SPI_CTRLR0_SPI_RXDS_EN ; + } +} + +/** + * @brief Enables or disables the clk stretch mode . + * @param NewState: new state of clk stretch mode. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ + +void QSPI_CLK_StretchCmd(FunctionalState NewState) +{ + + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the CLK STRECTH */ + QSPI->SPI_CTRLR0 |= QSPI_SPI_CTRLR0_CLK_STRETCH_EN; + } + else + { + /* Disable the CLK STRECTH */ + QSPI->SPI_CTRLR0 &= ~QSPI_SPI_CTRLR0_CLK_STRETCH_EN; + } +} +/** + * @brief Enables or disables the specified QSPI interrupts. + * @param QSPI_IT: specifies the QSPI interrupt source to be enabled or disabled. + * This parameter can be one of the following values: + * @arg QSPI_IT_TXEIM: Tx buffer empty interrupt mask + * @arg QSPI_IT_TXOIM: Tx buffer overflow interrupt mask + * @arg QSPI_IT_RXUIM: Rx buffer underflow interrupt mask + * @arg QSPI_IT_RXOIM: Rx buffer overflow interrupt mask + * @arg QSPI_IT_RXFIM: Rx buffer full interrupt mask + * @arg QSPI_IT_TXUIM: Tx buffer underflow interrupt mask + * @param NewState: new state of the specified QSPI interrupt. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void QSPI_ITConfig(uint32_t QSPI_IT, FunctionalState NewState) +{ + uint16_t itmask = 0 ; + + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + assert_param(IS_QSPI_CONFIG_IT(QSPI_IT)); + + /* Clear all the interrupt enable*/ + QSPI->IMR = 0 ; + + /* Set the IT mask */ + itmask = QSPI_IT; + + if (NewState != DISABLE) + { + /* Enable the selected QSPI interrupt */ + QSPI->IMR |= itmask; + } + else + { + /* Disable the selected QSPI interrupt */ + QSPI->IMR &= (uint16_t)~itmask; + } +} + +/** + * @brief Returns the current QSPI FIFO status,busy status. + * @retval The status . + * - QSPI_STATE_BUSY: when QSPI is working + * - QSPI_STATE_TFNF: Tx buffer not full. + * - QSPI_STATE_TFE: Tx buffer empty. + * - QSPI_STATE_RFNE: Rx buffer not empty. + * - QSPI_STATE_RFF: Rx buffer full. + */ +uint32_t QSPI_GetStatus(uint16_t QSPI_SR_FLAG) +{ + /* Get the QSPI status */ + return (uint16_t)((QSPI->SR & QSPI_SR_FLAG)); +} + +/** + * @brief Returns the FIFO Interrupt status after mask. + * @retval The Reception FIFO filling state. + * - QSPI_FLAG_TXEIS: Tx FIFO is empty + * - QSPI_FLAG_TXOIS: Tx FIFO is overflow. + * - QSPI_FLAG_RXUIS: Rx FIFO is underflow. + * - QSPI_FLAG_RXOIS: Rx FIFO is overflow. + * - QSPI_FLAG_RXFIS: Rx FIFO is full. + * - QSPI_FLAG_TXUIS: Tx FIFO is underflow. + */ +uint32_t QSPI_GetAfterMaskInterruptStatus(uint16_t QSPI_ISR_FLAG) +{ + /* Get the QSPI interrupt status */ + return (uint32_t)((QSPI->ISR & QSPI_ISR_FLAG)); +} + +/** + * @brief Returns the FIFO Interrupt status before mask. + * @retval The Reception FIFO filling state. + * - QSPI_FLAG_TXEIR: Tx FIFO is empty + * - QSPI_FLAG_TXOIR: Tx FIFO is overflow. + * - QSPI_FLAG_RXUIR: Rx FIFO is underflow. + * - QSPI_FLAG_RXOIR: Rx FIFO is overflow. + * - QSPI_FLAG_RXFIR: Rx FIFO is full. + * - QSPI_FLAG_TXUIR: Tx FIFO is underflow. + */ +uint32_t QSPI_GetBeforeMaskInterruptStatusuint16_t (uint16_t QSPI_RISR_FLAG) +{ + /* Get the QSPI interrupt status */ + return (uint32_t)((QSPI->RISR & QSPI_RISR_FLAG)); +} + + + + +/** + * @brief Clears the QSPI TxFIFO Error flag. + * @retval None + */ +void QSPI_ClearTxFIFOErrorInterrupt(void) +{ + uint32_t data; + + /* Read TXEICR register to Clear the Tx FIFO overflow/underflow interrupt */ + data = QSPI->TXEICR; +} + +/** + * @brief Clears the QSPI RxFIFO overflow interrupt. + * @retval None + */ +void QSPI_ClearRxFIFOOverflowInterrupt(void) +{ + uint32_t data; + + /* Read RXOICR register to Clear the Rx FIFO overflow interrupt */ + data = QSPI->RXOICR; +} + +/** + * @brief Clears the QSPI RxFIFO underflow interrupt. + * @retval None + */ +void QSPI_ClearRxFIFOUnderflowInterrupt(void) +{ + uint32_t data; + + /* Read RXUICR register to Clear the Rx FIFO underflow interrupt */ + data = QSPI->RXUICR; +} + +/** + * @brief Clears the QSPI Tx overflow/underflow,Rx overflow/underflow interrupt. + * @retval None + */ +void QSPI_ClearFIFOFlowInterrupt(void) +{ + uint32_t data; + + /* Read ICR register to Clear the FIFO flow interrupt */ + data = QSPI->ICR; +} + + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_rcc.c b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_rcc.c new file mode 100644 index 00000000000..12a3a96b92a --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_rcc.c @@ -0,0 +1,2730 @@ +/** + ****************************************************************************** + * @file ft32f4xx_rcc.c + * @author Rwang + * @brief This file provides firmware functions to manage the following + * functionalities of the Reset and clock control (RCC) peripheral: + * + Internal/external clocks, PLL, CSS and MCO configuration + * + System, AHB and APB busses clocks configuration + * + Peripheral clocks configuration + * + Interrupts and flags management + * @version V1.0.0 + * @data 2025-03-28 + ****************************************************************************** + */ + + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx_rcc.h" + + +/* ---------------------- RCC registers mask -------------------------------- */ +/* RCC Flag Mask */ +#define FLAG_MASK ((uint8_t)0x1F) + +/* CR register byte 2 (Bits[23:16]) base address */ +#define CR_BYTE2_ADDRESS ((uint32_t)0x40023802) + +/* CFGR register byte 3 (Bits[31:24]) base address */ +#define CFGR_BYTE3_ADDRESS ((uint32_t)0x4002380F) + +/* CIR register byte 1 (Bits[15:8]) base address */ +#define CIR_BYTE1_ADDRESS ((uint32_t)0x40023811) + +/* CIR register byte 2 (Bits[23:16]) base address */ +#define CIR_BYTE2_ADDRESS ((uint32_t)0x40023812) + +static __I uint8_t APBAHBPrescTable[16] = {0, 0, 0, 0, 1, 2, 3, 4, 1, 2, 3, 4, 6, 7, 8, 9}; + +/** + * @brief Resets the RCC clock configuration to the default reset state. + * @note The default reset state of the clock configuration is given below: + * @note HSI ON and used as system clock source + * @note HSI48, HSE and PLL OFF + * @note AHB, APB prescaler set to 1. + * @note CSS and MCO OFF + * @note All interrupts disabled + * @note However, this function doesn't modify the configuration of the + * @note Peripheral clocks LSI, LSE and RTC clocks + * @param None + * @retval None + */ +void RCC_DeInit(void) +{ + /* Set HSION bit */ + RCC->CR |= (uint32_t)0x00000001; + + /* Reset SW[1:0], HPRE[3:0], PPRE1[2:0], PPRE2[2:0], MCOSEL[2:0], MCOPRE[2:0] bits */ + RCC->CFGR &= (uint32_t)0x80FFC00C; + + /* Reset HSEON, CSSON, PLLON and PLL2ON bits */ + RCC->CR &= (uint32_t)0xFAF6FFFF; + + /* Reset HSEBYP bit */ + RCC->CR &= (uint32_t)0xFFFBFFFF; + + /* Reset PLLR[2:0], PLLREN, PLLQ[3:0], PLLQEN, PLLP[2:0], PLLPEN, PLLSRC, PLLN[7:0], and PLLM[4:0] bits */ + RCC->PLLCFGR &= (uint32_t)0xE0008020; + + /* Reset PLL2R[2:0], PLL2REN, PLL2Q[3:0], PLL2QEN, PLL2SRC, PLL2N[7:0], and PLL2M[4:0] bits */ + RCC->PLL2CFGR &= (uint32_t)0xE00F8020; + + /* Reset QSPISEL[1:0], ADC123SEL[1:0], CANSEL[3:0], LPTIMSEL[1:0], + * I2C3SEL[1:0], I2C2SEL[1:0], I2C1SEL[1:0], LPUARTSEL RNGDIV[1:0], + * CLK48SEL, PWMSEL[1:0], EQEPSEL[1:0], ECAPSEL[1:0], and I2SSEL bits */ + RCC->CCIPR &= (uint32_t)0x00F00400; + + /* Reset HSI48ON bit */ + RCC->CR2 &= (uint32_t)0xFFFEFFFF; + + /* Reset RAMSEL */ + RCC->RAMCTL &= (uint32_t)0xFFFFFFC0; + + /* Disable all interrupts */ + RCC->CIR = 0x00000000; +} + +/** + * @brief Configures 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. + * @param RCC_HSE: specifies the new state of the HSE. + * This parameter can be one of the following values: + * @arg RCC_HSE_OFF: turn OFF the HSE oscillator, HSERDY flag goes low after + * 6 HSE oscillator clock cycles. + * @arg RCC_HSE_ON: turn ON the HSE oscillator, HSERDY flag gose high after + * 512 HSE oscillator clock cycles. + * @arg RCC_HSE_Bypass: HSE oscillator bypassed with external clock + * @retval None + */ +void RCC_HSEConfig(uint32_t RCC_HSE) +{ + /* Check the parameters */ + assert_param(IS_RCC_HSE(RCC_HSE)); + + /* Reset HSEON and HSEBYP bits before configuring the HSE ------------------*/ + RCC->CR &= (uint32_t)(~RCC_HSE_Bypass); + + /* Set the new HSE configuration -------------------------------------------*/ + RCC->CR |= RCC_HSE; + +} + +/** + * @brief Waits for HSE start up. + * @note This function waits on HSERDY flag to be set and return SUCCESS if + * this flag is set, otherwise returns ERROR if the timeout is reached + * and this flag is not set. The timeout value is defined by the constant + * HSE_STARTUP_TIMEOUT in ft32f4xx.h file. You can tailor it depending + * on the HSE crystal used in your application. + * @note The HSE is stopped by hardware when entering STOP and STANDBY modes. + * @param None + * @retval An ErrorStatus enumeration value: + * - SUCCESS: HSE oscillator is stable and ready to use + * - ERROR: HSE oscillator not yet ready + */ +ErrorStatus RCC_WaitForHSEStartUp(void) +{ + __IO uint32_t StartUpCounter = 0; + ErrorStatus status = ERROR; + FlagStatus HSEStatus = RESET; + + /* Wait till HSE is ready and if timeout is reached exit */ + do + { + HSEStatus = RCC_GetFlagStatus(RCC_FLAG_REG_CR, RCC_FLAG_HSERDY); + StartUpCounter++; + } + while ((StartUpCounter != HSE_STARTUP_TIMEOUT) && (HSEStatus == RESET)); + + if (RCC_GetFlagStatus(RCC_FLAG_REG_CR, RCC_FLAG_HSERDY) != RESET) + { + status = SUCCESS; + } + else + { + status = ERROR; + } + return (status); +} + +/** + * @brief Adjusts the Internal High Speed 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. + * Refer to the Application Note AN4067 for more details on how to + * calibrate the HSI. + * @param HSICalibrationValue: specifies the HSI calibration trimming value. + * This parameter must be a number between 0 and 0x1F. + * @retval None + */ +void RCC_AdjustHSICalibrationValue(uint8_t HSICalibrationValue) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RCC_HSI_CALIBRATION_VALUE(HSICalibrationValue)); + + tmpreg = RCC->CR; + + /* Clear HSITRIM[4:0] bits */ + tmpreg &= ~RCC_CR_HSITRIM; + + /* Set the HSITRIM[4:0] bits according to HSICalibrationValue value */ + tmpreg |= ((uint32_t)HSICalibrationValue << 3); + + /* Store the new value */ + RCC->CR = tmpreg; +} + +/** + * @brief Enables or disables the Internal High Speed oscillator (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 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 NewState: new state of the HSI. + * This parameter can be: ENABLE or DISABLE. + * @note When the HSI is stopped, HSIRDY flag goes low after 6 HSI oscillator + * clock cycles. + * @retval None + */ +void RCC_HSICmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + RCC->CR |= RCC_CR_HSION; + } + else + { + RCC->CR &= ~RCC_CR_HSION; + } +} + +/** + * @brief Waits for HSI start up. + * @note This function waits on HSIRDY flag to be set and return SUCCESS if + * this flag is set, otherwise returns ERROR if the timeout is reached + * and this flag is not set. The timeout value is defined by the constant + * HSI_STARTUP_TIMEOUT in ft32f4xx.h file. You can tailor it depending + * on the HSI crystal used in your application. + * @note The HSI is stopped by hardware when entering STOP and STANDBY modes. + * @param None + * @retval An ErrorStatus enumeration value: + * - SUCCESS: HSU oscillator is stable and ready to use + * - ERROR: HSI oscillator not yet ready + */ +ErrorStatus RCC_WaitForHSIStartUp(void) +{ + __IO uint32_t StartUpCounter = 0; + ErrorStatus status = ERROR; + FlagStatus HSIStatus = RESET; + + /* Wait till HSI is ready and if timeout is reached exit */ + do + { + HSIStatus = RCC_GetFlagStatus(RCC_FLAG_REG_CR, RCC_FLAG_HSIRDY); + StartUpCounter++; + } + while ((StartUpCounter != HSI_STARTUP_TIMEOUT) && (HSIStatus == RESET)); + + if (RCC_GetFlagStatus(RCC_FLAG_REG_CR, RCC_FLAG_HSIRDY) != RESET) + { + status = SUCCESS; + } + else + { + status = ERROR; + } + return (status); +} + +/** + * @brief Adjusts the Internal High Speed oscillator for ADC (HSI48) + * 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. + * Refer to the Application Note AN4067 for more details on how to + * calibrate the HSI48. + * @param HSI48CalibrationValue: specifies the HSI48 calibration trimming value. + * This parameter must be a number between 0 and 0x1FF. + * @retval None + */ +void RCC_AdjustHSI48CalibrationValue(uint32_t HSI48CalibrationValue) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RCC_HSI48_CALIBRATION_VALUE(HSI48CalibrationValue)); + + tmpreg = RCC->CR2; + + /* Clear HSI48CAL[8:0] bits */ + tmpreg &= ~RCC_CR2_HSI48CAL; + + /* Set the HSICAL48[8:0] bits according to HSI48CalibrationValue value */ + tmpreg |= ((uint32_t)HSI48CalibrationValue << 23); + + /* Store the new value */ + RCC->CR2 = tmpreg; +} + +/** + * @brief Enables or disables the Internal High Speed oscillator for ADC (HSI48). + * @note After enabling the HSI48, the application software should wait on + * HSI48RDY flag to be set indicating that HSI clock is stable and can + * be used to clock the ADC. + * @note The HSI48 is stopped by hardware when entering STOP and STANDBY modes. + * @param NewState: new state of the HSI48. + * This parameter can be: ENABLE or DISABLE. + * @note When the HSI48 is stopped, HSI48RDY flag goes low after 6 HSI14 oscillator + * clock cycles. + * @retval None + */ +void RCC_HSI48Cmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + RCC->CR2 |= RCC_CR2_HSI48ON; + } + else + { + RCC->CR2 &= ~RCC_CR2_HSI48ON; + } +} + +/** + * @brief Waits for HSI48 start up. + * @note This function waits on HSI48RDY flag to be set and return SUCCESS if + * this flag is set, otherwise returns ERROR if the timeout is reached + * and this flag is not set. The timeout value is defined by the constant + * HSI48_STARTUP_TIMEOUT in ft32f4xx.h file. You can tailor it depending + * on the HSI48 crystal used in your application. + * @note The HSI48 is stopped by hardware when entering STOP and STANDBY modes. + * @param None + * @retval An ErrorStatus enumeration value: + * - SUCCESS: HSI48 oscillator is stable and ready to use + * - ERROR: HSI48 oscillator not yet ready + */ +ErrorStatus RCC_WaitForHSI48StartUp(void) +{ + __IO uint32_t StartUpCounter = 0; + ErrorStatus status = ERROR; + FlagStatus HSI48Status = RESET; + + /* Wait till HSI48 is ready and if timeout is reached exit */ + do + { + HSI48Status = RCC_GetFlagStatus(RCC_FLAG_REG_CR2, RCC_FLAG_HSI48RDY); + StartUpCounter++; + } + while ((StartUpCounter != HSI48_STARTUP_TIMEOUT) && (HSI48Status == RESET)); + + if (RCC_GetFlagStatus(RCC_FLAG_REG_CR2, RCC_FLAG_HSI48RDY) != RESET) + { + status = SUCCESS; + } + else + { + status = ERROR; + } + return (status); +} + + +/** + * @brief Configures the External Low Speed oscillator (LSE). + * @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 + * PWR_BackupAccessCmd(ENABLE) function before to configure the LSE + * (to be done once after reset). + * @note After enabling the LSE (RCC_LSE_ON or RCC_LSE_Bypass), the application + * software should wait on LSERDY flag to be set indicating that LSE clock + * is stable and can be used to clock the RTC. + * @param RCC_LSE: specifies the new state of the LSE. + * This parameter can be one of the following values: + * @arg RCC_LSE_OFF: turn OFF the LSE oscillator, LSERDY flag goes low after + * 6 LSE oscillator clock cycles. + * @arg RCC_LSE_ON: turn ON the LSE oscillator after 4096 clock cycle stable + * @arg RCC_LSE_BYP: LSE oscillator bypassed with external clock + * @retval None + */ +void RCC_LSEConfig(uint32_t RCC_LSE) +{ + /* Check the parameters */ + assert_param(IS_RCC_LSE(RCC_LSE)); + + /* Reset LSEON and LSEBYP bits before configuring the LSE ------------------*/ + /* Reset LSEON bit */ + RCC->BDCR &= ~(RCC_BDCR_LSEON); + + /* Reset LSEBYP bit */ + RCC->BDCR &= ~(RCC_BDCR_LSEBYP); + + /* Configure LSE */ + RCC->BDCR |= RCC_LSE | RCC_LSEDrive_MediumLow; +} + +/** + * @brief Waits for LSE start up. + * @note This function waits on LSERDY flag to be set and return SUCCESS if + * this flag is set, otherwise returns ERROR if the timeout is reached + * and this flag is not set. The timeout value is defined by the constant + * LSE_STARTUP_TIMEOUT in ft32f4xx.h file. You can tailor it depending + * on the LSE crystal used in your application. + * @note The LSE is stopped by hardware when entering STOP and STANDBY modes. + * @param None + * @retval An ErrorStatus enumeration value: + * - SUCCESS: LSE oscillator is stable and ready to use + * - ERROR: LSE oscillator not yet ready + */ +ErrorStatus RCC_WaitForLSEStartUp(void) +{ + __IO uint32_t StartUpCounter = 0; + ErrorStatus status = ERROR; + FlagStatus LSEStatus = RESET; + + /* Wait till LSE is ready and if timeout is reached exit */ + do + { + LSEStatus = RCC_GetFlagStatus(RCC_FLAG_REG_BDCR, RCC_FLAG_LSERDY); + StartUpCounter++; + } + while ((StartUpCounter != LSE_STARTUP_TIMEOUT) && (LSEStatus == RESET)); + + if (RCC_GetFlagStatus(RCC_FLAG_REG_BDCR, RCC_FLAG_LSERDY) != RESET) + { + status = SUCCESS; + } + else + { + status = ERROR; + } + return (status); +} + +/** + * @brief Configures the External Low Speed oscillator (LSE) drive capability. + * @param RCC_LSEDrive: specifies the new state of the LSE drive capability. + * This parameter can be one of the following values: + * @arg RCC_LSEDrive_Low: LSE oscillator low drive capability. + * @arg RCC_LSEDrive_MediumLow: LSE oscillator medium low drive capability. + * @arg RCC_LSEDrive_MediumHigh: LSE oscillator medium high drive capability. + * @arg RCC_LSEDrive_High: LSE oscillator high drive capability. + * @retval None + */ +void RCC_LSEDriveConfig(uint32_t RCC_LSEDrive) +{ + /* Check the parameters */ + assert_param(IS_RCC_LSE_DRIVE(RCC_LSEDrive)); + + /* Clear LSEDRV[1:0] bits */ + RCC->BDCR &= ~(RCC_BDCR_LSEDRV); + + /* Set the LSE Drive */ + RCC->BDCR |= RCC_LSEDrive; +} + +/** + * @brief Enables or disables 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. + * @param NewState: new state of the LSI. + * This parameter can be: ENABLE or DISABLE. + * @note When the LSI is stopped, LSIRDY flag goes low after 6 LSI oscillator + * clock cycles. + * @retval None + */ +void RCC_LSICmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + RCC->CSR |= RCC_CSR_LSION; + } + else + { + RCC->CSR &= ~RCC_CSR_LSION; + } +} + +/** + * @brief Waits for LSI start up. + * @note This function waits on LSIRDY flag to be set and return SUCCESS if + * this flag is set, otherwise returns ERROR if the timeout is reached + * and this flag is not set. The timeout value is defined by the constant + * LSI_STARTUP_TIMEOUT in ft32f4xx.h file. You can tailor it depending + * on the LSI crystal used in your application. + * @param None + * @retval An ErrorStatus enumeration value: + * - SUCCESS: LSI oscillator is stable and ready to use + * - ERROR: LSI oscillator not yet ready + */ +ErrorStatus RCC_WaitForLSIStartUp(void) +{ + __IO uint32_t StartUpCounter = 0; + ErrorStatus status = ERROR; + FlagStatus LSIStatus = RESET; + + /* Wait till LSI is ready and if timeout is reached exit */ + do + { + LSIStatus = RCC_GetFlagStatus(RCC_FLAG_REG_CSR, RCC_FLAG_LSIRDY); + StartUpCounter++; + } + while ((StartUpCounter != LSI_STARTUP_TIMEOUT) && (LSIStatus == RESET)); + + if (RCC_GetFlagStatus(RCC_FLAG_REG_CSR, RCC_FLAG_LSIRDY) != RESET) + { + status = SUCCESS; + } + else + { + status = ERROR; + } + return (status); +} + +/** + * @brief Configures the PLL clock source, multiplication and null factor. + * @note This function must be used only when the PLL is disabled. + * @param RCC_PLLSource: specifies the PLL entry clock source. + * This parameter can be one of the following values: + * @arg RCC_PLLSource_HSI: HSI oscillator clock selected as PLL clock source + * @arg RCC_PLLSource_HSE: HSE oscillator clock selected as PLL clock source + * @note The minimum input clock frequency for PLL is 2 MHz + * @param RCC_PLLNul: specifies the PLL multiplication factor, which drive the PLLVCO clock + * This parameter must be a number between 0 and 0xFF. + * @param RCC_PLLMul: specifies the PLL Division factor, which drive the PLLVCO clock + * This parameter must be a number between 0 and 0x1F. + * @retval None + */ +void RCC_PLLVcoOutputConfig(uint32_t RCC_PLLSource, uint32_t RCC_PLLNul, uint32_t RCC_PLLMul) +{ + /* Check the parameters */ + assert_param(IS_RCC_PLLSRC(RCC_PLLSource)); + assert_param(IS_RCC_PLLN_VALUE(RCC_PLLNul)); + assert_param(IS_RCC_PLLM_VALUE(RCC_PLLMul)); + + /* Clear PLLSRC[14], PLLN[7:0], and PLLM[4:0] bits */ + RCC->PLLCFGR &= ~(RCC_PLLCFGR_PLLSRC | RCC_PLLCFGR_PLLN | RCC_PLLCFGR_PLLM); + + /* Set the PLL Source PLLN and PLLM */ + RCC->PLLCFGR |= (uint32_t)(((uint32_t)RCC_PLLSource << 14) | + ((uint32_t)RCC_PLLNul << 6) | + ((uint32_t)RCC_PLLMul)); +} + +/** + * @brief Configures the PLLR clock enable, division factor. + * @note This function must be used only when the PLL is disabled. + * @param RCC_PLLRstatus: specifies the PLLR enable or disable. + * This parameter can be one of the following values: + * @arg RCC_PLLR_OFF: PLLR clock disable + * @arg RCC_PLLR_ON: PLLR clock enable + * @param RCC_PLLR: specifies the PLLR division factor + * This parameter must be a number between 0 and 0x07. + * @retval None + */ +void RCC_PLLROutputConfig(uint32_t RCC_PLLRStatus, uint32_t RCC_PLLR) +{ + /* Check the parameters */ + assert_param(IS_RCC_PLLR(RCC_PLLRStatus)); + assert_param(IS_RCC_PLLR_VALUE(RCC_PLLR)); + + /* Clear PLLR[2:0], PLLREN bits */ + RCC->PLLCFGR &= ~(RCC_PLLCFGR_PLLR | RCC_PLLCFGR_PLLREN); + + /* Set the PLLREN and PLLR[2:0] */ + RCC->PLLCFGR |= (uint32_t)(((uint32_t)RCC_PLLRStatus << 25) | + ((uint32_t)RCC_PLLR << 26)); +} + +/** + * @brief Configures the PLLQ clock enable, division factor. + * @note This function must be used only when the PLL is disabled. + * @param RCC_PLLQstatus: specifies the PLLQ enable or disable. + * This parameter can be one of the following values: + * @arg RCC_PLLQ_OFF: PLLQ clock disable + * @arg RCC_PLLQ_ON: PLLQ clock enable + * @param RCC_PLLQ: specifies the PLLQ division factor + * This parameter must be a number between 0 and 0x0F. + * @retval None + */ +void RCC_PLLQOutputConfig(uint32_t RCC_PLLQStatus, uint32_t RCC_PLLQ) +{ + /* Check the parameters */ + assert_param(IS_RCC_PLLQ(RCC_PLLQStatus)); + assert_param(IS_RCC_PLLQ_VALUE(RCC_PLLQ)); + + /* Clear PLLQ[3:0], PLLQEN bits */ + RCC->PLLCFGR &= ~(RCC_PLLCFGR_PLLQ | RCC_PLLCFGR_PLLQEN); + + /* Set the PLLQEN and PLLQ[3:0] */ + RCC->PLLCFGR |= (uint32_t)(((uint32_t)RCC_PLLQStatus << 20) | + ((uint32_t)RCC_PLLQ << 21)); +} + +/** + * @brief Configures the PLLP clock enable, division factor. + * @note This function must be used only when the PLL is disabled. + * @param RCC_PLLPstatus: specifies the PLLP enable or disable. + * This parameter can be one of the following values: + * @arg RCC_PLLP_OFF: PLLP clock disable + * @arg RCC_PLLP_ON: PLLP clock enable + * @param RCC_PLLP: specifies the PLLP division factor + * This parameter must be a number between 0 and 0x07. + * @retval None + */ +void RCC_PLLPOutputConfig(uint32_t RCC_PLLPStatus, uint32_t RCC_PLLP) +{ + /* Check the parameters */ + assert_param(IS_RCC_PLLP(RCC_PLLPStatus)); + assert_param(IS_RCC_PLLP_VALUE(RCC_PLLP)); + + /* Clear PLLP[2:0], PLLPEN bits */ + RCC->PLLCFGR &= ~(RCC_PLLCFGR_PLLP | RCC_PLLCFGR_PLLPEN); + + /* Set the PLLPEN and PLLP[2:0] */ + RCC->PLLCFGR |= (uint32_t)(((uint32_t)RCC_PLLPStatus << 16) | + ((uint32_t)RCC_PLLP << 17)); +} + +/** + * @brief Configures the PLL2 clock source, multiplication and null factor. + * @note This function must be used only when the PLL is disabled. + * @param RCC_PLL2Source: specifies the PLL entry clock source. + * This parameter can be one of the following values: + * @arg RCC_PLL2Source_HSI: HSI oscillator clock selected as PLL2 clock source + * @arg RCC_PLL2Source_HSE: HSE oscillator clock selected as PLL2 clock source + * @note The minimum input clock frequency for PLL2 is 2 MHz + * @param RCC_PLL2Nul: specifies the PLL2 multiplication factor, which drive the PLL2VCO clock + * This parameter must be a number between 0 and 0xFF. + * @param RCC_PLL2Mul: specifies the PLL2 Division factor, which drive the PLL2VCO clock + * This parameter must be a number between 0 and 0x1F. + * @retval None + */ +void RCC_PLL2VcoOutputConfig(uint32_t RCC_PLL2Source, uint32_t RCC_PLL2Nul, uint32_t RCC_PLL2Mul) +{ + /* Check the parameters */ + assert_param(IS_RCC_PLL2SRC(RCC_PLL2Source)); + assert_param(IS_RCC_PLL2N_VALUE(RCC_PLL2Nul)); + assert_param(IS_RCC_PLL2M_VALUE(RCC_PLL2Mul)); + + /* Clear PLL2SRC[14], PLL2N[7:0], and PLL2M[4:0] bits */ + RCC->PLL2CFGR &= ~(RCC_PLL2CFGR_PLL2SRC | RCC_PLL2CFGR_PLL2N | RCC_PLL2CFGR_PLL2M); + + /* Set the PLL2 Source, PLL2N and PLL2M */ + RCC->PLL2CFGR |= (uint32_t)(((uint32_t)RCC_PLL2Source << 14) | + ((uint32_t)RCC_PLL2Nul << 6) | + ((uint32_t)RCC_PLL2Mul)); +} + +/** + * @brief Configures the PLL2R clock enable, division factor. + * @note This function must be used only when the PLL2 is disabled. + * @param RCC_PLL2Rstatus: specifies the PLL2R enable or disable. + * This parameter can be one of the following values: + * @arg RCC_PLL2R_OFF: PLL2R clock disable + * @arg RCC_PLL2R_ON: PLL2R clock enable + * @param RCC_PLL2R: specifies the PLL2R division factor + * This parameter must be a number between 0 and 0x07. + * @retval None + */ +void RCC_PLL2ROutputConfig(uint32_t RCC_PLL2RStatus, uint32_t RCC_PLL2R) +{ + /* Check the parameters */ + assert_param(IS_RCC_PLL2R(RCC_PLL2RStatus)); + assert_param(IS_RCC_PLL2R_VALUE(RCC_PLL2R)); + + /* Clear PLL2R[2:0], PLL2REN bits */ + RCC->PLL2CFGR &= ~(RCC_PLL2CFGR_PLL2R | RCC_PLL2CFGR_PLL2REN); + + /* Set the PLL2REN and PLL2R[2:0] */ + RCC->PLL2CFGR |= (uint32_t)(((uint32_t)RCC_PLL2RStatus << 25) | + ((uint32_t)RCC_PLL2R << 26)); +} + +/** + * @brief Configures the PLL2Q clock enable, division factor. + * @note This function must be used only when the PLL2 is disabled. + * @param RCC_PLL2Qstatus: specifies the PLL2Q enable or disable. + * This parameter can be one of the following values: + * @arg RCC_PLL2Q_OFF: PLL2Q clock disable + * @arg RCC_PLL2Q_ON: PLL2Q clock enable + * @param RCC_PLL2Q: specifies the PLL2Q division factor + * This parameter must be a number between 0 and 0x0F. + * @retval None + */ +void RCC_PLL2QOutputConfig(uint32_t RCC_PLL2QStatus, uint32_t RCC_PLL2Q) +{ + /* Check the parameters */ + assert_param(IS_RCC_PLL2Q(RCC_PLL2QStatus)); + assert_param(IS_RCC_PLL2Q_VALUE(RCC_PLL2Q)); + + /* Clear PLL2Q[3:0], PLL2QEN bits */ + RCC->PLL2CFGR &= ~(RCC_PLL2CFGR_PLL2Q | RCC_PLL2CFGR_PLL2QEN); + + /* Set the PLL2QEN and PLL2Q[3:0] */ + RCC->PLL2CFGR |= (uint32_t)(((uint32_t)RCC_PLL2QStatus << 20) | + ((uint32_t)RCC_PLL2Q << 21)); +} + + +/** + * @brief Enables or disables the PLL. + * @note After enabling the PLL, the application software should wait on + * PLLRDY flag to be set indicating that PLL clock is stable and can + * be used as system clock source. + * @note The PLL can not be disabled if it is used as system clock source + * @note The PLL is disabled by hardware when entering STOP and STANDBY modes. + * @param RCC_PLLSelect: select enable pll or pll2. + * This parameter can be one of the following values: + * @arg RCC_SEL_PLL: PLL clock enable + * @arg RCC_SEL_PLL2: PLL2 clock enable + * @param NewState: new state of the PLL. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_PLLCmd(uint32_t RCC_PLLSelect, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_SEL(RCC_PLLSelect)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (RCC_PLLSelect == RCC_SEL_PLL) + { + if (NewState != DISABLE) + { + RCC->CR |= RCC_CR_PLLON; + } + else + { + RCC->CR &= ~RCC_CR_PLLON; + } + } + else if (RCC_PLLSelect == RCC_SEL_PLL2) + { + if (NewState != DISABLE) + { + RCC->CR |= RCC_CR_PLL2ON; + } + else + { + RCC->CR &= ~RCC_CR_PLL2ON; + } + } +} + +/** + * @brief Waits for PLL start up. + * @note This function waits on PLLRDY flag to be set and return SUCCESS if + * this flag is set, otherwise returns ERROR if the timeout is reached + * and this flag is not set. The timeout value is defined by the constant + * PLL_STARTUP_TIMEOUT in ft32f4xx.h file. You can tailor it depending + * on the PLL crystal used in your application. + * @param None + * @retval An ErrorStatus enumeration value: + * - SUCCESS: PLL oscillator is stable and ready to use + * - ERROR: PLL oscillator not yet ready + */ +ErrorStatus RCC_WaitForPLLStartUp(void) +{ + __IO uint32_t StartUpCounter = 0; + ErrorStatus status = ERROR; + FlagStatus PLLStatus = RESET; + + /* Wait till PLL is ready and if timeout is reached exit */ + do + { + PLLStatus = RCC_GetFlagStatus(RCC_FLAG_REG_CR, RCC_FLAG_PLLRDY); + StartUpCounter++; + } + while ((StartUpCounter != PLL_STARTUP_TIMEOUT) && (PLLStatus == RESET)); + + if (RCC_GetFlagStatus(RCC_FLAG_REG_CR, RCC_FLAG_PLLRDY) != RESET) + { + status = SUCCESS; + } + else + { + status = ERROR; + } + return (status); +} + +/** + * @brief Waits for PLL2 start up. + * @note This function waits on PLL2RDY flag to be set and return SUCCESS if + * this flag is set, otherwise returns ERROR if the timeout is reached + * and this flag is not set. The timeout value is defined by the constant + * PLL2_STARTUP_TIMEOUT in ft32f4xx.h file. You can tailor it depending + * on the PLL2 crystal used in your application. + * @param None + * @retval An ErrorStatus enumeration value: + * - SUCCESS: PLL2 oscillator is stable and ready to use + * - ERROR: PLL2 oscillator not yet ready + */ +ErrorStatus RCC_WaitForPLL2StartUp(void) +{ + __IO uint32_t StartUpCounter = 0; + ErrorStatus status = ERROR; + FlagStatus PLL2Status = RESET; + + /* Wait till PLL2 is ready and if timeout is reached exit */ + do + { + PLL2Status = RCC_GetFlagStatus(RCC_FLAG_REG_CR, RCC_FLAG_PLL2RDY); + StartUpCounter++; + } + while ((StartUpCounter != PLL2_STARTUP_TIMEOUT) && (PLL2Status == RESET)); + + if (RCC_GetFlagStatus(RCC_FLAG_REG_CR, RCC_FLAG_PLL2RDY) != RESET) + { + status = SUCCESS; + } + else + { + status = ERROR; + } + return (status); +} + +/** + * @brief Enables or disables 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-M0 NMI (Non-Maskable Interrupt) exception vector. + * @param NewState: new state of the Clock Security System. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_ClockSecuritySystemCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + RCC->CR |= RCC_CR_CSSON; + } + else + { + RCC->CR &= ~RCC_CR_CSSON; + } +} + +/** + * @brief Selects the clock source to output on MCO pin (PA8) and the corresponding + * prescsaler. + * @note PA8 should be configured in alternate function mode(AF0). + * @param RCC_MCOSource: specifies the clock source to output. + * This parameter can be one of the following values: + * @arg RCC_MCOSource_NoClock: No clock selected. + * @arg RCC_MCOSource_SYSCLK: System clock selected. + * @arg RCC_MCOSource_PLL2R: PLL2R clock selected. + * @arg RCC_MCOSource_HSI16: HSI16 oscillator clock selected. + * @arg RCC_MCOSource_HSE: HSE oscillator clock selected. + * @arg RCC_MCOSource_PLLP: PLLP clock selected. + * @arg RCC_MCOSource_LSI: LSI oscillator clock selected. + * @arg RCC_MCOSource_LSE: LSE oscillator clock selected. + * @arg RCC_MCOSource_HSI48: HSI48 clock selected. + * @param RCC_MCOPrescaler: specifies the prescaler on MCO pin. + * This parameter can be one of the following values: + * @arg RCC_MCOPrescaler_1: MCO clock is divided by 1. + * @arg RCC_MCOPrescaler_2: MCO clock is divided by 2. + * @arg RCC_MCOPrescaler_4: MCO clock is divided by 4. + * @arg RCC_MCOPrescaler_8: MCO clock is divided by 8. + * @arg RCC_MCOPrescaler_16: MCO clock is divided by 16. + * @arg RCC_MCOPrescaler_32: MCO clock is divided by 32. + * @arg RCC_MCOPrescaler_64: MCO clock is divided by 64. + * @arg RCC_MCOPrescaler_128: MCO clock is divided by 128. + * @retval None + */ +void RCC_MCOConfig(uint32_t RCC_MCOSource, uint32_t RCC_MCOPrescaler) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RCC_MCO_SOURCE(RCC_MCOSource)); + assert_param(IS_RCC_MCO_PRESCALER(RCC_MCOPrescaler)); + + /* Get CFGR value */ + tmpreg = RCC->CFGR; + /* Clear MCOPRE[2:0] and MCOSEL[3:0] bits */ + tmpreg &= ~(RCC_CFGR_MCOPRE | RCC_CFGR_MCOSEL); + /* Set the RCC_MCOSource and RCC_MCOPrescaler */ + tmpreg |= (RCC_MCOSource | RCC_MCOPrescaler); + /* Store the new value */ + RCC->CFGR = tmpreg; +} +/** + * @} + */ + +/** + * @brief Configures the system clock (SYSCLK). + * @note The HSI is used (enabled by hardware) as system clock source after + * startup 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 startup 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 RCC_GetSYSCLKSource() function to know which clock is + * currently used as system clock source. + * @param RCC_SYSCLKSource: specifies the clock source used as system clock source + * This parameter can be one of the following values: + * @arg RCC_SYSCLKSource_HSI16: HSI16 selected as system clock source + * @arg RCC_SYSCLKSource_HSE: HSE selected as system clock source + * @arg RCC_SYSCLKSource_PLLCLK: PLL selected as system clock source + * @retval None + */ +void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RCC_SYSCLK_SOURCE(RCC_SYSCLKSource)); + + tmpreg = RCC->CFGR; + + /* Clear SW[1:0] bits */ + tmpreg &= ~RCC_CFGR_SW; + + /* Set SW[1:0] bits according to RCC_SYSCLKSource value */ + tmpreg |= RCC_SYSCLKSource; + + /* Store the new value */ + RCC->CFGR = tmpreg; +} + +/** + * @brief Returns the clock source used as system clock. + * @param None + * @retval The clock source used as system clock. The returned value can be one + * of the following values: + * - 0x00000000: HSI16 used as system clock + * - 0x00000004: HSE used as system clock + * - 0x00000008: PLL used as system clock + */ +uint32_t RCC_GetSYSCLKSource(void) +{ + return ((uint32_t)(RCC->CFGR & RCC_CFGR_SWS)); +} + +/** + * @brief Configures the AHB clock (HCLK). + * @param RCC_SYSCLK: defines the AHB clock divider. This clock is derived from + * the system clock (SYSCLK). + * This parameter can be one of the following values: + * @arg RCC_SYSCLK_DIV1: AHB clock = SYSCLK + * @arg RCC_SYSCLK_DIV2: AHB clock = SYSCLK/2 + * @arg RCC_SYSCLK_DIV4: AHB clock = SYSCLK/4 + * @arg RCC_SYSCLK_DIV8: AHB clock = SYSCLK/8 + * @arg RCC_SYSCLK_DIV16: AHB clock = SYSCLK/16 + * @arg RCC_SYSCLK_DIV64: AHB clock = SYSCLK/64 + * @arg RCC_SYSCLK_DIV128: AHB clock = SYSCLK/128 + * @arg RCC_SYSCLK_DIV256: AHB clock = SYSCLK/256 + * @arg RCC_SYSCLK_DIV512: AHB clock = SYSCLK/512 + * @retval None + */ +void RCC_HCLKConfig(uint32_t RCC_SYSCLK) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RCC_HCLK(RCC_SYSCLK)); + + tmpreg = RCC->CFGR; + + /* Clear HPRE[3:0] bits */ + tmpreg &= ~RCC_CFGR_HPRE; + + /* Set HPRE[3:0] bits according to RCC_SYSCLK value */ + tmpreg |= RCC_SYSCLK; + + /* Store the new value */ + RCC->CFGR = tmpreg; +} + +/** + * @brief Configures the APB clock (PCLK). + * @param RCC_HCLK1: defines the APB clock divider. This clock is derived from + * the AHB clock (HCLK). + * This parameter can be one of the following values: + * @arg RCC_HCLK_DIV1: APB clock = HCLK + * @arg RCC_HCLK_DIV2: APB clock = HCLK/2 + * @arg RCC_HCLK_DIV4: APB clock = HCLK/4 + * @arg RCC_HCLK_DIV8: APB clock = HCLK/8 + * @arg RCC_HCLK_DIV16: APB clock = HCLK/16 + * @retval None + */ +void RCC_PCLK1Config(uint32_t RCC_HCLK1) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RCC_PCLK(RCC_HCLK1)); + + tmpreg = RCC->CFGR; + + /* Clear PPRE1[2:0] bits */ + tmpreg &= ~RCC_CFGR_PPRE1; + + /* Set PPRE1[2:0] bits according to RCC_HCLK value */ + tmpreg |= ((uint32_t)RCC_HCLK1 << 8); + + /* Store the new value */ + RCC->CFGR = tmpreg; +} + +/** + * @brief Configures the APB clock (PCLK). + * @param RCC_HCLK2: defines the APB clock divider. This clock is derived from + * the AHB clock (HCLK). + * This parameter can be one of the following values: + * @arg RCC_HCLK_DIV1: APB clock = HCLK + * @arg RCC_HCLK_DIV2: APB clock = HCLK/2 + * @arg RCC_HCLK_DIV4: APB clock = HCLK/4 + * @arg RCC_HCLK_DIV8: APB clock = HCLK/8 + * @arg RCC_HCLK_DIV16: APB clock = HCLK/16 + * @retval None + */ +void RCC_PCLK2Config(uint32_t RCC_HCLK2) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RCC_PCLK(RCC_HCLK2)); + + tmpreg = RCC->CFGR; + + /* Clear PPRE[2:0] bits */ + tmpreg &= ~RCC_CFGR_PPRE2; + + /* Set PPRE2[2:0] bits according to RCC_HCLK value */ + tmpreg |= ((uint32_t)RCC_HCLK2 << 11); + + /* Store the new value */ + RCC->CFGR = tmpreg; +} + +/** + * @brief Configures the QSPI clock (QSPICLK). + * @note This function is obsolete. + * For proper QSPI clock selection, refer to QSPI_ClockModeConfig() in the QSPI driver + * @param RCC_QSPICLK: defines the QSPI clock source. This clock is derived + * from the HSI16, PLL1Q or SYSCLK. + * This parameter can be one of the following values: + * @arg RCC_QSPICLK_SYSCLK: QSPI clock = SYSCLK + * @arg RCC_QSPICLK_HSI16: QSPI clock = HSI16 + * @arg RCC_QSPICLK_PLL1Q: QSPI clock = PLL1Q + * @retval None + */ +void RCC_QSPICLKConfig(uint32_t RCC_QSPICLK) +{ + /* Check the parameters */ + assert_param(IS_RCC_QSPICLK(RCC_QSPICLK)); + + /* Clear QSPISEL[1:0] bitS */ + RCC->CCIPR &= ~RCC_CCIPR_QSPISEL; + + /* Set QSPISEL bits according to RCC_QSPICLK value */ + RCC->CCIPR |= RCC_QSPICLK; +} + +/** + * @brief Configures the ADC clock (ADCCLK). + * @note This function is obsolete. + * For proper ADC clock selection, refer to ADC_ClockModeConfig() in the ADC driver + * @param RCC_ADCCLK: defines the ADC clock source. This clock is derived + * from the PLL1R or SYSCLK. + * This parameter can be one of the following values: + * @arg RCC_ADCCLK_NOCLK: ADC no clock + * @arg RCC_ADCCLK_PLL1R: ADC clock = PLL1R + * @arg RCC_ADCCLK_SYSCLK: ADC clock = SYSCLK + * @retval None + */ +void RCC_ADCCLKConfig(uint32_t RCC_ADCCLK) +{ + /* Check the parameters */ + assert_param(IS_RCC_ADCCLK(RCC_ADCCLK)); + + /* Clear ADC123SEL[1:0] bitS */ + RCC->CCIPR &= ~RCC_CCIPR_ADCSEL; + + /* Set ADCSEL bits according to RCC_ADCCLK value */ + RCC->CCIPR |= RCC_ADCCLK; +} + +/** + * @brief Configures the CAN clock (CANCLK). + * @note This function is obsolete. + * For proper CAN clock selection, refer to CAN_ClockModeConfig() in the CAN driver + * @param RCC_CANCLK: defines the CAN clock source. This clock is derived + * from the HCLK or HCLK's prescaler. + * This parameter can be one of the following values: + * @arg RCC_CANCLK_HCLK: CAN clock = HCLK + * @arg RCC_CANCLK_HCLK_DIV2: CAN clock = HCLK/2 + * @arg RCC_CANCLK_HCLK_DIV4: CAN clock = HCLK/4 + * @arg RCC_CANCLK_HCLK_DIV8: CAN clock = HCLK/8 + * @arg RCC_CANCLK_HCLK_DIV16: CAN clock = HCLK/16 + * @arg RCC_CANCLK_HCLK_DIV32: CAN clock = HCLK/32 + * @retval None + */ +void RCC_CANCLKConfig(uint32_t RCC_CANCLK) +{ + /* Check the parameters */ + assert_param(IS_RCC_CANCLK(RCC_CANCLK)); + + /* Clear CANSEL[3:0] bits */ + RCC->CCIPR &= ~RCC_CCIPR_CANSEL; + + /* Set CANSEL bits according to RCC_CANCLK value */ + RCC->CCIPR |= RCC_CANCLK; +} + +/** + * @brief Configures the LPTIM clock (LPTIMCLK). + * @note This function is obsolete. + * For proper LPTIM clock selection, refer to LPTIM_ClockModeConfig() in the LPTIM driver + * @param RCC_LPTIMCLK: defines the LPTIM clock source. This clock is derived + * from the PCLK, LSI, HSI16 or LSE prescaler. + * This parameter can be one of the following values: + * @arg RCC_LPTIMCLK_PCLK: LPTIM clock = PCLK + * @arg RCC_LPTIMCLK_LSI: LPTIM clock = LSI + * @arg RCC_LPTIMCLK_HSI16: LPTIM clock = HSI16 + * @arg RCC_LPTIMCLK_LSE: LPTIM clock = LSE + * @retval None + */ +void RCC_LPTIMCLKConfig(uint32_t RCC_LPTIMCLK) +{ + /* Check the parameters */ + assert_param(IS_RCC_LPTIMCLK(RCC_LPTIMCLK)); + + /* Clear LPTIMSEL[1:0] bits */ + RCC->CCIPR &= ~RCC_CCIPR_LPTIMSEL; + + /* Set LPTIMSEL bits according to RCC_LPTIMCLK value */ + RCC->CCIPR |= RCC_LPTIMCLK; +} + +/** + * @brief Configures the I2C3 clock (I2C3CLK). + * @note This function is obsolete. + * For proper I2C3 clock selection, refer to I2C3_ClockModeConfig() in the I2C3 driver + * @param RCC_I2C3CLK: defines the I2C3 clock source. This clock is derived + * from the PCLK, SYSCLK or HSI16. + * This parameter can be one of the following values: + * @arg RCC_I2C3CLK_PCLK: I2C3 clock = PCLK + * @arg RCC_I2C3CLK_SYSCLK: I2C3 clock = SYSCLK + * @arg RCC_I2C3CLK_HSI16: I2C3 clock = HSI16 + * @retval None + */ +void RCC_I2C3CLKConfig(uint32_t RCC_I2C3CLK) +{ + /* Check the parameters */ + assert_param(IS_RCC_I2C3CLK(RCC_I2C3CLK)); + + /* Clear I2C3SEL[1:0] bits */ + RCC->CCIPR &= ~RCC_CCIPR_I2C3SEL; + + /* Set I2C3SEL bits according to RCC_I2C3CLK value */ + RCC->CCIPR |= RCC_I2C3CLK; +} + +/** + * @brief Configures the I2C2 clock (I2C2CLK). + * @note This function is obsolete. + * For proper I2C2 clock selection, refer to I2C2_ClockModeConfig() in the I2C2 driver + * @param RCC_I2C2CLK: defines the I2C2 clock source. This clock is derived + * from the PCLK, SYSCLK or HSI16. + * This parameter can be one of the following values: + * @arg RCC_I2C2CLK_PCLK: I2C2 clock = PCLK + * @arg RCC_I2C2CLK_SYSCLK: I2C2 clock = SYSCLK + * @arg RCC_I2C2CLK_HSI16: I2C2 clock = HSI16 + * @retval None + */ +void RCC_I2C2CLKConfig(uint32_t RCC_I2C2CLK) +{ + /* Check the parameters */ + assert_param(IS_RCC_I2C2CLK(RCC_I2C2CLK)); + + /* Clear I2C2SEL[1:0] bits */ + RCC->CCIPR &= ~RCC_CCIPR_I2C2SEL; + + /* Set I2C2SEL bits according to RCC_I2C2CLK value */ + RCC->CCIPR |= RCC_I2C2CLK; +} + +/** + * @brief Configures the I2C1 clock (I2C1CLK). + * @note This function is obsolete. + * For proper I2C1 clock selection, refer to I2C1_ClockModeConfig() in the I2C1 driver + * @param RCC_I2C1CLK: defines the I2C1 clock source. This clock is derived + * from the PCLK, SYSCLK or HSI16. + * This parameter can be one of the following values: + * @arg RCC_I2C1CLK_PCLK: I2C1 clock = PCLK + * @arg RCC_I2C1CLK_SYSCLK: I2C1 clock = SYSCLK + * @arg RCC_I2C1CLK_HSI16: I2C1 clock = HSI16 + * @retval None + */ +void RCC_I2C1CLKConfig(uint32_t RCC_I2C1CLK) +{ + /* Check the parameters */ + assert_param(IS_RCC_I2C1CLK(RCC_I2C1CLK)); + + /* Clear I2C1SEL[1:0] bits */ + RCC->CCIPR &= ~RCC_CCIPR_I2C1SEL; + + /* Set I2C1SEL bits according to RCC_I2C1CLK value */ + RCC->CCIPR |= RCC_I2C1CLK; +} + +/** + * @brief Configures the LPUART clock (LPUARTCLK). + * @note This function is obsolete. + * For proper LPUART clock selection, refer to LPUART_ClockModeConfig() in the LPUART driver + * @param RCC_LPUARTCLK: defines the LPUART clock source. This clock is derived + * from the PCLK or LSE. + * This parameter can be one of the following values: + * @arg RCC_LPUARTCLK_PCLK: LPUART clock = PCLK + * @arg RCC_LPUARTCLK_LSE: LPUART clock = LSE + * @retval None + */ +void RCC_LPUARTCLKConfig(uint32_t RCC_LPUARTCLK) +{ + /* Check the parameters */ + assert_param(IS_RCC_LPUARTCLK(RCC_LPUARTCLK)); + + /* Clear LPUARTSEL[1:0] bits */ + RCC->CCIPR &= ~RCC_CCIPR_LPUARTSEL; + + /* Set LPUARTSEL bits according to RCC_LPUARTCLK value */ + RCC->CCIPR |= RCC_LPUARTCLK; +} + +/** + * @brief Configures the RNG clock division(RNGCLKDIV). + * @note This function is obsolete. + * For proper RNG clock selection, refer to RNG_ClockModeConfig() in the RNG driver + * @param RCC_RNGCLKDIV: defines the RNG clock division. This clock is derived + * from the work clk's 1/2/4/8. + * This parameter can be one of the following values: + * @arg RCC_RNGCLK_DIV1: RNG clock = RNG work clock/1 + * @arg RCC_RNGCLK_DIV2: RNG clock = RNG work clock/2 + * @arg RCC_RNGCLK_DIV4: RNG clock = RNG work clock/4 + * @arg RCC_RNGCLK_DIV8: RNG clock = RNG work clock/8 + * @retval None + */ +void RCC_RNGCLKDIVConfig(uint32_t RCC_RNGCLKDIV) +{ + /* Check the parameters */ + assert_param(IS_RCC_RNGCLK_DIV(RCC_RNGCLKDIV)); + + /* Clear RNGDIV[1:0] bits */ + RCC->CCIPR &= ~RCC_CCIPR_RNGDIV; + + /* Set RNGDIV[1:0] bits according to RCC_RNGCLKDIV value */ + RCC->CCIPR |= RCC_RNGCLKDIV; +} + +/** + * @brief Configures the 48M clock source(48MCLK). + * @note This function is obsolete. + * For proper 48M clock selection + * @param RCC_48MCLK: defines the 48M clock source. This clock is derived + * from the HSI48 or PLLQ . + * This parameter can be one of the following values: + * @arg RCC_48MCLK_HSI48: 48M clock = HSI48 + * @arg RCC_48MCLK_PLLQ: 48M clock = PLLQ + * @retval None + */ +void RCC_48MCLKConfig(uint32_t RCC_48MCLK) +{ + /* Check the parameters */ + assert_param(IS_RCC_48MCLK(RCC_48MCLK)); + + /* Clear CLK48SEL bit */ + RCC->CCIPR &= ~RCC_CCIPR_CLK48SEL; + + /* Set CLK48SEL bits according to RCC_48MCLK value */ + RCC->CCIPR |= RCC_48MCLK; +} + +/** + * @brief Configures the EPWM clock source(EPWMCLK). + * @note This function is obsolete. + * For proper EPWM clock selection + * @param RCC_EPWMCLK: defines the EPWM clock source. This clock is derived + * from the SYSCLK or SYSCLK/2/4 . + * This parameter can be one of the following values: + * @arg RCC_EPWMCLK_SYSCLK: EPWM clock = SYSCLK + * @arg RCC_EPWMCLK_SYSCLK_DIV2: EPWM clock = SYSCLK/2 + * @arg RCC_EPWMCLK_SYSCLK_DIV4: EPWM clock = SYSCLK/4 + * @retval None + */ +void RCC_EPWMCLKConfig(uint32_t RCC_EPWMCLK) +{ + /* Check the parameters */ + assert_param(IS_RCC_EPWMCLK(RCC_EPWMCLK)); + + /* Clear PWMSEL[1:0] bit */ + RCC->CCIPR &= ~RCC_CCIPR_PWMSEL; + + /* Set PWMSEL bits according to RCC_EPWMCLK value */ + RCC->CCIPR |= RCC_EPWMCLK; +} + +/** + * @brief Configures the EQEP clock source(EQEPCLK). + * @note This function is obsolete. + * For proper EQEP clock selection + * @param RCC_EQEPCLK: defines the EQEP clock source. This clock is derived + * from the SYSCLK or SYSCLK/2/4 . + * This parameter can be one of the following values: + * @arg RCC_EQEPCLK_SYSCLK: EQEP clock = SYSCLK + * @arg RCC_EQEPCLK_SYSCLK_DIV2: EQEP clock = SYSCLK/2 + * @arg RCC_EQEPCLK_SYSCLK_DIV4: EQEP clock = SYSCLK/4 + * @retval None + */ +void RCC_EQEPCLKConfig(uint32_t RCC_EQEPCLK) +{ + /* Check the parameters */ + assert_param(IS_RCC_EQEPCLK(RCC_EQEPCLK)); + + /* Clear EQEPSEL[1:0] bit */ + RCC->CCIPR &= ~RCC_CCIPR_EQEPSEL; + + /* Set EQEPSEL bits according to RCC_EQEPCLK value */ + RCC->CCIPR |= RCC_EQEPCLK; +} + +/** + * @brief Configures the ECAP clock source(ECAPCLK). + * @note This function is obsolete. + * For proper ECAP clock selection + * @param RCC_ECAPCLK: defines the ECAP clock source. This clock is derived + * from the SYSCLK or SYSCLK/2/4 . + * This parameter can be one of the following values: + * @arg RCC_ECAPCLK_SYSCLK: ECAP clock = SYSCLK + * @arg RCC_ECAPCLK_SYSCLK_DIV2: ECAP clock = SYSCLK/2 + * @arg RCC_ECAPCLK_SYSCLK_DIV4: ECAP clock = SYSCLK/4 + * @retval None + */ +void RCC_ECAPCLKConfig(uint32_t RCC_ECAPCLK) +{ + /* Check the parameters */ + assert_param(IS_RCC_ECAPCLK(RCC_ECAPCLK)); + + /* Clear ECAPSEL[1:0] bit */ + RCC->CCIPR &= ~RCC_CCIPR_ECAPSEL; + + /* Set ECAPSEL bits according to RCC_ECAPCLK value */ + RCC->CCIPR |= RCC_ECAPCLK; +} + +/** + * @brief Configures the I2S clock source(I2SCLK). + * @note This function is obsolete. + * For proper I2S clock selection + * @param RCC_I2SCLK: defines the I2S clock source. This clock is derived + * from the PLL2Q or external I2S_CKIN . + * This parameter can be one of the following values: + * @arg RCC_I2SCLK_PLL2Q: I2S clock = PLL2Q + * @arg RCC_I2SCLK_I2S_CLKIN: I2S clock = EXTERNAL I2S_CKIN + * @retval None + */ +void RCC_I2SCLKConfig(uint32_t RCC_I2SCLK) +{ + /* Check the parameters */ + assert_param(IS_RCC_I2SCLK(RCC_I2SCLK)); + + /* Clear I2SSEL bit */ + RCC->CCIPR &= ~RCC_CCIPR_I2SSEL; + + /* Set I2SSEL bits according to RCC_I2SCLK value */ + RCC->CCIPR |= RCC_I2SCLK; +} + + + +/** + * @brief Returns the frequencies of the System, AHB and APB busses clocks. + * @note The frequency returned by this function is not the real frequency + * in the chip. It is calculated based on the predefined constant and + * the source selected by RCC_SYSCLKConfig(): + * + * @note If SYSCLK source is HSI16, function returns constant HSI_VALUE(*) + * + * @note If SYSCLK source is HSE, function returns constant HSE_VALUE(**) + * + * @note If SYSCLK source is PLL, function returns constant HSE_VALUE(**) + * or HSI_VALUE(*) multiplied by the PLLN and PLLM factors. + * + * @note (*) HSI_VALUE is a constant defined in ft32f0xx.h file (default value + * 16 MHz) but the real value may vary depending on the variations + * in voltage and temperature, refer to RCC_AdjustHSICalibrationValue(). + * + * @note (**) HSE_VALUE is a constant defined in ft32f0xx.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 + * return wrong result. + * + * @note (***) HSI48_VALUE is a constant defined in ft32f0xx.h file (default value + * 48 MHz) but the real value may vary depending on the variations + * in voltage and temperature. + * + * @note The result of this function could be not correct when using fractional + * value for HSE crystal. + * + * @param RCC_Clocks: pointer to a RCC_ClocksTypeDef structure which will hold + * the clocks frequencies. + * + * @note This function can be used by the user application to compute the + * baudrate for the communication peripherals or configure other parameters. + * @note Each time SYSCLK, HCLK and/or PCLK clock changes, this function + * must be called to update the structure's field. Otherwise, any + * configuration based on this function will be incorrect. + * + * @retval None + */ +void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks) +{ + uint32_t tmp = 0, pllmul = 0, pllnul = 0, pllp = 0, pllr = 0, pllq = 0, pllsource = 0, pllvcoclk = 0, pllpclk = 0, + pll2mul = 0, pll2nul = 0, pll2r = 0, pll2q = 0, pll2source = 0, pll2vcoclk = 0, + hpresc = 0, presc1 = 0, presc2 = 0; + + /* Get SYSCLK source -------------------------------------------------------*/ + tmp = RCC->CFGR & RCC_CFGR_SWS; + + switch (tmp) + { + case 0x00: /* HSI used as system clock */ + RCC_Clocks->SYSCLK_Frequency = HSI_VALUE; + break; + + case 0x04: /* HSE used as system clock */ + RCC_Clocks->SYSCLK_Frequency = HSE_VALUE; + break; + + case 0x08: /* PLL used as system clock */ + /* Get PLL clock source and pllm and plln factor ----------------------*/ + pllp = (((RCC -> PLLCFGR) & RCC_PLLCFGR_PLLP) >> 17); + pllsource = (((RCC -> PLLCFGR) & RCC_PLLCFGR_PLLSRC) >> 14); + pllnul = (((RCC -> PLLCFGR) & RCC_PLLCFGR_PLLN) >> 6); + pllmul = (RCC -> PLLCFGR) & RCC_PLLCFGR_PLLM; + if (pllsource == 0x00) + { + /* HSI oscillator clock divided by pllmul and multiplicat by pllnul as pllvcoclk output */ + pllvcoclk = (HSI_VALUE * pllnul) / pllmul; + if (pllp == 0) + { + pllpclk = pllvcoclk / 2; + } + else + { + pllpclk = pllvcoclk / (pllp + 1); + } + } + else + { + /* HSE oscillator clock divided by pllmul and multiplicat by pllnul as pllvcoclk output */ + pllvcoclk = (HSE_VALUE * pllnul) / pllmul; + if (pllp == 0) + { + pllpclk = pllvcoclk / 2; + } + else + { + pllpclk = pllvcoclk / (pllp + 1); + } + } + + RCC_Clocks->SYSCLK_Frequency = pllpclk; + break; + + default: /* HSI used as system clock */ + RCC_Clocks->SYSCLK_Frequency = HSI_VALUE; + break; + } + + /* Compute HCLK, PCLK and P2CLK clocks frequencies */ + /* Get HCLK prescaler */ + tmp = RCC->CFGR & RCC_CFGR_HPRE; + tmp = tmp >> 4; + hpresc = APBAHBPrescTable[tmp]; + /* HCLK clock frequency */ + RCC_Clocks->HCLK_Frequency = ((RCC_Clocks->SYSCLK_Frequency) >> hpresc); + + /* Get PCLK prescaler */ + tmp = RCC->CFGR & RCC_CFGR_PPRE1; + tmp = tmp >> 8; + presc1 = APBAHBPrescTable[tmp]; + /* PCLK clock frequency */ + RCC_Clocks->PCLK_Frequency = ((RCC_Clocks->HCLK_Frequency) >> presc1); + /* Get PLLQ and PLLR clk */ + pllr = (((RCC -> PLLCFGR) & RCC_PLLCFGR_PLLR) >> 26); + pllq = (((RCC -> PLLCFGR) & RCC_PLLCFGR_PLLQ) >> 21); + pllsource = (((RCC -> PLLCFGR) & RCC_PLLCFGR_PLLSRC) >> 14); + pllnul = (((RCC -> PLLCFGR) & RCC_PLLCFGR_PLLN) >> 6); + pllmul = (RCC -> PLLCFGR) & RCC_PLLCFGR_PLLM; + if (pllsource == 0x00) + { + /* HSI oscillator clock divided by pllmul and multiplicat by pllnul as pllvcoclk output */ + pllvcoclk = (HSI_VALUE * pllnul) / pllmul; + if (pllq == 0) + { + RCC_Clocks->PLLQ_Frequency = pllvcoclk / 2; + } + else + { + RCC_Clocks->PLLQ_Frequency = pllvcoclk / (pllq + 1); + } + if (pllr == 0) + { + RCC_Clocks->PLLR_Frequency = pllvcoclk / 2; + } + else + { + RCC_Clocks->PLLR_Frequency = pllvcoclk / (pllr + 1); + } + } + else + { + /* HSE oscillator clock divided by pllmul and multiplicat by pllnul as pllvcoclk output */ + pllvcoclk = (HSE_VALUE * pllnul) / pllmul; + if (pllq == 0) + { + RCC_Clocks->PLLQ_Frequency = pllvcoclk / 2; + } + else + { + RCC_Clocks->PLLQ_Frequency = pllvcoclk / (pllq + 1); + } + if (pllr == 0) + { + RCC_Clocks->PLLR_Frequency = pllvcoclk / 2; + } + else + { + RCC_Clocks->PLLR_Frequency = pllvcoclk / (pllr + 1); + } + } + + /* Get P2CLK prescaler */ + tmp = RCC->CFGR & RCC_CFGR_PPRE2; + tmp = tmp >> 11; + presc2 = APBAHBPrescTable[tmp]; + /* PCLK clock frequency */ + RCC_Clocks->P2CLK_Frequency = ((RCC_Clocks->HCLK_Frequency) >> presc2); + /* Get PLL2Q and PLL2R clk */ + pll2r = (((RCC -> PLL2CFGR) & RCC_PLL2CFGR_PLL2R) >> 26); + pll2q = (((RCC -> PLL2CFGR) & RCC_PLL2CFGR_PLL2Q) >> 21); + pll2source = (((RCC -> PLL2CFGR) & RCC_PLL2CFGR_PLL2SRC) >> 14); + pll2nul = (((RCC -> PLL2CFGR) & RCC_PLL2CFGR_PLL2N) >> 6); + pll2mul = (RCC -> PLL2CFGR) & RCC_PLL2CFGR_PLL2M; + if (pll2source == 0x00) + { + /* HSI oscillator clock divided by pll2mul and multiplicat by pll2nul as pll2vcoclk output */ + pll2vcoclk = (HSI_VALUE * pll2nul) / pll2mul; + if (pll2q == 0) + { + RCC_Clocks->PLLQ_Frequency = pllvcoclk / 2; + } + else + { + RCC_Clocks->PLLQ_Frequency = pllvcoclk / (pll2q + 1); + } + if (pll2r == 0) + { + RCC_Clocks->PLLR_Frequency = pllvcoclk / 2; + } + else + { + RCC_Clocks->PLLR_Frequency = pllvcoclk / (pll2r + 1); + } + } + else + { + /* HSE oscillator clock divided by pll2mul and multiplicat by pll2nul as pll2vcoclk output */ + pll2vcoclk = (HSE_VALUE * pll2nul) / pll2mul; + if (pll2q == 0) + { + RCC_Clocks->PLLQ_Frequency = pllvcoclk / 2; + } + else + { + RCC_Clocks->PLLQ_Frequency = pllvcoclk / (pll2q + 1); + } + if (pll2r == 0) + { + RCC_Clocks->PLLR_Frequency = pllvcoclk / 2; + } + else + { + RCC_Clocks->PLLR_Frequency = pllvcoclk / (pll2r + 1); + } + } + + /* QSPICLK clock frequency */ + if ((RCC->CCIPR & RCC_CCIPR_QSPISEL) == RESET) + { + RCC_Clocks->QSPICLK_Frequency = RCC_Clocks->SYSCLK_Frequency ; + } + else if ((RCC->CCIPR & RCC_CCIPR_QSPISEL) == RCC_CCIPR_QSPISEL_HSI16) + { + RCC_Clocks->QSPICLK_Frequency = HSI_VALUE; + } + else if ((RCC->CCIPR & RCC_CCIPR_QSPISEL) == RCC_CCIPR_QSPISEL_PLLQ) + { + RCC_Clocks->QSPICLK_Frequency = RCC_Clocks->PLLQ_Frequency; + } + + /* ADCCLK clock frequency */ + if ((RCC->CCIPR & RCC_CCIPR_ADCSEL) == RESET) + { + RCC_Clocks->ADCCLK_Frequency = RESET ; + } + else if ((RCC->CCIPR & RCC_CCIPR_ADCSEL) == RCC_CCIPR_ADCSEL_PLLR) + { + RCC_Clocks->ADCCLK_Frequency = RCC_Clocks->PLLR_Frequency; + } + else if ((RCC->CCIPR & RCC_CCIPR_ADCSEL) == RCC_CCIPR_ADCSEL_SYS) + { + RCC_Clocks->ADCCLK_Frequency = RCC_Clocks->SYSCLK_Frequency; + } + + /* CANCLK clock frequency */ + if ((RCC->CCIPR & RCC_CCIPR_CANSEL) == RCC_CCIPR_CANSEL_HD2) + { + RCC_Clocks->CANCLK_Frequency = (RCC_Clocks->HCLK_Frequency >> 1); + } + else if ((RCC->CCIPR & RCC_CCIPR_CANSEL) == RCC_CCIPR_CANSEL_HD4) + { + RCC_Clocks->CANCLK_Frequency = (RCC_Clocks->HCLK_Frequency >> 2); + } + else if ((RCC->CCIPR & RCC_CCIPR_CANSEL) == RCC_CCIPR_CANSEL_HD8) + { + RCC_Clocks->CANCLK_Frequency = (RCC_Clocks->HCLK_Frequency >> 3); + } + else if ((RCC->CCIPR & RCC_CCIPR_CANSEL) == RCC_CCIPR_CANSEL_HD16) + { + RCC_Clocks->CANCLK_Frequency = (RCC_Clocks->HCLK_Frequency >> 4); + } + else if ((RCC->CCIPR & RCC_CCIPR_CANSEL) == RCC_CCIPR_CANSEL_HD32) + { + RCC_Clocks->CANCLK_Frequency = (RCC_Clocks->HCLK_Frequency >> 5); + } + else + { + RCC_Clocks->CANCLK_Frequency = RCC_Clocks->HCLK_Frequency; + } + + /* LPTIMCLK clock frequency */ + if ((RCC->CCIPR & RCC_CCIPR_LPTIMSEL) == RCC_CCIPR_LPTIMSEL_PCLK) + { + RCC_Clocks->LPTIMCLK_Frequency = RCC_Clocks->PCLK_Frequency; + } + else if ((RCC->CCIPR & RCC_CCIPR_LPTIMSEL) == RCC_CCIPR_LPTIMSEL_LSI) + { + RCC_Clocks->LPTIMCLK_Frequency = LSI_VALUE; + } + else if ((RCC->CCIPR & RCC_CCIPR_LPTIMSEL) == RCC_CCIPR_LPTIMSEL_HSI16) + { + RCC_Clocks->LPTIMCLK_Frequency = HSI_VALUE; + } + else if ((RCC->CCIPR & RCC_CCIPR_LPTIMSEL) == RCC_CCIPR_LPTIMSEL_LSE) + { + RCC_Clocks->LPTIMCLK_Frequency = LSE_VALUE; + } + + /* I2C3CLK clock frequency */ + if ((RCC->CCIPR & RCC_CCIPR_I2C3SEL) == RCC_CCIPR_I2C3SEL_PCLK) + { + RCC_Clocks->I2C3CLK_Frequency = RCC_Clocks->PCLK_Frequency; + } + else if ((RCC->CCIPR & RCC_CCIPR_I2C3SEL) == RCC_CCIPR_I2C3SEL_SYS) + { + RCC_Clocks->I2C3CLK_Frequency = RCC_Clocks->SYSCLK_Frequency; + } + else if ((RCC->CCIPR & RCC_CCIPR_I2C3SEL) == RCC_CCIPR_I2C3SEL_HSI16) + { + RCC_Clocks->I2C3CLK_Frequency = HSI_VALUE; + } + + /* I2C2CLK clock frequency */ + if ((RCC->CCIPR & RCC_CCIPR_I2C2SEL) == RCC_CCIPR_I2C2SEL_PCLK) + { + RCC_Clocks->I2C2CLK_Frequency = RCC_Clocks->PCLK_Frequency; + } + else if ((RCC->CCIPR & RCC_CCIPR_I2C2SEL) == RCC_CCIPR_I2C2SEL_SYS) + { + RCC_Clocks->I2C2CLK_Frequency = RCC_Clocks->SYSCLK_Frequency; + } + else if ((RCC->CCIPR & RCC_CCIPR_I2C2SEL) == RCC_CCIPR_I2C2SEL_HSI16) + { + RCC_Clocks->I2C2CLK_Frequency = HSI_VALUE; + } + + /* I2C1CLK clock frequency */ + if ((RCC->CCIPR & RCC_CCIPR_I2C1SEL) == RCC_CCIPR_I2C1SEL_PCLK) + { + RCC_Clocks->I2C1CLK_Frequency = RCC_Clocks->PCLK_Frequency; + } + else if ((RCC->CCIPR & RCC_CCIPR_I2C1SEL) == RCC_CCIPR_I2C1SEL_SYS) + { + RCC_Clocks->I2C1CLK_Frequency = RCC_Clocks->SYSCLK_Frequency; + } + else if ((RCC->CCIPR & RCC_CCIPR_I2C1SEL) == RCC_CCIPR_I2C1SEL_HSI16) + { + RCC_Clocks->I2C1CLK_Frequency = HSI_VALUE; + } + + /* LPUARTCLK clock frequency */ + if ((RCC->CCIPR & RCC_CCIPR_LPUARTSEL) == RCC_CCIPR_LPUARTSEL_PCLK) + { + RCC_Clocks->LPUARTCLK_Frequency = RCC_Clocks->PCLK_Frequency; + } + else if ((RCC->CCIPR & RCC_CCIPR_LPUARTSEL) == RCC_CCIPR_LPUARTSEL_LSE) + { + RCC_Clocks->LPUARTCLK_Frequency = LSE_VALUE; + } + + /* PWMCLK clock frequency */ + if ((RCC->CCIPR & RCC_CCIPR_PWMSEL) == RCC_CCIPR_PWMSEL_SYS) + { + RCC_Clocks->PWMCLK_Frequency = RCC_Clocks->SYSCLK_Frequency; + } + else if ((RCC->CCIPR & RCC_CCIPR_PWMSEL) == RCC_CCIPR_PWMSEL_SYSD2) + { + RCC_Clocks->PWMCLK_Frequency = (RCC_Clocks->SYSCLK_Frequency >> 1); + } + else if ((RCC->CCIPR & RCC_CCIPR_PWMSEL) == RCC_CCIPR_PWMSEL_SYSD4) + { + RCC_Clocks->PWMCLK_Frequency = (RCC_Clocks->SYSCLK_Frequency >> 2); + } + + /* EQEPCLK clock frrequency */ + if ((RCC->CCIPR & RCC_CCIPR_EQEPSEL) == RCC_CCIPR_EQEPSEL_SYS) + { + RCC_Clocks->EQEPCLK_Frequency = RCC_Clocks->SYSCLK_Frequency; + } + else if ((RCC->CCIPR & RCC_CCIPR_EQEPSEL) == RCC_CCIPR_EQEPSEL_SYSD2) + { + RCC_Clocks->EQEPCLK_Frequency = (RCC_Clocks->SYSCLK_Frequency >> 1); + } + else if ((RCC->CCIPR & RCC_CCIPR_EQEPSEL) == RCC_CCIPR_EQEPSEL_SYSD4) + { + RCC_Clocks->EQEPCLK_Frequency = (RCC_Clocks->SYSCLK_Frequency >> 2); + } + + /* ECAPCLK clock frrequency */ + if ((RCC->CCIPR & RCC_CCIPR_ECAPSEL) == RCC_CCIPR_ECAPSEL_SYS) + { + RCC_Clocks->ECAPCLK_Frequency = RCC_Clocks->SYSCLK_Frequency; + } + else if ((RCC->CCIPR & RCC_CCIPR_ECAPSEL) == RCC_CCIPR_ECAPSEL_SYSD2) + { + RCC_Clocks->ECAPCLK_Frequency = (RCC_Clocks->SYSCLK_Frequency >> 1); + } + else if ((RCC->CCIPR & RCC_CCIPR_ECAPSEL) == RCC_CCIPR_ECAPSEL_SYSD4) + { + RCC_Clocks->ECAPCLK_Frequency = (RCC_Clocks->SYSCLK_Frequency >> 2); + } + + /* I2SCLK clock frequency */ + if ((RCC->CCIPR & RCC_CCIPR_I2SSEL) == RESET) + { + RCC_Clocks->I2SCLK_Frequency = RCC_Clocks->PLL2Q_Frequency; + } + else + { + RCC_Clocks->I2SCLK_Frequency = ((uint32_t)0x00000000);//I2S_CKIN; + } +} +/** + * @} + */ + +/** + * @brief Configures the LSCO clock (LSCOCLK). + * @note As the LSCO 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 PWR_BackupAccessCmd(ENABLE) function before to configure + * the LSCO clock source (to be done once after reset). + * @param RCC_LSCOCLKSource: specifies the LSCO clock source. + * This parameter can be one of the following values: + * @arg RCC_LSCOCLK_LSE: LSE selected as LSCO clock + * @arg RCC_LSCOCLK_LSI: LSI selected as LSCO clock + * @retval None + */ +void RCC_LSCOCLKConfig(uint32_t RCC_LSCOCLKSource) +{ + /* Check the parameters */ + assert_param(IS_RCC_LSCOCLK_SRC(RCC_LSCOCLKSource)); + + /* Select the LSCO clock source */ + RCC->BDCR |= RCC_LSCOCLKSource; +} + +/** + * @brief Enables or disables the LSCO clock. + * @note This function must be used only after the LSCO clock source was selected + * using the RCC_LSCOCLKConfig function. + * @param NewState: new state of the RTC clock. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_LSCOCLKCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + RCC->BDCR |= RCC_LSCOCLK_ON; + } + else + { + RCC->BDCR &= ~RCC_LSCOCLK_ON; + } +} + +/** + * @brief Configures 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 PWR_BackupAccessCmd(ENABLE) function before to configure + * the RTC clock source (to be done once after reset). + * @note Once the RTC clock is configured it can't be changed unless the RTC + * is reset using RCC_BackupResetCmd function, or by a Power On Reset (POR) + * @param RCC_RTCCLKSource: specifies the RTC clock source. + * This parameter can be one of the following values: + * @arg RCC_RTCCLKSource_LSE: LSE selected as RTC clock + * @arg RCC_RTCCLKSource_LSI: LSI selected as RTC clock + * @arg RCC_RTCCLKSource_HSE_Div32: HSE divided by 32 selected as RTC clock + * @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 2MHz (when using HSE as + * RTC clock source). + * @retval None + */ +void RCC_RTCCLKConfig(uint32_t RCC_RTCCLKSource) +{ + /* Check the parameters */ + assert_param(IS_RCC_RTCCLK_SOURCE(RCC_RTCCLKSource)); + + /* Select the RTC clock source */ + RCC->BDCR |= RCC_RTCCLKSource; +} + +/** + * @brief Enables or disables the RTC clock. + * @note This function must be used only after the RTC clock source was selected + * using the RCC_RTCCLKConfig function. + * @param NewState: new state of the RTC clock. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_RTCCLKCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + RCC->BDCR |= RCC_BDCR_RTCEN; + } + else + { + RCC->BDCR &= ~RCC_BDCR_RTCEN; + } +} + +/** + * @brief Forces or releases the Backup domain reset. + * @note This function resets the RTC peripheral (including the backup registers) + * and the RTC clock source selection in RCC_BDCR register. + * @param NewState: new state of the Backup domain reset. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_BackupResetCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + RCC->BDCR |= RCC_BDCR_BDRST; + } + else + { + RCC->BDCR &= ~RCC_BDCR_BDRST; + } +} + +/** + * @brief Enables or disables 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. + * @param RCC_AHB1Periph: specifies the AHB1 peripheral to gates its clock. + * This parameter can be any combination of the following values: + * @arg RCC_AHB1Periph_USBOTGHS: USBOTGHS clock + * @arg RCC_AHB1Periph_ETHMACPTP: ETHMACPTP clock + * @arg RCC_AHB1Periph_ETHMACRX: ETHMACRX clock + * @arg RCC_AHB1Periph_ETHMACTX: ETHMACTX clock + * @arg RCC_AHB1Periph_ETHMAC: ETHMAC clock + * @arg RCC_AHB1Periph_DMA2: DMA2 clock + * @arg RCC_AHB1Periph_DMA1: DMA1 clock + * @arg RCC_AHB1Periph_CCMDATARAM: CCMDATARAM clock + * @arg RCC_AHB1Periph_BKPSRAM: BKPSRAM clock + * @arg RCC_AHB1Periph_CRC: CRC clock + * @arg RCC_AHB1Periph_GPIOH: GPIOH clock + * @arg RCC_AHB1Periph_GPIOE: GPIOE clock + * @arg RCC_AHB1Periph_GPIOD: GPIOD clock + * @arg RCC_AHB1Periph_GPIOC: GPIOC clock + * @arg RCC_AHB1Periph_GPIOB: GPIOB clock + * @arg RCC_AHB1Periph_GPIOA: GPIOA clock + * @param NewState: new state of the specified peripheral clock. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_AHB1PeriphClockCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_AHB1_PERIPH(RCC_AHB1Periph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + RCC->AHB1ENR |= RCC_AHB1Periph; + volatile uint32_t tmpreg = RCC->AHB1ENR; + (void)tmpreg; + } + else + { + RCC->AHB1ENR &= ~RCC_AHB1Periph; + } +} + +/** + * @brief Enables or disables 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. + * @param RCC_AHB2Periph: specifies the AHB2 peripheral to gates its clock. + * This parameter can be any combination of the following values: + * @arg RCC_AHB2Periph_USBOTGFS: USBOTGFS clock + * @arg RCC_AHB2Periph_RNG: RNG clock + * @param NewState: new state of the specified peripheral clock. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_AHB2PeriphClockCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_AHB2_PERIPH(RCC_AHB2Periph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + RCC->AHB2ENR |= RCC_AHB2Periph; + volatile uint32_t tmpreg = RCC->AHB2ENR; + (void)tmpreg; + } + else + { + RCC->AHB2ENR &= ~RCC_AHB2Periph; + } +} + +/** + * @brief Enables or disables 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. + * @param RCC_AHB3Periph: specifies the AHB3 peripheral to gates its clock. + * This parameter can be any combination of the following values: + * @arg RCC_AHB3Periph_QSPI: QSPI clock + * @arg RCC_AHB3Periph_FMC: FMC clock + * @param NewState: new state of the specified peripheral clock. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_AHB3PeriphClockCmd(uint32_t RCC_AHB3Periph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_AHB3_PERIPH(RCC_AHB3Periph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + RCC->AHB3ENR |= RCC_AHB3Periph; + volatile uint32_t tmpreg = RCC->AHB3ENR; + (void)tmpreg; + } + else + { + RCC->AHB3ENR &= ~RCC_AHB3Periph; + } +} + +/** + * @brief Enables or disables the High Speed APB (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. + * @param RCC_APB1Periph: specifies the APB1 peripheral to gates its clock. + * This parameter can be any combination of the following values: + * @arg RCC_APB1Periph_USART7: USART7 clock + * @arg RCC_APB1Periph_RAMP: RAMP clock + * @arg RCC_APB1Periph_DAC: DAC clock + * @arg RCC_APB1Periph_PWR: PWR clock + * @arg RCC_APB1Periph_CAN4: CAN4 clock + * @arg RCC_APB1Periph_CAN3: CAN3 clock + * @arg RCC_APB1Periph_CAN2: CAN2 clock + * @arg RCC_APB1Periph_CAN1: CAN1 clock + * @arg RCC_APB1Periph_I2C3: I2C3 clock + * @arg RCC_APB1Periph_I2C2: I2C2 clock + * @arg RCC_APB1Periph_I2C1: I2C1 clock + * @arg RCC_APB1Periph_UART5: UART5 clock + * @arg RCC_APB1Periph_UART4: UART4 clock + * @arg RCC_APB1Periph_UART3: UART3 clock + * @arg RCC_APB1Periph_UART2: UART2 clock + * @arg RCC_APB1Periph_LPUART: LPUART clock + * @arg RCC_APB1Periph_SPI3: SPI3 clock + * @arg RCC_APB1Periph_SPI2: SPI2 clock + * @arg RCC_APB1Periph_I2S3: I2S3 clock + * @arg RCC_APB1Periph_I2S2: I2S2 clock + * @arg RCC_APB1Periph_WWDG: WWDG clock + * @arg RCC_APB1Periph_AC97: AC97 clock + * @arg RCC_APB1Periph_CRS: CRS clock + * @arg RCC_APB1Periph_TIM14: TIM14 clock + * @arg RCC_APB1Periph_TIM13: TIM13 clock + * @arg RCC_APB1Periph_TIM12: TIM12 clock + * @arg RCC_APB1Periph_TIM7: TIM7 clock + * @arg RCC_APB1Periph_TIM6: TIM6 clock + * @arg RCC_APB1Periph_TIM5: TIM5 clock + * @arg RCC_APB1Periph_TIM4: TIM4 clock + * @arg RCC_APB1Periph_TIM3: TIM3 clock + * @arg RCC_APB1Periph_TIM2: TIM2 clock + * @param NewState: new state of the specified peripheral clock. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_APB1_PERIPH(RCC_APB1Periph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + RCC->APB1ENR |= RCC_APB1Periph; + volatile uint32_t tmpreg = RCC->APB1ENR; + (void)tmpreg; + } + else + { + RCC->APB1ENR &= ~RCC_APB1Periph; + } +} + +/** + * @brief Enables or disables the Low Speed APB (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. + * @param RCC_APB2Periph: specifies the APB2 peripheral to gates its clock. + * This parameter can be any combination of the following values: + * @arg RCC_APB2Periph_TBCLK: TBCLK clock + * @arg RCC_APB2Periph_EQEP: EQEP clock + * @arg RCC_APB2Periph_ECAP: ECAP clock + * @arg RCC_APB2Periph_EPWM4: EPWM4 clock + * @arg RCC_APB2Periph_EPWM3: EPWM3 clock + * @arg RCC_APB2Periph_EPWM2: EPWM2 clock + * @arg RCC_APB2Periph_EPWM1: EPWM1 clock + * @arg RCC_APB2Periph_TIM11: TIM11 clock + * @arg RCC_APB2Periph_TIM10: TIM10 clock + * @arg RCC_APB2Periph_TIM9: TIM9 clock + * @arg RCC_APB2Periph_LPTIM: LPTIM clock + * @arg RCC_APB2Periph_SYSCFG: SYSCFG clock + * @arg RCC_APB2Periph_SPI1: SPI1 clock + * @arg RCC_APB2Periph_SDIO: SDIO clock + * @arg RCC_APB2Periph_SPD: SPD clock + * @arg RCC_APB2Periph_ADC: ADC clock + * @arg RCC_APB2Periph_USART6: USART6 clock + * @arg RCC_APB2Periph_USART1: USART1 clock + * @arg RCC_APB2Periph_TIM8: TIM8 clock + * @arg RCC_APB2Periph_TIM1: TIM1 clock + * @param NewState: new state of the specified peripheral clock. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_APB2_PERIPH(RCC_APB2Periph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + RCC->APB2ENR |= RCC_APB2Periph; + volatile uint32_t tmpreg = RCC->APB2ENR; + (void)tmpreg; + } + else + { + RCC->APB2ENR &= ~RCC_APB2Periph; + } +} + +/** + * @brief Enables or disables the AHB1 peripheral low-power clock. + * @note while enter sleep, want periph will work contiue, shoule enable + * this periph's lpen. + * @param RCC_AHB1PeriphLpen: specifies the AHB1 peripheral low-power to gates its clock. + * This parameter can be any combination of the following values: + * @arg RCC_AHB1PeriphLpen_USBOTGHS: USBOTGHS low-power clock + * @arg RCC_AHB1PeriphLpen_ETHMACPTP: ETHMACPTP low-power clock + * @arg RCC_AHB1PeriphLpen_ETHMACRX: ETHMACRX low-power clock + * @arg RCC_AHB1PeriphLpen_ETHMACTX: ETHMACTX low-power clock + * @arg RCC_AHB1PeriphLpen_ETHMAC: ETHMAC low-power clock + * @arg RCC_AHB1PeriphLpen_DMA2: DMA2 low-power clock + * @arg RCC_AHB1PeriphLpen_DMA1: DMA1 low-power clock + * @arg RCC_AHB1PeriphLpen_CCMDATARAM: CCMDATARAM low-power clock + * @arg RCC_AHB1PeriphLpen_BKPSRAM: BKPSRAM low-power clock + * @arg RCC_AHB1PeriphLpen_CRC: CRC low-power clock + * @arg RCC_AHB1PeriphLpen_GPIOH: GPIOH low-power clock + * @arg RCC_AHB1PeriphLpen_GPIOE: GPIOE low-power clock + * @arg RCC_AHB1PeriphLpen_GPIOD: GPIOD low-power clock + * @arg RCC_AHB1PeriphLpen_GPIOC: GPIOC low-power clock + * @arg RCC_AHB1PeriphLpen_GPIOB: GPIOB low-power clock + * @arg RCC_AHB1PeriphLpen_GPIOA: GPIOA low-power clock + * @param NewState: new state of the specified peripheral clock. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_AHB1PeriphLpenCmd(uint32_t RCC_AHB1PeriphLpen, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_AHB1LP_PERIPH(RCC_AHB1PeriphLpen)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + RCC->AHB1LPENR |= RCC_AHB1PeriphLpen; + } + else + { + RCC->AHB1LPENR &= ~RCC_AHB1PeriphLpen; + } +} + +/** + * @brief Enables or disables the AHB2 peripheral low-power clock. + * @note while enter sleep, want periph will work contiue, shoule enable + * this periph's lpen. + * @param RCC_AHB2PeriphLpen: specifies the AHB2 peripheral low-power to gates its clock. + * This parameter can be any combination of the following values: + * @arg RCC_AHB2PeriphLpen_USBOTGFS: USBOTGFS low-power clock + * @arg RCC_AHB2PeriphLpen_RNG: RNG low-power clock + * @param NewState: new state of the specified peripheral clock. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_AHB2PeriphLpenCmd(uint32_t RCC_AHB2PeriphLpen, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_AHB2LP_PERIPH(RCC_AHB2PeriphLpen)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + RCC->AHB2LPENR |= RCC_AHB2PeriphLpen; + } + else + { + RCC->AHB2LPENR &= ~RCC_AHB2PeriphLpen; + } +} + +/** + * @brief Enables or disables the AHB3 peripheral low-power clock. + * @note while enter sleep, want periph will work contiue, shoule enable + * this periph's lpen. + * @param RCC_AHB3PeriphLpen: specifies the AHB3 peripheral low-power to gates its clock. + * This parameter can be any combination of the following values: + * @arg RCC_AHB3PeriphLpen_QSPI: QSPI low-power clock + * @arg RCC_AHB3PeriphLpen_FMC: FMC low-power clock + * @param NewState: new state of the specified peripheral clock. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_AHB3PeriphLpenCmd(uint32_t RCC_AHB3PeriphLpen, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_AHB2LP_PERIPH(RCC_AHB3PeriphLpen)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + RCC->AHB3LPENR |= RCC_AHB3PeriphLpen; + } + else + { + RCC->AHB3LPENR &= ~RCC_AHB3PeriphLpen; + } +} + +/** + * @brief Enables or disables the High Speed APB (APB1) peripheral low-power clock. + * @note while enter sleep, want periph will work contiue, shoule enable + * this periph's lpen. + * @param RCC_APB1PeriphLpen: specifies the APB1 peripheral low-power to gates its clock. + * This parameter can be any combination of the following values: + * @arg RCC_APB1PeriphLpen_UART7: UART7 low-power clock + * @arg RCC_APB1PeriphLpen_RAMP: RAMP low-power clock + * @arg RCC_APB1PeriphLpen_DAC: DAC low-power clock + * @arg RCC_APB1PeriphLpen_PWR: PWR low-power clock + * @arg RCC_APB1PeriphLpen_CAN4: CAN4 low-power clock + * @arg RCC_APB1PeriphLpen_CAN3: CAN3 low-power clock + * @arg RCC_APB1PeriphLpen_CAN2: CAN2 low-power clock + * @arg RCC_APB1PeriphLpen_CAN1: CAN1 low-power clock + * @arg RCC_APB1PeriphLpen_I2C3: I2C3 low-power clock + * @arg RCC_APB1PeriphLpen_I2C2: I2C2 low-power clock + * @arg RCC_APB1PeriphLpen_I2C1: I2C1 low-power clock + * @arg RCC_APB1PeriphLpen_UART5: UART5 low-power clock + * @arg RCC_APB1PeriphLpen_UART4: UART4 low-power clock + * @arg RCC_APB1PeriphLpen_UART3: UART3 low-power clock + * @arg RCC_APB1PeriphLpen_UART2: UART2 low-power clock + * @arg RCC_APB1PeriphLpen_LPUART: LPUART low-power clock + * @arg RCC_APB1PeriphLpen_SPI3: SPI3 low-power clock + * @arg RCC_APB1PeriphLpen_SPI2: SPI2 low-power clock + * @arg RCC_APB1PeriphLpen_I2S3: I2S3 low-power clock + * @arg RCC_APB1PeriphLpen_I2S2: I2S2 low-power clock + * @arg RCC_APB1PeriphLpen_WWDG: WWDG low-power clock + * @arg RCC_APB1PeriphLpen_AC97: AC97 low-power clock + * @arg RCC_APB1PeriphLpen_CRS: CRS low-power clock + * @arg RCC_APB1PeriphLpen_TIM14: TIM14 low-power clock + * @arg RCC_APB1PeriphLpen_TIM13: TIM13 low-power clock + * @arg RCC_APB1PeriphLpen_TIM12: TIM12 low-power clock + * @arg RCC_APB1PeriphLpen_TIM7: TIM7 low-power clock + * @arg RCC_APB1PeriphLpen_TIM6: TIM6 low-power clock + * @arg RCC_APB1PeriphLpen_TIM5: TIM5 low-power clock + * @arg RCC_APB1PeriphLpen_TIM4: TIM4 low-power clock + * @arg RCC_APB1PeriphLpen_TIM3: TIM3 low-power clock + * @arg RCC_APB1PeriphLpen_TIM2: TIM2 low-power clock + * @param NewState: new state of the specified peripheral clock. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_APB1PeriphLpenCmd(uint32_t RCC_APB1PeriphLpen, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_APB1LP_PERIPH(RCC_APB1PeriphLpen)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + RCC->APB1LPENR |= RCC_APB1PeriphLpen; + } + else + { + RCC->APB1LPENR &= ~RCC_APB1PeriphLpen; + } +} + +/** + * @brief Enables or disables the Low Speed APB (APB2) peripheral low-power clock. + * @note while enter sleep, want periph will work contiue, shoule enable + * this periph's lpen. + * @param RCC_APB2PeriphLpen: specifies the APB2 peripheral low-power to gates its clock. + * This parameter can be any combination of the following values: + * @arg RCC_APB2PeriphLpen_TBCLK: TBCLK low-power clock + * @arg RCC_APB2PeriphLpen_EQEP: EQEP low-power clock + * @arg RCC_APB2PeriphLpen_ECAP: ECAP low-power clock + * @arg RCC_APB2PeriphLpen_EPWM4: EPWM4 low-power clock + * @arg RCC_APB2PeriphLpen_EPWM3: EPWM3 low-power clock + * @arg RCC_APB2PeriphLpen_EPWM2: EPWM2 low-power clock + * @arg RCC_APB2PeriphLpen_EPWM1: EPWM1 low-power clock + * @arg RCC_APB2PeriphLpen_TIM11: TIM11 low-power clock + * @arg RCC_APB2PeriphLpen_TIM10: TIM10 low-power clock + * @arg RCC_APB2PeriphLpen_TIM9: TIM9 low-power clock + * @arg RCC_APB2PeriphLpen_LPTIM: LPTIM low-power clock + * @arg RCC_APB2PeriphLpen_SYSCFG: SYSCFG low-power clock + * @arg RCC_APB2PeriphLpen_SPI1: SPI1 low-power clock + * @arg RCC_APB2PeriphLpen_SDIO: SDIO low-power clock + * @arg RCC_APB2PeriphLpen_SPD: SPD low-power clock + * @arg RCC_APB2PeriphLpen_ADC: ADC low-power clock + * @arg RCC_APB2PeriphLpen_USART6: USART6 low-power clock + * @arg RCC_APB2PeriphLpen_USART1: USART1 low-power clock + * @arg RCC_APB2PeriphLpen_TIM8: TIM8 low-power clock + * @arg RCC_APB2PeriphLpen_TIM1: TIM1 low-power clock + * @param NewState: new state of the specified peripheral clock. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_APB2PeriphLpenCmd(uint32_t RCC_APB2PeriphLpen, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_APB2LP_PERIPH(RCC_APB2PeriphLpen)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + RCC->APB2LPENR |= RCC_APB2PeriphLpen; + } + else + { + RCC->APB2LPENR &= ~RCC_APB2PeriphLpen; + } +} + +/** + * @brief Forces or releases AHB1 peripheral reset. + * @param RCC_AHB1PeriphRst: specifies the AHB1 peripheral to reset. + * This parameter can be any combination of the following values: + * @arg RCC_AHB1PeriphRst_USBOTGHS: USBOTGHS reset + * @arg RCC_AHB1PeriphRst_ETHMAC: ETHMAC reset + * @arg RCC_AHB1PeriphRst_DMA2: DMA2 reset + * @arg RCC_AHB1PeriphRst_DMA1: DMA1 reset + * @arg RCC_AHB1PeriphRst_CRC: CRC reset + * @arg RCC_AHB1PeriphRst_GPIOH: GPIOH reset + * @arg RCC_AHB1PeriphRst_GPIOE: GPIOE reset + * @arg RCC_AHB1PeriphRst_GPIOD: GPIOD reset + * @arg RCC_AHB1PeriphRst_GPIOC: GPIOC reset + * @arg RCC_AHB1PeriphRst_GPIOB: GPIOB reset + * @arg RCC_AHB1PeriphRst_GPIOA: GPIOA reset + * @param NewState: new state of the specified peripheral reset. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_AHB1PeriphResetCmd(uint32_t RCC_AHB1PeriphRst, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_AHB1RST_PERIPH(RCC_AHB1PeriphRst)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + RCC->AHB1RSTR |= RCC_AHB1PeriphRst; + } + else + { + RCC->AHB1RSTR &= ~RCC_AHB1PeriphRst; + } +} + +/** + * @brief Forces or releases AHB2 peripheral reset. + * @param RCC_AHB2PeriphRst: specifies the AHB2 peripheral to reset. + * This parameter can be any combination of the following values: + * @arg RCC_AHB2PeriphRst_USBOTGFS: USBOTGFS reset + * @arg RCC_AHB2PeriphRst_RNG: RNG reset + * @param NewState: new state of the specified peripheral reset. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_AHB2PeriphResetCmd(uint32_t RCC_AHB2PeriphRst, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_AHB2RST_PERIPH(RCC_AHB2PeriphRst)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + RCC->AHB2RSTR |= RCC_AHB2PeriphRst; + } + else + { + RCC->AHB2RSTR &= ~RCC_AHB2PeriphRst; + } +} + +/** + * @brief Forces or releases AHB3 peripheral reset. + * @param RCC_AHB3PeriphRst: specifies the AHB3 peripheral to reset. + * This parameter can be any combination of the following values: + * @arg RCC_AHB3PeriphRst_QSPI: QSPI reset + * @arg RCC_AHB3PeriphRst_FMC: FMC reset + * @param NewState: new state of the specified peripheral reset. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_AHB3PeriphResetCmd(uint32_t RCC_AHB3PeriphRst, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_AHB3RST_PERIPH(RCC_AHB3PeriphRst)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + RCC->AHB3RSTR |= RCC_AHB3PeriphRst; + } + else + { + RCC->AHB3RSTR &= ~RCC_AHB3PeriphRst; + } +} + +/** + * @brief Forces or releases High Speed APB (APB1) peripheral reset. + * @param RCC_APB1PeriphRst: specifies the APB1 peripheral to reset. + * This parameter can be any combination of the following values: + * @arg RCC_APB1PeriphRst_UART7: UART7 reset + * @arg RCC_APB1PeriphRst_DAC: DAC reset + * @arg RCC_APB1PeriphRst_PWR: PWR reset + * @arg RCC_APB1PeriphRst_CAN4: CAN4 reset + * @arg RCC_APB1PeriphRst_CAN3: CAN3 reset + * @arg RCC_APB1PeriphRst_CAN2: CAN2 reset + * @arg RCC_APB1PeriphRst_CAN1: CAN1 reset + * @arg RCC_APB1PeriphRst_I2C3: I2C3 reset + * @arg RCC_APB1PeriphRst_I2C2: I2C2 reset + * @arg RCC_APB1PeriphRst_I2C1: I2C1 reset + * @arg RCC_APB1PeriphRst_UART5: UART5 reset + * @arg RCC_APB1PeriphRst_UART4: UART4 reset + * @arg RCC_APB1PeriphRst_UART3: UART3 reset + * @arg RCC_APB1PeriphRst_UART2: UART2 reset + * @arg RCC_APB1PeriphRst_LPUART: LPUART reset + * @arg RCC_APB1PeriphRst_SPI3: SPI3 reset + * @arg RCC_APB1PeriphRst_SPI2: SPI2 reset + * @arg RCC_APB1PeriphRst_I2S3: I2S3 reset + * @arg RCC_APB1PeriphRst_I2S2: I2S2 reset + * @arg RCC_APB1PeriphRst_WWDG: WWDG reset + * @arg RCC_APB1PeriphRst_AC97: AC97 reset + * @arg RCC_APB1PeriphRst_CRS: CRS reset + * @arg RCC_APB1PeriphRst_TIM14: TIM14 reset + * @arg RCC_APB1PeriphRst_TIM13: TIM13 reset + * @arg RCC_APB1PeriphRst_TIM12: TIM12 reset + * @arg RCC_APB1PeriphRst_TIM7: TIM7 reset + * @arg RCC_APB1PeriphRst_TIM6: TIM6 reset + * @arg RCC_APB1PeriphRst_TIM5: TIM5 reset + * @arg RCC_APB1PeriphRst_TIM4: TIM4 reset + * @arg RCC_APB1PeriphRst_TIM3: TIM3 reset + * @arg RCC_APB1PeriphRst_TIM2: TIM2 reset + * @param NewState: new state of the specified peripheral reset. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_APB1PeriphResetCmd(uint32_t RCC_APB1PeriphRst, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_APB1RST_PERIPH(RCC_APB1PeriphRst)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + RCC->APB1RSTR |= RCC_APB1PeriphRst; + } + else + { + RCC->APB1RSTR &= ~RCC_APB1PeriphRst; + } +} + +/** + * @brief Forces or releases High Speed APB (APB2) peripheral reset. + * @param RCC_APB2PeriphRst: specifies the APB2 peripheral to reset. + * This parameter can be any combination of the following values: + * @arg RCC_APB2PeriphRst_EQEP: EQEP reset + * @arg RCC_APB2PeriphRst_ECAP: ECAP reset + * @arg RCC_APB2PeriphRst_EPWM4: EPWM4 reset + * @arg RCC_APB2PeriphRst_EPWM3: EPWM3 reset + * @arg RCC_APB2PeriphRst_EPWM2: EPWM2 reset + * @arg RCC_APB2PeriphRst_EPWM1: EPWM1 reset + * @arg RCC_APB2PeriphRst_TIM11: TIM11 reset + * @arg RCC_APB2PeriphRst_TIM10: TIM10 reset + * @arg RCC_APB2PeriphRst_TIM9: TIM9 reset + * @arg RCC_APB2PeriphRst_LPTIM: LPTIM reset + * @arg RCC_APB2PeriphRst_SYSCFG: SYSCFG reset + * @arg RCC_APB2PeriphRst_SPI1: SPI1 reset + * @arg RCC_APB2PeriphRst_SDIO: SDIO reset + * @arg RCC_APB2PeriphRst_SPD: SPD reset + * @arg RCC_APB2PeriphRst_ADC: ADC reset + * @arg RCC_APB2PeriphRst_USART6: USART6 reset + * @arg RCC_APB2PeriphRst_USART1: USART1 reset + * @arg RCC_APB2PeriphRst_TIM8: TIM8 reset + * @arg RCC_APB2PeriphRst_TIM1: TIM1 reset + * @param NewState: new state of the specified peripheral reset. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_APB2PeriphResetCmd(uint32_t RCC_APB2PeriphRst, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_APB2RST_PERIPH(RCC_APB2PeriphRst)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + RCC->APB2RSTR |= RCC_APB2PeriphRst; + } + else + { + RCC->APB2RSTR &= ~RCC_APB2PeriphRst; + } +} +/** + * @} + */ + +/** + * @brief Checks whether the specified RCC flag is set or not. + * @param RCC_FLAG_REG: the flag in which register. + * This parameter can be one of the following values: + * @arg RCC_FLAG_REG_CR: The flag in cr register + * @arg RCC_FLAG_REG_CR2: The flag in cr2 register + * @arg RCC_FLAG_REG_BDCR:The flag in bdcr register + * @arg RCC_FLAG_REG_CSR: The flag in csr register + * @param RCC_FLAG: specifies the flag to check. + * This parameter can be one of the following values: + * @arg RCC_FLAG_PLL2RDY: PLL2 clock ready + * @arg RCC_FLAG_PLLRDY: PLL clock ready + * @arg RCC_FLAG_HSERDY: HSE oscillator clock ready + * @arg RCC_FLAG_HSIRDY: HSI oscillator clock ready + * @arg RCC_FLAG_HSI48RDY:HSI48 oscillator clock ready + * @arg RCC_FLAG_LSERDY: LSE oscillator clock ready + * @arg RCC_FLAG_LPWRRST: Low Power reset + * @arg RCC_FLAG_WWDGRST: Window Watchdog reset + * @arg RCC_FLAG_IWDGRST: Independent Watchdog reset + * @arg RCC_FLAG_SFTRST: Software reset + * @arg RCC_FLAG_PORRST: POR/PDR reset + * @arg RCC_FLAG_PINRST: Pin reset + * @arg RCC_FLAG_RMVF: Remove all reset flag + * @arg RCC_FLAG_LSIRDY: LSI oscillator clock ready + * @retval The new state of RCC_FLAG (SET or RESET). + */ +FlagStatus RCC_GetFlagStatus(uint8_t RCC_FLAG_REG, uint32_t RCC_FLAG) +{ + uint8_t tmp = 0; + uint32_t statusreg = 0; + FlagStatus bitstatus = RESET; + + /* Check the parameters */ + assert_param(IS_RCC_FLAG_REG(RCC_FLAG_REG)); + assert_param(IS_RCC_FLAG(RCC_FLAG)); + + /* Get the RCC register index */ + tmp = RCC_FLAG_REG; + + if (tmp == 0) /* The flag to check is in CR register */ + { + statusreg = RCC->CR; + } + else if (tmp == 1) /* The flag to check is in CR2 register */ + { + statusreg = RCC->CR2; + } + else if (tmp == 2) /* The flag to check is in BDCR register */ + { + statusreg = RCC->BDCR; + } + else /* The flag to check is in CSR register */ + { + statusreg = RCC->CSR; + } + + if ((statusreg & RCC_FLAG) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + + /* Return the flag status */ + return bitstatus; +} + +/** + * @brief Clears the RCC reset flags. + * The reset flags are: RCC_FLAG_PINRSTF, RCC_FLAG_PORRSTF, RCC_FLAG_SFTRSTF, + * RCC_FLAG_IWDGRSTF, RCC_FLAG_WWDGRSTF, RCC_FLAG_LPWRRSTF. + * @param None + * @retval None + */ +void RCC_ClrRstFlag(void) +{ + /* Set RMVF bit to clear the reset flags */ + RCC->CSR |= RCC_CSR_RMVF; +} + +/** + * @brief Enables or disables the specified RCC interrupts. + * @note The CSS interrupt doesn't have an enable bit; once the CSS is enabled + * and if the HSE clock fails, the CSS interrupt occurs and an NMI is + * automatically generated. The NMI will be executed indefinitely, and + * since NMI has higher priority than any other IRQ (and main program) + * the application will be stacked in the NMI ISR unless the CSS interrupt + * pending bit is cleared. + * @param RCC_IT: specifies the RCC interrupt sources to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg RCC_ITEN_PLL2RDY: PLL2 ready interrupt enable + * @arg RCC_ITEN_PLLRDY: PLL ready interrupt enable + * @arg RCC_ITEN_HSERDY: HSE ready interrupt enable + * @arg RCC_ITEN_HSI48RDY: HSI48 ready interrupt enable + * @arg RCC_ITEN_HSIRDY: HSI ready interrupt enable + * @arg RCC_ITEN_LSERDY: LSE ready interrupt enable + * @arg RCC_ITEN_LSIRDY: LSI ready interrupt enable + * @param NewState: new state of the specified RCC interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_ITConfig(uint32_t RCC_IT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_ITEN(RCC_IT)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* enable the selected interrupts */ + RCC->CIR |= RCC_IT; + } + else + { + /* disable the selected interrupts */ + RCC->CIR &= ~RCC_IT; + } +} + +/** + * @brief Checks whether the specified RCC interrupt flag is set or not. + * @param RCC_IT_FLAG: specifies the flag to check. + * This parameter can be one of the following values: + * @arg RCC_ITFLAG_CSS: CSS clock secure system interrupt flag + * @arg RCC_ITFLAG_PLL2RDY: PLL2 clock ready interrupt flag + * @arg RCC_ITFLAG_PLLRDY: PLL clock ready interrupt flag + * @arg RCC_ITFLAG_HSERDY: HSE oscillator clock ready interrupt flag + * @arg RCC_ITFLAG_HSI48RDY: HSI48 oscillator clock ready interrupt flag + * @arg RCC_ITFLAG_HSIRDY: HSI oscillator clock ready interrupt flag + * @arg RCC_ITFLAG_LSIRDY: LSI oscillator clock ready interrupt flag + * @arg RCC_ITFLAG_LSERDY: LSE oscillator clock ready interrupt flag + * @retval The new state of RCC_FLAG (SET or RESET). + */ +ITStatus RCC_GetITStatus(uint32_t RCC_IT_FLAG) +{ + uint32_t statusreg = 0; + ITStatus bitstatus = RESET; + + /* Check the parameters */ + assert_param(IS_RCC_ITFLAG(RCC_IT_FLAG)); + + /* Get the interrupts flag */ + statusreg = RCC->CIR; + + if ((statusreg & RCC_IT_FLAG) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + + /* Return the flag status */ + return bitstatus; +} + +/** + * @brief Clears the RCC's interrupt pending bits. + * @param RCC_IT_CLR: specifies the interrupt pending bit to clear. + * This parameter can be any combination of the following values: + * @arg RCC_ITCLR_CSS: Clear Clock Security System interrupt Pending + * @arg RCC_ITCLR_PLL2RDY: Clear PLL2 ready interrupt Pending + * @arg RCC_ITCLR_PLLRDY: Clear PLL ready interrupt Pending + * @arg RCC_ITCLR_HSERDY: Clear HSE ready interrupt Pending + * @arg RCC_ITCLR_HSI48RDY: Clear HSI48 ready interrupt Pending + * @arg RCC_ITCLR_HSIRDY: Clear HSI ready interrupt Pending + * @arg RCC_ITCLR_LSERDY: Clear LSE ready interrupt Pending + * @arg RCC_ITCLR_LSIRDY: Clear LSI ready interrupt Pending + * @retval None + */ +void RCC_ClearITPendingBit(uint32_t RCC_IT_CLR) +{ + /* Check the parameters */ + assert_param(IS_RCC_ITCLR(RCC_IT_CLR)); + + /* Clear the selected interrupt pending bits */ + RCC->CIR |= RCC_IT_CLR; +} + +/** + * @brief Select the RAM Control by themself or AHB. + * @param RCC_RAM_CTL: specifies the RAM. + * This parameter can be any combination of the following values: + * @arg RCC_DCACHE_CTL: Dcache Ram Control by Dcache or AHB + * @arg RCC_ICACHE_CTL: Icache Ram Control by Icache or AHB + * @arg RCC_ETHMAC_CTL: Ethmac Ram Control by Ethmac or AHB + * @arg RCC_CAN_CTL: Can Ram Control by Can or AHB + * @arg RCC_USBHS_CTL: Usbhs Ram Control by Usbhs or AHB + * @arg RCC_USBFS_CTL: Usbfs Ram Control by Usbfs or AHB + * @param RCC_RAM_CTL_SEL: specifies the RAM Control by Themself or AHB. + * This parameter can be any combination of the following values: + * @arg RCC_RAM_CTL_SELF: Ram Control by Themself + * @arg RCC_RAM_CTL_AHB: Ram Control by AHB + * @retval None + */ +void RCC_RamCtrlSel(uint32_t RCC_RAM_CTL, uint32_t RCC_RAM_CTL_SEL) +{ + /* Check the parameters */ + assert_param(IS_RCC_RAMCTL(RCC_RAM_CTL)); + assert_param(IS_RCC_RAMCTL_SEL(RCC_RAM_CTL_SEL)); + + if (RCC_RAM_CTL_SEL == RCC_RAM_CTL_SELF) + { + /* Select the Ram Control by Themself */ + RCC->RAMCTL &= ~RCC_RAM_CTL; + } + else if (RCC_RAM_CTL_SEL == RCC_RAM_CTL_AHB) + { + /* Select the Ram Control by AHB */ + RCC->RAMCTL |= RCC_RAM_CTL; + } +} +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_rng.c b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_rng.c new file mode 100644 index 00000000000..26c94031b3d --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_rng.c @@ -0,0 +1,103 @@ +/* ****************************************************************************** + * @file ft32f0xx_dac.c + * @author FMD xzhang + * @brief This file provides firmware functions to manage the following + * functionalities of RNG peripheral + * @version V1.0.0 + * @data 2025-03-11 + *******************************************************************************/ +#include "ft32f4xx_rng.h" +/*RNG initial config include:1 rng_clk config (48mhz) + * 2 rng enable + * 3 rng interrupt enable + */ +/** + * @brief Initializes the RNG peripheral. + * @param + * @retval + */ +void RNG_Init() +{ + /* Enable the RNG Peripheral */ + RNG -> RNG_CR |= RNG_EN; +} + +/** + * @brief DeInitializes the RNG peripheral and all register. + * @param NewState: new state of the configed undervoltage reset :BOR_EN. + * This parameter can be: ENABLE or DISABLE. + * @retval + */ +void RNG_DeInit(FunctionalState NewState) +{ + if (NewState != DISABLE) + { + /* Disable the RNG Peripheral */ + RNG -> RNG_CR &= ~RNG_EN; + /* Disable the RNG interrupt and SEIS CEIS */ + RNG -> RNG_CR &= ~RNG_IE; + /* SEIS and CEIS RC_W0 */ + RNG -> RNG_SR &= ~RNG_SEIS; + RNG -> RNG_SR &= ~RNG_CEIS; + } +} +/** + * @brief Generates a 32-bit random number. + * @note When no more random number data is available in DR register, RNG_DRDY + * flag is automatically cleared. + * @retval + */ +uint32_t RNG_GenerateRandomNumber() +{ + uint32_t random32bit; + /* Check if data register contains valid random data */ + if ((RNG->RNG_SR & RNG_DRDY) == RNG_DRDY) + { + //if DRDY is ready random data can be read + random32bit = RNG -> RNG_DR; //if random data is read DRDY will be clear auto + } + return random32bit; +} + + +/** + * @brief enable interrupt mode. + * @param NewState: new state of the configed undervoltage reset :BOR_EN. + * This parameter can be: ENABLE or DISABLE. + * @retval + */ +void RNG_IT(FunctionalState NewState) +{ + if (NewState != DISABLE) + { + /* Enable the RNG Interrupts: Data Ready, Clock error, Seed error */ + RNG -> RNG_CR |= RNG_IE; + } + else + { + RNG -> RNG_CR &= ~RNG_IE; + } +} +/** + * @brief Back ERROR status include SEIS:0x01 SECS:0x02 CEIS:0x10 CECS:0x20. + * @param + * @retval + */ +uint8_t RNG_get_error_status() +{ + + uint8_t bit_status; + if ((RNG -> RNG_CR & RNG_IE) == RNG_IE) + { + + if (((RNG -> RNG_SR) & RNG_SECS) == RNG_SECS) + + bit_status = 0x01; + + if ((RNG -> RNG_SR & RNG_CECS) == RNG_CECS) + + bit_status = 0x10; + } + return bit_status; +} + diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_rtc.c b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_rtc.c new file mode 100644 index 00000000000..192b603c242 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_rtc.c @@ -0,0 +1,2403 @@ +/** + ****************************************************************************** + * @file ft32f4xx_rtc.c + * @author FMD AE + * @brief This file provides firmware functions to manage the following + * functionalities of the Real-Time Clock (RTC) peripheral: + * + Initialization + * + Calendar (Time and Date) configuration + * + Alarms (Alarm A and Alarm B) configuration + * + Daylight Saving configuration + * + Output pin Configuration + * + Digital Calibration configuration + * + Rough Digtial Calibration configuration + * + TimeStamp configuration + * + Tampers (tamp1 and tamp2)configuration + * + Output Type Config configuration + * + Shift control synchronisation + * + Interrupts and flags management + * + Auot WeakUp Config configuration + * + Backup Data Registers configuration + * @version V1.0.0 + * @data 2025-03-25 + ****************************************************************************** + */ + + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx_rtc.h" +#include "ft32f4xx_rcc.h" + +/* Masks Definition */ +#define RTC_TR_RESERVED_MASK ((uint32_t)0x007F7F7F) +#define RTC_DR_RESERVED_MASK ((uint32_t)0x00FFFF3F) +#define RTC_TSTR_RESERVED_MASK ((uint32_t)0x007F7F7F) +#define RTC_TSDR_RESERVED_MASK ((uint32_t)0x00FFFF3F) +#define RTC_INIT_MASK ((uint32_t)0xFFFFFFFF) +#define RTC_RSF_MASK ((uint32_t)0xFFFFFFDF) +#define RTC_WUTR_MASK ((uint32_t)0x0000FFFF) +#define RTC_FLAGS_MASK ((uint32_t)(RTC_FLAG_RECALPF | RTC_FLAG_TAMP2F | RTC_FLAG_TAMP1F | \ + RTC_FLAG_TSOVF | RTC_FLAG_TSF | RTC_FLAG_WUTF | \ + RTC_FLAG_ALRBF | RTC_FLAG_ALRAF | RTC_FLAG_INITF | \ + RTC_FLAG_RSF | RTC_FLAG_INITS | RTC_FLAG_SHPF | \ + RTC_FLAG_WUTWF | RTC_FLAG_ALRBWF | RTC_FLAG_ALRAWF )) + +#define INITMODE_TIMEOUT ((uint32_t) 0x00004000) +#define SYNCHRO_TIMEOUT ((uint32_t) 0x00008000) +#define RECALPF_TIMEOUT ((uint32_t) 0x00001000) +#define SHPF_TIMEOUT ((uint32_t) 0x00001000) + + +static uint8_t RTC_ByteToBcd2(uint8_t Value); +static uint8_t RTC_Bcd2ToByte(uint8_t Value); + +/** + * @brief Deinitializes the RTC registers to their default reset values. + * @note This function doesn't reset the RTC Clock source and RTC Backup Data + * registers. + * @param None + * @retval An ErrorStatus enumeration value: + * - SUCCESS: RTC registers are deinitialized + * - ERROR: RTC registers are not deinitialized + */ +ErrorStatus RTC_DeInit(void) +{ + ErrorStatus status = ERROR; + + /* Disable the write protection for RTC registers */ + RTC->WPR = 0xCA; + RTC->WPR = 0x53; + + /* Set Initialization mode */ + if (RTC_EnterInitMode() == ERROR) + { + status = ERROR; + } + else + { + /* Reset TR, DR and CR registers */ + RTC->TR = (uint32_t)0x00000000; + RTC->DR = (uint32_t)0x00002101; + RTC->CR = (uint32_t)0x00000000; + RTC->PRER = (uint32_t)0x007F00FF; + RTC->WUTR = (uint32_t)0x0000FFFF; + RTC->CALIBR = (uint32_t)0x00000000; + RTC->ALRMAR = (uint32_t)0x00000000; + RTC->ALRMBR = (uint32_t)0x00000000; + RTC->SHIFTR = (uint32_t)0x00000000; + RTC->CALR = (uint32_t)0x00000000; + RTC->ALRMASSR = (uint32_t)0x00000000; + RTC->ALRMBSSR = (uint32_t)0x00000000; + + /* Reset ISR register and exit initialization mode */ + RTC->ISR = (uint32_t)0x00000000; + + /* Reset Tamper and alternate functions configuration register */ + RTC->TAFCR = (uint32_t)0x00000000; + + /* Wait till the RTC RSF flag is set */ + if (RTC_WaitForSynchro() == ERROR) + { + status = ERROR; + } + else + { + status = SUCCESS; + } + } + + /* Enable the write protection for RTC registers */ + RTC->WPR = 0xFF; + + return status; +} + +/** + * @brief Initializes the RTC registers according to the specified parameters + * in RTC_InitStruct. + * @param RTC_InitStruct: pointer to a RTC_InitTypeDef structure that contains + * the configuration information for the RTC peripheral. + * @note The RTC Prescaler register is write protected and can be written in + * initialization mode only. + * The function use config hour format, async and sync value + */ +void RTC_SetInit(RTC_InitTypeDef* RTC_InitStruct) +{ + /* Check the parameters */ + assert_param(IS_RTC_HOUR_FORMAT(RTC_InitStruct->RTC_HourFormat)); + assert_param(IS_RTC_ASYNCH_PREDIV(RTC_InitStruct->RTC_AsynchPrediv)); + assert_param(IS_RTC_SYNCH_PREDIV(RTC_InitStruct->RTC_SynchPrediv)); + + /* Clear RTC CR FMT Bit set 24 hour*/ + RTC->CR &= ((uint32_t)~(RTC_CR_FMT)); + /* Set RTC_CR register */ + RTC->CR |= ((uint32_t)(RTC_InitStruct->RTC_HourFormat)); + + /*clear async and sync value*/ + RTC->PRER &= ~(RTC_PRER_PREDIV_A | RTC_PRER_PREDIV_S); + + /* Configure the RTC PRER */ + RTC->PRER |= (uint32_t)(RTC_InitStruct->RTC_SynchPrediv); + RTC->PRER |= (uint32_t)(RTC_InitStruct->RTC_AsynchPrediv << 16); +} + +/** + * @brief Fills each RTC_InitStruct member with its default value. + * @param RTC_InitStruct: pointer to a RTC_InitTypeDef structure which will be + * initialized.async lower than 0x7F,sync lower than 0x1FFF + * Use this function config specific value to Rtc_InitStruct + * @retval None + */ +void RTC_StructInit(RTC_InitTypeDef* RTC_InitStruct) +{ + /* Initialize the RTC_HourFormat member */ + RTC_InitStruct->RTC_HourFormat = RTC_HourFormat_24 /*RTC_HourFormat_12*/; + + /* Initialize the RTC_AsynchPrediv member */ + RTC_InitStruct->RTC_AsynchPrediv = (uint32_t)0x7F; + + /* Initialize the RTC_SynchPrediv member */ + RTC_InitStruct->RTC_SynchPrediv = (uint32_t)0xFF; +} + +/** + * @brief Enables or disables the RTC registers write protection. + * @note All the RTC registers are write protected except for RTC_ISR[13:8], + * RTC_TAFCR and RTC_BKPxR. + * @note Writing a wrong key reactivates the write protection. + * @note The protection mechanism is not affected by system reset. + * @param NewState: new state of the write protection. + * This parameter can be: ENABLE reactive write protect + * DISABLE open write protect. + * @retval None + */ +void RTC_WriteProtectionCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the write protection for RTC registers */ + RTC->WPR = 0xFF; + } + else + { + /* Disable the write protection for RTC registers */ + RTC->WPR = 0xCA; + RTC->WPR = 0x53; + } +} + +/** + * @brief Enters the RTC Initialization mode. + * @note The RTC Initialization mode is write protected, use the + * RTC_WriteProtectionCmd(DISABLE) open write protect + * before calling this function. + * @param None + * @retval An ErrorStatus enumeration value: + * - SUCCESS: RTC is in Init mode + * - ERROR: RTC is not in Init mode + */ +ErrorStatus RTC_EnterInitMode(void) +{ + __IO uint32_t initcounter = 0x00; + ErrorStatus status = ERROR; + uint32_t initstatus = 0x00; + + /* Check if the Initialization mode is set */ + if ((RTC->ISR & RTC_ISR_INITF) == (uint32_t)RESET)/*the init not be set*/ + { + /* Set the Initialization mode */ + RTC->ISR |= RTC_ISR_INIT; + + /* Wait till RTC is in INIT state INITF be set + * and if Time out is reached exit */ + do + { + initstatus = (uint32_t)(RTC->ISR & RTC_ISR_INITF); + initcounter++; + } + while ((initcounter != INITMODE_TIMEOUT) && (initstatus == 0x00)); + + if ((RTC->ISR & RTC_ISR_INITF) != RESET)/*check if initf be set*/ + { + status = SUCCESS;/*initf has be set,enter init mode*/ + } + else + { + status = ERROR;/*enter init mode has error*/ + } + } + else/*the init has be set*/ + { + status = SUCCESS; + } + return (status); +} + +/** + * @brief Exits the RTC Initialization mode + * @note When the initialization sequence is complete, the calendar restarts + * counting after 4 RTCCLK cycles. + * @note The RTC Initialization mode is write protected, use the + * RTC_WriteProtectionCmd(DISABLE) before calling this function. + * @param None + * @retval None + */ +void RTC_ExitInitMode(void) +{ + /* Exit Initialization mode */ + RTC->ISR &= ~RTC_ISR_INIT;/* clear init bit */ + + /*when BypassShadow is enable,should wait initf bit clear zero*/ + if ((RTC->CR & RTC_CR_BYPSHAD) == RTC_CR_BYPSHAD) + { + while ((RTC->ISR & RTC_ISR_INITF) != RESET) {} + } +} + +/** + * @brief Waits until the RTC Time and Date registers (RTC_TR and RTC_DR) are + * synchronized with RTC APB clock. + * @note The RTC Resynchronization mode is write protected, use the + * RTC_WriteProtectionCmd(DISABLE) before calling this function. + * @note To read the calendar through the shadow registers after Calendar + * initialization, calendar update or after wakeup from low power modes + * the software must first clear the RSF flag. + * The software must then wait until it is set again before reading + * the calendar, which means that the calendar registers have been + * correctly copied into the RTC_TR and RTC_DR shadow registers. + * @param None + * @retval An ErrorStatus enumeration value: + * - SUCCESS: RTC registers are synchronised + * - ERROR: RTC registers are not synchronised + */ +ErrorStatus RTC_WaitForSynchro(void) +{ + __IO uint32_t synchrocounter = 0; + ErrorStatus status = ERROR; + uint32_t synchrostatus = 0x00; + + /* check if bypass shadow register */ + if ((RTC->CR & RTC_CR_BYPSHAD) != RESET) + { + /* Bypass shadow register,read calendar will + * direct access rtc_ssr,rtc_tr and rtc_dr register */ + status = SUCCESS; + } + else/*read calendar from rtc_ssr,rtc_tr,rtc_dr's shadow register*/ + { + /* Disable the write protection for RTC registers */ + RTC->WPR = 0xCA; + RTC->WPR = 0x53; + + /* Clear RSF flag */ + RTC->ISR &= (uint32_t)RTC_RSF_MASK; + + /* Wait the registers to be synchronised */ + do + { + synchrostatus = (uint32_t)(RTC->ISR & RTC_ISR_RSF);/* rsf be set again */ + synchrocounter++; + } + while ((synchrocounter != SYNCHRO_TIMEOUT) && (synchrostatus == 0x00)); + + /* check if RSF be set again */ + if ((RTC->ISR & RTC_ISR_RSF) != RESET) + { + /* while not in bypass mode, rsf be set again + * the calendar update finish*/ + status = SUCCESS; + } + else + { + status = ERROR; + } + + /* Disable the write protection for RTC registers */ + RTC->WPR = 0xFF; + } + + return (status); +} + +/** + * @brief Enables or disables the RTC reference clock detection. + * @param NewState: new state of the RTC reference clock. + * This parameter can be: ENABLE or DISABLE. + */ +void RTC_RefClockCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the RTC reference clock detection */ + RTC->CR |= (uint32_t)RTC_CR_REFCKON; + } + else + { + /* Disable the RTC reference clock detection */ + RTC->CR &= (uint32_t)(~RTC_CR_REFCKON); + } + +} + +/** + * @brief Enables or Disables the Bypass Shadow feature. + * @note When the Bypass Shadow is enabled the calendar value are taken + * directly from the Calendar counter. + * @param NewState: new state of the Bypass Shadow feature. + * This parameter can be: ENABLE or DISABLE. + * @retval None +*/ +void RTC_BypassShadowCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Set the BYPSHAD bit */ + RTC->CR |= (uint32_t)RTC_CR_BYPSHAD; + } + else + { + /* Reset the BYPSHAD bit */ + RTC->CR &= (uint32_t)(~RTC_CR_BYPSHAD); + } +} +/** + * @} + */ + +/** + * @brief Set the RTC current time. + * @param RTC_Format: specifies the format of the entered parameters. + * This parameter can be one of the following values: + * @arg RTC_Format_BIN: Binary data format + * @arg RTC_Format_BCD: BCD data format + * @param RTC_TimeStruct: pointer to a RTC_TimeTypeDef structure that contains + * the time configuration information for the RTC. + * rtc's hours minutes and seconds,that rtc_h12 represent am/pm + */ +void RTC_SetTime(uint32_t RTC_Format, RTC_TimeTypeDef* RTC_TimeStruct) +{ + uint32_t tmpreg = 0; + + /* Check the parameters if RTC_Format_BIN or RTC_Format_BCD */ + assert_param(IS_RTC_FORMAT(RTC_Format)); + + /* check rtc time format if binary */ + if (RTC_Format == RTC_Format_BIN) + { + /* check if hour format is 12 or 24 */ + if ((RTC->CR & RTC_CR_FMT) != (uint32_t)RESET) + { + /* set rtc_hours format is 12 + * check rtc hour if in range 0-12 + * set hour is am/pm */ + assert_param(IS_RTC_HOUR12(RTC_TimeStruct->RTC_Hours)); + assert_param(IS_RTC_H12(RTC_TimeStruct->RTC_H12)); + } + else + { + /* set rtc_hours format is 24 */ + RTC_TimeStruct->RTC_H12 = 0x00; + /* check hour if in range 0-23 */ + assert_param(IS_RTC_HOUR24(RTC_TimeStruct->RTC_Hours)); + } + /* check rtc minutes and seconds in right range */ + assert_param(IS_RTC_MINUTES(RTC_TimeStruct->RTC_Minutes)); + assert_param(IS_RTC_SECONDS(RTC_TimeStruct->RTC_Seconds)); + } + else/* rtc time format is bcd */ + { + /* check if hour format is 12 or 24 */ + if ((RTC->CR & RTC_CR_FMT) != (uint32_t)RESET) + { + /* set rtc_hours format is 12 and am/pm + * convert bcd to binary and set am/pm*/ + tmpreg = RTC_Bcd2ToByte(RTC_TimeStruct->RTC_Hours); + /* check hour if in range 0-12 */ + assert_param(IS_RTC_HOUR12(tmpreg)); + assert_param(IS_RTC_H12(RTC_TimeStruct->RTC_H12)); + } + else + { + /* set rtc_hours format is 24 */ + RTC_TimeStruct->RTC_H12 = 0x00; + /* check hour if in range 0-23 */ + assert_param(IS_RTC_HOUR24(RTC_Bcd2ToByte(RTC_TimeStruct->RTC_Hours))); + } + /* check rtc minutes and seconds in right range */ + assert_param(IS_RTC_MINUTES(RTC_Bcd2ToByte(RTC_TimeStruct->RTC_Minutes))); + assert_param(IS_RTC_SECONDS(RTC_Bcd2ToByte(RTC_TimeStruct->RTC_Seconds))); + } + + /* Check the input parameters format */ + if (RTC_Format != RTC_Format_BIN) + { + /* rtc time format is binary */ + tmpreg = (((uint32_t)(RTC_TimeStruct->RTC_H12) << 22) | \ + ((uint32_t)(RTC_TimeStruct->RTC_Hours) << 16) | \ + ((uint32_t)(RTC_TimeStruct->RTC_Minutes) << 8) | \ + ((uint32_t) RTC_TimeStruct->RTC_Seconds)); + } + else + { + /* rtc time format is bcd + * convert byte to bcd */ + tmpreg = (uint32_t)((((uint32_t)RTC_TimeStruct->RTC_H12) << 22) | \ + ((uint32_t)RTC_ByteToBcd2(RTC_TimeStruct->RTC_Hours) << 16) | \ + ((uint32_t)RTC_ByteToBcd2(RTC_TimeStruct->RTC_Minutes) << 8) | \ + ((uint32_t)RTC_ByteToBcd2(RTC_TimeStruct->RTC_Seconds))); + } + + /* Set the RTC_TR register */ + RTC->TR = (uint32_t)(tmpreg & RTC_TR_RESERVED_MASK); +} + +/** + * @brief Fills each RTC_TimeStruct member with its default value + * (Time = 00h:00min:00sec). + * @param RTC_TimeStruct: pointer to a RTC_TimeTypeDef structure which will be + * initialized. + * @retval None + */ +void RTC_TimeStructInit(RTC_TimeTypeDef* RTC_TimeStruct) +{ + /* Time = 00h:00min:00sec */ + RTC_TimeStruct->RTC_H12 = RTC_H12_AM; + RTC_TimeStruct->RTC_Hours = 0; + RTC_TimeStruct->RTC_Minutes = 0; + RTC_TimeStruct->RTC_Seconds = 0; +} + +/** + * @brief Get the RTC current Time. + * @param RTC_Format: specifies the format of the returned parameters. + * This parameter can be one of the following values: + * @arg RTC_Format_BIN: Binary data format + * @arg RTC_Format_BCD: BCD data format + * @param RTC_TimeStruct: pointer to a RTC_TimeTypeDef structure that will + * contain the returned current time configuration. + * @retval None + */ +void RTC_GetTime(uint32_t RTC_Format, RTC_TimeTypeDef* RTC_TimeStruct) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RTC_FORMAT(RTC_Format)); + + /* Get the RTC_TR register */ + /* the get's rtc time is bcd format*/ + tmpreg = (uint32_t)(RTC->TR & RTC_TR_RESERVED_MASK); + + /* Fill the structure fields with the read parameters */ + RTC_TimeStruct->RTC_Hours = (uint8_t)((tmpreg & (RTC_TR_HT | RTC_TR_HU)) >> 16); + RTC_TimeStruct->RTC_Minutes = (uint8_t)((tmpreg & (RTC_TR_MNT | RTC_TR_MNU)) >> 8); + RTC_TimeStruct->RTC_Seconds = (uint8_t)(tmpreg & (RTC_TR_ST | RTC_TR_SU)); + RTC_TimeStruct->RTC_H12 = (uint8_t)((tmpreg & (RTC_TR_PM)) >> 22); + + /* Check the input parameters format */ + if (RTC_Format == RTC_Format_BIN) + { + /* want get the binary format rtc time */ + /* Convert the structure parameters to Binary format */ + RTC_TimeStruct->RTC_Hours = (uint8_t)RTC_Bcd2ToByte(RTC_TimeStruct->RTC_Hours); + RTC_TimeStruct->RTC_Minutes = (uint8_t)RTC_Bcd2ToByte(RTC_TimeStruct->RTC_Minutes); + RTC_TimeStruct->RTC_Seconds = (uint8_t)RTC_Bcd2ToByte(RTC_TimeStruct->RTC_Seconds); + } +} + +/** + * @brief Gets the RTC current Calendar Subseconds value. + * @note This function freeze the Time and Date registers after reading the + * SSR register. + * @param None + * @retval RTC current Calendar Subseconds value. + */ +uint32_t RTC_GetSubSecond(void) +{ + uint32_t tmpreg = 0; + + /* Get subseconds values from the correspondent registers*/ + tmpreg = (uint32_t)(RTC->SSR); + + /* Read DR register to unfroze calendar registers */ + (void)(RTC->DR); + + return (tmpreg); +} + +/** + * @brief Set the RTC current date. + * @param RTC_Format: specifies the format of the entered parameters. + * This parameter can be one of the following values: + * @arg RTC_Format_BIN: Binary data format + * @arg RTC_Format_BCD: BCD data format + * @param RTC_DateStruct: pointer to a RTC_DateTypeDef structure that contains + * the date configuration information for the RTC. + */ +void RTC_SetDate(uint32_t RTC_Format, RTC_DateTypeDef* RTC_DateStruct) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RTC_FORMAT(RTC_Format)); + + /* check rtc_month's mt if is 1 */ + if ((RTC_Format == RTC_Format_BIN) && ((RTC_DateStruct->RTC_Month & 0x10) == 0x10)) + { + /* rtc_month's mt is 1,convert as low 4 bits expression */ + RTC_DateStruct->RTC_Month = (RTC_DateStruct->RTC_Month & (uint32_t)~(0x10)) + 0x0A; + } + if (RTC_Format == RTC_Format_BIN) + { + /* rtc_date is binary + * check the rtc date in right range */ + assert_param(IS_RTC_YEAR(RTC_DateStruct->RTC_Year)); + assert_param(IS_RTC_MONTH(RTC_DateStruct->RTC_Month)); + assert_param(IS_RTC_DATE(RTC_DateStruct->RTC_Date)); + } + else + { + /* rtc_date is bcd need convert as binary + * check the rtc date in right range */ + assert_param(IS_RTC_YEAR(RTC_Bcd2ToByte(RTC_DateStruct->RTC_Year))); + assert_param(IS_RTC_MONTH(RTC_Bcd2ToByte(RTC_DateStruct->RTC_Month))); + assert_param(IS_RTC_DATE(RTC_Bcd2ToByte(RTC_DateStruct->RTC_Date))); + } + /* check the weekday in right range */ + assert_param(IS_RTC_WEEKDAY(RTC_DateStruct->RTC_WeekDay)); + + /* Check the input parameters format */ + if (RTC_Format != RTC_Format_BIN) + { + /* rtc_datestruct as binary format */ + tmpreg = ((((uint32_t)RTC_DateStruct->RTC_Year) << 16) | \ + (((uint32_t)RTC_DateStruct->RTC_Month) << 8) | \ + ((uint32_t)RTC_DateStruct->RTC_Date) | \ + (((uint32_t)RTC_DateStruct->RTC_WeekDay) << 13)); + } + else + { + /* rtc_datestruct as bcd format + * need convert as binary format */ + tmpreg = (((uint32_t)RTC_ByteToBcd2(RTC_DateStruct->RTC_Year) << 16) | \ + ((uint32_t)RTC_ByteToBcd2(RTC_DateStruct->RTC_Month) << 8) | \ + ((uint32_t)RTC_ByteToBcd2(RTC_DateStruct->RTC_Date)) | \ + ((uint32_t)RTC_DateStruct->RTC_WeekDay << 13)); + } + + /* Set the RTC_DR register */ + RTC->DR = (uint32_t)(tmpreg & RTC_DR_RESERVED_MASK); +} + +/** + * @brief Fills each RTC_DateStruct member with its default value + * (Monday, January 01 xx00). + * @param RTC_DateStruct: pointer to a RTC_DateTypeDef structure + * which will be initialized. + * @retval None + */ +void RTC_DateStructInit(RTC_DateTypeDef* RTC_DateStruct) +{ + /* Monday, January 01 xx00 */ + RTC_DateStruct->RTC_WeekDay = RTC_Weekday_Monday; + RTC_DateStruct->RTC_Date = 1; + RTC_DateStruct->RTC_Month = RTC_Month_January; + RTC_DateStruct->RTC_Year = 0; +} + +/** + * @brief Get the RTC current date. + * @param RTC_Format: specifies the format of the returned parameters. + * This parameter can be one of the following values: + * @arg RTC_Format_BIN: Binary data format + * @arg RTC_Format_BCD: BCD data format + * @param RTC_DateStruct: pointer to a RTC_DateTypeDef structure that will + * contain the returned current date configuration. + * @retval None + */ +uint32_t RTC_GetDate(uint32_t RTC_Format, RTC_DateTypeDef* RTC_DateStruct) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RTC_FORMAT(RTC_Format)); + + /* Get the RTC_TR register */ + tmpreg = (uint32_t)(RTC->DR & RTC_DR_RESERVED_MASK); + + /* Fill the structure fields with the read parameters */ + /* the rtc_date format as bcd */ + RTC_DateStruct->RTC_Year = (uint8_t)((tmpreg & (RTC_DR_YT | RTC_DR_YU)) >> 16); + RTC_DateStruct->RTC_Month = (uint8_t)((tmpreg & (RTC_DR_MT | RTC_DR_MU)) >> 8); + RTC_DateStruct->RTC_Date = (uint8_t)(tmpreg & (RTC_DR_DT | RTC_DR_DU)); + RTC_DateStruct->RTC_WeekDay = (uint8_t)((tmpreg & (RTC_DR_WDU)) >> 13); + + /* Check the input parameters format */ + /* the rtc_date format as binary */ + if (RTC_Format == RTC_Format_BIN) + { + /* Convert the structure parameters to Binary format */ + RTC_DateStruct->RTC_Year = (uint8_t) RTC_Bcd2ToByte(RTC_DateStruct->RTC_Year); + RTC_DateStruct->RTC_Month = (uint8_t) RTC_Bcd2ToByte(RTC_DateStruct->RTC_Month); + RTC_DateStruct->RTC_Date = (uint8_t) RTC_Bcd2ToByte(RTC_DateStruct->RTC_Date); + RTC_DateStruct->RTC_WeekDay = (uint8_t)(RTC_DateStruct->RTC_WeekDay); + } + return 0; +} +/** + * @} + */ + + +/** + * @brief Set the specified RTC Alarm. + * @note The Alarm register can only be written when the corresponding + * Alarm is disabled (Use the RTC_AlarmaCmd(DISABLE)). + * @param RTC_Format: specifies the format of the returned parameters. + * This parameter can be one of the following values: + * @arg RTC_Format_BIN: Binary data format + * @arg RTC_Format_BCD: BCD data format + * @param RTC_Alarm: specifies the alarm to be configured. + * This parameter can be one of the following values: + * @arg RTC_Alarm_A: to select Alarm A + * @arg RTC_Alarm_B: to select Alarm B + * @param RTC_AlarmStruct: pointer to a RTC_AlarmTypeDef structure that + * contains the alarm configuration parameters. + * This parameter can be one of the following values: + * @arg RTC_AlarmTime: RTC_Hours RTC_Minutes RTC_Seconds RTC_H12 + * @arg RTC_AlarmMask: RTC_AlarmMask_None RTC_AlarmMask_DateWeekDay + * RTC_AlarmMask_Hours RTC_AlarmMask_Minutes + * RTC_AlarmMask_Seconds RTC_AlarmMask_All + * @arg RTC_AlarmDateWeekDaySel:RTC_AlarmDateWeekDaySel_Date + * RTC_AlarmDateWeekDaySel_WeekDay + * @arg RTC_AlarmDateWeekDay:date range 1-31 + * RTC_Weekday_Monday RTC_Weekday_Tuesday + * RTC_Weekday_Wednesday RTC_Weekday_Thursday + * RTC_Weekday_Friday RTC_Weekday_Saturday + * RTC_Weekday_Sunday + * @retval None + */ +void RTC_SetAlarm(uint32_t RTC_Format, uint32_t RTC_Alarm, RTC_AlarmTypeDef* RTC_AlarmStruct) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RTC_FORMAT(RTC_Format));/* config alarma/alarmb register's struct format */ + assert_param(IS_RTC_ALARM(RTC_Alarm));/* choose alarma/alarmb */ + assert_param(IS_RTC_ALARM_MASK(RTC_AlarmStruct->RTC_AlarmMask));/* config alarm mask */ + assert_param(IS_RTC_ALARM_DATE_WEEKDAY_SEL(RTC_AlarmStruct->RTC_AlarmDateWeekDaySel));/* config alarm wdsel */ + + if (RTC_Format == RTC_Format_BIN)/* rtc alarma/alarmb struct format is binary */ + { + if ((RTC->CR & RTC_CR_FMT) != (uint32_t)RESET)/* rtc hour format is 12 */ + { + /* check alarma/alarmb's hour range in 0-12 */ + assert_param(IS_RTC_HOUR12(RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours)); + assert_param(IS_RTC_H12(RTC_AlarmStruct->RTC_AlarmTime.RTC_H12)); + } + else/* rtc hour format is 24 */ + { + /* check alarma/alarmb's hour range in 0-23 */ + RTC_AlarmStruct->RTC_AlarmTime.RTC_H12 = 0x00; + assert_param(IS_RTC_HOUR24(RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours)); + } + /* check alarma/alarmb's minutes and seconds in right range */ + assert_param(IS_RTC_MINUTES(RTC_AlarmStruct->RTC_AlarmTime.RTC_Minutes)); + assert_param(IS_RTC_SECONDS(RTC_AlarmStruct->RTC_AlarmTime.RTC_Seconds)); + + /* judgement alarma/alarmb's wdsel=0 or 1 */ + if (RTC_AlarmStruct->RTC_AlarmDateWeekDaySel == RTC_AlarmDateWeekDaySel_Date) + { + /* while wdsel=0 check DU[3:0] if express day */ + assert_param(IS_RTC_ALARM_DATE_WEEKDAY_DATE(RTC_AlarmStruct->RTC_AlarmDateWeekDay)); + } + else + { + /* while wdsel=1 check DU[3:0] if express weekday */ + assert_param(IS_RTC_ALARM_DATE_WEEKDAY_WEEKDAY(RTC_AlarmStruct->RTC_AlarmDateWeekDay)); + } + } + else/* rtc alarma/alarmb struct format is bcd */ + { + if ((RTC->CR & RTC_CR_FMT) != (uint32_t)RESET) + { + /* check alarma/alarmb's hour range in 0-12 */ + tmpreg = RTC_Bcd2ToByte(RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours); + assert_param(IS_RTC_HOUR12(tmpreg)); + assert_param(IS_RTC_H12(RTC_AlarmStruct->RTC_AlarmTime.RTC_H12)); + } + else/* rtc hour format is 24 */ + { + /* check alarma/alarmb's hour range in 0-23 */ + RTC_AlarmStruct->RTC_AlarmTime.RTC_H12 = 0x00; + assert_param(IS_RTC_HOUR24(RTC_Bcd2ToByte(RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours))); + } + /* check alarma/alarmb's minutes and seconds in right range */ + assert_param(IS_RTC_MINUTES(RTC_Bcd2ToByte(RTC_AlarmStruct->RTC_AlarmTime.RTC_Minutes))); + assert_param(IS_RTC_SECONDS(RTC_Bcd2ToByte(RTC_AlarmStruct->RTC_AlarmTime.RTC_Seconds))); + + /* judgement alarma/alarmb's wdsel=0 or 1 */ + if (RTC_AlarmStruct->RTC_AlarmDateWeekDaySel == RTC_AlarmDateWeekDaySel_Date) + { + /* while wdsel=0 check DU[3:0] if express day */ + tmpreg = RTC_Bcd2ToByte(RTC_AlarmStruct->RTC_AlarmDateWeekDay); + assert_param(IS_RTC_ALARM_DATE_WEEKDAY_DATE(tmpreg)); + } + else + { + /* while wdsel=1 check DU[3:0] if express weekday */ + tmpreg = RTC_Bcd2ToByte(RTC_AlarmStruct->RTC_AlarmDateWeekDay); + assert_param(IS_RTC_ALARM_DATE_WEEKDAY_WEEKDAY(tmpreg)); + } + } + + /* Check the input parameters format */ + if (RTC_Format != RTC_Format_BIN) + { + tmpreg = (((uint32_t)(RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours) << 16) | \ + ((uint32_t)(RTC_AlarmStruct->RTC_AlarmTime.RTC_Minutes) << 8) | \ + ((uint32_t)RTC_AlarmStruct->RTC_AlarmTime.RTC_Seconds) | \ + ((uint32_t)(RTC_AlarmStruct->RTC_AlarmTime.RTC_H12) << 22) | \ + ((uint32_t)(RTC_AlarmStruct->RTC_AlarmDateWeekDay) << 24) | \ + ((uint32_t)RTC_AlarmStruct->RTC_AlarmDateWeekDaySel) | \ + ((uint32_t)RTC_AlarmStruct->RTC_AlarmMask)); + } + else + { + tmpreg = (((uint32_t)RTC_ByteToBcd2(RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours) << 16) | \ + ((uint32_t)RTC_ByteToBcd2(RTC_AlarmStruct->RTC_AlarmTime.RTC_Minutes) << 8) | \ + ((uint32_t)RTC_ByteToBcd2(RTC_AlarmStruct->RTC_AlarmTime.RTC_Seconds)) | \ + ((uint32_t)(RTC_AlarmStruct->RTC_AlarmTime.RTC_H12) << 22) | \ + ((uint32_t)RTC_ByteToBcd2(RTC_AlarmStruct->RTC_AlarmDateWeekDay) << 24) | \ + ((uint32_t)RTC_AlarmStruct->RTC_AlarmDateWeekDaySel) | \ + ((uint32_t)RTC_AlarmStruct->RTC_AlarmMask)); + } + + if (RTC_Alarm == RTC_Alarm_A) + { + /* Configure the Alarm register */ + RTC->ALRMAR = (uint32_t)tmpreg; + } + else if (RTC_Alarm == RTC_Alarm_B) + { + /* Configure the Alarm register */ + RTC->ALRMBR = (uint32_t)tmpreg; + } + +} + +/** + * @brief Fills each RTC_AlarmStruct member with its default value + * (Time = 00h:00mn:00sec / Date = 1st day of the month/Mask = + * all fields are masked). + * @param RTC_AlarmStruct: pointer to a @ref RTC_AlarmTypeDef structure which + * will be initialized. + * @retval None + */ +void RTC_AlarmStructInit(RTC_AlarmTypeDef* RTC_AlarmStruct) +{ + /* Alarm Time Settings : Time = 00h:00mn:00sec */ + RTC_AlarmStruct->RTC_AlarmTime.RTC_H12 = RTC_H12_AM; + RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours = 0; + RTC_AlarmStruct->RTC_AlarmTime.RTC_Minutes = 0; + RTC_AlarmStruct->RTC_AlarmTime.RTC_Seconds = 0; + + /* Alarm Date Settings : Date = 1st day of the month */ + RTC_AlarmStruct->RTC_AlarmDateWeekDaySel = RTC_AlarmDateWeekDaySel_Date; + RTC_AlarmStruct->RTC_AlarmDateWeekDay = 1; + + /* Alarm Masks Settings : Mask = all fields are not masked */ + RTC_AlarmStruct->RTC_AlarmMask = RTC_AlarmMask_None; +} + +/** + * @brief Get the RTC Alarm value and masks. + * @param RTC_Format: specifies the format of the output parameters. + * This parameter can be one of the following values: + * @arg RTC_Format_BIN: Binary data format + * @arg RTC_Format_BCD: BCD data format + * @param RTC_Alarm: specifies the alarm to be read. + * This parameter can be one of the following values: + * @arg RTC_Alarm_A: to select Alarm A + * @arg RTC_Alarm_B: to select Alarm B + * @param RTC_AlarmStruct: pointer to a RTC_AlarmTypeDef structure that will + * contains the output alarm configuration values. + * This parameter can be one of the following values: + * @arg RTC_AlarmTime: RTC_Hours RTC_Minutes RTC_Seconds RTC_H12 + * @arg RTC_AlarmMask: RTC_AlarmMask_None RTC_AlarmMask_DateWeekDay + * RTC_AlarmMask_Hours RTC_AlarmMask_Minutes + * RTC_AlarmMask_Seconds RTC_AlarmMask_All + * @arg RTC_AlarmDateWeekDaySel:RTC_AlarmDateWeekDaySel_Date + * RTC_AlarmDateWeekDaySel_WeekDay + * @arg RTC_AlarmDateWeekDay:date range 1-31 + * RTC_Weekday_Monday RTC_Weekday_Tuesday + * RTC_Weekday_Wednesday RTC_Weekday_Thursday + * RTC_Weekday_Friday RTC_Weekday_Saturday + * RTC_Weekday_Sunday + * @retval None + */ +void RTC_GetAlarm(uint32_t RTC_Format, uint32_t RTC_Alarm, RTC_AlarmTypeDef* RTC_AlarmStruct) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RTC_FORMAT(RTC_Format)); + assert_param(IS_RTC_ALARM(RTC_Alarm)); + + if (RTC_Alarm == RTC_Alarm_A) + { + /* Get the RTC_ALRMAR register */ + tmpreg = (uint32_t)(RTC->ALRMAR); + } + else if (RTC_Alarm == RTC_Alarm_B) + { + /* Get the RTC_ALRMBR register */ + tmpreg = (uint32_t)(RTC->ALRMBR); + } + + /* Fill the structure with the read parameters */ + RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours = (uint32_t)((tmpreg & (RTC_ALRMAR_HT | RTC_ALRMAR_HU)) >> 16); + RTC_AlarmStruct->RTC_AlarmTime.RTC_Minutes = (uint32_t)((tmpreg & (RTC_ALRMAR_MNT | RTC_ALRMAR_MNU)) >> 8); + RTC_AlarmStruct->RTC_AlarmTime.RTC_Seconds = (uint32_t)(tmpreg & (RTC_ALRMAR_ST | RTC_ALRMAR_SU)); + RTC_AlarmStruct->RTC_AlarmTime.RTC_H12 = (uint32_t)((tmpreg & RTC_ALRMAR_PM) >> 22); + RTC_AlarmStruct->RTC_AlarmDateWeekDay = (uint32_t)((tmpreg & (RTC_ALRMAR_DT | RTC_ALRMAR_DU)) >> 24); + RTC_AlarmStruct->RTC_AlarmDateWeekDaySel = (uint32_t)(tmpreg & RTC_ALRMAR_WDSEL); + RTC_AlarmStruct->RTC_AlarmMask = (uint32_t)(tmpreg & RTC_AlarmMask_All); + + if (RTC_Format == RTC_Format_BIN) + { + RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours = RTC_Bcd2ToByte(RTC_AlarmStruct -> RTC_AlarmTime.RTC_Hours); + RTC_AlarmStruct->RTC_AlarmTime.RTC_Minutes = RTC_Bcd2ToByte(RTC_AlarmStruct -> RTC_AlarmTime.RTC_Minutes); + RTC_AlarmStruct->RTC_AlarmTime.RTC_Seconds = RTC_Bcd2ToByte(RTC_AlarmStruct -> RTC_AlarmTime.RTC_Seconds); + RTC_AlarmStruct->RTC_AlarmDateWeekDay = RTC_Bcd2ToByte(RTC_AlarmStruct -> RTC_AlarmDateWeekDay); + } +} + +/** + * @brief Enables or disables the specified RTC Alarm. + * @param RTC_Alarm: specifies the alarm to be configured. + * This parameter can be any combination of the following values: + * @arg RTC_Alarm_A: to select Alarm A + * @arg RTC_Alarm_B: to select Alarm B + * @param NewState: new state of the specified alarm. + * This parameter can be: ENABLE or DISABLE. + */ +void RTC_AlarmCmd(uint32_t RTC_Alarm, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RTC_CMD_ALARM(RTC_Alarm)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + /* Configure the Alarm state */ + if (NewState != DISABLE) + { + RTC->CR |= (uint32_t)RTC_Alarm;/* enable rtc alarma or alarmb */ + } + else + { + /* Disable the Alarm in RTC_CR register */ + RTC->CR &= (uint32_t)~RTC_Alarm; + } +} + +/** + * @brief Configure the RTC AlarmA/B Subseconds value and mask. + * @note This function is performed only when the Alarm is disabled. + * @param RTC_Alarm: specifies the alarm to be configured. + * This parameter can be one of the following values: + * @arg RTC_Alarm_A: to select Alarm A + * @arg RTC_Alarm_B: to select Alarm B + * @param RTC_AlarmSubSecondValue: specifies the Subseconds value. + * This parameter can be a value from 0 to 0x00007FFF. + * @param RTC_AlarmSubSecondMask: specifies the Subseconds Mask. + * This parameter can be any combination of the following values: + * @arg RTC_AlarmSubSecondMask_All: All Alarm SS fields are masked. + * There is no comparison on sub seconds for Alarm. + * @arg RTC_AlarmSubSecondMask_SS14_1: SS[14:1] are don't care in Alarm comparison. + * Only SS[0] is compared + * @arg RTC_AlarmSubSecondMask_SS14_2: SS[14:2] are don't care in Alarm comparison. + * Only SS[1:0] are compared + * @arg RTC_AlarmSubSecondMask_SS14_3: SS[14:3] are don't care in Alarm comparison. + * Only SS[2:0] are compared + * @arg RTC_AlarmSubSecondMask_SS14_4: SS[14:4] are don't care in Alarm comparison. + * Only SS[3:0] are compared + * @arg RTC_AlarmSubSecondMask_SS14_5: SS[14:5] are don't care in Alarm comparison. + * Only SS[4:0] are compared + * @arg RTC_AlarmSubSecondMask_SS14_6: SS[14:6] are don't care in Alarm comparison. + * Only SS[5:0] are compared + * @arg RTC_AlarmSubSecondMask_SS14_7: SS[14:7] are don't care in Alarm comparison. + * Only SS[6:0] are compared + * @arg RTC_AlarmSubSecondMask_SS14_8: SS[14:8] are don't care in Alarm comparison. + * Only SS[7:0] are compared + * @arg RTC_AlarmSubSecondMask_SS14_9: SS[14:9] are don't care in Alarm comparison. + * Only SS[8:0] are compared + * @arg RTC_AlarmSubSecondMask_SS14_10: SS[14:10] are don't care in Alarm comparison. + * Only SS[9:0] are compared + * @arg RTC_AlarmSubSecondMask_SS14_11: SS[14:11] are don't care in Alarm comparison. + * Only SS[10:0] are compared + * @arg RTC_AlarmSubSecondMask_SS14_12: SS[14:12] are don't care in Alarm comparison. + * Only SS[11:0] are compared + * @arg RTC_AlarmSubSecondMask_SS14_13: SS[14:13] are don't care in Alarm comparison. + * Only SS[12:0] are compared + * @arg RTC_AlarmSubSecondMask_SS14: SS[14] is don't care in Alarm comparison. + * Only SS[13:0] are compared + * @arg RTC_AlarmSubSecondMask_None: SS[14:0] are compared and must match to activate alarm + * @retval None + */ +void RTC_AlarmSubSecondConfig(uint32_t RTC_Alarm, uint32_t RTC_AlarmSubSecondValue, uint8_t RTC_AlarmSubSecondMask) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RTC_ALARM(RTC_Alarm)); + assert_param(IS_RTC_ALARM_SUB_SECOND_VALUE(RTC_AlarmSubSecondValue)); + assert_param(IS_RTC_ALARM_SUB_SECOND_MASK(RTC_AlarmSubSecondMask)); + + /* Configure the Alarm A or Alarm B SubSecond registers */ + tmpreg = (uint32_t)(((uint32_t)(RTC_AlarmSubSecondValue)) | ((uint32_t)(RTC_AlarmSubSecondMask) << 24)); + + if (RTC_Alarm == RTC_Alarm_A) + { + /* Configure the AlarmA SubSecond register */ + RTC->ALRMASSR = (uint32_t)tmpreg; + } + else if (RTC_Alarm == RTC_Alarm_B) + { + /* Configure the AlarmB SubSecond register */ + RTC->ALRMBSSR = (uint32_t)tmpreg; + } +} + +/** + * @brief Gets the RTC Alarm Subseconds value. + * @param RTC_Alarm: specifies the alarm to be read. + * This parameter can be one of the following values: + * @arg RTC_Alarm_A: to select Alarm A + * @arg RTC_Alarm_B: to select Alarm B + * @param None + * @retval RTC Alarm Subseconds value. + */ +uint32_t RTC_GetAlarmSubSecond(uint32_t RTC_Alarm) +{ + uint32_t tmpreg = 0; + + if (RTC_Alarm == RTC_Alarm_A) + { + /* Get the RTC_ALRMAR register */ + tmpreg = (uint32_t)((RTC->ALRMASSR) & RTC_ALRMASSR_SS); + } + else if (RTC_Alarm == RTC_Alarm_B) + { + /* Get the RTC_ALRMBR register */ + tmpreg = (uint32_t)((RTC->ALRMBSSR) & RTC_ALRMBSSR_SS); + } + + return (tmpreg); +} +/** + * @} + */ + + + +/** + * @brief Adds or substract one hour from the current time. + * @param RTC_DayLightSaveOperation: the value of hour adjustment. + * This parameter can be one of the following values: + * @arg RTC_DayLightSaving_SUB1H: Substract one hour (winter time) + * @arg RTC_DayLightSaving_ADD1H: Add one hour (summer time) + * @param RTC_StoreOperation: Specifies the value to be written in the BCK bit + * in CR register to store the operation. + * This parameter can be one of the following values: + * @arg RTC_StoreOperation_Reset: BKP Bit Reset + * @arg RTC_StoreOperation_Set: BKP Bit Set + * @retval None + */ +void RTC_DayLightSavingConfig(uint32_t RTC_DayLightSaving, uint32_t RTC_StoreOperation) +{ + /* Check the parameters */ + assert_param(IS_RTC_DAYLIGHT_SAVING(RTC_DayLightSaving)); + assert_param(IS_RTC_STORE_OPERATION(RTC_StoreOperation)); + + /* Clear the bits to be configured */ + RTC->CR &= (uint32_t)~(RTC_CR_BKP); + + /* Configure the RTC_CR register */ + /* Based on the parameter config DayLightSaving ADD1H/SUB1H + * and StoreOperation set/clear RTC_CR[BKP]*/ + RTC->CR |= (uint32_t)(RTC_DayLightSaving | RTC_StoreOperation); +} + +/** + * @brief Returns the RTC Day Light Saving stored operation. + * @param None + * @retval RTC Day Light Saving stored operation. + * - RTC_StoreOperation_Reset + * - RTC_StoreOperation_Set + */ +uint32_t RTC_GetStoreOperation(void) +{ + return (RTC->CR & RTC_CR_BKP); +} + +/** + * @} + */ + +/** + * @brief Configures the RTC output source (AFO_ALARM). + * @param RTC_Output: Specifies which signal will be routed to the RTC output. + * This parameter can be one of the following values: + * @arg RTC_Output_Disable: No output selected + * @arg RTC_Output_AlarmA: signal of AlarmA mapped to output + * @arg RTC_Output_AlarmB: signal of AlarmB mapped to output + * @arg RTC_Output_WakeUp: signal of WakeUp mapped to output + * @param RTC_OutputPolarity: Specifies the polarity of the output signal. + * This parameter can be one of the following: + * @arg RTC_OutputPolarity_High: The output pin is high when the + * ALRAF is high (depending on OSEL) + * @arg RTC_OutputPolarity_Low: The output pin is low when the + * ALRAF is high (depending on OSEL) + * @retval None + */ +void RTC_OutputConfig(uint32_t RTC_Output, uint32_t RTC_OutputPolarity) +{ + /* Check the parameters */ + assert_param(IS_RTC_OUTPUT(RTC_Output)); + assert_param(IS_RTC_OUTPUT_POL(RTC_OutputPolarity)); + + /* Clear the bits before configured */ + RTC->CR &= (uint32_t)~(RTC_CR_OSEL | RTC_CR_POL); + + /* Configure the output selection and polarity + * select rtc_alarm output is alraf/alrbf/wutf + * and rtc_alarm output polarity is high/low*/ + RTC->CR |= (uint32_t)(RTC_Output | RTC_OutputPolarity); +} +/** + * @} + */ + + +/** + * @brief Enables or disables the RTC_CALIB output through the relative pin. + * @param NewState: new state of the digital calibration Output. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RTC_CalibOutputCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the RTC_CALIB output */ + RTC->CR |= (uint32_t)RTC_CR_COE; + } + else + { + /* Disable the RTC_CALIB output */ + RTC->CR &= (uint32_t)~RTC_CR_COE; + } + +} + +/** + * @brief Configure the Calibration Pinout (RTC_CALIB) Selection (512Hz or 1Hz). + * @param RTC_CalibOutput: Select the Calibration output Selection . + * This parameter can be one of the following values: + * @arg RTC_CalibOutput_512Hz: A signal has a regular waveform at 512Hz. + * @arg RTC_CalibOutput_1Hz: A signal has a regular waveform at 1Hz. + * @retval None +*/ +void RTC_CalibOutputConfig(uint32_t RTC_CalibOutput) +{ + /* Check the parameters */ + assert_param(IS_RTC_CALIB_OUTPUT(RTC_CalibOutput)); + + /*clear flags before config*/ + RTC->CR &= (uint32_t)~(RTC_CR_COSEL); + + /* Configure the RTC_CR register + * Based on parameter RTC_CalibOutput_512Hz/1Hz*/ + RTC->CR |= (uint32_t)RTC_CalibOutput; + +} + +/** + * @brief Configures the Smooth Calibration Settings. + * @param RTC_SmoothCalibPeriod: Select the Smooth Calibration Period. + * This parameter can be can be one of the following values: + * @arg RTC_SmoothCalibPeriod_32sec: The smooth calibration periode is 32s. + * @arg RTC_SmoothCalibPeriod_16sec: The smooth calibration periode is 16s. + * @arg RTC_SmoothCalibPeriod_8sec: The smooth calibartion periode is 8s. + * @param RTC_SmoothCalibPlusPulses: Select to Set or reset the CALP bit. + * This parameter can be one of the following values: + * @arg RTC_SmoothCalibPlusPulses_Set: Add one RTCCLK puls every 2**11 pulses. + * @arg RTC_SmoothCalibPlusPulses_Reset: No RTCCLK pulses are added. + * @param RTC_SmoothCalibMinusPulsesValue: Select the value of CALM[8:0] bits. + * This parameter can be one any value from 0 to 0x000001FF. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: RTC Calib registers are configured + * - ERROR: RTC Calib registers are not configured +*/ +ErrorStatus RTC_SmoothCalibConfig(uint32_t RTC_SmoothCalibPeriod, + uint32_t RTC_SmoothCalibPlusPulses, + uint32_t RTC_SmoothCalibMinusPulsesValue) +{ + ErrorStatus status = ERROR; + uint32_t recalpfcount = 0; + + /* Check the parameters satisfy format*/ + assert_param(IS_RTC_SMOOTH_CALIB_PERIOD(RTC_SmoothCalibPeriod)); + assert_param(IS_RTC_SMOOTH_CALIB_PLUS(RTC_SmoothCalibPlusPulses)); + assert_param(IS_RTC_SMOOTH_CALIB_MINUS(RTC_SmoothCalibMinusPulsesValue)); + + /* check if a calibration is pending*/ + if ((RTC->ISR & RTC_ISR_RECALPF) != RESET) + { + /* wait until the Calibration is completed*/ + while (((RTC->ISR & RTC_ISR_RECALPF) != RESET) && (recalpfcount != RECALPF_TIMEOUT)) + { + recalpfcount++; + } + } + + /* check if the calibration pending is completed or if there is no calibration operation at all*/ + if ((RTC->ISR & RTC_ISR_RECALPF) == RESET) + { + /* Configure the Smooth calibration settings */ + RTC->CALR = (uint32_t)((uint32_t)RTC_SmoothCalibPeriod | \ + (uint32_t)RTC_SmoothCalibPlusPulses | \ + (uint32_t)RTC_SmoothCalibMinusPulsesValue); + status = SUCCESS; + } + else + { + status = ERROR; + } + + return (ErrorStatus)(status); +} +/** + * @} + */ + +/** + * @brief Enables or disables the RTC Rough Calibration. + * @param NewState: new state of the digital calibration Output. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RTC_RoughCalibration(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the RTC Rough Calibration */ + RTC->CR |= (uint32_t)RTC_CR_DCE; + } + else + { + /* Disable the RTC Rough Calibration */ + RTC->CR &= (uint32_t)~RTC_CR_DCE; + } + +} + +/** + * @brief Configures the Rough Digtial Calibration Settings. + * @param RTC_RoughCalibPlority: Select to Set or reset the DCS bit. + * This parameter can be one of the following values: + * @arg RTC_RoughCalibSymbol_Positive: Add calendar update frequence. + * @arg RTC_RoughCalibSymbol_Negative: Substract calendar update frequence. + * @param RTC_RoughCalibMinusPulsesValue: Select the value of DC[4:0] bits. + * This parameter can be one any value from 0 to 0x000001F. +*/ +void RTC_RoughDigtialCalibConfig(uint32_t RTC_RoughCalibPolarity, + uint32_t RTC_RoughCalibMinusPulsesValue) +{ + + /* Check the parameters satisfy format*/ + assert_param(IS_RTC_ROUGH_CALIB_SYMBOL(RTC_RoughCalibPolarity)); + assert_param(IS_RTC_ROUGH_CALIB_DC_VALUE(RTC_RoughCalibMinusPulsesValue)); + + /* clear the bits before config */ + RTC->CALIBR &= (uint32_t)~(RTC_CALIBR_DCS | RTC_CALIBR_DC); + + /* Configure the Smooth calibration settings */ + RTC->CALIBR |= (uint32_t)((uint32_t)RTC_RoughCalibPolarity | \ + (uint32_t)RTC_RoughCalibMinusPulsesValue); +} +/** + * @} + */ + + +/** + * @brief Enables or Disables the RTC TimeStamp functionality with + * the specified time stamp pin stimulating edge. + * @param RTC_TimeStampEdge: Specifies the pin edge on which the + * TimeStamp is activated. + * This parameter can be one of the following: + * @arg RTC_TimeStampEdge_Rising: the Time stamp event occurs on the rising + * edge of the related pin. + * @arg RTC_TimeStampEdge_Falling:the Time stamp event occurs on the + * falling edge of the related pin. + * @param NewState: new state of the TimeStamp. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RTC_TimeStampCmd(uint32_t RTC_TimeStampEdge, FunctionalState NewState) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RTC_TIMESTAMP_EDGE(RTC_TimeStampEdge)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + /* Get the RTC_CR register and clear the bits before configured */ + tmpreg = (uint32_t)(RTC->CR & (uint32_t)~(RTC_CR_TSEDGE | RTC_CR_TSE)); + + /* Get the new configuration */ + if (NewState != DISABLE) + { + /* Enable Timestamp and config occur edge */ + tmpreg |= (uint32_t)(RTC_TimeStampEdge | RTC_CR_TSE); + } + else + { + /* Not Enable Timestamp */ + tmpreg |= (uint32_t)(RTC_TimeStampEdge); + } + + /* Configure the Time Stamp TSEDGE and Enable bits */ + RTC->CR = (uint32_t)tmpreg; +} + +/** + * @brief Get the RTC TimeStamp value and masks. + * @param RTC_Format: specifies the format of the output parameters. + * This parameter can be one of the following values: + * @arg RTC_Format_BIN: Binary data format + * @arg RTC_Format_BCD: BCD data format + * @param RTC_StampTimeStruct: pointer to a RTC_TimeTypeDef structure that will + * contains the TimeStamp time values. + * @param RTC_StampDateStruct: pointer to a RTC_DateTypeDef structure that will + * contains the TimeStamp date values. + * @retval None + */ +void RTC_GetTimeStamp(uint32_t RTC_Format, + RTC_TimeTypeDef* RTC_StampTimeStruct, + RTC_DateTypeDef* RTC_StampDateStruct) +{ + uint32_t tmptime = 0, tmpdate = 0; + + /* Check the parameters */ + assert_param(IS_RTC_FORMAT(RTC_Format)); + + /* Get the TimeStamp time and date registers values */ + tmptime = (uint32_t)(RTC->TSTR & RTC_TSTR_RESERVED_MASK); + tmpdate = (uint32_t)(RTC->TSDR & RTC_TSDR_RESERVED_MASK); + + /* Fill the Time structure fields with the read parameters */ + RTC_StampTimeStruct->RTC_Hours = (uint8_t)((tmptime & (RTC_TSTR_HT | RTC_TSTR_HU)) >> 16); + RTC_StampTimeStruct->RTC_Minutes = (uint8_t)((tmptime & (RTC_TSTR_MNT | RTC_TSTR_MNU)) >> 8); + RTC_StampTimeStruct->RTC_Seconds = (uint8_t)(tmptime & (RTC_TSTR_ST | RTC_TSTR_SU)); + RTC_StampTimeStruct->RTC_H12 = (uint8_t)((tmptime & (RTC_TSTR_PM)) >> 22); + + /* Fill the Date structure fields with the read parameters */ + RTC_StampDateStruct->RTC_Year = 0; + RTC_StampDateStruct->RTC_Month = (uint8_t)((tmpdate & (RTC_TSDR_MT | RTC_TSDR_MU)) >> 8); + RTC_StampDateStruct->RTC_Date = (uint8_t)(tmpdate & (RTC_TSDR_DT | RTC_TSDR_DU)); + RTC_StampDateStruct->RTC_WeekDay = (uint8_t)((tmpdate & (RTC_TSDR_WDU)) >> 13); + + /* Check the input parameters format */ + if (RTC_Format == RTC_Format_BIN) + { + /* Convert the Time structure parameters to Binary format */ + RTC_StampTimeStruct->RTC_Hours = (uint8_t)RTC_Bcd2ToByte(RTC_StampTimeStruct->RTC_Hours); + RTC_StampTimeStruct->RTC_Minutes = (uint8_t)RTC_Bcd2ToByte(RTC_StampTimeStruct->RTC_Minutes); + RTC_StampTimeStruct->RTC_Seconds = (uint8_t)RTC_Bcd2ToByte(RTC_StampTimeStruct->RTC_Seconds); + + /* Convert the Date structure parameters to Binary format */ + RTC_StampDateStruct->RTC_Month = (uint8_t)RTC_Bcd2ToByte(RTC_StampDateStruct->RTC_Month); + RTC_StampDateStruct->RTC_Date = (uint8_t)RTC_Bcd2ToByte(RTC_StampDateStruct->RTC_Date); + RTC_StampDateStruct->RTC_WeekDay = (uint8_t)RTC_Bcd2ToByte(RTC_StampDateStruct->RTC_WeekDay); + } +} + +/** + * @brief Get the RTC timestamp Subseconds value. + * @param None + * @retval RTC current timestamp Subseconds value. + */ +uint32_t RTC_GetTimeStampSubSecond(void) +{ + /* Get timestamp subseconds values from the correspondent registers */ + return (uint32_t)(RTC->TSSSR); +} +/** + * @} + */ + +/** + * @brief Configures the select Tamper pin edge. + * @param RTC_Tamper: Selected tamper pin. + * This parameter can be any combination of the following values: + * @arg RTC_Tamper_1: Select Tamper 1. + * @arg RTC_Tamper_2: Select Tamper 2. + * @param RTC_TamperTrigger: Specifies the trigger on the tamper pin that + * stimulates tamper event. + * This parameter can be one of the following values: + * @arg RTC_TamperTrigger_RisingEdge: Rising Edge of the tamper pin causes tamper event. + * @arg RTC_TamperTrigger_FallingEdge: Falling Edge of the tamper pin causes tamper event. + * @arg RTC_TamperTrigger_LowLevel: Low Level of the tamper pin causes tamper event. + * @arg RTC_TamperTrigger_HighLevel: High Level of the tamper pin causes tamper event. + * @retval None + */ +void RTC_TamperTriggerConfig(uint32_t RTC_Tamper, uint32_t RTC_TamperTrigger) +{ + /* Check the parameters */ + assert_param(IS_RTC_TAMPER(RTC_Tamper)); + assert_param(IS_RTC_TAMPER_TRIGGER(RTC_TamperTrigger)); + + /* while tampflt==00,the pin edge trigger tamper event */ + if (RTC_TamperTrigger == RTC_TamperTrigger_RisingEdge) + { + /* Configure the RTC_TAFCR register */ + /* Clear Tamp1trg or Tamp2trg */ + RTC->TAFCR &= (uint32_t)((uint32_t)~(RTC_Tamper << 1)); + } + + if (RTC_TamperTrigger == RTC_TamperTrigger_FallingEdge) + { + /* Configure the RTC_TAFCR register */ + /* Set Tamp1trg or Tamp2trg */ + RTC->TAFCR |= (uint32_t)(RTC_Tamper << 1); + } + + /* while tampflt!=00,the pin level trigger tamper event */ + if (RTC_TamperTrigger == RTC_TamperTrigger_LowLevel) + { + /* Configure the RTC_TAFCR register */ + /* Clear Tamp1trg or Tamp2trg */ + RTC->TAFCR &= (uint32_t)((uint32_t)~(RTC_Tamper << 1)); + } + + if (RTC_TamperTrigger == RTC_TamperTrigger_HighLevel) + { + /* Configure the RTC_TAFCR register */ + /* Set Tamp1trg or Tamp2trg */ + RTC->TAFCR |= (uint32_t)(RTC_Tamper << 1); + } +} + +/** + * @brief Enables or Disables the Tamper detection. + * @param RTC_Tamper: Selected tamper pin. + * This parameter can be any combination of the following values: + * @arg RTC_Tamper_1: Select Tamper 1. + * @arg RTC_Tamper_2: Select Tamper 2. + * @param NewState: new state of the tamper pin. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RTC_TamperCmd(uint32_t RTC_Tamper, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RTC_TAMPER(RTC_Tamper)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected Tamper1 or Tamper2 pin */ + RTC->TAFCR |= (uint32_t)RTC_Tamper; + } + else + { + /* Disable the selected Tamper1 or Tamper2 pin */ + RTC->TAFCR &= (uint32_t)~RTC_Tamper; + } +} + +/** + * @brief Configures the Tampers Filter. + * @param RTC_TamperFilter: Specifies the tampers filter. + * This parameter can be one of the following values: + * @arg RTC_TamperFilter_Disable: Tamper filter is disabled. + * @arg RTC_TamperFilter_2Sample: Tamper is activated after 2 + * consecutive samples at the active level + * @arg RTC_TamperFilter_4Sample: Tamper is activated after 4 + * consecutive samples at the active level + * @arg RTC_TamperFilter_8Sample: Tamper is activated after 8 + * consecutive samples at the active level + * @retval None + */ +void RTC_TamperFilterConfig(uint32_t RTC_TamperFilter) +{ + /* Check the parameters */ + assert_param(IS_RTC_TAMPER_FILTER(RTC_TamperFilter)); + + /* Clear TAMPFLT[1:0] bits in the RTC_TAFCR register */ + RTC->TAFCR &= (uint32_t)~(RTC_TAFCR_TAMPFLT); + + /* Configure the RTC_TAFCR register */ + RTC->TAFCR |= (uint32_t)RTC_TamperFilter; +} + +/** + * @brief Configures the Tampers Sampling Frequency. + * @param RTC_TamperSamplingFreq: Specifies the tampers Sampling Frequency. + * This parameter can be one of the following values: + * @arg RTC_TamperSamplingFreq_RTCCLK_Div32768: Tamper inputs sampled frequency = RTCCLK / 32768 + * @arg RTC_TamperSamplingFreq_RTCCLK_Div16384: Tamper inputs sampled frequency = RTCCLK / 16384 + * @arg RTC_TamperSamplingFreq_RTCCLK_Div8192: Tamper inputs sampled frequency = RTCCLK / 8192 + * @arg RTC_TamperSamplingFreq_RTCCLK_Div4096: Tamper inputs sampled frequency = RTCCLK / 4096 + * @arg RTC_TamperSamplingFreq_RTCCLK_Div2048: Tamper inputs sampled frequency = RTCCLK / 2048 + * @arg RTC_TamperSamplingFreq_RTCCLK_Div1024: Tamper inputs sampled frequency = RTCCLK / 1024 + * @arg RTC_TamperSamplingFreq_RTCCLK_Div512: Tamper inputs sampled frequency = RTCCLK / 512 + * @arg RTC_TamperSamplingFreq_RTCCLK_Div256: Tamper inputs sampled frequency = RTCCLK / 256 + * @retval None + */ +void RTC_TamperSamplingFreqConfig(uint32_t RTC_TamperSamplingFreq) +{ + /* Check the parameters */ + assert_param(IS_RTC_TAMPER_SAMPLING_FREQ(RTC_TamperSamplingFreq)); + + /* Clear TAMPFREQ[2:0] bits in the RTC_TAFCR register */ + RTC->TAFCR &= (uint32_t)~(RTC_TAFCR_TAMPFREQ); + + /* Configure the RTC_TAFCR register */ + RTC->TAFCR |= (uint32_t)RTC_TamperSamplingFreq; +} + +/** + * @brief Configures the Tampers Pins input Precharge Duration. + * @param RTC_TamperPrechargeDuration: Specifies the Tampers Pins input Precharge Duration. + * This parameter can be one of the following values: + * @arg RTC_TamperPrechargeDuration_1RTCCLK: Tamper pins are precharged 1 RTCCLK + * @arg RTC_TamperPrechargeDuration_2RTCCLK: Tamper pins are precharged 2 RTCCLK + * @arg RTC_TamperPrechargeDuration_4RTCCLK: Tamper pins are precharged 4 RTCCLK + * @arg RTC_TamperPrechargeDuration_8RTCCLK: Tamper pins are precharged 8 RTCCLK + * @retval None + */ +void RTC_TamperPinsPrechargeDuration(uint32_t RTC_TamperPrechargeDuration) +{ + /* Check the parameters */ + assert_param(IS_RTC_TAMPER_PRECHARGE_DURATION(RTC_TamperPrechargeDuration)); + + /* Clear TAMPPRCH[1:0] bits in the RTC_TAFCR register */ + RTC->TAFCR &= (uint32_t)~(RTC_TAFCR_TAMPPRCH); + + /* Configure the RTC_TAFCR register */ + RTC->TAFCR |= (uint32_t)RTC_TamperPrechargeDuration; +} + +/** + * @brief Enables or Disables the TimeStamp on Tamper Detection Event. + * @note The timestamp is valid even the TSE bit in tamper control register + * is reset. + * @param NewState: new state of the timestamp on tamper event. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RTC_TimeStampOnTamperDetectionCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Save timestamp on tamper detection event */ + /* tamp event trigger timestamp */ + RTC->TAFCR |= (uint32_t)RTC_TAFCR_TAMPTS; + } + else + { + /* Tamper detection does not cause a timestamp to be saved */ + RTC->TAFCR &= (uint32_t)~RTC_TAFCR_TAMPTS; + } +} + +/** + * @brief Enables or Disables the Precharge of Tamper pin. + * @param NewState: new state of tamper pull up. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RTC_TamperPullUpCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable precharge of the selected Tamper pin */ + /* precharge tamp pin before sampled */ + RTC->TAFCR &= (uint32_t)~RTC_TAFCR_TAMPPUDIS; + } + else + { + /* Disable precharge of the selected Tamper pin */ + /* Forbidded tamp pins precharge function */ + RTC->TAFCR |= (uint32_t)RTC_TAFCR_TAMPPUDIS; + } +} +/** + * @} + */ + +/** + * @brief Configures the RTC Output Pin mode. + * @param RTC_OutputType: specifies the RTC Output (PC13) pin mode. + * This parameter can be one of the following values: + * @arg RTC_OutputType_OpenDrain: RTC Output (PC13) is configured in + * Open Drain mode. + * @arg RTC_OutputType_PushPull: RTC Output (PC13) is configured in + * Push Pull mode. + * @retval None + */ +void RTC_OutputTypeConfig(uint32_t RTC_OutputType) +{ + /* Check the parameters */ + assert_param(IS_RTC_OUTPUT_TYPE(RTC_OutputType)); + + RTC->TAFCR &= (uint32_t)~(RTC_TAFCR_PC13VALUE); + RTC->TAFCR |= (uint32_t)(RTC_OutputType); +} +/** + * @} + */ + +/** + * @brief Configures the RTC Output Pin mode. + * @param RTC_OutputMode: specifies the RTC Output (PC13) pin mode. + * This parameter can be one of the following values: + * @arg RTC_PC13_OutputType_GPIO: RTC Output (PC13) is configured in + * gpio. + * @arg RTC_PC13_OutputType_PushPull: RTC Output (PC13) is configured in + * Push Pull mode. + * @retval None + */ +void RTC_OutputModeConfig(uint32_t RTC_OutputMode) +{ + /* Check the parameters */ + assert_param(IS_RTC_PC13_OUTPUT_TYPE(RTC_OutputMode)); + + RTC->TAFCR &= (uint32_t)~(RTC_TAFCR_PC13MODE); + RTC->TAFCR |= (uint32_t)(RTC_OutputMode); +} +/** + * @} + */ + +/** + * @brief Configures the RTC Pc15 Output Pin mode. + * @param RTC_Pc15_OutputType: specifies the RTC Output (PC15) pin mode. + * This parameter can be one of the following values: + * @arg RTC_PC15_OutputType_GPIO: RTC Output (PC15) is configured by gpio. + * @arg RTC_PC15_OutputType_PushPull: RTC Output (PC15) is configured Push Pull mode. + * @param RTC_Pc15_OutputData: specifies the RTC Output (PC15) data. + * This parameter can be one of the following values: + * @arg RTC_PC15_OutputData_0: RTC Output Data (PC15) is configured 0. + * @arg RTC_PC15_OutputData_1: RTC Output Data (PC15) is configured 1. + * @retval None + */ +void RTC_Pc15_OutputTypeDataConfig(uint32_t RTC_Pc15_OutputType, uint32_t RTC_Pc15_OutputData) +{ + /* Check the parameters */ + assert_param(IS_RTC_PC15_OUTPUT_TYPE(RTC_Pc15_OutputType)); + assert_param(IS_RTC_PC15_OUTPUT_DATA(RTC_Pc15_OutputData)); + + /*clear pc15mode and value*/ + RTC->TAFCR &= ~(uint32_t)(RTC_PC15_OutputType_PushPull | RTC_PC15_OutputData_1); + + /* config pc14mode and value */ + RTC->TAFCR |= (uint32_t)(RTC_Pc15_OutputType | RTC_Pc15_OutputData); +} +/** + * @} + */ + +/** + * @brief Configures the RTC Pc14 Output Pin mode. + * @param RTC_Pc14_OutputType: specifies the RTC Output (PC14) pin mode. + * This parameter can be one of the following values: + * @arg RTC_PC14_OutputType_GPIO: RTC Output (PC14) is configured by gpio. + * @arg RTC_PC14_OutputType_PushPull: RTC Output (PC14) is configured Push Pull mode. + * @param RTC_Pc14_OutputData: specifies the RTC Output (PC14) data. + * This parameter can be one of the following values: + * @arg RTC_PC14_OutputData_0: RTC Output Data (PC14) is configured 0. + * @arg RTC_PC14_OutputData_1: RTC Output Data (PC14) is configured 1. + * @retval None + */ +void RTC_Pc14_OutputTypeDataConfig(uint32_t RTC_Pc14_OutputType, uint32_t RTC_Pc14_OutputData) +{ + /* Check the parameters */ + assert_param(IS_RTC_PC14_OUTPUT_TYPE(RTC_Pc14_OutputType)); + assert_param(IS_RTC_PC14_OUTPUT_DATA(RTC_Pc14_OutputData)); + + /*clear pc14mode and value*/ + RTC->TAFCR &= ~(uint32_t)(RTC_PC14_OutputType_PushPull | RTC_PC14_OutputData_1); + + /* config pc14mode and value */ + RTC->TAFCR |= (uint32_t)(RTC_Pc14_OutputType | RTC_Pc14_OutputData); +} +/** + * @} + */ + +/** + * @brief Configures the Synchronization Shift Control Settings. + * @note When REFCKON is set, firmware must not write to Shift control register + * @param RTC_ShiftAdd1S: Select to add or not 1 second to the time Calendar. + * This parameter can be one of the following values : + * @arg RTC_ShiftAdd1S_Set: Add one second to the clock calendar. + * @arg RTC_ShiftAdd1S_Reset: No effect. + * @param RTC_ShiftSubFS: Select the number of Second Fractions to Substitute. + * This parameter can be one any value from 0 to 0x7FFF. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: RTC Shift registers are configured + * - ERROR: RTC Shift registers are not configured +*/ +ErrorStatus RTC_SynchroShiftConfig(uint32_t RTC_ShiftAdd1S, uint32_t RTC_ShiftSubFS) +{ + ErrorStatus status = ERROR; + uint32_t shpfcount = 0; + + /* Check the parameters */ + assert_param(IS_RTC_SHIFT_ADD1S(RTC_ShiftAdd1S)); + assert_param(IS_RTC_SHIFT_SUBFS(RTC_ShiftSubFS)); + + /* Check if a Shift is pending*/ + if ((RTC->ISR & RTC_ISR_SHPF) != RESET) + { + /* Wait until the shift is completed*/ + while (((RTC->ISR & RTC_ISR_SHPF) != RESET) && (shpfcount != SHPF_TIMEOUT)) + { + shpfcount++; + } + } + + /* Check if the Shift pending is completed or if there is no Shift operation at all*/ + if ((RTC->ISR & RTC_ISR_SHPF) == RESET) + { + /* check if the reference clock detection is disabled */ + if ((RTC->CR & RTC_CR_REFCKON) == RESET) + { + /* Configure the Shift settings */ + RTC->SHIFTR = (uint32_t)(uint32_t)(RTC_ShiftSubFS) | (uint32_t)(RTC_ShiftAdd1S); + status = SUCCESS;/* reference clock detection is disabled, shiftr can be config */ + } + else + { + status = ERROR;/* reference clock detection is enabled, shiftr can not config */ + } + } + else + { + status = ERROR;/* shpf be set, shiftr can not config */ + } + + return (ErrorStatus)(status); +} +/** + * @} + */ + +/** + * @brief Enables or disables the specified RTC interrupts. + * @param RTC_IT_ENABLE: specifies the RTC interrupt sources to + * be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg RTC_IT_TS_EN: Time Stamp interrupt mask + * @arg RTC_IT_WUT_EN: WakeUp Timer interrupt mask + * @arg RTC_IT_ALRB_EN: Alarm B interrupt mask + * @arg RTC_IT_ALRA_EN: Alarm A interrupt mask + * @arg RTC_IT_TAMP_EN: Tamper event interrupt mask + * @param NewState: new state of the specified RTC interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RTC_ITConfig(uint32_t RTC_IT_ENABLE, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RTC_CONFIG_IT(RTC_IT_ENABLE)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Configure the Interrupts in the RTC_CR register */ + RTC->CR |= (uint32_t)(RTC_IT_ENABLE & ~RTC_TAFCR_TAMPIE); + /* Configure the Tamper Interrupt in the RTC_TAFCR */ + RTC->TAFCR |= (uint32_t)(RTC_IT_ENABLE & RTC_TAFCR_TAMPIE); + } + else + { + /* Configure the Interrupts in the RTC_CR register */ + RTC->CR &= (uint32_t)~(RTC_IT_ENABLE & ~RTC_TAFCR_TAMPIE); + /* Configure the Tamper Interrupt in the RTC_TAFCR */ + RTC->TAFCR &= (uint32_t)~(RTC_IT_ENABLE & RTC_TAFCR_TAMPIE); + } +} + +/** + * @brief Checks whether the specified RTC flag is set or not. + * @param RTC_FLAG: specifies the flag to check. + * This parameter can be one of the following values: + * @arg RTC_FLAG_RECALPF: RECALPF event flag + * @arg RTC_FLAG_TAMP2F: Tamper 2 event flag + * @arg RTC_FLAG_TAMP1F: Tamper 1 event flag + * @arg RTC_FLAG_TSOVF: Time Stamp OverFlow flag + * @arg RTC_FLAG_TSF: Time Stamp event flag + * @arg RTC_FLAG_WUTF: Auto WakeUp Timer flag + * @arg RTC_FLAG_ALRBF: Alarm B flag + * @arg RTC_FLAG_ALRAF: Alarm A flag + * @arg RTC_FLAG_INITF: Initialization mode flag + * @arg RTC_FLAG_RSF: Calendar Shadow Registers Synchronized flag + * @arg RTC_FLAG_INITS: Calendar initialization flag + * @arg RTC_FLAG_SHPF: Shift Operation Pending flag + * @arg RTC_FLAG_WUTWF: Auto Weakup Register allow write flag + * @arg RTC_FLAG_ALRBWF: Alarma Registers allow write flag + * @arg RTC_FLAG_ALRAWF: Alarmb Registers allow write flag + * @retval The new state of RTC_FLAG (SET or RESET). + */ +FlagStatus RTC_GetFlagStatus(uint32_t RTC_FLAG) +{ + FlagStatus bitstatus = RESET; + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RTC_GET_FLAG(RTC_FLAG)); + + /* Get all the flags */ + tmpreg = (uint32_t)(RTC->ISR & RTC_FLAGS_MASK); + + /* Return the status of the flag */ + /* Check Rtc_Flag if be set */ + if ((tmpreg & RTC_FLAG) != (uint32_t)RESET) + { + bitstatus = SET;/* rtc_flag be set */ + } + else + { + bitstatus = RESET;/* rtc_flag not be set */ + } + return bitstatus; +} + +/** + * @brief Clears the RTC's pending flags. + * @param RTC_FLAG: specifies the RTC flag to clear. + * This parameter can be any combination of the following values: + * @arg RTC_FLAG_TAMP2F: Tamper 2 event flag + * @arg RTC_FLAG_TAMP1F: Tamper 1 event flag + * @arg RTC_FLAG_TSOVF: Time Stamp Overflow flag + * @arg RTC_FLAG_TSF: Time Stamp event flag + * @arg RTC_FLAG_WUTF: aUTO WakeUp Timer flag + * @arg RTC_FLAG_ALRBF: Alarm B flag + * @arg RTC_FLAG_ALRAF: Alarm A flag + * @arg RTC_FLAG_RSF: Calendar Shadow Registers Synchronized flag + * @retval None + */ +void RTC_ClearFlag(uint32_t RTC_FLAG) +{ + /* Check the parameters */ + assert_param(IS_RTC_CLEAR_FLAG(RTC_FLAG)); + + /* Clear the Flags in the RTC_ISR register */ + RTC->ISR &= ~(uint32_t)RTC_FLAG; +} + +/** + * @brief Checks whether the specified RTC interrupt has occurred or not. + * @param RTC_IT_ENABLE: specifies the RTC interrupt source to check. + * This parameter can be one of the following values: + * @arg RTC_IT_TS_EN: Time Stamp interrupt + * @arg RTC_IT_WUT_EN: Auto WakeUp Timer interrupt + * @arg RTC_IT_ALRB_EN: Alarm B interrupt + * @arg RTC_IT_ALRA_EN: Alarm A interrupt + * @arg RTC_IT_TAMP_EN: Tamper interrupt + * @retval The new state of RTC_IT (SET or RESET). + */ +ITStatus RTC_GetITStatus(uint32_t RTC_IT_ENABLE) +{ + ITStatus bitstatus = RESET; + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RTC_GET_IT(RTC_IT_ENABLE)); + + if (RTC_IT_ENABLE == RTC_IT_TAMP_EN) + { + /* Get rtc_tamp interrupt enable */ + tmpreg = (uint32_t)(RTC->TAFCR & RTC_TAFCR_TAMPIE); + /* Check rtc_tamp interrupt if be enable */ + if (tmpreg != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + } + else + { + /* Get rtc_cr register's interrupt enable */ + tmpreg = (uint32_t)(RTC->CR & RTC_IT_ENABLE); + /* Check rtc_cr register's interrupt if be enable */ + if (tmpreg != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + } + + return bitstatus; +} + +/** + * @brief Clears the RTC's interrupt pending bits. + * @param RTC_IT_FLAG: specifies the RTC interrupt pending bit to clear. + * This parameter can be any combination of the following values: + * @arg RTC_IT_TS: Time Stamp interrupt + * @arg RTC_IT_WUT: WakeUp Timer interrupt + * @arg RTC_IT_ALRB: Alarm B interrupt + * @arg RTC_IT_ALRA: Alarm A interrupt + * @arg RTC_IT_TAMP1: Tamper1 event interrupt + * @arg RTC_IT_TAMP2: Tamper2 event interrupt + * @retval None + */ +void RTC_ClearITPendingBit(uint32_t RTC_IT_FLAG) +{ + + /* Check the parameters */ + assert_param(IS_RTC_CLEAR_IT(RTC_IT_FLAG)); + + /* Clear the interrupt pending bits in the RTC_ISR register */ + RTC->ISR &= (uint32_t)~((uint32_t)RTC_IT_FLAG); +} +/** + * @} + */ + +/** + * @brief Enables or Disables the Auto Weakup. + * @note The auto weakup is valid even the WUTE bit in rtc control register + * is defaut reset. + * @param NewState: new state of the timestamp on tamper event. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RTC_WeakUpCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable Auto WeakUp Function */ + RTC->CR |= (uint32_t)RTC_CR_WUTE; + } + else + { + /* Disable Auto WeakUp Function */ + RTC->CR &= (uint32_t)~RTC_CR_WUTE; + } +} + +/** + * @brief Configures the Auto WeakUp Counter. + * @param RTC_WeakUp_Counter: Specifies the tampers filter. + * This parameter only on the range of 0~0xFFFF + * @retval None + */ +void RTC_SetWeakUpCounter(uint32_t RTC_WeakUp_Counter) +{ + /* Check the parameters */ + assert_param(IS_RTC_WKUP_COUNTER(RTC_WeakUp_Counter)); + + /* Clear WUTR[15:0] bits in the RTC_WUTR register */ + RTC->WUTR &= (uint32_t)~(RTC_WUTR_MASK); + + /* Configure the RTC_WUTR register */ + RTC->WUTR |= (uint32_t)RTC_WeakUp_Counter; +} + +/** + * @brief Get the Auto WeakUp Counter. + * @param RTC_WeakUp_Counter: Specifies the tampers filter. + * This parameter only on the range of 0~0xFFFF + * @retval None + */ +uint32_t RTC_GetWeakUpCounter(void) +{ + /* Return the RTC_WUTR register */ + return (uint32_t)(RTC->WUTR); +} + +/** + * @brief Configures the Auto WeakUp Counting Frequency. + * @param RTC_WeakUpCountFreq: Specifies the tampers Sampling Frequency. + * This parameter can be one of the following values: + * @arg RTC_WeakUp_RTCCLK_Div16: Auto WeakUp Counting frequency = RTCCLK/16 + * @arg RTC_WeakUp_RTCCLK_Div8: Auto WeakUp Counting frequency = RTCCLK/8 + * @arg RTC_WeakUp_RTCCLK_Div4: Auto WeakUp Counting frequency = RTCCLK/4 + * @arg RTC_WeakUp_RTCCLK_Div2: Auto WeakUp Counting frequency = RTCCLK/2 + * @arg RTC_WeakUp_RTCCLK_CkSpre4: Auto WeakUp Counting frequency = CK_SPRE4 + * @arg RTC_WeakUp_RTCCLK_CkSpre5: Auto WeakUp Counting frequency = CK_SPRE5 + * @arg RTC_WeakUp_RTCCLK_CkSpre6: Auto WeakUp Counting frequency = CK_SPRE6 + * @arg RTC_WeakUp_RTCCLK_CkSpre7: Auto WeakUp Counting frequency = CK_SPRE7 + * @retval None + */ +void RTC_WeakUpCountFreqConfig(uint32_t RTC_WeakUpCountFreq) +{ + /* Check the parameters */ + assert_param(IS_RTC_WKUP_COUNTER(RTC_WeakUpCountFreq)); + + /* Clear WUCKSEL[2:0] bits in the RTC_CR register */ + RTC->CR &= (uint32_t)~(RTC_CR_WUCKSEL); + + /* Configure the RTC_CR register */ + RTC->CR |= (uint32_t)RTC_WeakUpCountFreq; +} + +/** + * @brief Configures the BackUp Register Data. + * @param RTC_BackUpReg:choose rtc backup reg + * This parameter can be one of the following values: + * @arg RTC_BackUp0Reg: choose bkp0r reg + * @arg RTC_BackUp1Reg: choose bkp1r reg + * @arg RTC_BackUp2Reg: choose bkp2r reg + * @arg RTC_BackUp3Reg: choose bkp3r reg + * @arg RTC_BackUp4Reg: choose bkp4r reg + * @arg RTC_BackUp5Reg: choose bkp5r reg + * @arg RTC_BackUp6Reg: choose bkp6r reg + * @arg RTC_BackUp7Reg: choose bkp7r reg + * @arg RTC_BackUp8Reg: choose bkp8r reg + * @arg RTC_BackUp9Reg: choose bkp9r reg + * @arg RTC_BackUp10Reg: choose bkp10r reg + * @arg RTC_BackUp11Reg: choose bkp11r reg + * @arg RTC_BackUp12Reg: choose bkp12r reg + * @arg RTC_BackUp13Reg: choose bkp13r reg + * @arg RTC_BackUp14Reg: choose bkp14r reg + * @arg RTC_BackUp15Reg: choose bkp15r reg + * @arg RTC_BackUp16Reg: choose bkp16r reg + * @arg RTC_BackUp17Reg: choose bkp17r reg + * @arg RTC_BackUp18Reg: choose bkp18r reg + * @arg RTC_BackUp19Reg: choose bkp19r reg + * @param RTC_BackUpRegData: Specifies the rtc backup register data. + * This parameter can be only range of the 0~0xFFFFFFFF: + * @retval None + */ +void RTC_BackUpRegConfig(uint32_t RTC_BackUpReg, uint32_t RTC_BackUpRegData) +{ + /* Check the parameters */ + assert_param(IS_RTC_BACKUP_REG(RTC_BackUpReg)); + assert_param(IS_RTC_BACKUP_DATA(RTC_BackUpRegData)); + + if (RTC_BackUpReg == RTC_BackUp0Reg) + { + /* Clear BackUp0 register */ + RTC->BKP0R &= (uint32_t)~(RTC_BKP0R); + + /* Configure the RTC_BKP0R register */ + RTC->BKP0R |= (uint32_t)RTC_BackUpRegData; + } + + if (RTC_BackUpReg == RTC_BackUp1Reg) + { + /* Clear BackUp1 register */ + RTC->BKP1R &= (uint32_t)~(RTC_BKP1R); + + /* Configure the RTC_BKP1R register */ + RTC->BKP1R |= (uint32_t)RTC_BackUpRegData; + } + + if (RTC_BackUpReg == RTC_BackUp2Reg) + { + /* Clear BackUp2 register */ + RTC->BKP2R &= (uint32_t)~(RTC_BKP2R); + + /* Configure the RTC_BKP2R register */ + RTC->BKP2R |= (uint32_t)RTC_BackUpRegData; + } + + if (RTC_BackUpReg == RTC_BackUp3Reg) + { + /* Clear BackUp3 register */ + RTC->BKP3R &= (uint32_t)~(RTC_BKP3R); + + /* Configure the RTC_BKP3R register */ + RTC->BKP3R |= (uint32_t)RTC_BackUpRegData; + } + + if (RTC_BackUpReg == RTC_BackUp4Reg) + { + /* Clear BackUp4 register */ + RTC->BKP4R &= (uint32_t)~(RTC_BKP4R); + + /* Configure the RTC_BKP4R register */ + RTC->BKP4R |= (uint32_t)RTC_BackUpRegData; + } + + if (RTC_BackUpReg == RTC_BackUp5Reg) + { + /* Clear BackUp5 register */ + RTC->BKP5R &= (uint32_t)~(RTC_BKP5R); + + /* Configure the RTC_BKP5R register */ + RTC->BKP5R |= (uint32_t)RTC_BackUpRegData; + } + + if (RTC_BackUpReg == RTC_BackUp6Reg) + { + /* Clear BackUp6 register */ + RTC->BKP6R &= (uint32_t)~(RTC_BKP6R); + + /* Configure the RTC_BKP6R register */ + RTC->BKP6R |= (uint32_t)RTC_BackUpRegData; + } + + if (RTC_BackUpReg == RTC_BackUp7Reg) + { + /* Clear BackUp7 register */ + RTC->BKP7R &= (uint32_t)~(RTC_BKP7R); + + /* Configure the RTC_BKP7R register */ + RTC->BKP7R |= (uint32_t)RTC_BackUpRegData; + } + + if (RTC_BackUpReg == RTC_BackUp8Reg) + { + /* Clear BackUp8 register */ + RTC->BKP8R &= (uint32_t)~(RTC_BKP8R); + + /* Configure the RTC_BKP8R register */ + RTC->BKP8R |= (uint32_t)RTC_BackUpRegData; + } + + if (RTC_BackUpReg == RTC_BackUp9Reg) + { + /* Clear BackUp9 register */ + RTC->BKP9R &= (uint32_t)~(RTC_BKP9R); + + /* Configure the RTC_BKP9R register */ + RTC->BKP9R |= (uint32_t)RTC_BackUpRegData; + } + + if (RTC_BackUpReg == RTC_BackUp10Reg) + { + /* Clear BackUp10 register */ + RTC->BKP10R &= (uint32_t)~(RTC_BKP10R); + + /* Configure the RTC_BKP10R register */ + RTC->BKP10R |= (uint32_t)RTC_BackUpRegData; + } + + if (RTC_BackUpReg == RTC_BackUp11Reg) + { + /* Clear BackUp11 register */ + RTC->BKP11R &= (uint32_t)~(RTC_BKP11R); + + /* Configure the RTC_BKP11R register */ + RTC->BKP11R |= (uint32_t)RTC_BackUpRegData; + } + + if (RTC_BackUpReg == RTC_BackUp12Reg) + { + /* Clear BackUp12 register */ + RTC->BKP12R &= (uint32_t)~(RTC_BKP12R); + + /* Configure the RTC_BKP12R register */ + RTC->BKP12R |= (uint32_t)RTC_BackUpRegData; + } + + if (RTC_BackUpReg == RTC_BackUp13Reg) + { + /* Clear BackUp13 register */ + RTC->BKP13R &= (uint32_t)~(RTC_BKP13R); + + /* Configure the RTC_BKP13R register */ + RTC->BKP13R |= (uint32_t)RTC_BackUpRegData; + } + + if (RTC_BackUpReg == RTC_BackUp14Reg) + { + /* Clear BackUp14 register */ + RTC->BKP14R &= (uint32_t)~(RTC_BKP14R); + + /* Configure the RTC_BKP14R register */ + RTC->BKP14R |= (uint32_t)RTC_BackUpRegData; + } + + if (RTC_BackUpReg == RTC_BackUp15Reg) + { + /* Clear BackUp15 register */ + RTC->BKP15R &= (uint32_t)~(RTC_BKP15R); + + /* Configure the RTC_BKP15R register */ + RTC->BKP15R |= (uint32_t)RTC_BackUpRegData; + } + + if (RTC_BackUpReg == RTC_BackUp16Reg) + { + /* Clear BackUp16 register */ + RTC->BKP16R &= (uint32_t)~(RTC_BKP16R); + + /* Configure the RTC_BKP16R register */ + RTC->BKP16R |= (uint32_t)RTC_BackUpRegData; + } + + if (RTC_BackUpReg == RTC_BackUp17Reg) + { + /* Clear BackUp17 register */ + RTC->BKP17R &= (uint32_t)~(RTC_BKP17R); + + /* Configure the RTC_BKP17R register */ + RTC->BKP17R |= (uint32_t)RTC_BackUpRegData; + } + + if (RTC_BackUpReg == RTC_BackUp18Reg) + { + /* Clear BackUp18 register */ + RTC->BKP18R &= (uint32_t)~(RTC_BKP18R); + + /* Configure the RTC_BKP18R register */ + RTC->BKP18R |= (uint32_t)RTC_BackUpRegData; + } + + if (RTC_BackUpReg == RTC_BackUp19Reg) + { + /* Clear BackUp19 register */ + RTC->BKP19R &= (uint32_t)~(RTC_BKP19R); + + /* Configure the RTC_BKP19R register */ + RTC->BKP19R |= (uint32_t)RTC_BackUpRegData; + } +} + +/** + * @brief Get the RTC BackUp Register value. + * @param RTC_BackUpReg:choose rtc backup reg + * This parameter can be one of the following values: + * @arg RTC_BackUp0Reg: choose bkp0r reg + * @arg RTC_BackUp1Reg: choose bkp1r reg + * @arg RTC_BackUp2Reg: choose bkp2r reg + * @arg RTC_BackUp3Reg: choose bkp3r reg + * @arg RTC_BackUp4Reg: choose bkp4r reg + * @arg RTC_BackUp5Reg: choose bkp5r reg + * @arg RTC_BackUp6Reg: choose bkp6r reg + * @arg RTC_BackUp7Reg: choose bkp7r reg + * @arg RTC_BackUp8Reg: choose bkp8r reg + * @arg RTC_BackUp9Reg: choose bkp9r reg + * @arg RTC_BackUp10Reg: choose bkp10r reg + * @arg RTC_BackUp11Reg: choose bkp11r reg + * @arg RTC_BackUp12Reg: choose bkp12r reg + * @arg RTC_BackUp13Reg: choose bkp13r reg + * @arg RTC_BackUp14Reg: choose bkp14r reg + * @arg RTC_BackUp15Reg: choose bkp15r reg + * @arg RTC_BackUp16Reg: choose bkp16r reg + * @arg RTC_BackUp17Reg: choose bkp17r reg + * @arg RTC_BackUp18Reg: choose bkp18r reg + * @arg RTC_BackUp19Reg: choose bkp19r reg + * * @retval RTC current BackUp Register value. + */ +uint32_t RTC_GetBackUpReg(uint32_t RTC_BackUpReg) +{ + /* Get BackUp Register values from the correspondent registers */ + /* Check the parameters */ + assert_param(IS_RTC_BACKUP_REG(RTC_BackUpReg)); + + if (RTC_BackUpReg == RTC_BackUp0Reg) + { + /* Return the RTC_BKP0R register */ + return (uint32_t)(RTC->BKP0R); + } + + if (RTC_BackUpReg == RTC_BackUp1Reg) + { + /* Return the RTC_BKP1R register */ + return (uint32_t)(RTC->BKP1R); + } + + if (RTC_BackUpReg == RTC_BackUp2Reg) + { + /* Return the RTC_BKP2R register */ + return (uint32_t)(RTC->BKP2R); + } + + if (RTC_BackUpReg == RTC_BackUp3Reg) + { + /* Return the RTC_BKP3R register */ + return (uint32_t)(RTC->BKP3R); + } + + if (RTC_BackUpReg == RTC_BackUp4Reg) + { + /* Return the RTC_BKP4R register */ + return (uint32_t)(RTC->BKP4R); + } + + if (RTC_BackUpReg == RTC_BackUp5Reg) + { + /* Return the RTC_BKP5R register */ + return (uint32_t)(RTC->BKP5R); + } + + if (RTC_BackUpReg == RTC_BackUp6Reg) + { + /* Return the RTC_BKP6R register */ + return (uint32_t)(RTC->BKP6R); + } + + if (RTC_BackUpReg == RTC_BackUp7Reg) + { + /* Return the RTC_BKP7R register */ + return (uint32_t)(RTC->BKP7R); + } + + if (RTC_BackUpReg == RTC_BackUp8Reg) + { + /* Return the RTC_BKP8R register */ + return (uint32_t)(RTC->BKP8R); + } + + if (RTC_BackUpReg == RTC_BackUp9Reg) + { + /* Return the RTC_BKP9R register */ + return (uint32_t)(RTC->BKP9R); + } + + if (RTC_BackUpReg == RTC_BackUp10Reg) + { + /* Return the RTC_BKP10R register */ + return (uint32_t)(RTC->BKP10R); + } + + if (RTC_BackUpReg == RTC_BackUp11Reg) + { + /* Return the RTC_BKP11R register */ + return (uint32_t)(RTC->BKP11R); + } + + if (RTC_BackUpReg == RTC_BackUp12Reg) + { + /* Return the RTC_BKP12R register */ + return (uint32_t)(RTC->BKP12R); + } + + if (RTC_BackUpReg == RTC_BackUp13Reg) + { + /* Return the RTC_BKP13R register */ + return (uint32_t)(RTC->BKP13R); + } + + if (RTC_BackUpReg == RTC_BackUp14Reg) + { + /* Return the RTC_BKP14R register */ + return (uint32_t)(RTC->BKP14R); + } + + if (RTC_BackUpReg == RTC_BackUp15Reg) + { + /* Return the RTC_BKP15R register */ + return (uint32_t)(RTC->BKP15R); + } + + if (RTC_BackUpReg == RTC_BackUp16Reg) + { + /* Return the RTC_BKP16R register */ + return (uint32_t)(RTC->BKP16R); + } + + if (RTC_BackUpReg == RTC_BackUp17Reg) + { + /* Return the RTC_BKP17R register */ + return (uint32_t)(RTC->BKP17R); + } + + if (RTC_BackUpReg == RTC_BackUp18Reg) + { + /* Return the RTC_BKP18R register */ + return (uint32_t)(RTC->BKP18R); + } + + if (RTC_BackUpReg == RTC_BackUp19Reg) + { + /* Return the RTC_BKP19R register */ + return (uint32_t)(RTC->BKP19R); + } + return 0; +} + + + + + + +/** + * @} + */ + + +/** + * @brief Converts a 2 digit decimal to BCD format. + * @param Value: Byte to be converted. + * @retval Converted byte + */ +static uint8_t RTC_ByteToBcd2(uint8_t Value) +{ + uint8_t bcdhigh = 0; + + while (Value >= 10) + { + bcdhigh++; + Value -= 10; + } + + return ((uint8_t)(bcdhigh << 4) | Value); +} + +/** + * @brief Convert from 2 digit BCD to Binary. + * @param Value: BCD value to be converted. + * @retval Converted word + */ +static uint8_t RTC_Bcd2ToByte(uint8_t Value) +{ + uint8_t tmp = 0; + tmp = ((uint8_t)(Value & (uint8_t)0xF0) >> (uint8_t)0x4) * 10; + return (tmp + (Value & (uint8_t)0x0F)); +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_sdio.c b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_sdio.c new file mode 100644 index 00000000000..3046101d0df --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_sdio.c @@ -0,0 +1,246 @@ +/** + ****************************************************************************** + * @file ft32f4xx_sdio.c + ****************************************************************************** + */ + + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx_sdio.h" +#include "system_ft32f4xx.h" +#include "ft32f4xx_rcc.h" + + +/** @defgroup SDIO + * @brief SDIO driver modules + * @{ + */ + +/*******************/ +void SDIO_DeInit(void) +{ + RCC_APB2PeriphResetCmd(RCC_APB2Periph_SDIO, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_SDIO, DISABLE); +} + +/*******************/ +void SDIO_odpullupConfig(uint32_t SDIO_odenable) +{ + /* 1.Clear CTRL_enable_OD_pullup bit */ + SDIO -> CTRL &= ~(0x1 << 24); + assert_param(IS_SDIO_OD_PULLUP(SDIO_odenable)); + SDIO -> CTRL |= SDIO_odenable; +} + + +/*******************/ +void SDIO_UseholdregConfig(uint32_t SDIO_Useholdregenable) +{ + /* 1.Clear CMD_use_hold_reg bit */ + SDIO -> CMD &= ~(0x1 << 29); + assert_param(IS_SDIO_USE_HOLD_REG(SDIO_Useholdregenable)); + SDIO -> CMD |= SDIO_Useholdregenable; +} + +/*******************/ +void SDIO_PowerEnableConfig(uint32_t SDIO_PowerEnable) +{ + assert_param(IS_SDIO_POWER_ON(SDIO_PowerEnable)); + SDIO -> PWREN = SDIO_PowerEnable; +} + + +/*******************/ +void SDIO_TimeOutConfig(uint32_t SDIO_TMOUTValue) +{ + /* Set the TMOUT bits include RESPONSE TMOUT and DATA TMOUT values */ + SDIO -> TMOUT = (uint32_t)SDIO_TMOUTValue; +} + + +/*******************/ +void SDIO_FifoThConfig(uint32_t SDIO_FIFOTHValue) +{ + /* Set the FIFOTH bits include Tx_WMark and Rx_WMark values */ + SDIO -> FIFOTH = (uint32_t)SDIO_FIFOTHValue; +} + + +/*******************/ +void SDIO_CardWidthConfig(uint32_t SDIO_CardWidth) +{ + assert_param(IS_SDIO_CARD_WIDE(SDIO_CardWidth)); + SDIO -> CTYPE = SDIO_CardWidth; +} + + +/*******************/ +void SDIO_TransferModeConfig(uint32_t SDIO_TransferMode) +{ + SDIO -> CMD &= ~(0x1 << 11); + assert_param(IS_SDIO_TRANSFER_MODE(SDIO_TransferMode)); + SDIO -> CMD |= SDIO_TransferMode; +} + + +/*******************/ +void SDIO_TransferDirectionConfig(uint32_t SDIO_ReadWrite) +{ + SDIO -> CMD &= ~(0x1 << 10); + assert_param(IS_SDIO_TRANSFER_DIR(SDIO_ReadWrite)); + SDIO -> CMD |= SDIO_ReadWrite; +} + + +/*******************/ +void SDIO_DataExpectedConfig(uint32_t SDIO_DataExpected) +{ + /* 1.Clear DataExpected bit */ + SDIO -> CMD &= ~(0x1 << 9); + assert_param(IS_SDIO_DATA_EXPECT(SDIO_DataExpected)); + SDIO -> CMD |= SDIO_DataExpected; +} + + +/*******************/ +void SDIO_CheckResponseCRCConfig(uint32_t SDIO_CheckResponseCRC) +{ + /* 1.Clear CheckResponseCRC bit */ + SDIO -> CMD &= ~(0x1 << 8); + assert_param(IS_SDIO_CHECK_RESPONSE_CRC(SDIO_CheckResponseCRC)); + SDIO -> CMD |= SDIO_CheckResponseCRC; +} + + +/*******************/ +void SDIO_ResponseLengthConfig(uint32_t SDIO_ResponseLength) +{ + /* 1.Clear ResponseLength bit */ + SDIO -> CMD &= ~(0x1 << 7); + assert_param(IS_SDIO_RESPONSE(SDIO_ResponseLength)); + SDIO -> CMD |= SDIO_ResponseLength; +} + + +/*******************/ +void SDIO_ResponseExpectConfig(uint32_t SDIO_ResponseExpect) +{ + /* 1.Clear ResponseExpect bit */ + SDIO -> CMD &= ~(0x1 << 6); + assert_param(IS_SDIO_RESPONSE_EXPECT(SDIO_ResponseExpect)); + SDIO -> CMD |= SDIO_ResponseExpect; +} + + +/*******************/ +void SDIO_ChangeCardClock(uint32_t SDIO_Clkdiv) +{ + /* 1.Clear CLKENA[0] bit */ + SDIO->CLKENA &= ~SDIO_CLKENA_CCLK_ENABLE_0; + /* 2.1.Check the parameters */ + assert_param(IS_SDIO_CLKDIV(SDIO_Clkdiv)); + /* 2.2.Clear CLKDIV[7:0] bits */ + SDIO->CLKDIV &= ~SDIO_CLKDIV_CLK_DIVIDER0; + /* 2.3.Set the SDIO_CLKDIV[7:0] bits according to SDIO_Clkdiv value */ + SDIO->CLKDIV |= SDIO_Clkdiv; + /* 3.Enable CMD_UPDATE_CLOCK_REGISTERS_ONLY bit */ + SDIO->CMD |= SDIO_CMD_UPDATE_CLOCK_REGISTERS_ONLY; + /* 4.Enable CLKENA[0] bit */ + SDIO->CLKENA |= SDIO_CLKENA_CCLK_ENABLE_0; + /* 5.Enable CMD_START_CMD bit */ + SDIO->CMD |= SDIO_CMD_START_CMD; + while (((SDIO -> CMD) & SDIO_CMD_START_CMD) == SDIO_CMD_START_CMD); + /* 6.Clean CMD_UPDATE_CLOCK_REGISTERS_ONLY bit */ + SDIO->CMD &= ~SDIO_CMD_UPDATE_CLOCK_REGISTERS_ONLY; +} + +/*******************/ +void SDIO_SendCMD(uint32_t SDIO_CmdIndex) +{ + /* 1.Clear CMD_INDEX bit */ + SDIO -> CMD &= ~(0x3F << 0); + /* 2.1.Check the parameters */ + assert_param(IS_SDIO_CMD_INDEX(SDIO_CmdIndex)); + /* 2.2.Send Command */ + SDIO -> CMD |= SDIO_CmdIndex; + /* 3.Enable CMD_START_CMD bit */ + SDIO->CMD |= SDIO_CMD_START_CMD; + while (((SDIO -> CMD) & SDIO_CMD_START_CMD) == SDIO_CMD_START_CMD); +} + + +/*******************/ +void SDIO_CMDARGConfig(uint32_t SDIO_CmdArgument) +{ + assert_param(IS_SDIO_CMD_ARG(SDIO_CmdArgument)); + SDIO -> CMDARG = SDIO_CmdArgument; +} + + +/*******************/ +void SDIO_BlockSizeConfig(uint32_t SDIO_BlockSize) +{ + assert_param(IS_SDIO_BLOCK_SIZE(SDIO_BlockSize)); + SDIO -> BLKSIZ = SDIO_BlockSize; +} + + +/*******************/ +void SDIO_ByteCountConfig(uint32_t SDIO_ByteCount) +{ + assert_param(IS_SDIO_DATA_BYTE_COUNT(SDIO_ByteCount)); + SDIO -> BYTCNT = SDIO_ByteCount; +} + + +/*******************/ +void SDIO_ITConfig(uint32_t SDIO_IT) +{ + /* 1.enable CTRL_int_enable bit */ + SDIO -> CTRL |= SDIO_CTRL_INT_ENABLE; + /* Check the parameters */ + assert_param(IS_SDIO_IT_MASK(SDIO_IT)); + SDIO->INTMASK |= SDIO_IT; +} + + +/*******************/ +FlagStatus SDIO_GetITFlag(uint32_t SDIO_FLAG) +{ + /* Check the parameters */ + assert_param(IS_SDIO_IT_FLAG(SDIO_FLAG)); + return ((FlagStatus)(SDIO->MINTSTS & SDIO_FLAG)); +} + + +/*******************/ +void SDIO_ClearITFlag(uint32_t SDIO_FLAG) +{ + /* Check the parameters */ + assert_param(IS_SDIO_IT_CLEAN(SDIO_FLAG)); + SDIO->RINTSTS |= SDIO_FLAG; +} + + +/*************/ +uint32_t SDIO_GetFifoStatus(uint32_t SDIO_FIFOStatus) +{ + /* Check the parameters */ + assert_param(IS_SDIO_STATUS(SDIO_FIFOStatus)); + return (uint32_t)((SDIO->STATUS) & SDIO_FIFOStatus); +} + + +/*************/ +uint32_t SDIO_GetStatus(uint32_t SDIO_Status) +{ + /* Check the parameters */ + assert_param(IS_SDIO_STATUS(SDIO_Status)); + return (uint32_t)((SDIO->STATUS) & SDIO_Status); +} +/***********************************************************************************/ +/***********************************************************************************/ + + + + diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_spdif.c b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_spdif.c new file mode 100644 index 00000000000..6dfead8dfb8 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_spdif.c @@ -0,0 +1,207 @@ +/** + ****************************************************************************** + * @file ft32f4xx_spdif.c + * @author xcao + * @brief This file provides firmware functions to manage the following + * functionalities of the SPDIFRX audio interface: + * + Initialization and Configuration + * + Data transfers functions + * + DMA transfers management + * + Interrupts and flags management + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx_spdif.h" +#include "ft32f4xx_misc.h" +#define MAX_DELAY 0xFFFF +/** @addtogroup FT32F4XX_Driver + * @{ + */ + +/** @defgroup SPDIF SPDIF + * @brief SPDIFmodule driver + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @defgroup SPDIF_Private_Defines SPDIF Private Defines + * @{ + */ + +/** + * @} + */ + +/* Exported functions ---------------------------------------------------------*/ + +/** @defgroup SPDIF_Exported_Functions SPDIF Exported Functions + * @{ + */ + +/** @defgroup SPDIF_Exported_Functions_Group1 Initialization + * @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 SPDIF peripheral: + + @endverbatim + * @{ + */ + +/** + * @brief Initializes the SPDIF according to the specified parameters + * in the SPDIF_InitTypeDef and create the associated handle. + * @param spdif SPDIF handle + * @retval NONE + */ +void SPDIFRX_Init(SPDIF_HandleTypeDef *spdif, SPDIFRX_InitTypeDef *spdifrx_init) +{ + uint32_t tmpreg; + + /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */ + SPDIF_MspInit(spdif); + + /* SFR block register reset */ + spdif->Instance->SPDIF_CTRL &= ~SPDIF_CTRL_SFR_ENABLE; + //while((spdif->Instance->SPDIF_CTRL&SPDIF_CTRL_SFR_ENABLE) != SPDIF_CTRL_SFR_ENABLE) + spdif->Instance->SPDIF_CTRL |= SPDIF_CTRL_SFR_ENABLE; + + /* SPDIF core reset */ + spdif->Instance->SPDIF_CTRL &= ~SPDIF_CTRL_SPDIF_ENABLE; + /* SPDIF core enable */ + spdif->Instance->SPDIF_CTRL |= SPDIF_CTRL_SPDIF_ENABLE; + + /* FIFO reset */ + spdif->Instance->SPDIF_CTRL &= ~SPDIF_CTRL_FIFO_ENABLE; + while ((spdif->Instance->SPDIF_CTRL & SPDIF_CTRL_FIFO_ENABLE) != SPDIF_CTRL_FIFO_ENABLE) + + /* Reset the old SPDIF CTRL configuration */ + tmpreg = spdif->Instance->SPDIF_CTRL; + + tmpreg &= ~(SPDIF_CTRL_TR_MODE | SPDIF_CTRL_VALIDITYCHECK | SPDIF_CTRL_PARITYCHECK); + + tmpreg |= (uint32_t)(spdifrx_init->StereoMode | + spdifrx_init->ValidityBitMask | + spdifrx_init->ParityErrorMask | + SPDIF_CTRL_INTREQ_MASK); + + spdif->Instance->SPDIF_CTRL = tmpreg; + + /* Set receive fifo almost full and empty threshold */ + spdif->Instance->FIFO_CTRL = ((spdifrx_init->FifoAfullThreshold << 16U) | (spdifrx_init->FifoAemptyThreshold)); +} + +/** + * @brief SPDIF MSP Init + * @param spdif SPDIF handle + * @retval None + */ +void __attribute__((weak)) SPDIF_MspInit(SPDIF_HandleTypeDef *spdif) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(spdif); + + /* NOTE : This function Should not be modified, when the callback is needed, + the SPDIFRX_MspInit could be implemented in the user file + */ +} + + +/** + * @brief Receives an amount of data (Data Flow) in blocking mode. + * @param spdif pointer to SPDIF_HandleTypeDef structure that contains + * the configuration information for SPDIF module. + * @param pData Pointer to data buffer + * @param Size Amount of data to be received + * @param Timeout Timeout duration + * @retval none + */ +void SPDIF_ReceiveDataFlow(SPDIF_HandleTypeDef *spdif, uint32_t *pData, uint16_t Size, + uint32_t Timeout) +{ + uint32_t tickstart; + uint16_t sizeCounter = Size; + uint32_t *pTmpBuf = pData; + + if ((pData == NULL) || (Size == 0U)) + { + return; + } + + /* Start reception */ + spdif->Instance->SPDIF_CTRL |= SPDIF_CTRL_SPDIF_ENABLE; + + /* Wait until lock flag is set */ + while ((spdif->Instance->STAT & SPDIF_STAT_LOCK_FLAG) != SPDIF_STAT_LOCK_FLAG) + { + if (Timeout != MAX_DELAY) + { + if ((GetTick() - tickstart > Timeout) || (Timeout == 0U)) + { + return; + } + } + } + + /* Receive data flow */ + while (sizeCounter > 0U) + { + if ((spdif->Instance->STAT & SPDIF_STAT_EMPTY_FLAG) != SPDIF_STAT_EMPTY_FLAG) + { + (*pTmpBuf) = spdif->Instance->DATA; + pTmpBuf++; + sizeCounter--; + } + } +} + +/** + * @brief Receives an amount of data (Data Flow) in non-blocking mode. + * @param spdif pointer to SPDIF_HandleTypeDef structure that contains + * the configuration information for SPDIF module. + * @param pData Pointer to data buffer + * @param Size Amount of data to be received + * @param Timeout Timeout duration + * @retval none + */ +void SPDIFRX_ReceiveDataFlow_IT(SPDIF_HandleTypeDef *spdif, uint32_t *pData, uint16_t Size, + uint32_t Timeout) +{ + uint32_t tickstart; + uint16_t sizeCounter = Size; + uint32_t *pTmpBuf = pData; + + if ((pData == NULL) || (Size == 0U)) + { + return; + } + + /* Enable the SPDIFRX Parity Error Interrupt */ + spdif->Instance->SPDIF_CTRL |= SPDIF_CTRL_PARITY_MASK; + + /* Enable the SPDIFRX OVR Error Interrupt */ + spdif->Instance->SPDIF_CTRL |= SPDIF_CTRL_OVRERR_MASK; + + /* Start reception */ + spdif->Instance->SPDIF_CTRL |= SPDIF_CTRL_SPDIF_ENABLE; + + /* Wait until lock flag is set */ + while ((spdif->Instance->STAT & SPDIF_STAT_LOCK_FLAG) != SPDIF_STAT_LOCK_FLAG) + { + if (Timeout != MAX_DELAY) + { + if ((GetTick() - tickstart > Timeout) || (Timeout == 0U)) + { + return; + } + } + } + +} diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_spi.c b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_spi.c new file mode 100644 index 00000000000..c9e395c7641 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_spi.c @@ -0,0 +1,827 @@ +/** + ****************************************************************************** + * @file ft32f4xx_spi.c + * @author FMD AE + * @brief This file provides firmware functions to manage the following + * functionalities of the Serial peripheral interface (SPI): + * + Initialization and Configuration + * + Data transfers functions + * + Hardware CRC Calculation + * + DMA transfers management + * + Interrupts and flags management + * @version V1.0.0 + * @data 2025-03-06 + ****************************************************************************** + */ +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx_spi.h" +#include "ft32f4xx_rcc.h" + +/* SPI registers Masks */ +#define CR1_CLEAR_MASK ((uint16_t)0x3040) +#define CR1_CLEAR_MASK2 ((uint16_t)0xFFFB) +#define CR2_LDMA_MASK ((uint16_t)0x9FFF) + +#define I2SCFGR_CLEAR_Mask ((uint16_t)0xF040) + + +/** + * @brief Deinitializes the SPIx peripheral registers to their default + * reset values. + * @param SPIx: where x can be 1 or 2 or 3 to select the SPI peripheral. + * @retval None + */ +void SPI_DeInit(SPI_TypeDef* SPIx) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + + if (SPIx == SPI1) + { + /* Enable SPI1 reset state */ + RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1, ENABLE); + /* Release SPI1 from reset state */ + RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1, DISABLE); + } + else if (SPIx == SPI2) + { + /* Enable SPI2 reset state */ + RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2, ENABLE); + /* Release SPI2 from reset state */ + RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2, DISABLE); + } + else if (SPIx == SPI3) + { + /* Enable SPI3 reset state */ + RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI3, ENABLE); + /* Release SPI3 from reset state */ + RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI3, DISABLE); + } + +} + +/** + * @brief Fills each SPI_InitStruct member with its default value. + * @param SPI_InitStruct: pointer to a SPI_InitTypeDef structure which will be initialized. + * @retval None + */ +void SPI_StructInit(SPI_InitTypeDef* SPI_InitStruct) +{ + /*--------------- Reset SPI init structure parameters values -----------------*/ + /* Initialize the SPI_Direction member */ + SPI_InitStruct->SPI_Direction = SPI_Direction_2Lines_FullDuplex; + /* Initialize the SPI_Mode member */ + SPI_InitStruct->SPI_Mode = SPI_Mode_Slave; + /* Initialize the SPI_DataSize member */ + SPI_InitStruct->SPI_DataSize = SPI_DataSize_8b; + /* Initialize the SPI_CPOL member */ + SPI_InitStruct->SPI_CPOL = SPI_CPOL_Low; + /* Initialize the SPI_CPHA member */ + SPI_InitStruct->SPI_CPHA = SPI_CPHA_1Edge; + /* Initialize the SPI_NSS member */ + SPI_InitStruct->SPI_NSS = SPI_NSS_Hard; + /* Initialize the SPI_BaudRatePrescaler member */ + SPI_InitStruct->SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2; + /* Initialize the SPI_FirstBit member */ + SPI_InitStruct->SPI_FirstBit = SPI_FirstBit_MSB; + /* Initialize the SPI_CRCPolynomial member */ + SPI_InitStruct->SPI_CRCPolynomial = 7; +} + +/** + * @brief Initializes the SPIx peripheral according to the specified + * parameters in the SPI_InitStruct. + * @param SPIx: where x can be 1 or 2 or 3 to select the SPI peripheral. + * @param SPI_InitStruct: pointer to a SPI_InitTypeDef structure that + * contains the configuration information for the specified SPI peripheral. + * @retval None + */ +void SPI_Init(SPI_TypeDef* SPIx, SPI_InitTypeDef* SPI_InitStruct) +{ + uint16_t tmpreg = 0; + + /* check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + + /* Check the SPI parameters */ + assert_param(IS_SPI_DIRECTION_MODE(SPI_InitStruct->SPI_Direction)); + assert_param(IS_SPI_MODE(SPI_InitStruct->SPI_Mode)); + assert_param(IS_SPI_DATA_SIZE(SPI_InitStruct->SPI_DataSize)); + assert_param(IS_SPI_CPOL(SPI_InitStruct->SPI_CPOL)); + assert_param(IS_SPI_CPHA(SPI_InitStruct->SPI_CPHA)); + assert_param(IS_SPI_NSS(SPI_InitStruct->SPI_NSS)); + assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_InitStruct->SPI_BaudRatePrescaler)); + assert_param(IS_SPI_FIRST_BIT(SPI_InitStruct->SPI_FirstBit)); + assert_param(IS_SPI_CRC_POLYNOMIAL(SPI_InitStruct->SPI_CRCPolynomial)); + + /*---------------------------- SPIx CR1 Configuration ------------------------*/ + /* Get the SPIx CR1 value */ + tmpreg = SPIx->CR1; + /* Clear BIDIMode, BIDIOE, RxONLY, SSM, SSI, LSBFirst, BR, CPOL and CPHA bits */ + tmpreg &= CR1_CLEAR_MASK; + /* Configure SPIx: direction, NSS management, first transmitted bit, BaudRate prescaler + master/slave mode, CPOL and CPHA */ + /* Set BIDImode, BIDIOE and RxONLY bits according to SPI_Direction value */ + /* Set SSM, SSI bit according to SPI_NSS values */ + /* Set LSBFirst bit according to SPI_FirstBit value */ + /* Set BR bits according to SPI_BaudRatePrescaler value */ + /* Set CPOL bit according to SPI_CPOL value */ + /* Set CPHA bit according to SPI_CPHA value */ + tmpreg |= (uint16_t)((uint32_t)SPI_InitStruct->SPI_Direction | SPI_InitStruct->SPI_FirstBit | + SPI_InitStruct->SPI_CPOL | SPI_InitStruct->SPI_CPHA | + SPI_InitStruct->SPI_NSS | SPI_InitStruct->SPI_BaudRatePrescaler); + /* Write to SPIx CR1 */ + SPIx->CR1 = tmpreg; + /*-------------------------Data Size Configuration -----------------------*/ + /* Get the SPIx CR2 value */ + tmpreg = SPIx->CR2; + /* Clear DS[3:0] bits */ + tmpreg &= (uint16_t)~SPI_CR2_DS; + /* Configure SPIx: Data Size */ + tmpreg |= (uint16_t)(SPI_InitStruct->SPI_DataSize); + /* Write to SPIx CR2 */ + SPIx->CR2 = tmpreg; + + /*---------------------------- SPIx CRCPOLY Configuration --------------------*/ + /* Write to SPIx CRCPOLY */ + SPIx->CRCPR = SPI_InitStruct->SPI_CRCPolynomial; + + /*---------------------------- SPIx CR1 Configuration ------------------------*/ + /* Get the SPIx CR1 value */ + tmpreg = SPIx->CR1; + /* Clear MSTR bit */ + tmpreg &= CR1_CLEAR_MASK2; + /* Configure SPIx: master/slave mode */ + /* Set MSTR bit according to SPI_Mode */ + tmpreg |= (uint16_t)((uint32_t)SPI_InitStruct->SPI_Mode); + /* Write to SPIx CR1 */ + SPIx->CR1 = tmpreg; + +// /* Activate the SPI mode (Reset I2SMOD bit in I2SCFGR register) */ +// SPIx->I2SCFGR &= (uint16_t)~((uint16_t)SPI_I2SCFGR_I2SMOD); +} +/** + * @brief Enables or disables the specified SPI peripheral. + * @param SPIx: where x can be 1 or 2 or 3 to select the SPI peripheral. + * @param NewState: new state of the SPIx peripheral. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SPI_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected SPI peripheral */ + SPIx->CR1 |= SPI_CR1_SPE; + } + else + { + /* Disable the selected SPI peripheral */ + SPIx->CR1 &= (uint16_t)~((uint16_t)SPI_CR1_SPE); + } +} + +/** + * @brief Enables or disables the TI Mode. + * + * @note This function can be called only after the SPI_Init() function has + * been called. + * @note When TI mode is selected, the control bits SSM, SSI, CPOL and CPHA + * are not taken into consideration and are configured by hardware + * respectively to the TI mode requirements. + * + * @param SPIx: where x can be 1 or 2 or 3 to select the SPI peripheral. + * @param NewState: new state of the selected SPI TI communication mode. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SPI_TIModeCmd(SPI_TypeDef* SPIx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the TI mode for the selected SPI peripheral */ + SPIx->CR2 |= SPI_CR2_FRF; + } + else + { + /* Disable the TI mode for the selected SPI peripheral */ + SPIx->CR2 &= (uint16_t)~((uint16_t)SPI_CR2_FRF); + } +} +/** + * @brief Configures the data size for the selected SPI. + * @param SPIx: where x can be 1 or 2 or 3 to select the SPI peripheral. + * @param SPI_DataSize: specifies the SPI data size. + * For the SPIx peripheral this parameter can be one of the following values: + * @arg SPI_DataSize_4b: Set data size to 4 bits + * @arg SPI_DataSize_5b: Set data size to 5 bits + * @arg SPI_DataSize_6b: Set data size to 6 bits + * @arg SPI_DataSize_7b: Set data size to 7 bits + * @arg SPI_DataSize_8b: Set data size to 8 bits + * @arg SPI_DataSize_9b: Set data size to 9 bits + * @arg SPI_DataSize_10b: Set data size to 10 bits + * @arg SPI_DataSize_11b: Set data size to 11 bits + * @arg SPI_DataSize_12b: Set data size to 12 bits + * @arg SPI_DataSize_13b: Set data size to 13 bits + * @arg SPI_DataSize_14b: Set data size to 14 bits + * @arg SPI_DataSize_15b: Set data size to 15 bits + * @arg SPI_DataSize_16b: Set data size to 16 bits + * @retval None + */ +void SPI_DataSizeConfig(SPI_TypeDef* SPIx, uint16_t SPI_DataSize) +{ + uint16_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_SPI_DATA_SIZE(SPI_DataSize)); + /* Read the CR2 register */ + tmpreg = SPIx->CR2; + /* Clear DS[3:0] bits */ + tmpreg &= (uint16_t)~SPI_CR2_DS; + /* Set new DS[3:0] bits value */ + tmpreg |= SPI_DataSize; + SPIx->CR2 = tmpreg; +} + +/** + * @brief Configures the FIFO reception threshold for the selected SPI. + * @param SPIx: where x can be 1 or 2 or 3 to select the SPI peripheral. + * @param SPI_RxFIFOThreshold: specifies the FIFO reception threshold. + * This parameter can be one of the following values: + * @arg SPI_RxFIFOThreshold_HF: RXNE event is generated if the FIFO + * level is greater or equal to 1/2. + * @arg SPI_RxFIFOThreshold_QF: RXNE event is generated if the FIFO + * level is greater or equal to 1/4. + * @retval None + */ +void SPI_RxFIFOThresholdConfig(SPI_TypeDef* SPIx, uint16_t SPI_RxFIFOThreshold) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_SPI_RX_FIFO_THRESHOLD(SPI_RxFIFOThreshold)); + + /* Clear FRXTH bit */ + SPIx->CR2 &= (uint16_t)~((uint16_t)SPI_CR2_FRXTH); + + /* Set new FRXTH bit value */ + SPIx->CR2 |= SPI_RxFIFOThreshold; +} + +/** + * @brief Selects the data transfer direction in bidirectional mode for the specified SPI. + * @param SPIx: where x can be 1 or 2 or 3 to select the SPI peripheral. + * @param SPI_Direction: specifies the data transfer direction in bidirectional mode. + * This parameter can be one of the following values: + * @arg SPI_Direction_Tx: Selects Tx transmission direction + * @arg SPI_Direction_Rx: Selects Rx receive direction + * @retval None + */ +void SPI_BiDirectionalLineConfig(SPI_TypeDef* SPIx, uint16_t SPI_Direction) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_SPI_DIRECTION(SPI_Direction)); + if (SPI_Direction == SPI_Direction_Tx) + { + /* Set the Tx only mode */ + SPIx->CR1 |= SPI_Direction_Tx; + } + else + { + /* Set the Rx only mode */ + SPIx->CR1 &= SPI_Direction_Rx; + } +} + +/** + * @brief Configures internally by software the NSS pin for the selected SPI. + * @note This function can be called only after the SPI_Init() function has + * been called. + * @param SPIx: where x can be 1 or 2 or 3 to select the SPI peripheral. + * @param SPI_NSSInternalSoft: specifies the SPI NSS internal state. + * This parameter can be one of the following values: + * @arg SPI_NSSInternalSoft_Set: Set NSS pin internally + * @arg SPI_NSSInternalSoft_Reset: Reset NSS pin internally + * @retval None + */ +void SPI_NSSInternalSoftwareConfig(SPI_TypeDef* SPIx, uint16_t SPI_NSSInternalSoft) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_SPI_NSS_INTERNAL(SPI_NSSInternalSoft)); + + if (SPI_NSSInternalSoft != SPI_NSSInternalSoft_Reset) + { + /* Set NSS pin internally by software */ + SPIx->CR1 |= SPI_NSSInternalSoft_Set; + } + else + { + /* Reset NSS pin internally by software */ + SPIx->CR1 &= SPI_NSSInternalSoft_Reset; + } +} + +/** + * @brief Enables or disables the SS output for the selected SPI. + * @note This function can be called only after the SPI_Init() function has + * been called and the NSS hardware management mode is selected. + * @param SPIx: where x can be 1 or 2 or 3 to select the SPI peripheral. + * @param NewState: new state of the SPIx SS output. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SPI_SSOutputCmd(SPI_TypeDef* SPIx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the selected SPI SS output */ + SPIx->CR2 |= SPI_CR2_SSOE; + } + else + { + /* Disable the selected SPI SS output */ + SPIx->CR2 &= (uint16_t)~((uint16_t)SPI_CR2_SSOE); + } +} + +/** + * @brief Enables or disables the NSS pulse management mode. + * @note This function can be called only after the SPI_Init() function has + * been called. + * @note When TI mode is selected, the control bits NSSP is not taken into + * consideration and are configured by hardware respectively to the + * TI mode requirements. + * @param SPIx: where x can be 1 or 2 or 3 to select the SPI peripheral. + * @param NewState: new state of the NSS pulse management mode. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SPI_NSSPulseModeCmd(SPI_TypeDef* SPIx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the NSS pulse management mode */ + SPIx->CR2 |= SPI_CR2_NSSP; + } + else + { + /* Disable the NSS pulse management mode */ + SPIx->CR2 &= (uint16_t)~((uint16_t)SPI_CR2_NSSP); + } +} + +/** + * @} + */ +/** + * @brief Transmits a Data through the SPIx/I2Sx peripheral. + * @param SPIx: where x can be 1 or 2 or 3 in SPI mode to select the SPI peripheral. + * @param Data: Data to be transmitted. + * @retval None + */ +void SPI_SendData8(SPI_TypeDef* SPIx, uint8_t Data) +{ + uint32_t spixbase = 0x00; + + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + + spixbase = (uint32_t)SPIx; + spixbase += 0x0C; + + *(__IO uint8_t *) spixbase = Data; +} + +/** + * @brief Transmits a Data through the SPIx/I2Sx peripheral. + * @param SPIx: where x can be 1 or 2 or 3 in SPI mode or 1 in I2S mode to select + * the SPI peripheral. + * @param Data: Data to be transmitted. + * @retval None + */ +void SPI_SendData16(SPI_TypeDef* SPIx, uint16_t Data) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + + SPIx->DR = (uint16_t)Data; +} + +/** + * @brief Returns the most recent received data by the SPIx/I2Sx peripheral. + * @param SPIx: where x can be 1 or 2 or 3 in SPI mode to select the SPI peripheral. + * @retval The value of the received data. + */ +uint8_t SPI_ReceiveData8(SPI_TypeDef* SPIx) +{ + uint32_t spixbase = 0x00; + + spixbase = (uint32_t)SPIx; + spixbase += 0x0C; + + return *(__IO uint8_t *) spixbase; +} + +/** + * @brief Returns the most recent received data by the SPIx peripheral. + * @param SPIx: where x can be 1 or 2 or 3 in SPI mode or 1 in I2S mode to select + * the SPI peripheral. + * @retval The value of the received data. + */ +uint16_t SPI_ReceiveData16(SPI_TypeDef* SPIx) +{ + return SPIx->DR; +} +/** + * @} + */ +/** + * @brief Configures the CRC calculation length for the selected SPI. + * @note This function can be called only after the SPI_Init() function has + * been called. + * @param SPIx: where x can be 1 or 2 or 3 to select the SPI peripheral. + * @param SPI_CRCLength: specifies the SPI CRC calculation length. + * This parameter can be one of the following values: + * @arg SPI_CRCLength_8b: Set CRC Calculation to 8 bits + * @arg SPI_CRCLength_16b: Set CRC Calculation to 16 bits + * @retval None + */ +void SPI_CRCLengthConfig(SPI_TypeDef* SPIx, uint16_t SPI_CRCLength) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_SPI_CRC_LENGTH(SPI_CRCLength)); + + /* Clear CRCL bit */ + SPIx->CR1 &= (uint16_t)~((uint16_t)SPI_CR1_CRCL); + + /* Set new CRCL bit value */ + SPIx->CR1 |= SPI_CRCLength; +} + +/** + * @brief Enables or disables the CRC value calculation of the transferred bytes. + * @note This function can be called only after the SPI_Init() function has + * been called. + * @param SPIx: where x can be 1 or 2 or 3 to select the SPI peripheral. + * @param NewState: new state of the SPIx CRC value calculation. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SPI_CalculateCRC(SPI_TypeDef* SPIx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected SPI CRC calculation */ + SPIx->CR1 |= SPI_CR1_CRCEN; + } + else + { + /* Disable the selected SPI CRC calculation */ + SPIx->CR1 &= (uint16_t)~((uint16_t)SPI_CR1_CRCEN); + } +} + +/** + * @brief Transmit the SPIx CRC value. + * @param SPIx: where x can be 1 or 2 or 3 to select the SPI peripheral. + * @retval None + */ +void SPI_TransmitCRC(SPI_TypeDef* SPIx) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + + /* Enable the selected SPI CRC transmission */ + SPIx->CR1 |= SPI_CR1_CRCNEXT; +} + +/** + * @brief Returns the transmit or the receive CRC register value for the specified SPI. + * @param SPIx: where x can be 1 or 2 or 3 to select the SPI peripheral. + * @param SPI_CRC: specifies the CRC register to be read. + * This parameter can be one of the following values: + * @arg SPI_CRC_Tx: Selects Tx CRC register + * @arg SPI_CRC_Rx: Selects Rx CRC register + * @retval The selected CRC register value.. + */ +uint16_t SPI_GetCRC(SPI_TypeDef* SPIx, uint8_t SPI_CRC) +{ + uint16_t crcreg = 0; + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_SPI_CRC(SPI_CRC)); + + if (SPI_CRC != SPI_CRC_Rx) + { + /* Get the Tx CRC register */ + crcreg = SPIx->TXCRCR; + } + else + { + /* Get the Rx CRC register */ + crcreg = SPIx->RXCRCR; + } + /* Return the selected CRC register */ + return crcreg; +} + +/** + * @brief Returns the CRC Polynomial register value for the specified SPI. + * @param SPIx: where x can be 1 or 2 or 3 to select the SPI peripheral. + * @retval The CRC Polynomial register value. + */ +uint16_t SPI_GetCRCPolynomial(SPI_TypeDef* SPIx) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + + /* Return the CRC polynomial register */ + return SPIx->CRCPR; +} + +/** + * @} + */ +/** + * @brief Enables or disables the SPIx/I2Sx DMA interface. + * @param SPIx: where x can be 1 or 2 or 3 in SPI mode or 1 in I2S mode to select + * the SPI peripheral. + * @param SPI_DMAReq: specifies the SPI DMA transfer request to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg SPI_DMAReq_Tx: Tx buffer DMA transfer request + * @arg SPI_DMAReq_Rx: Rx buffer DMA transfer request + * @param NewState: new state of the selected SPI DMA transfer request. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SPI_DMACmd(SPI_TypeDef* SPIx, uint16_t SPI_DMAReq, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + assert_param(IS_SPI_DMA_REQ(SPI_DMAReq)); + + if (NewState != DISABLE) + { + /* Enable the selected SPI DMA requests */ + SPIx->CR2 |= SPI_DMAReq; + } + else + { + /* Disable the selected SPI DMA requests */ + SPIx->CR2 &= (uint16_t)~SPI_DMAReq; + } +} + +/** + * @brief Configures the number of data to transfer type(Even/Odd) for the DMA + * last transfers and for the selected SPI. + * @note This function have a meaning only if DMA mode is selected and if + * the packing mode is used (data length <= 8 and DMA transfer size halfword) + * @param SPIx: where x can be 1 or 2 or 3 to select the SPI peripheral. + * @param SPI_LastDMATransfer: specifies the SPI last DMA transfers state. + * This parameter can be one of the following values: + * @arg SPI_LastDMATransfer_TxEvenRxEven: Number of data for transmission Even + * and number of data for reception Even. + * @arg SPI_LastDMATransfer_TxOddRxEven: Number of data for transmission Odd + * and number of data for reception Even. + * @arg SPI_LastDMATransfer_TxEvenRxOdd: Number of data for transmission Even + * and number of data for reception Odd. + * @arg SPI_LastDMATransfer_TxOddRxOdd: Number of data for transmission Odd + * and number of data for reception Odd. + * @retval None + */ +void SPI_LastDMATransferCmd(SPI_TypeDef* SPIx, uint16_t SPI_LastDMATransfer) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_SPI_LAST_DMA_TRANSFER(SPI_LastDMATransfer)); + + /* Clear LDMA_TX and LDMA_RX bits */ + SPIx->CR2 &= CR2_LDMA_MASK; + + /* Set new LDMA_TX and LDMA_RX bits value */ + SPIx->CR2 |= SPI_LastDMATransfer; +} + +/** + * @} + */ +/** + * @brief Enables or disables the specified SPI/I2S interrupts. + * @param SPIx: where x can be 1 or 2 or 3 in SPI mode or 1 in I2S mode to select + * the SPI peripheral. + * @param SPI_IT: specifies the SPI interrupt source to be enabled or disabled. + * This parameter can be one of the following values: + * @arg SPI_IT_TXE: Tx buffer empty interrupt mask + * @arg SPI_IT_RXNE: Rx buffer not empty interrupt mask + * @arg SPI_IT_ERR: Error interrupt mask + * @param NewState: new state of the specified SPI interrupt. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SPI_ITConfig(SPI_TypeDef* SPIx, uint8_t SPI_IT, FunctionalState NewState) +{ + uint16_t itpos = 0, itmask = 0 ; + + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + assert_param(IS_SPI_CONFIG_IT(SPI_IT)); + + /* Get the SPI IT index */ + itpos = SPI_IT >> 4; + + /* Set the IT mask */ + itmask = (uint16_t)1 << (uint16_t)itpos; + + if (NewState != DISABLE) + { + /* Enable the selected SPI interrupt */ + SPIx->CR2 |= itmask; + } + else + { + /* Disable the selected SPI interrupt */ + SPIx->CR2 &= (uint16_t)~itmask; + } +} + +/** + * @brief Returns the current SPIx Transmission FIFO filled level. + * @param SPIx: where x can be 1 or 2 or 3 to select the SPI peripheral. + * @retval The Transmission FIFO filling state. + * - SPI_TransmissionFIFOStatus_Empty: when FIFO is empty + * - SPI_TransmissionFIFOStatus_1QuarterFull: if more than 1 quarter-full. + * - SPI_TransmissionFIFOStatus_HalfFull: if more than 1 half-full. + * - SPI_TransmissionFIFOStatus_Full: when FIFO is full. + */ +uint16_t SPI_GetTransmissionFIFOStatus(SPI_TypeDef* SPIx) +{ + /* Get the SPIx Transmission FIFO level bits */ + return (uint16_t)((SPIx->SR & SPI_SR_FTLVL)); +} + +/** + * @brief Returns the current SPIx Reception FIFO filled level. + * @param SPIx: where x can be 1 or 2 or 3 to select the SPI peripheral. + * @retval The Reception FIFO filling state. + * - SPI_ReceptionFIFOStatus_Empty: when FIFO is empty + * - SPI_ReceptionFIFOStatus_1QuarterFull: if more than 1 quarter-full. + * - SPI_ReceptionFIFOStatus_HalfFull: if more than 1 half-full. + * - SPI_ReceptionFIFOStatus_Full: when FIFO is full. + */ +uint16_t SPI_GetReceptionFIFOStatus(SPI_TypeDef* SPIx) +{ + /* Get the SPIx Reception FIFO level bits */ + return (uint16_t)((SPIx->SR & SPI_SR_FRLVL)); +} + +/** + * @brief Checks whether the specified SPI flag is set or not. + * @param SPIx: where x can be 1 or 2 or 3 in SPI mode or 1 in I2S mode to select + * the SPI peripheral. + * @param SPI_FLAG: specifies the SPI flag to check. + * This parameter can be one of the following values: + * @arg SPI_FLAG_TXE: Transmit buffer empty flag. + * @arg SPI_FLAG_RXNE: Receive buffer not empty flag. + * @arg SPI_FLAG_BSY: Busy flag. + * @arg SPI_FLAG_OVR: Overrun flag. + * @arg SPI_FLAG_MODF: Mode Fault flag. + * @arg SPI_FLAG_CRCERR: CRC Error flag. + * @arg SPI_FLAG_FRE: TI frame format error flag. + * @retval The new state of SPI_FLAG (SET or RESET). + */ +FlagStatus SPI_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_FLAG) +{ + FlagStatus bitstatus = RESET; + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_SPI_GET_FLAG(SPI_FLAG)); + + /* Check the status of the specified SPI flag */ + if ((SPIx->SR & SPI_FLAG) != (uint16_t)RESET) + { + /* SPI_FLAG is set */ + bitstatus = SET; + } + else + { + /* SPI_FLAG is reset */ + bitstatus = RESET; + } + /* Return the SPI_FLAG status */ + return bitstatus; +} + +/** + * @brief Clears the SPIx CRC Error (CRCERR) flag. + * @param SPIx: where x can be 1 or 2 or 3 to select the SPI peripheral. + * @param SPI_FLAG: specifies the SPI flag to clear. + * This function clears only CRCERR flag. + * @note OVR (OverRun error) flag is cleared by software sequence: a read + * operation to SPI_DR register (SPI_ReceiveData()) followed by + * a read operation to SPI_SR register (SPI_GetFlagStatus()). + * @note MODF (Mode Fault) flag is cleared by software sequence: a read/write + * operation to SPI_SR register (SPI_GetFlagStatus()) followed by + * a write operation to SPI_CR1 register (SPI_Cmd() to enable the SPI). + * @retval None + */ +void SPI_ClearFlag(SPI_TypeDef* SPIx, uint16_t SPI_FLAG) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_SPI_CLEAR_FLAG(SPI_FLAG)); + + /* Clear the selected SPI CRC Error (CRCERR) flag */ + SPIx->SR = (uint16_t)~SPI_FLAG; +} + +/** + * @brief Checks whether the specified SPI/I2S interrupt has occurred or not. + * @param SPIx: where x can be 1 or 2 or 3 in SPI mode or 1 in I2S mode to select + * the SPI peripheral. + * @param SPI_IT: specifies the SPI interrupt source to check. + * This parameter can be one of the following values: + * @arg SPI_IT_TXE: Transmit buffer empty interrupt. + * @arg SPI_IT_RXNE: Receive buffer not empty interrupt. + * @arg SPI_IT_MODF: Mode Fault interrupt. + * @arg SPI_IT_OVR: Overrun interrupt. + * @arg SPI_IT_FRE: Format Error interrupt. + * @retval The new state of SPI_IT (SET or RESET). + */ +ITStatus SPI_GetITStatus(SPI_TypeDef* SPIx, uint8_t SPI_IT) +{ + ITStatus bitstatus = RESET; + uint16_t itpos = 0, itmask = 0, enablestatus = 0; + + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_SPI_GET_IT(SPI_IT)); + + /* Get the SPI_IT index */ + itpos = 0x01 << (SPI_IT & 0x0F); + + /* Get the SPI_IT IT mask */ + itmask = SPI_IT >> 4; + + /* Set the IT mask */ + itmask = 0x01 << itmask; + + /* Get the SPI_IT enable bit status */ + enablestatus = (SPIx->CR2 & itmask) ; + + /* Check the status of the specified SPI interrupt */ + if (((SPIx->SR & itpos) != (uint16_t)RESET) && enablestatus) + { + /* SPI_IT is set */ + bitstatus = SET; + } + else + { + /* SPI_IT is reset */ + bitstatus = RESET; + } + /* Return the SPI_IT status */ + return bitstatus; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_ssi.c b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_ssi.c new file mode 100644 index 00000000000..70ea014bc44 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_ssi.c @@ -0,0 +1,1297 @@ +/** + ************************************************************************** + * @file ft32f4xx_eth.c + * @author xcao + * @brief ssi module driver + * This file provides firmware functions to manage the following + * functionalities of the ssi peripheral: + * + Initialization and deinitialization functions + * + IO operation :functions + * + Peripheral Control funtions + * + Peripheral State and Errors functions + * + ************************************************************************** + * @attention + * + ************************************************************************** + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + + [..] + The SSI driver can be used as follows: + + (#) Declare a SSI_HandleTypeDef handle structure (eg. SSI_HandleTypeDef hssi). + (#) Initialize the SSI low level resources by implementing the SSI_MspInit() API: + (##) ENABLE the SSI interface clock. + (##) SSI pins configuration: + (+++) ENABLE the clock for the SSI GPIOs. + (+++) Configure these SSI pins as alternate function pull-up. + (##) NVIC configuration if you need to use interrupt process (SSI_Transmit_IT() + and SSI_Receive_IT() APIs): + (+++) Configure the SSI interrupt priority. + (+++) ENABLE the NVIC SSI IRQ handle. + + [..] + (@) The specific SSI interrupts (FIFO request and Overrun underrun interrupt) + will be managed using the macros __SSI_ENABLE_IT() and __SSI_DISABLE_IT() + inside the transmit and receive process. + + + [..] + Two operation modes are available within this driver : + + *** Polling mode IO operation *** + ================================= + [..] + (+) Send an amount of data in blocking mode using _SSI_Transmit() + (+) Receive an amount of data in blocking mode using _SSI_Receive() + + *** Interrupt mode IO operation *** + =================================== + + + @endverbatim + */ + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx_ssi.h" +#include "ft32f4xx_misc.h" +#define MAX_DELAY 0xFFFF +/** @addtogroup FT32F4xx__Driver + * @{ + */ + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/** @defgroup SSI_Private_Functions SSI Private Functions + * @{ + */ +static void TxClkFreqSet(SSI_HandleTypeDef *ssi, SSI_TxInitTypeDef *ssi_txinit); +static void RxClkFreqSet(SSI_HandleTypeDef *ssi, SSI_RxInitTypeDef *ssi_rxinit); +static void SSI_Fifo0Tx(SSI_HandleTypeDef *ssi, SSI_TxInitTypeDef *ssi_txinit, uint32_t Timeout, uint32_t tickstart); +static void SSI_Fifo1Tx(SSI_HandleTypeDef *ssi, SSI_TxInitTypeDef *ssi_txinit, uint32_t Timeout, uint32_t tickstart); +static void SSI_STX0Tx(SSI_HandleTypeDef *ssi, SSI_TxInitTypeDef *ssi_txinit, uint32_t Timeout, uint32_t tickstart); +static void SSI_SRX0Rx(SSI_HandleTypeDef *ssi, SSI_RxInitTypeDef *ssi_rxinit, uint32_t Timeout, uint32_t tickstart); +static void SSI_Fifo0Rx(SSI_HandleTypeDef *ssi, SSI_RxInitTypeDef *ssi_rxinit, uint32_t Timeout, uint32_t tickstart); +static void SSI_Fifo1Rx(SSI_HandleTypeDef *ssi, SSI_RxInitTypeDef *ssi_rxinit, uint32_t Timeout, uint32_t tickstart); +static void SSI_STX0Rx(SSI_HandleTypeDef *ssi, SSI_RxInitTypeDef *ssi_rxinit, uint32_t Timeout, uint32_t tickstart); +static void SSI_FillDfifo(SSI_HandleTypeDef *ssi, SSI_TxInitTypeDef *ssi_txinit); +static void SSI_FillFifo_0(SSI_HandleTypeDef *ssi, SSI_TxInitTypeDef *ssi_txinit); +static void SSI_FillFifo_1(SSI_HandleTypeDef *ssi, SSI_TxInitTypeDef *ssi_txinit); +/* Exported functions ---------------------------------------------------------*/ +/** @defgroup SSI_Exported_Functions SSI Exported Functions + * @{ + */ + +/** @defgroup SSI_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 SSI peripheral: + + (+) User must implement SSI_MspInit() function in which he configures + all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ). + + (+) Call the function SSI_Init() to configure the selected device with + the selected configuration: + (++) Mode (Normal/Net/I2S/AC97) + (++) Data Size + (++) Bit clk frequency + (++) FIFO Threshold + (++) Frame Config + (++) Slot Config + +@endverbatim + * @{ + */ + + +/** + * @brief Initialize the SSI according to the specified parameters. + * in the SSI_InitTypeDef structure and initialize the associated handle. + * @param ssi pointer to a SSI_HandleTypeDef structure that contains + * the configuration information for SSI module. + * @param ssi_init pointer to a SSI_InitTypeDef structure that contains + * the SSI initialization information + * @param ssi_txinit pointer to a SSI_TxInitTypeDef structure that contains + * the SSI Tx initialization information + * @param ssi_rxinit pointer to a SSI_RxInitTypeDef structure that contains + * the SSI Rx initialization information + * @retval void + */ +void SSI_Init(SSI_HandleTypeDef *ssi, + SSI_InitTypeDef *ssi_init, + SSI_TxInitTypeDef *ssi_txinit, + SSI_RxInitTypeDef *ssi_rxinit) +{ + uint32_t temreg = (uint32_t)0U; + + /* Check the SSI parameters */ + assert_param(IS_SSI_MODE(ssi_init->Mode)); + + if (ssi->State == SSI_STATE_RESET) + { + /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */ + SSI_MspInit(ssi); + printf("Low level initialization finish!\n"); + } + + ssi->State = SSI_STATE_BUSY; + + /*Disable SSI*/ + ssi->Instance->SCR &= ~SSI_SCR_SSIEN; + + switch (ssi_init->Mode) + { + case NET : + { + temreg |= (uint32_t)SSI_SCR_NET; + } + break; + case I2S_MASTER : + { + temreg |= (uint32_t)I2S_MASTER_PARAM; + } + break; + case I2S_SLAVE: + { + temreg |= (uint32_t)I2S_SLAVE_PARAM; + } + case AC97: + { + assert_param(IS_SSI_AC97SLOTWIDTH(ssi_init->AC97SLOTWIDTH)); + } + break; + default: + break; + } + + if (ssi_init->SyncMode == ENABLE) + { + temreg |= (uint32_t)SSI_SCR_SYN; + } + + if (ssi_init->TCHEN == ENABLE) + { + temreg |= (uint32_t)SSI_SCR_TCH_EN; + } + + if (ssi_init->OVERSAMPLE == ENABLE) + { + temreg |= (uint32_t)SSI_SCR_SYS_CLK_EN; + } + + if (ssi_init->RFRCLKDIS == ENABLE) + { + temreg |= (uint32_t)SSI_SCR_RFR_CLK_DIS; + } + + if (ssi_init->TFRCLKDIS == ENABLE) + { + temreg |= (uint32_t)SSI_SCR_TFR_CLK_DIS; + } + + ssi->Instance->SCR &= (uint32_t)(~(SSI_SCR_RFR_CLK_DIS | SSI_SCR_TFR_CLK_DIS + | SSI_SCR_TCH_EN | SSI_SCR_SYS_CLK_EN + | SSI_SCR_I2SMODE | SSI_SCR_SYN | SSI_SCR_NET + | SSI_SCR_TE | SSI_SCR_RE)); + + if (ssi_init->Mode == AC97) + { + ssi->Instance->STCCR &= (uint32_t)(~(SSI_STCCR_WL | SSI_STCCR_DC)); + ssi->Instance->SRCCR &= (uint32_t)(~(SSI_SRCCR_WL | SSI_SRCCR_DC)); + + /*AC97 word lenth can only set to 16 or 20 , and frame length can only set to 13 slots*/ + if (ssi_init->AC97SLOTWIDTH == SLOTWIDEQ20) + { + ssi->Instance->STCCR |= (uint32_t)((SSI_DATA_WL20 << 13U) | (SSI_FRAME_LEN12 << 8U)); + ssi->Instance->SRCCR |= (uint32_t)((SSI_DATA_WL20 << 13U) | (SSI_FRAME_LEN12 << 8U)); + } + else if (ssi_init->AC97SLOTWIDTH == SLOTWIDEQ16) + { + ssi->Instance->STCCR |= (uint32_t)((SSI_DATA_WL16 << 13U) | (SSI_FRAME_LEN12 << 8U)); + ssi->Instance->SRCCR |= (uint32_t)((SSI_DATA_WL16 << 13U) | (SSI_FRAME_LEN12 << 8U)); + } + + ssi->Instance->SACNT &= (uint32_t)(~(SSI_SACNT_FRDIV | SSI_SACNT_TIF + | SSI_SACNT_FV | SSI_SACNT_AC97EN)); + + /*AC97 frame rate divider*/ + ssi->Instance->SACNT |= (uint32_t)((ssi_init->AC97FRDIV) << 5U); + + if (ssi_init->AC97RXTAGINFIFO == ENABLE) + { + ssi->Instance->SACNT |= SSI_SACNT_TIF; + } + + if (ssi_init->AC97VarMode == ENABLE) + { + ssi->Instance->SACNT |= SSI_SACNT_FV; + } + + } + + ssi->Instance->SCR |= temreg | (uint32_t)SSI_SCR_SSIEN; + + ssi->State = SSI_STATE_READY; +} +/** + * @} + */ + + +/** + * @brief Configure TX bit clock frequency using specified parameters. + * @param ssi pointer to a SSI_HandleTypeDef structure that contains + * the configuration information for SSI module + * + * @param ssi_txinit pointer to a SSI_TxInitTypeDef structure that contains + * the SSI initialization information + * @retval NONE + */ +static void TxClkFreqSet(SSI_HandleTypeDef *ssi, SSI_TxInitTypeDef *ssi_txinit) +{ + uint32_t temreg = (uint32_t)0U; + + assert_param(IS_SSI_BITCLK_FIXDIV(ssi_txinit->FixedDivParam)); + assert_param(IS_SSI_DATA_SIZE(ssi_txinit->DataSize)); + + /*Configure bit clock frequency using the following formula : + f(Bit_clk) = f(ssi_system_clk(pll2_q)) / ((DIV2 + 1) * ((PSR * 7)+1) * ((PM + 1)*2)) + DIV2 and PSR are bit configuration option which belongs fixed prescaler paramter. + PM can be modify by usrs according to application. + */ + + /* Note:f(Bit_clk) is never greater than 1/5 of the f(pclk1) */ + + switch (ssi_txinit->FixedDivParam) + { + case FIX_CLOCK_DIV4: + { + temreg = (uint32_t)SSI_STCCR_DIV2; + } + break; + case FIX_CLOCK_DIV16: + { + temreg = (uint32_t)SSI_STCCR_PSR; + } + break; + case FIX_CLOCK_DIV32: + { + temreg = (uint32_t)(SSI_STCCR_DIV2 | SSI_STCCR_PSR); + } + break; + default: + break; + } + + + temreg |= (uint32_t)((ssi_txinit->CustomDivParam) & 0x000000ff); + + /* Configure Word clock */ + temreg |= (uint32_t)((ssi_txinit-> DataSize) << 13U); + + /* Configure Frame length */ + temreg |= (uint32_t)((ssi_txinit-> FrameRate) << 8U); + + ssi->Instance->STCCR &= (uint32_t)(~(SSI_STCCR_DIV2 | SSI_STCCR_PSR + | SSI_STCCR_WL | SSI_STCCR_DC + | SSI_STCCR_PM)); + ssi->Instance->STCCR |= temreg; +} + + +/** + * @brief Configure RX bit clock frequency using specified parameters. + * @param ssi pointer to a SSI_HandleTypeDef structure that contains + * the configuration information for SSI module + * + * @param ssi_rxinit pointer to a SSI_RxInitTypeDef structure that contains + * the SSI Rx initialization information + * @retval NONE + */ +static void RxClkFreqSet(SSI_HandleTypeDef *ssi, SSI_RxInitTypeDef *ssi_rxinit) +{ + uint32_t temreg = (uint32_t)0U; + + assert_param(IS_SSI_BITCLK_FIXDIV(ssi_rxinit->FixedDivParam)); + assert_param(IS_DATA_SIZE(ssi_rxinit->DataSize)); + + /*Configure bit clock frequency using the following formula : + f(Bit_clk) = f(ssi_system_clk(pll2_q)) / ((DIV2 + 1) * ((PSR * 7)+1) * ((PM + 1)*2)) + DIV2 and PSR are bit configuration option which belongs fixed prescaler paramter. + PM can be modify by usrs according to application. + */ + + /* Note:f(Bit_clk) is never greater than 1/5 of the f(pclk1) */ + + switch (ssi_rxinit->FixedDivParam) + { + case FIX_CLOCK_DIV4: + { + temreg = (uint32_t)SSI_SRCCR_DIV2; + } + break; + case FIX_CLOCK_DIV16: + { + temreg = (uint32_t)SSI_SRCCR_PSR; + } + break; + case FIX_CLOCK_DIV32: + { + temreg = (uint32_t)(SSI_SRCCR_DIV2 | SSI_SRCCR_PSR); + } + break; + default: + break; + } + + + temreg |= (uint32_t)((ssi_rxinit->CustomDivParam) & 0x000000ff); + + + /* Configure Word clock */ + temreg |= (uint32_t)((ssi_rxinit->DataSize) << 13U); + + /* Configure Frame length */ + temreg |= (uint32_t)((ssi_rxinit->FrameRate) << 8U); + + ssi->Instance->SRCCR &= (uint32_t)(~(SSI_SRCCR_DIV2 | SSI_SRCCR_PSR + | SSI_SRCCR_WL | SSI_SRCCR_DC + | SSI_SRCCR_PM)); + ssi->Instance->SRCCR |= temreg; +} + +/** @addtogroup SSI_Private_Functions SSI Private Functions + * @{ + */ + + + + +/** + * @brief Configure Transmit initial flow . + * @param ssi pointer to a SSI_HandleTypeDef structure that contains + * the configuration information for SSI module + * + * @param ssi_txinit pointer to a SSI_TxInitTypeDef structure that contains + * the SSI Tx initialization information + * @retval NONE + */ +void TxConfigInit(SSI_HandleTypeDef *ssi, SSI_InitTypeDef *ssi_init, SSI_TxInitTypeDef *ssi_txinit) +{ + uint32_t temreg1 = (uint32_t)0U; + uint32_t temreg2 = (uint32_t)0U; + + assert_param(IS_SSI_TRANSDATA_TYPE(ssi_txinit->TxDataType)); + assert_param(IS_SSI_FIFO_WATERMARK(ssi_txinit->FIFO0WaterMark)); + assert_param(IS_SSI_FIFO_WATERMARK(ssi_txinit->FIFO1WaterMark)); + assert_param(IS_SSI_FRAMESYNC_POLARITY(ssi_txinit->FrameSyncPolarity)); + assert_param(IS_SSI_CLOCK_POLARITY(ssi_txinit->TxClkPolarity)); + + /* ENABLE Tx FIFO */ + /* Configure Tx FIFO Water Mark */ + if (ssi_txinit->FIFO0EN == ENABLE) + { + temreg1 |= (uint32_t)(SSI_STCR_TFEN0); + temreg2 |= ssi_txinit->FIFO0WaterMark; + } + + if (ssi_txinit->FIFO1EN == ENABLE) + { + temreg1 |= (uint32_t)(SSI_STCR_TFEN1); + temreg2 |= (uint32_t)(ssi_txinit->FIFO1WaterMark << 16U); + } + + /*Configure Tx data MSB or LSB transmission*/ + switch (ssi_txinit->TxDataType) + { + case MSB_MSW: + { + temreg1 &= (uint32_t)(~(SSI_STCR_TXBIT0 | SSI_STCR_TSHFD)); + } + break; + case LSB_MSW: + { + temreg1 |= (uint32_t)SSI_STCR_TSHFD; + temreg1 &= (uint32_t)(~(SSI_STCR_TXBIT0)); + } + break; + case MSB_LSW: + { + temreg1 &= (uint32_t)(~(SSI_STCR_TSHFD)); + temreg1 |= (uint32_t)SSI_STCR_TXBIT0; + } + break; + default: + break; + } + + + /* Configure frame sync direction */ + if (ssi_txinit->FrameSyncFromExit != ENABLE) + { + temreg1 |= (uint32_t)SSI_STCR_TFDIR; + } + + /* Configure Tx direction */ + if (ssi_txinit->TxClkFromExit != ENABLE) + { + temreg1 |= (uint32_t)SSI_STCR_TXDIR; + } + + /* Configure Tx clock polarity */ + if (ssi_txinit->TxClkPolarity == FALLINGEDGE) + { + temreg1 |= (uint32_t)SSI_STCR_TSCKP; + } + + /* Configure Frame sync Length mode*/ + if (ssi_txinit->FrameSyncLenBit == ENABLE) + { + temreg1 |= (uint32_t)SSI_STCR_TFSL; + } + + /* Configure Frame sync early */ + if (ssi_txinit->FrameSyncEarly == ENABLE) + { + temreg1 |= (uint32_t)SSI_STCR_TEFS; + } + + /* Configure Frame sync polarity */ + if (ssi_txinit->FrameSyncPolarity == ACTIVELOW) + { + temreg1 |= (uint32_t)SSI_STCR_TFSI; + } + + ssi->Instance->STCR &= (uint32_t)(~(SSI_STCR_TFEN0 | SSI_STCR_TFEN1 + | SSI_STCR_TSHFD | SSI_STCR_TXBIT0 + | SSI_STCR_TFDIR | SSI_STCR_TXDIR + | SSI_STCR_TSCKP | SSI_STCR_TEFS + | SSI_STCR_TFSL | SSI_STCR_TFSI)); + + ssi->Instance->STCR |= temreg1; + + ssi->Instance->SFCSR &= (uint32_t)(~(SSI_SFCSR_TFWM0 | SSI_SFCSR_TFWM1)); + + ssi->Instance->SFCSR |= temreg2; + + ssi->Instance->STMSK &= ~(SSI_STMSK_STMSK); + + ssi->Instance->STMSK = ssi_txinit->TxSlotMsk; + + /* fill tag register if AC97 fixed mode */ + if (ssi_init->Mode == AC97) + { + if (ssi_init->AC97VarMode != ENABLE) + { + ssi->Instance->SATAG &= ~(SSI_SATAG_SATAG); + + ssi->Instance->SATAG |= (uint32_t)(ssi_txinit->AC97TxSlotEn); + } + else + { + /* Disable all slots when initial ac97 tx flow at variable mode */ + ssi->Instance->SACCDIS |= SSI_SACCDIS_SACCDIS; + } + } + + TxClkFreqSet(ssi, ssi_txinit); + +} + +/** + * @brief Configure Receive initial flow . + * @param ssi pointer to a SSI_HandleTypeDef structure that contains + * the configuration information for SSI module + * + * @param ssi_rxinit pointer to a SSI_RxInitTypeDef structure that contains + * the SSI Rx initialization information + * @retval NONE + */ +void RxConfigInit(SSI_HandleTypeDef *ssi, SSI_RxInitTypeDef *ssi_rxinit) +{ + uint32_t temreg1 = (uint32_t)0U; + uint32_t temreg2 = (uint32_t)0U; + + assert_param(IS_SSI_TRANSDATA_TYPE(ssi_rxinit->RxDataType)); + assert_param(IS_SSI_FIFO_WATERMARK(ssi_rxinit->FIFO0WaterMark)); + assert_param(IS_SSI_FIFO_WATERMARK(ssi_rxinit->FIFO1WaterMark)); + assert_param(IS_SSI_FRAMESYNC_POLARITY(ssi_rxinit->FrameSyncPolarity)); + assert_param(IS_SSI_CLOCK_POLARITY(ssi_rxinit->RxClkPolarity)); + + /* ENABLE Rx FIFO */ + /* Configure Rx FIFO Water Mark */ + if (ssi_rxinit->FIFO0EN == ENABLE) + { + temreg1 |= (uint32_t)(SSI_SRCR_RFEN0); + temreg2 |= (uint32_t)(ssi_rxinit->FIFO0WaterMark << 4U); + } + + if (ssi_rxinit->FIFO1EN == ENABLE) + { + temreg1 |= (uint32_t)(SSI_SRCR_RFEN1); + temreg2 |= (uint32_t)(ssi_rxinit->FIFO1WaterMark << 20U); + } + + /*Configure Rx data MSB or LSB transmission*/ + switch (ssi_rxinit->RxDataType) + { + case MSB_MSW: + { + temreg1 &= (uint32_t)(~(SSI_SRCR_RXBIT0 | SSI_SRCR_RSHFD)); + } + break; + case LSB_MSW: + { + temreg1 |= (uint32_t)SSI_SRCR_RSHFD; + temreg1 &= (uint32_t)(~(SSI_SRCR_RXBIT0)); + } + break; + case MSB_LSW: + { + temreg1 &= (uint32_t)(~(SSI_SRCR_RSHFD)); + temreg1 |= (uint32_t)SSI_SRCR_RXBIT0; + } + break; + default: + break; + } + + /* Configure frame sync direction */ + if (ssi_rxinit->FrameSyncFromExit != ENABLE) + { + temreg1 |= (uint32_t)SSI_SRCR_RFDIR; + } + + /* Configure Rx direction */ + if (ssi_rxinit->RxClkFromExit != ENABLE) + { + temreg1 |= (uint32_t)SSI_SRCR_RXDIR; + } + + /* Configure Rx clock polarity */ + if (ssi_rxinit->RxClkPolarity == FALLINGEDGE) + { + temreg1 |= (uint32_t)SSI_SRCR_RSCKP; + } + + /* Configure Frame sync Length mode*/ + if (ssi_rxinit->FrameSyncLenBit == ENABLE) + { + temreg1 |= (uint32_t)SSI_SRCR_RFSL; + } + + /* Configure Frame sync early */ + if (ssi_rxinit->FrameSyncEarly == ENABLE) + { + temreg1 |= (uint32_t)SSI_SRCR_REFS; + } + + /* Configure Frame sync polarity */ + if (ssi_rxinit->FrameSyncPolarity == ACTIVELOW) + { + temreg1 |= (uint32_t)SSI_SRCR_RFSI; + } + + ssi->Instance->SRCR &= (uint32_t)(~(SSI_SRCR_RFEN0 | SSI_SRCR_RFEN1 + | SSI_SRCR_RSHFD | SSI_SRCR_RXBIT0 + | SSI_SRCR_RFDIR | SSI_SRCR_RXDIR + | SSI_SRCR_RSCKP | SSI_SRCR_REFS + | SSI_SRCR_RFSL | SSI_SRCR_RFSI)); + + ssi->Instance->SRCR |= temreg1; + + ssi->Instance->SFCSR &= (uint32_t)(~(SSI_SFCSR_RFWM0 | SSI_SFCSR_RFWM1)); + + ssi->Instance->SFCSR |= temreg2; + + ssi->Instance->SRMSK &= ~(SSI_SRMSK_SRMSK); + + ssi->Instance->SRMSK = ssi_rxinit->RxSlotMsk; + + RxClkFreqSet(ssi, ssi_rxinit); +} + + +/** + * @brief Initialize the SSI MSP. + * @param ssi pointer to a SSI_HandleTypeDef structure that contains + * the configuration information for SSI module. + * @retval None + */ +void __attribute__((weak)) SSI_MspInit(SSI_HandleTypeDef *ssi) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(ssi); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SSI_MspInit could be implemented in the user file + */ +} + + +/** + * @} + */ + +/** @defgroup SSI_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 SSI 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 SSI IRQ when using Interrupt mode or the DMA IRQ when + using DMA mode. + + (+) Blocking mode functions are : + (++) SSI_Transmit() + (++) SSI_Receive() + +@endverbatim + * @{ + */ + +/** + * @brief Transmit an amount of data in polling mode. + * @param ssi pointer to a SSI_HandleTypeDef structure that contains + * the configuration information for SSI module. + * @param ssi_txinit pointer to a SSI_TxInitTypeDef structure that contains + * the SSI Tx initialization information + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param Timeout Timeout duration + * @retval void + * + */ +void SSI_Transmit(SSI_HandleTypeDef *ssi, \ + SSI_InitTypeDef *ssi_init, \ + SSI_TxInitTypeDef *ssi_txinit, \ + uint8_t *pData0, \ + uint8_t *pData1, \ + uint16_t Size0, \ + uint16_t Size1, \ + uint32_t Timeout) +{ + uint32_t tickstart = GetTick(); + + if (((pData0 == NULL) && (pData1 == NULL)) + || ((Size0 == 0)) && (Size1 == 0)) + { + return; + } + + if (ssi->State == SSI_STATE_READY) + { + ssi->XferSize0 = Size0; + ssi->XferSize1 = Size1; + ssi->XferCount0 = Size0; + ssi->XferCount1 = Size1; + ssi->pBuffPtr0 = pData0; + ssi->pBuffPtr1 = pData1; + ssi->State = SSI_STATE_BUSY_TX; + ssi->ErrorCode = SSI_ERROR_NONE; + + if (ssi_init->Mode == AC97) + { + if ((ssi->Instance->SACNT & SSI_SACNT_AC97EN) != SSI_SACNT_AC97EN) + { + if (ssi_init->AC97VarMode == ENABLE) + { + ssi->Instance->SACADD = (uint32_t)((ssi_txinit->CODECCMDADDR) & 0x0007ffff); + ssi->Instance->SACNT |= SSI_SACNT_RD | SSI_SACNT_AC97EN; + } + else + { + printf("CODEC ADDR = %08x\n", ((ssi_txinit->CODECCMDADDR) & 0x0007ffff)); + printf("Write data = %08x\n", ((ssi_txinit->CODECCMDDATA) & 0x000fffff)); + ssi->Instance->SACADD = (uint32_t)((ssi_txinit->CODECCMDADDR) & 0x0007ffff); + ssi->Instance->SACDAT = (uint32_t)((ssi_txinit->CODECCMDDATA) & 0x000fffff); + ssi->Instance->SACNT |= SSI_SACNT_WR | SSI_SACNT_AC97EN; + } + } + else if (ssi_init->AC97VarMode == ENABLE) + { + ssi->Instance->SACADD = (uint32_t)((ssi_txinit->CODECCMDADDR) & 0x0007ffff); + ssi->Instance->SACDAT = (uint32_t)((ssi_txinit->CODECCMDDATA) & 0x000fffff); + ssi->Instance->SACNT |= SSI_SACNT_WR; + + uint32_t slotreq = ((ssi->Instance->SACCST) & 0x000003ff); + + ssi->Instance->SACCEN = slotreq; + + ssi->Instance->SACCDIS = slotreq; + } + else + { + ssi->Instance->SACADD = (uint32_t)((ssi_txinit->CODECCMDADDR) & 0x0007ffff); + ssi->Instance->SACDAT = (uint32_t)((ssi_txinit->CODECCMDDATA) & 0x000fffff); + ssi->Instance->SACNT |= SSI_SACNT_WR; + } + } + + /* Prepare tx data before trasmit start */ + if ((ssi->Instance->SCR & SSI_SCR_TE) != SSI_SCR_TE) + { + if (ssi_init->TCHEN == ENABLE) + { + /* Two FIFOs are filled with data if enbale two channels */ + SSI_FillDfifo(ssi, ssi_txinit); + } + else if (ssi_txinit->FIFO0EN || ssi_init->Mode == AC97) + { + + //printf("Use FIFO0 to transmit data!\n"); + /* Only channel 0 is enabled if single channel mode */ + SSI_FillFifo_0(ssi, ssi_txinit); + } + else + { + if ((ssi->Instance->SISR & SSI_SISR_TDE0) == SSI_SISR_TDE0) + { + if (ssi_txinit->DataSize == SSI_DATA_WL8) + { + ssi->Instance->STX0 = (*ssi->pBuffPtr0++); + } + else if (ssi_txinit->DataSize == SSI_DATA_WL16) + { + ssi->Instance->STX0 = *((uint16_t *)(ssi->pBuffPtr0)); + ssi->pBuffPtr0 += 2U; + } + else + { + ssi->Instance->STX0 = *((uint32_t *)(ssi->pBuffPtr0)); + ssi->pBuffPtr0 += 4U; + } + ssi->XferCount0--; + } + } + /* Start transmit */ + ssi->Instance->SCR |= SSI_SCR_TE; + printf("Start transmit data!\n"); + } + + if (ssi_init->TCHEN == ENABLE) + { + while ((ssi->XferCount0 > 0U) || (ssi->XferCount1 > 0U)) + { + if (ssi->XferCount0 > 0U) + { + SSI_Fifo0Tx(ssi, ssi_txinit, Timeout, tickstart); + } + + if (ssi->XferCount1 > 0U) + { + SSI_Fifo1Tx(ssi, ssi_txinit, Timeout, tickstart); + } + } + } + else if ((ssi_txinit->FIFO0EN == ENABLE) || (ssi_init->Mode == AC97)) + { + while (ssi->XferCount0 > 0U) + { + printf("Remain %d data need to be send!\n", ssi->XferCount0); + SSI_Fifo0Tx(ssi, ssi_txinit, Timeout, tickstart); + } + } + else + { + while (ssi->XferCount0 > 0U) + { + SSI_STX0Tx(ssi, ssi_txinit, Timeout, tickstart); + } + } + + } + + ssi->State = SSI_STATE_READY; + + while ((ssi->Instance->SISR & SSI_SISR_TUE0) != SSI_SISR_TUE0) + { + + } + + ssi->Instance->SCR &= ~SSI_SCR_TE; +} + + +/** + * @brief Tx fifo_0 transmit function + * @param ssi pointer to a SSI_HandleTypeDef structure that contains + * the configuration information for SSI module. + * @param ssi_txinit pointer to a SSI_TxInitTypeDef structure that contains + * the SSI Tx initialization information + * @param Timeout Timeout duration + * @param tickstart Transmit start time + * @retval None + */ +static void SSI_Fifo0Tx(SSI_HandleTypeDef *ssi, SSI_TxInitTypeDef *ssi_txinit, uint32_t Timeout, uint32_t tickstart) +{ + if (ssi->Instance->SISR & SSI_SISR_TFE0) + { + + if (ssi_txinit->DataSize == SSI_DATA_WL8) + { + ssi->Instance->STX0 = (*ssi->pBuffPtr0++); + } + else if (ssi_txinit->DataSize == SSI_DATA_WL16) + { + ssi->Instance->STX0 = *((uint16_t *)(ssi->pBuffPtr0)); + ssi->pBuffPtr0 += 2U; + } + else + { + ssi->Instance->STX0 = *((uint32_t *)(ssi->pBuffPtr0)); + ssi->pBuffPtr0 += 4U; + } + ssi->XferCount0--; + } + else + { + if ((Timeout != MAX_DELAY) && ((Timeout == 0U) || ((GetTick() - tickstart) > Timeout))) + { + /* Update error code */ + ssi->ErrorCode |= SSI_ERROR_TIMEOUT; + + /* Disable SSI peripheral */ + ssi->Instance->SCR &= ~(SSI_SCR_TE); + + /* Flush the fifo */ + ssi->Instance->SOR |= SSI_SOR_TX_CLR; + + /* Change the SSI state */ + ssi->State = SSI_STATE_READY; + + return ; + } + } +} + + +/** + * @brief Tx fifo_1 transmit function + * @param ssi pointer to a SSI_HandleTypeDef structure that contains + * the configuration information for SSI module. + * @param ssi_txinit pointer to a SSI_TxInitTypeDef structure that contains + * the SSI Tx initialization information + * @param Timeout Timeout duration + * @param tickstart Transmit start time + * @retval None + */ +static void SSI_Fifo1Tx(SSI_HandleTypeDef *ssi, SSI_TxInitTypeDef *ssi_txinit, uint32_t Timeout, uint32_t tickstart) +{ + if (ssi->Instance->SISR & SSI_SISR_TFE1) + { + if (ssi_txinit->DataSize == SSI_DATA_WL8) + { + ssi->Instance->STX1 = (*ssi->pBuffPtr1++); + } + else if (ssi_txinit->DataSize == SSI_DATA_WL16) + { + ssi->Instance->STX1 = *((uint16_t *)(ssi->pBuffPtr1)); + ssi->pBuffPtr1 += 2U; + } + else + { + ssi->Instance->STX1 = *((uint32_t *)(ssi->pBuffPtr1)); + ssi->pBuffPtr1 += 4U; + } + ssi->XferCount1--; + } + else + { + if ((Timeout != MAX_DELAY) && ((Timeout == 0U) || ((GetTick() - tickstart) > Timeout))) + { + /* Update error code */ + ssi->ErrorCode |= SSI_ERROR_TIMEOUT; + + /* Disable SSI peripheral */ + ssi->Instance->SCR &= ~(SSI_SCR_TE); + + /* Change the SSI state */ + ssi->State = SSI_STATE_READY; + + return ; + } + } +} + +/** + * @brief Tx stx register transmit function + * @param ssi pointer to a SSI_HandleTypeDef structure that contains + * the configuration information for SSI module. + * @param ssi_txinit pointer to a SSI_TxInitTypeDef structure that contains + * the SSI Tx initialization information + * @param Timeout Timeout duration + * @param tickstart Transmit start time + * @retval None + */ +static void SSI_STX0Tx(SSI_HandleTypeDef *ssi, SSI_TxInitTypeDef *ssi_txinit, uint32_t Timeout, uint32_t tickstart) +{ + if ((ssi->Instance->SISR & SSI_SISR_TDE0) == SSI_SISR_TDE0) + { + if (ssi_txinit->DataSize == SSI_DATA_WL8) + { + ssi->Instance->STX0 = (*ssi->pBuffPtr0++); + } + else if (ssi_txinit->DataSize == SSI_DATA_WL16) + { + ssi->Instance->STX0 = *((uint16_t *)(ssi->pBuffPtr0)); + ssi->pBuffPtr0 += 2U; + } + else + { + ssi->Instance->STX0 = *((uint32_t *)(ssi->pBuffPtr0)); + ssi->pBuffPtr0 += 4U; + } + ssi->XferCount0--; + } + else + { + if ((Timeout != MAX_DELAY) && ((Timeout == 0U) || ((GetTick() - tickstart) > Timeout))) + { + /* Update error code */ + ssi->ErrorCode |= SSI_ERROR_TIMEOUT; + + /* Disable SSI peripheral */ + ssi->Instance->SCR &= ~(SSI_SCR_TE); + + /* Change the SSI state */ + ssi->State = SSI_STATE_READY; + + return ; + } + } +} +/** + * @brief Fill the tx fifo_0 + * @param ssi pointer to a SSI_HandleTypeDef structure that contains + * the configuration information for SSI module. + * @param ssi_txinit pointer to a SSI_TxInitTypeDef structure that contains + * the SSI Tx initialization information + * @retval None + */ +static void SSI_FillFifo_0(SSI_HandleTypeDef *ssi, SSI_TxInitTypeDef *ssi_txinit) +{ + /* fill the fifo with data before to enable the SSI*/ + while (((ssi->Instance->SISR & SSI_SISR_TFE0) == SSI_SISR_TFE0) && (ssi->XferCount0 > 0U)) + { + //printf("Fill FIFO0!\n"); + //printf("There are %d data need to be sended!\n",ssi->XferCount0); + if (ssi_txinit->DataSize == SSI_DATA_WL8) + { + ssi->Instance->STX0 = (*ssi->pBuffPtr0++); + } + else if (ssi_txinit->DataSize == SSI_DATA_WL16) + { + ssi->Instance->STX0 = *((uint16_t *)(ssi->pBuffPtr0)); + ssi->pBuffPtr0 += 2U; + } + else + { + //printf("Fill data = %08x\n",*((uint32_t *)(ssi->pBuffPtr0))); + ssi->Instance->STX0 = *((uint32_t *)(ssi->pBuffPtr0)); + ssi->pBuffPtr0 += 4U; + } + ssi->XferCount0--; + } +} + + +/** + * @brief Fill the tx fifo_1 and fifo_2 alternatively + * @param ssi pointer to a SSI_HandleTypeDef structure that contains + * the configuration information for SSI module. + * @param ssi_txinit pointer to a SSI_TxInitTypeDef structure that contains + * the SSI Tx initialization information + * @retval None + */ +static void SSI_FillDfifo(SSI_HandleTypeDef *ssi, SSI_TxInitTypeDef *ssi_txinit) +{ + while (((ssi->Instance->SISR & SSI_SISR_TFE0) == SSI_SISR_TFE0) && (ssi->XferCount0 > 0U)) + { + if (ssi_txinit->DataSize == SSI_DATA_WL8) + { + ssi->Instance->STX0 = (*ssi->pBuffPtr0++); + } + else if (ssi_txinit->DataSize == SSI_DATA_WL16) + { + ssi->Instance->STX0 = *((uint16_t *)(ssi->pBuffPtr0)); + ssi->pBuffPtr0 += 2U; + } + else + { + ssi->Instance->STX0 = *((uint32_t *)(ssi->pBuffPtr0)); + ssi->pBuffPtr0 += 4U; + } + ssi->XferCount0--; + } + + while (((ssi->Instance->SISR & SSI_SISR_TFE1) == SSI_SISR_TFE1) && (ssi->XferCount1 > 0U)) + { + if (ssi_txinit->DataSize == SSI_DATA_WL8) + { + ssi->Instance->STX1 = (*ssi->pBuffPtr1++); + } + else if (ssi_txinit->DataSize == SSI_DATA_WL16) + { + ssi->Instance->STX1 = *((uint16_t *)(ssi->pBuffPtr1)); + ssi->pBuffPtr1 += 2U; + } + else + { + ssi->Instance->STX1 = *((uint32_t *)(ssi->pBuffPtr1)); + ssi->pBuffPtr1 += 4U; + } + ssi->XferCount1--; + } +} + +/** + * @brief Receive an amount of data in polling mode. + * @param ssi pointer to a SSI_HandleTypeDef structure that contains + * the configuration information for SSI module. + * @param ssi_rxinit pointer to a SSI_RxInitTypeDef structure that contains + * the SSI Rx initialization information + * @param pData0 Pointer to data buffer for channel 0 + * @param pData1 Pointer to data buffer for channel 1 + * @param Size0 Amount of data to be sent for channel 0 + * @param Size1 Amount of data to be sent for channel 1 + * @param Timeout Timeout duration + * @retval void + */ +void SSI_Receive(SSI_HandleTypeDef *ssi, \ + SSI_InitTypeDef *ssi_init, \ + SSI_RxInitTypeDef *ssi_rxinit, \ + uint8_t *pData0, \ + uint8_t *pData1, \ + uint16_t Size0, \ + uint16_t Size1, \ + uint32_t Timeout) +{ + uint32_t tickstart = GetTick(); + + if (((pData0 == NULL) && (pData1 == NULL)) + || ((Size0 == 0)) && (Size1 == 0)) + { + return; + } + + if (ssi->State == SSI_STATE_READY) + { + ssi->XferSize0 = Size0; + ssi->XferSize1 = Size1; + ssi->XferCount0 = Size0; + ssi->XferCount1 = Size1; + ssi->pBuffPtr0 = pData0; + ssi->pBuffPtr1 = pData1; + ssi->State = SSI_STATE_BUSY_RX; + ssi->ErrorCode = SSI_ERROR_NONE; + + if ((ssi->Instance->SCR & SSI_SCR_RE) != SSI_SCR_RE) + { + ssi->Instance->SCR |= SSI_SCR_RE; + } + + /* Receive Data*/ + + if (ssi_init->TCHEN == ENABLE) + { + while ((ssi->XferCount0 > 0U) || (ssi->XferCount1 > 0U)) + { + if (ssi->XferCount0 > 0U) + { + SSI_Fifo0Rx(ssi, ssi_rxinit, Timeout, tickstart); + } + + + if (ssi->XferCount1 > 0U) + { + SSI_Fifo1Rx(ssi, ssi_rxinit, Timeout, tickstart); + } + } + } + else if (ssi_rxinit->FIFO0EN || ssi_init->Mode == AC97) + { + while (ssi->XferCount0 > 0U) + { + SSI_Fifo0Rx(ssi, ssi_rxinit, Timeout, tickstart); + } + } + else + { + while (ssi->XferCount0 > 0U) + { + SSI_SRX0Rx(ssi, ssi_rxinit, Timeout, tickstart); + } + } + } +} + + +/** + * @brief Rx fifo_0 transmit function + * @param ssi pointer to a SSI_HandleTypeDef structure that contains + * the configuration information for SSI module. + * @param ssi_rxinit pointer to a SSI_RxInitTypeDef structure that contains + * the SSI Rx initialization information + * @param Timeout Timeout duration + * @param tickstart Receive start time + * @retval None + */ +static void SSI_Fifo0Rx(SSI_HandleTypeDef *ssi, SSI_RxInitTypeDef *ssi_rxinit, uint32_t Timeout, uint32_t tickstart) +{ + if ((ssi->Instance->SISR & SSI_SISR_RFF0) == SSI_SISR_RFF0) + { + if (ssi_rxinit->DataSize == SSI_DATA_WL8) + { + (*ssi->pBuffPtr0++) = ssi->Instance->SRX0; + } + else if (ssi_rxinit->DataSize == SSI_DATA_WL16) + { + *((uint16_t *)(ssi->pBuffPtr0)) = ssi->Instance->SRX0; + ssi->pBuffPtr0 += 2U; + } + else + { + *((uint32_t *)(ssi->pBuffPtr0)) = ssi->Instance->SRX0; + ssi->pBuffPtr0 += 4U; + } + ssi->XferCount0--; + } + else + { + if ((Timeout != MAX_DELAY) && ((Timeout == 0U) || ((GetTick() - tickstart) > Timeout))) + { + /* Update error code */ + ssi->ErrorCode |= SSI_ERROR_TIMEOUT; + + /* Disable SSI Rx channel */ + ssi->Instance->SCR &= ~(SSI_SCR_RE); + + /* Flush the fifo */ + ssi->Instance->SOR |= SSI_SOR_RX_CLR; + + /* Change the SSI state */ + ssi->State = SSI_STATE_READY; + + return ; + } + } +} + +/** + * @brief Rx fifo_1 transmit function + * @param ssi pointer to a SSI_HandleTypeDef structure that contains + * the configuration information for SSI module. + * @param ssi_rxinit pointer to a SSI_RxInitTypeDef structure that contains + * the SSI Rx initialization information + * @param Timeout Timeout duration + * @param tickstart Receive start time + * @retval None + */ +static void SSI_Fifo1Rx(SSI_HandleTypeDef *ssi, SSI_RxInitTypeDef *ssi_rxinit, uint32_t Timeout, uint32_t tickstart) +{ + if ((ssi->Instance->SISR & SSI_SISR_RFF1) == SSI_SISR_RFF1) + { + if (ssi_rxinit->DataSize == SSI_DATA_WL8) + { + (*ssi->pBuffPtr1++) = ssi->Instance->SRX1; + } + else if (ssi_rxinit->DataSize == SSI_DATA_WL16) + { + *((uint16_t *)(ssi->pBuffPtr1)) = ssi->Instance->SRX1; + ssi->pBuffPtr1 += 2U; + } + else + { + *((uint32_t *)(ssi->pBuffPtr1)) = ssi->Instance->SRX1; + ssi->pBuffPtr1 += 4U; + } + ssi->XferCount1--; + } + else + { + if ((Timeout != MAX_DELAY) && ((Timeout == 0U) || ((GetTick() - tickstart) > Timeout))) + { + /* Update error code */ + ssi->ErrorCode |= SSI_ERROR_TIMEOUT; + + /* Disable SSI Rx Function */ + ssi->Instance->SCR &= ~(SSI_SCR_RE); + + /* Change the SSI state */ + ssi->State = SSI_STATE_READY; + + return ; + } + } +} + +/** + * @brief Rx srx register transmit function + * @param ssi pointer to a SSI_HandleTypeDef structure that contains + * the configuration information for SSI module. + * @param ssi_rxinit pointer to a SSI_RxInitTypeDef structure that contains + * the SSI Rx initialization information + * @param Timeout Timeout duration + * @param tickstart Receive start time + * @retval None + */ +static void SSI_SRX0Rx(SSI_HandleTypeDef *ssi, SSI_RxInitTypeDef *ssi_rxinit, uint32_t Timeout, uint32_t tickstart) +{ + if ((ssi->Instance->SISR & SSI_SISR_RDR0) == SSI_SISR_RDR0) + { + if (ssi_rxinit->DataSize == SSI_DATA_WL8) + { + (*ssi->pBuffPtr0++) = ssi->Instance->SRX0; + } + else if (ssi_rxinit->DataSize == SSI_DATA_WL16) + { + *((uint16_t *)(ssi->pBuffPtr0)) = ssi->Instance->SRX0; + ssi->pBuffPtr0 += 2U; + } + else + { + *((uint32_t *)(ssi->pBuffPtr0)) = ssi->Instance->SRX0; + ssi->pBuffPtr0 += 4U; + } + ssi->XferCount0--; + } + else + { + if ((Timeout != MAX_DELAY) && ((Timeout == 0U) || ((GetTick() - tickstart) > Timeout))) + { + /* Update error code */ + ssi->ErrorCode |= SSI_ERROR_TIMEOUT; + + /* Disable SSI Rx Function */ + ssi->Instance->SCR &= ~(SSI_SCR_RE); + + /* Change the SSI state */ + ssi->State = SSI_STATE_READY; + + return ; + } + } +} + diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_syscfg.c b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_syscfg.c new file mode 100644 index 00000000000..246c6dae8b6 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_syscfg.c @@ -0,0 +1,252 @@ +/** + ****************************************************************************** + * @file ft32f4xx_syscfg.c + * @author FMD XA + * @brief This file provides firmware functions to manage the following + * functionalities of the SYSCFG peripheral: + * + Remapping the memory mapped at 0x00000000 + * + Enabling I2C fast mode plus driving capability for I2C pins + * + Configuring the EXTI lines connection to the GPIO port + * + Configuring the CFGR features (Connecting some internal signal + * to the break input of TIM1/8 and EPWM) + * @version V1.0.0 + * @data 2025-04-08 + ****************************************************************************** + */ +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx_syscfg.h" + +/** + * @brief Deinitializes the SYSCFG registers to their default reset values. + * @param None + * @retval None + * @note MEM_MODE bits took the value from bootpin after por_reset. + */ +void SYSCFG_DeInit(void) +{ + /* Set SYSCFG_MEMRMP register to reset value without affecting MEM_MODE bits */ + SYSCFG->MEMRMP &= SYSCFG_MEMRMP_MEM_MODE; + /* Set PMC registers to reset value */ + SYSCFG->PMC = 0; + /* Set EXTICRx registers to reset value */ + SYSCFG->EXTICR[0] = 0; + SYSCFG->EXTICR[1] = 0; + SYSCFG->EXTICR[2] = 0; + SYSCFG->EXTICR[3] = 0; + /* Set CFGR register to reset value */ + SYSCFG->CFGR |= 0; +} + +/** + * @brief Configures the memory mapping at address 0x00000000. + * @param SYSCFG_MemoryRemap: selects the memory remapping. + * This parameter can be one of the following values: + * @arg SYSCFG_MemoryRemap_Flash: Main Flash memory mapped at 0x00000000 + * @arg SYSCFG_MemoryRemap_SystemMemory: System Flash memory mapped at 0x00000000 + * @arg SYSCFG_MemoryRemap_SRAM: Embedded SRAM mapped at 0x00000000 + * @arg SYSCFG_MemoryRemap_FMC1: Embedded FMC1 mapped at 0x00000000 + * @arg SYSCFG_MemoryRemap_FMC2: Embedded FMC2 mapped at 0x00000000 + * @arg SYSCFG_MemoryRemap_QSPI: Embedded QSPI mapped at 0x00000000 + * @retval None + */ +void SYSCFG_MemoryRemapConfig(uint32_t SYSCFG_MemoryRemap) +{ + uint32_t tmpctrl = 0; + + /* Check the parameter */ + assert_param(IS_SYSCFG_MEMORY_REMAP(SYSCFG_MemoryRemap)); + + /* Get MEMRMP register value */ + tmpctrl = SYSCFG->MEMRMP; + + /* Clear MEM_MODE bits */ + tmpctrl &= (uint32_t)(~SYSCFG_MEMRMP_MEM_MODE); + + /* Set the new MEM_MODE bits value */ + tmpctrl |= (uint32_t) SYSCFG_MemoryRemap; + + /* Set MEMRMP register with the new memory remap configuration */ + SYSCFG->MEMRMP = tmpctrl; +} + +/** + * @brief Configure FMC memory mapping swap. + * @param SYSCFG_FMCSWPConfig: enable or disable FMC memory mapping swap. + * This parameter can be one of the following values: + * @arg SYSCFG_FMC_SWP_ENABLE: Configure FMC memory mapping swap enable + * SDRAM bank1/2 and NAND bank1/2 mapping are swap + * @arg SYSCFG_FMC_SWP_DISABLE: Configure FMC memory mapping swap disable + * + * @retval None + */ +void SYSCFG_FMCSWPConfig(uint32_t SYSCFG_FMCSWPCFG) +{ + /* Check the parameters */ + assert_param(IS_SYSCFG_FMC_SWP(SYSCFG_FMCSWPCFG)); + + if (SYSCFG_FMCSWPCFG != DISABLE) + { + /* Enable FMC memory mapping swap */ + SYSCFG->MEMRMP &= (uint32_t)(~SYSCFG_MEMRMP_SWP_FMC); + SYSCFG->MEMRMP |= (uint32_t)SYSCFG_FMCSWPCFG; + } + else + { + /* Disable FMC memory mapping swap */ + SYSCFG->MEMRMP &= (uint32_t)(~SYSCFG_FMCSWPCFG); + } +} + + +/** + * @brief Configure the boost enable for adc. + * @param SYSCFG_BoostENConfig: enable or disable boost function. + * This parameter can be one of the following values: + * @arg SYSCFG_PMC_BoostEN_ENABLE: Configure boost function enable + * @arg SYSCFG_PMC_BoostEN_DISABLE: Configure boost function disable + * + * @retval None + */ +void SYSCFG_BoostENConfig(uint32_t SYSCFG_BoostENCFG) +{ + /* Check the parameters */ + assert_param(IS_SYSCFG_PMC_BoostEN(SYSCFG_BoostENCFG)); + + if (SYSCFG_BoostENCFG != DISABLE) + { + /* Enable boost function */ + SYSCFG->PMC |= (uint32_t)SYSCFG_BoostENCFG; + } + else + { + /* Disable boost function */ + SYSCFG->PMC &= (uint32_t)(~SYSCFG_BoostENCFG); + } +} + + +/** + * @brief Configure the I2C fast mode plus driving capability. + * @param SYSCFG_I2CFastModePlus: selects the pin. + * This parameter can be one of the following values: + * @arg SYSCFG_I2CFastModePlus_PB6: Configure fast mode plus driving capability for PB6 + * @arg SYSCFG_I2CFastModePlus_PB7: Configure fast mode plus driving capability for PB7 + * @arg SYSCFG_I2CFastModePlus_PB8: Configure fast mode plus driving capability for PB8 + * @arg SYSCFG_I2CFastModePlus_PB9: Configure fast mode plus driving capability for PB9 + * @arg SYSCFG_I2CFastModePlus_PA9: Configure fast mode plus driving capability for PA9 + * @arg SYSCFG_I2CFastModePlus_PA10: Configure fast mode plus driving capability for PA10 + * @arg SYSCFG_I2CFastModePlus_I2C1: Configure fast mode plus driving capability for PB10, PB11, PF6 and PF7 + * @arg SYSCFG_I2CFastModePlus_I2C2: Configure fast mode plus driving capability for I2C2 pins + * + * @param NewState: new state of the DMA channel remapping. + * This parameter can be: ENABLE or DISABLE. + * @note ENABLE: Enable fast mode plus driving capability for selected I2C pin + * @note DISABLE: Disable fast mode plus driving capability for selected I2C pin + * @note For I2C1, fast mode plus driving capability can be enabled on all selected + * I2C1 pins using SYSCFG_I2CFastModePlus_I2C1 parameter or independently + * on each one of the following pins PB6, PB7, PB8 and PB9. + * @note For remaining I2C1 pins (PA14, PA15...) fast mode plus driving capability + * can be enabled only by using SYSCFG_I2CFastModePlus_I2C1 parameter. + * @note For all I2C2 pins fast mode plus driving capability can be enabled + * only by using SYSCFG_I2CFastModePlus_I2C2 parameter. + * @retval None + */ +void SYSCFG_I2CFastModePlusConfig(uint32_t SYSCFG_I2CFastModePlus, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_SYSCFG_I2C_FMP(SYSCFG_I2CFastModePlus)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable fast mode plus driving capability for selected pin */ + SYSCFG->PMC |= (uint32_t)SYSCFG_I2CFastModePlus; + } + else + { + /* Disable fast mode plus driving capability for selected pin */ + SYSCFG->PMC &= (uint32_t)(~SYSCFG_I2CFastModePlus); + } +} + +/** + * @brief Configure the mii function or rmii function for ethernet. + * @param SYSCFG_MII_RMIIConfig: select ethernet use mii or rmii. + * This parameter can be one of the following values: + * @arg SYSCFG_ETH_MII_RMII_SEL_MII: select mii function + * @arg SYSCFG_ETH_MII_RMII_SEL_RMII: select rmii function + * + * @retval None + */ +void SYSCFG_MII_RMIIConfig(uint32_t SYSCFG_MII_RMIICFG) +{ + /* Check the parameters */ + assert_param(IS_SYSCFG_ETH_MII_RMII_SEL(SYSCFG_MII_RMIICFG)); + + if (SYSCFG_MII_RMIICFG != DISABLE) + { + /* select rmii function */ + SYSCFG->PMC |= (uint32_t)SYSCFG_MII_RMIICFG; + } + else + { + /* select mii function */ + SYSCFG->PMC &= (uint32_t)(~SYSCFG_MII_RMIICFG); + } +} + +/** + * @brief Selects the GPIO pin used as EXTI Line. + * @param EXTI_PortSourceGPIOx: selects the GPIO port to be used as source + * for EXTI lines where x can be (A, B, C, D, E or H). + * @param EXTI_PinSourcex: specifies the EXTI line to be configured. + * @note This parameter can be EXTI_PinSourcex where x can be: + * (0..15) for GPIOA, GPIOB, GPIOC, GPIOD, GPIOE, (0,1) for GPIOH. + * @retval None + */ +void SYSCFG_EXTILineConfig(uint8_t EXTI_PortSourceGPIOx, uint8_t EXTI_PinSourcex) +{ + uint32_t tmp = 0x00; + + /* Check the parameters */ + assert_param(IS_EXTI_PORT_SOURCE(EXTI_PortSourceGPIOx)); + assert_param(IS_EXTI_PIN_SOURCE(EXTI_PinSourcex)); + + tmp = ((uint32_t)0x0F) << (0x04 * (EXTI_PinSourcex & (uint8_t)0x03)); + SYSCFG->EXTICR[EXTI_PinSourcex >> 0x02] &= ~tmp; + SYSCFG->EXTICR[EXTI_PinSourcex >> 0x02] |= (((uint32_t)EXTI_PortSourceGPIOx) << (0x04 * (EXTI_PinSourcex & (uint8_t)0x03))); +} + +/** + * @brief Connect the selected parameter to the break input of TIM. + * @param SYSCFG_Break: selects the configuration to be connected to break + * input of TIM + * This parameter can be any combination of the following values: + * @arg SYSCFG_Break_PVD: Connects the PVD event to the Break + * @arg SYSCFG_Break_Lockup: Connects Lockup output of CortexM0 to the break input of TIM1/8 or EPWM + * @retval None + */ +void SYSCFG_BreakConfig(uint32_t SYSCFG_Break) +{ + /* Check the parameter */ + assert_param(IS_SYSCFG_LOCK_CONFIG(SYSCFG_Break)); + + SYSCFG->CFGR |= (uint32_t) SYSCFG_Break; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_tim.c b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_tim.c new file mode 100644 index 00000000000..b221579f7d9 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_tim.c @@ -0,0 +1,4243 @@ +/** + ****************************************************************************** + * @file ft32f4xx_tim.c + * @author FMD AE + * @brief This file provides firmware functions to manage the following + * functionalities of the TIM peripheral: + * + TimeBase management + * + Advanced-control timers specific features + * + Output Compare management + * + Input Capture management + * + Interrupts, DMA and flags management + * + Clocks management + * + Synchronization management + * + Specific interface management + * + Specific remapping management + * @version V1.0.0 + * @date 2025-04-07 + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx_tim.h" +#include "ft32f4xx_rcc.h" + + +/* ------------------------ TIM registers bit mask -------------------------- */ +#define SMCR_ETR_MASK ((uint32_t)0x000000FF) +#define CCMR_OFFSET ((uint32_t)0x00000018) +#define CCER_CCE_SET ((uint32_t)0x00000001) +#define CCER_CCNE_SET ((uint32_t)0x00000004) + + +static void TI1_Config(TIM_TypeDef* TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection, + uint32_t TIM_ICFilter); +static void TI2_Config(TIM_TypeDef* TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection, + uint32_t TIM_ICFilter); +static void TI3_Config(TIM_TypeDef* TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection, + uint32_t TIM_ICFilter); +static void TI4_Config(TIM_TypeDef* TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection, + uint32_t TIM_ICFilter); + +/** + * @brief Deinitializes the TIMx peripheral registers to their default reset values. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 and 14 to + * select the TIM peripheral. + * @retval None + * + */ +void TIM_DeInit(TIM_TypeDef* TIMx) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + + if (TIMx == TIM1) + { + RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM1, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM1, DISABLE); + } + else if (TIMx == TIM2) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM2, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM2, DISABLE); + } + else if (TIMx == TIM3) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM3, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM3, DISABLE); + } + else if (TIMx == TIM4) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM4, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM4, DISABLE); + } + else if (TIMx == TIM5) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM5, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM5, DISABLE); + } + else if (TIMx == TIM6) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM6, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM6, DISABLE); + } + else if (TIMx == TIM7) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM7, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM7, DISABLE); + } + else if (TIMx == TIM8) + { + RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM8, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM8, DISABLE); + } + else if (TIMx == TIM9) + { + RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM9, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM9, DISABLE); + } + else if (TIMx == TIM10) + { + RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM10, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM10, DISABLE); + } + else if (TIMx == TIM11) + { + RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM11, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM11, DISABLE); + } + else if (TIMx == TIM12) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM12, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM12, DISABLE); + } + else if (TIMx == TIM13) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM13, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM13, DISABLE); + } + else + { + if (TIMx == TIM14) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM14, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM14, DISABLE); + } + } +} + +/** + * @brief Initializes the TIMx Time Base Unit peripheral according to + * the specified parameters in the TIM_TimeBaseInitStruct. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 and 14 to + * select the TIM peripheral. + * @param TIM_TimeBaseInitStruct: pointer to a TIM_TimeBaseInitTypeDef + * structure that contains the configuration information for + * the specified TIM peripheral. + * @retval None + */ +void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct) +{ + uint32_t tmpcr1 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_TIM_COUNTER_MODE(TIM_TimeBaseInitStruct->TIM_CounterMode)); + assert_param(IS_TIM_CKD_DIV(TIM_TimeBaseInitStruct->TIM_ClockDivision)); + + tmpcr1 = TIMx->CR1; + + if ((TIMx == TIM1) || (TIMx == TIM8) || (TIMx == TIM2) || + (TIMx == TIM3) || (TIMx == TIM4) || (TIMx == TIM5)) + { + /* Select the Counter Mode */ + tmpcr1 &= (uint32_t)(~((uint32_t)(TIM_CR1_DIR | TIM_CR1_CMS))); + tmpcr1 |= (uint32_t)TIM_TimeBaseInitStruct->TIM_CounterMode; + } + + if ((TIMx != TIM6) || (TIMx != TIM7)) + { + /* Set the clock division */ + tmpcr1 &= (uint32_t)(~((uint32_t)TIM_CR1_CKD)); + tmpcr1 |= (uint32_t)TIM_TimeBaseInitStruct->TIM_ClockDivision; + } + + TIMx->CR1 = tmpcr1; + + /* Set the Autoreload value */ + TIMx->ARR = TIM_TimeBaseInitStruct->TIM_Period ; + + /* Set the Prescaler value */ + TIMx->PSC = TIM_TimeBaseInitStruct->TIM_Prescaler; + + if ((TIMx == TIM1) || (TIMx == TIM8)) + { + /* Set the Repetition Counter value */ + TIMx->RCR = TIM_TimeBaseInitStruct->TIM_RepetitionCounter; + } + + /* Generate an update event to reload the Prescaler and the Repetition counter + values immediately */ + TIMx->EGR = TIM_PSCReloadMode_Immediate; +} + +/** + * @brief Fills each TIM_TimeBaseInitStruct member with its default value. + * @param TIM_TimeBaseInitStruct: pointer to a TIM_TimeBaseInitTypeDef structure + * which will be initialized. + * @retval None + */ +void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct) +{ + /* Set the default configuration */ + TIM_TimeBaseInitStruct->TIM_Period = 0xFFFFFFFF; + TIM_TimeBaseInitStruct->TIM_Prescaler = 0x0000; + TIM_TimeBaseInitStruct->TIM_ClockDivision = TIM_CKD_DIV1; + TIM_TimeBaseInitStruct->TIM_CounterMode = TIM_CounterMode_Up; + TIM_TimeBaseInitStruct->TIM_RepetitionCounter = 0x0000; +} + +/** + * @brief Configures the TIMx Prescaler. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 and 14 to + * select the TIM peripheral. + * @param Prescaler: specifies the Prescaler Register value + * @param TIM_PSCReloadMode: specifies the TIM Prescaler Reload mode + * This parameter can be one of the following values: + * @arg TIM_PSCReloadMode_Update : The Prescaler is loaded at the update event. + * @arg TIM_PSCReloadMode_Immediate: The Prescaler is loaded immediatly. + * @retval None + */ +void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint32_t Prescaler, uint32_t TIM_PSCReloadMode) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_TIM_PRESCALER_RELOAD(TIM_PSCReloadMode)); + + /* Set the Prescaler value */ + TIMx->PSC = Prescaler; + /* Set or reset the UG Bit */ + TIMx->EGR = TIM_PSCReloadMode; +} + +/** + * @brief Specifies the TIMx Counter Mode to be used. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_CounterMode: specifies the Counter Mode to be used + * This parameter can be one of the following values: + * @arg TIM_CounterMode_Up : TIM Up Counting Mode + * @arg TIM_CounterMode_Down : TIM Down Counting Mode + * @arg TIM_CounterMode_CenterAligned1: TIM Center Aligned Mode1 + * @arg TIM_CounterMode_CenterAligned2: TIM Center Aligned Mode2 + * @arg TIM_CounterMode_CenterAligned3: TIM Center Aligned Mode3 + * @retval None + */ +void TIM_CounterModeConfig(TIM_TypeDef* TIMx, uint32_t TIM_CounterMode) +{ + uint32_t tmpcr1 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_COUNTER_MODE(TIM_CounterMode)); + tmpcr1 = TIMx->CR1; + + /* Reset the CMS and DIR Bits */ + tmpcr1 &= (uint32_t)(~((uint32_t)(TIM_CR1_DIR | TIM_CR1_CMS))); + + /* Set the Counter Mode */ + tmpcr1 |= TIM_CounterMode; + + /* Write to TIMx CR1 register */ + TIMx->CR1 = tmpcr1; +} + +/** + * @brief Sets the TIMx Counter Register value + * @param TIMx: where x can be 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 and 14 to + * select the TIM peripheral. + * @param Counter: specifies the Counter register new value. + * @retval None + */ +void TIM_SetCounter(TIM_TypeDef* TIMx, uint32_t Counter) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + + /* Set the Counter Register value */ + TIMx->CNT = Counter; +} + +/** + * @brief Sets the TIMx Autoreload Register value + * @param TIMx: where x can be 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 and 14 to + * select the TIM peripheral. + * @param Autoreload: specifies the Autoreload register new value. + * @retval None + */ +void TIM_SetAutoreload(TIM_TypeDef* TIMx, uint32_t Autoreload) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + + /* Set the Autoreload Register value */ + TIMx->ARR = Autoreload; +} + +/** + * @brief Sets the TIMx RepetitionCounter Register value + * @param TIMx: where x can be 1 or 8 to select the TIM peripheral. + * @param RepetitionCounter: specifies the RepetitionCounter register new value. + * @retval None + */ +void TIM_SetRepetitionCounter(TIM_TypeDef* TIMx, uint32_t RepetitionCounter) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + + /* Set the RepetitionCounter Register value */ + TIMx->RCR = RepetitionCounter; +} + +/** + * @brief Gets the TIMx Counter value. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 and 14 to + * select the TIM peripheral. + * @retval Counter Register value. + */ +uint32_t TIM_GetCounter(TIM_TypeDef* TIMx) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + + /* Get the Counter Register value */ + return TIMx->CNT; +} + +/** + * @brief Gets the TIMx Prescaler value. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 and 14 to + * select the TIM peripheral. + * @retval Prescaler Register value. + */ +uint32_t TIM_GetPrescaler(TIM_TypeDef* TIMx) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + + /* Get the Prescaler Register value */ + return TIMx->PSC; +} + +/** + * @brief Enables or Disables the TIMx Update event. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 and 14 to + * select the TIM peripheral. + * @param NewState: new state of the TIMx UDIS bit + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void TIM_UpdateDisableConfig(TIM_TypeDef* TIMx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Set the Update Disable Bit */ + TIMx->CR1 |= TIM_CR1_UDIS; + } + else + { + /* Reset the Update Disable Bit */ + TIMx->CR1 &= (uint32_t)~((uint32_t)TIM_CR1_UDIS); + } +} + +/** + * @brief Configures the TIMx Update Request Interrupt source. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 and 14 to + * select the TIM peripheral. + * @param TIM_UpdateSource: specifies the Update source. + * This parameter can be one of the following values: + * @arg TIM_UpdateSource_Global : Source of update is the counter overflow/underflow + * or the setting of UG bit, or an update generation + * through the slave mode controller. + * @arg TIM_UpdateSource_Regular: Source of update is counter overflow/underflow. + * @retval None + */ +void TIM_UpdateRequestConfig(TIM_TypeDef* TIMx, uint32_t TIM_UpdateSource) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_TIM_UPDATE_SOURCE(TIM_UpdateSource)); + + if (TIM_UpdateSource != TIM_UpdateSource_Global) + { + /* Set the URS Bit */ + TIMx->CR1 |= TIM_CR1_URS; + } + else + { + /* Reset the URS Bit */ + TIMx->CR1 &= (uint32_t)~((uint32_t)TIM_CR1_URS); + } +} + +/** + * @brief Enables or disables TIMx peripheral Preload register on ARR. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 and 14 to + * select the TIM peripheral. + * @param NewState: new state of the TIMx peripheral Preload register + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Set the ARR Preload Bit */ + TIMx->CR1 |= TIM_CR1_ARPE; + TIMx->EGR |= TIM_EGR_UG; + TIMx->SR &= (uint32_t)~((uint32_t)TIM_SR_UIF); + } + else + { + /* Reset the ARR Preload Bit */ + TIMx->CR1 &= (uint32_t)~((uint32_t)TIM_CR1_ARPE); + } +} + +/** + * @brief Selects the TIMx's One Pulse Mode. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 and 14 to + * select the TIM peripheral. + * @param TIM_OPMode: specifies the OPM Mode to be used. + * This parameter can be one of the following values: + * @arg TIM_OPMode_Single + * @arg TIM_OPMode_Repetitive + * @retval None + */ +void TIM_SelectOnePulseMode(TIM_TypeDef* TIMx, uint32_t TIM_OPMode) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_TIM_OPM_MODE(TIM_OPMode)); + + /* Reset the OPM Bit */ + TIMx->CR1 &= (uint32_t)~((uint32_t)TIM_CR1_OPM); + + /* Configure the OPM Mode */ + TIMx->CR1 |= TIM_OPMode; +} + +/** + * @brief Sets the TIMx Clock Division value. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, + * 13 and 14 to select the TIM peripheral. + * @param TIM_CKD: specifies the clock division value. + * This parameter can be one of the following value: + * @arg TIM_CKD_DIV1: TDTS = 1*Tck_tim + * @arg TIM_CKD_DIV2: TDTS = 2*Tck_tim + * @arg TIM_CKD_DIV4: TDTS = 4*Tck_tim + * @retval None + */ +void TIM_SetClockDivision(TIM_TypeDef* TIMx, uint32_t TIM_CKD) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST4_PERIPH(TIMx)); + assert_param(IS_TIM_CKD_DIV(TIM_CKD)); + + /* Reset the CKD Bits */ + TIMx->CR1 &= (uint32_t)~((uint32_t)TIM_CR1_CKD); + + /* Set the CKD value */ + TIMx->CR1 |= TIM_CKD; +} + +/** + * @brief Enables or disables the specified TIM peripheral. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 and 14 to + * select the TIM peripheral. + * @param NewState: new state of the TIMx peripheral. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the TIM Counter */ + TIMx->CR1 |= TIM_CR1_CEN; + } + else + { + /* Disable the TIM Counter */ + TIMx->CR1 &= (uint32_t)(~((uint32_t)TIM_CR1_CEN)); + } +} + +/** + * @} + */ + +/** + * @brief Configures the: Break feature, dead time, Lock level, OSSI/OSSR State + * and the AOE(automatic output enable). + * @param TIMx: where x can be 1 or 8 to select the TIM + * @param TIM_BDTRInitStruct: pointer to a TIM_BDTRInitTypeDef structure that + * contains the BDTR Register configuration information for the TIM peripheral. + * @retval None + */ +void TIM_BDTRConfig(TIM_TypeDef* TIMx, TIM_BDTRInitTypeDef* TIM_BDTRInitStruct) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_TIM_DEADTIME(TIM_BDTRInitStruct->TIM_DeadTime)); + assert_param(IS_TIM_LOCK_LEVEL(TIM_BDTRInitStruct->TIM_LOCKLevel)); + assert_param(IS_TIM_OSSI_STATE(TIM_BDTRInitStruct->TIM_OSSIState)); + assert_param(IS_TIM_OSSR_STATE(TIM_BDTRInitStruct->TIM_OSSRState)); + assert_param(IS_TIM_BREAK_STATE(TIM_BDTRInitStruct->TIM_Break)); + assert_param(IS_TIM_BREAK_POLARITY(TIM_BDTRInitStruct->TIM_BreakPolarity)); + assert_param(IS_TIM_AUTOMATIC_OUTPUT_STATE(TIM_BDTRInitStruct->TIM_AutomaticOutput)); + assert_param(IS_TIM_BREAK_FILTER(TIM_BDTRInitStruct->TIM_BreakFilter)); + assert_param(IS_TIM_BREAK_BID_MODE(TIM_BDTRInitStruct->TIM_BreakBIDMode)); + assert_param(IS_TIM_CONTROL_PWM_OUTPUT_STATE(TIM_BDTRInitStruct->TIM_CtrlPWMOutput)); + + /* Set the Lock level LOCK[1:0], the Break enable Bit BKE and the Ploarity BKP, the OSSR State, + the OSSI State, the dead time value DTG[7:0], the Automatic Output Enable Bit AOE, the Break + Filter BKF[3:0], output control MOE bit and the bidirectional function mode of break input + bit BKBID */ + TIMx->BDTR = (uint32_t)TIM_BDTRInitStruct->TIM_DeadTime | + TIM_BDTRInitStruct->TIM_LOCKLevel | + TIM_BDTRInitStruct->TIM_OSSIState | + TIM_BDTRInitStruct->TIM_OSSRState | + TIM_BDTRInitStruct->TIM_Break | + TIM_BDTRInitStruct->TIM_BreakPolarity | + TIM_BDTRInitStruct->TIM_AutomaticOutput | + TIM_BDTRInitStruct->TIM_CtrlPWMOutput | + ((TIM_BDTRInitStruct->TIM_BreakFilter) << (uint32_t)16) | + TIM_BDTRInitStruct->TIM_BreakBIDMode ; +} + +/** + * @brief Fills each TIM_BDTRInitStruct member with its default value. + * @param TIM_BDTRInitStruct: pointer to a TIM_BDTRInitTypeDef structure which + * will be initialized. + * @retval None + */ +void TIM_BDTRStructInit(TIM_BDTRInitTypeDef* TIM_BDTRInitStruct) +{ + /* Set the default configuration */ + TIM_BDTRInitStruct->TIM_DeadTime = 0x00; + TIM_BDTRInitStruct->TIM_LOCKLevel = TIM_LOCKLevel_OFF; + TIM_BDTRInitStruct->TIM_OSSIState = TIM_OSSIState_Disable; + TIM_BDTRInitStruct->TIM_OSSRState = TIM_OSSRState_Disable; + TIM_BDTRInitStruct->TIM_Break = TIM_Break_Disable; + TIM_BDTRInitStruct->TIM_BreakPolarity = TIM_BreakPolarity_Low; + TIM_BDTRInitStruct->TIM_AutomaticOutput = TIM_AutomaticOutput_Disable; + TIM_BDTRInitStruct->TIM_BreakFilter = 0x0; + TIM_BDTRInitStruct->TIM_BreakBIDMode = TIM_Break_Bid_MODE_INPUT; +} + +/** + * @brief Configures the: Break feature, dead time, Lock level, OSSI/OSSR State + * and the AOE(automatic output enable). + * @param TIMx: where x can be 1 or 8 to select the TIM + * @param TIM_BDTRInitStruct: pointer to a TIM_BDTRInitTypeDef structure that + * contains the BDTR Register configuration information for the TIM peripheral. + * @retval None + */ + +/** + * @brief Configures the break input source. + * @param TIMx: where x can be 1 or 8 to select the TIM + * @param BreakInputConfig: pointer to a TIMx_BreakInputConfigTypeDef structure that + * contains the AF1 Register Break input source configuration information for + * the TIM peripheral. + * + * There are three instance variables in BreakInputConfig as follows: + * + * - TIM_Break_Input_Source: specifies the source of the timer break input. + * This parameter can be one of the following value: + * @arg TIM_BREAKINPUTSOURCE_BKIN : An external source (GPIO) is connected to the BKIN pin + * @arg TIM_BREAKINPUTSOURCE_COMP1: The COMP1 output is connected to the break input + * @arg TIM_BREAKINPUTSOURCE_COMP2: The COMP2 output is connected to the break input + * @arg TIM_BREAKINPUTSOURCE_COMP3: The COMP3 output is connected to the break input + * @arg TIM_BREAKINPUTSOURCE_COMP4: The COMP4 output is connected to the break input + * @arg TIM_BREAKINPUTSOURCE_COMP5: The COMP5 output is connected to the break input + * @arg TIM_BREAKINPUTSOURCE_COMP6: The COMP6 output is connected to the break input + * + * - TIM_Enable: specifies whether or not the break input source is enabled. + * This parameter can be one of the following value: + * @arg TIM_BREAKINPUTSOURCE_DISABLE: Break input source is disabled + * @arg TIM_BREAKINPUTSOURCE_ENABLE : Break input source is enabled + * + * - TIM_Polarity: specifies the break input source polarity. + * This parameter can be one of the following value: + * @arg TIM_BREAKINPUTSOURCE_POLARITY_INVERTED : Break input source is inverted + * (active high if BKP = 0, active low if BKP = 1) + * @arg TIM_BREAKINPUTSOURCE_POLARITY_NOT_INVERTED: Break input source is not inverted + * (active low if BKP = 0, active high if BKP = 1) + * + * @retval None + */ +void TIM_ConfigBreakInput(TIM_TypeDef* TIMx, TIM_BreakInputConfigTypeDef* BreakInputConfig) + +{ + 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_LIST2_PERIPH(TIMx)); + assert_param(IS_TIM_BREAKINPUTSOURCE(BreakInputConfig->TIM_Source)); + assert_param(IS_TIM_BREAKINPUTSOURCE_STATE(BreakInputConfig->TIM_Enable)); + assert_param(IS_TIM_BREAKINPUTSOURCE_POLARITY(BreakInputConfig->TIM_Polarity)); + + switch (BreakInputConfig->TIM_Source) + { + case TIM_BREAKINPUTSOURCE_BKIN: + { + bkin_enable_mask = TIM_AF_BKINE; + bkin_enable_bitpos = TIM_AF_BKINE_Pos; + bkin_polarity_mask = TIM_AF_BKINP; + bkin_polarity_bitpos = TIM_AF_BKINP_Pos; + break; + } + case TIM_BREAKINPUTSOURCE_COMP1: + { + bkin_enable_mask = TIM_AF_BKCMP1E; + bkin_enable_bitpos = TIM_AF_BKCMP1E_Pos; + bkin_polarity_mask = TIM_AF_BKCMP1P; + bkin_polarity_bitpos = TIM_AF_BKCMP1P_Pos; + break; + } + case TIM_BREAKINPUTSOURCE_COMP2: + { + bkin_enable_mask = TIM_AF_BKCMP2E; + bkin_enable_bitpos = TIM_AF_BKCMP2E_Pos; + bkin_polarity_mask = TIM_AF_BKCMP2P; + bkin_polarity_bitpos = TIM_AF_BKCMP2P_Pos; + break; + } + case TIM_BREAKINPUTSOURCE_COMP3: + { + bkin_enable_mask = TIM_AF_BKCMP3E; + bkin_enable_bitpos = TIM_AF_BKCMP3E_Pos; + bkin_polarity_mask = TIM_AF_BKCMP3P; + bkin_polarity_bitpos = TIM_AF_BKCMP3P_Pos; + break; + } + case TIM_BREAKINPUTSOURCE_COMP4: + { + bkin_enable_mask = TIM_AF_BKCMP4E; + bkin_enable_bitpos = TIM_AF_BKCMP4E_Pos; + bkin_polarity_mask = TIM_AF_BKCMP4P; + bkin_polarity_bitpos = TIM_AF_BKCMP4P_Pos; + break; + } + case TIM_BREAKINPUTSOURCE_COMP5: + { + bkin_enable_mask = TIM_AF_BKCMP5E; + bkin_enable_bitpos = TIM_AF_BKCMP5E_Pos; + /* No palarity bit for this COMP. Variable bkin_polarity_mask keeps its default value 0 */ + bkin_polarity_mask = 0U; + bkin_polarity_bitpos = 0U; + break; + } + case TIM_BREAKINPUTSOURCE_COMP6: + { + bkin_enable_mask = TIM_AF_BKCMP6E; + bkin_enable_bitpos = TIM_AF_BKCMP6E_Pos; + /* No palarity bit for this COMP. Variable bkin_polarity_mask keeps its default value 0 */ + bkin_polarity_mask = 0U; + bkin_polarity_bitpos = 0U; + break; + } + default: + { + bkin_enable_mask = 0U; + bkin_polarity_mask = 0U; + bkin_enable_bitpos = 0U; + bkin_polarity_bitpos = 0U; + break; + } + } + + /* Get the TIMx_AF1 register value */ + tmporx = TIMx->AF1; + + /* Enable the break input */ + tmporx &= ~bkin_enable_mask; + tmporx |= (BreakInputConfig->TIM_Enable << bkin_enable_bitpos) & bkin_enable_mask; + + /* Set the break input polarity */ + tmporx &= ~bkin_polarity_mask; + tmporx |= (BreakInputConfig->TIM_Polarity << bkin_polarity_bitpos) & bkin_polarity_mask; + + /* Set TIMx_AF1 */ + TIMx->AF1 = tmporx; +} + +/** + * @brief Enables or disables the TIM peripheral Main Outputs. + * @param TIMx: where x can be 1 or 8 to select the TIMx peripheral. + * @param NewState: new state of the TIM peripheral Main Outputs. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void TIM_CtrlPWMOutputs(TIM_TypeDef* TIMx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the TIM Main Output */ + TIMx->BDTR |= TIM_BDTR_MOE; + } + else + { + /* Disable the TIM Main Output */ + TIMx->BDTR &= (uint32_t)(~((uint32_t)TIM_BDTR_MOE)); + } +} + +/** + * @brief Disarm the designated break input (when it operates in bidirectional mode). + * @param TIMx: where x can be 1 or 8 to select the TIMx peripheral. + * @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 None + */ +void TIM_DisarmBreakInput(TIM_TypeDef* TIMx) +{ + uint32_t tmpbdtr; + + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + + /* Check initial conditions */ + tmpbdtr = TIMx->BDTR; + + if ((((TIMx->BDTR)&TIM_BDTR_BKBID) == TIM_BDTR_BKBID) && + (((TIMx->BDTR)&TIM_BDTR_MOE) != TIM_BDTR_MOE)) + { + /* Break input BRK is disarmed */ + TIMx->BDTR |= TIM_BDTR_BKDSRM; + } +} + +/** + * @brief Wait the BKDSRM bit is cleared by hardware when no break source active + * (when it operates in bidirectional mode). + * @param TIMx: where x can be 1 or 8 to select the TIMx peripheral. + * @note The BKDSRM bit is cleared by hardware when no break source active. + * @retval The new state of BKDSRM (SET or RESET). + */ +FlagStatus TIM_WaitBkdsrmIsHardwareClear(TIM_TypeDef* TIMx) +{ + ITStatus bitstatus = RESET; + + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + + /* Check initial conditions */ + if (((TIMx->BDTR)&TIM_BDTR_BKBID) == TIM_BDTR_BKBID) + { + /* Break input BRK is re-armed automatically by hardware. Poll to check whether fault condition disappeared */ + if ((TIMx->BDTR & TIM_BDTR_BKDSRM) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + } + return bitstatus; +} + +/** + * @} + */ + +/** + * @brief Initializes the TIMx Channel1 according to the specified + * parameters in the TIM_OCInitStruct. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13 + * and 14 to select the TIM peripheral. + * @param TIM_OCInitStruct: pointer to a TIM_OCInitTypeDef structure + * that contains the configuration information for the specified TIM + * peripheral. + * @retval None + */ +void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct) +{ + uint32_t tmpccmrx = 0, tmpccer = 0, tmpcr2 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST4_PERIPH(TIMx)); + assert_param(IS_TIM_OC_MODE(TIM_OCInitStruct->TIM_OCMode)); + assert_param(IS_TIM_OUTPUT_STATE(TIM_OCInitStruct->TIM_OutputState)); + assert_param(IS_TIM_OC_POLARITY(TIM_OCInitStruct->TIM_OCPolarity)); + + /* Disable the Channel 1: Reset the CC1E Bit */ + TIMx->CCER &= (uint32_t)(~(uint32_t)TIM_CCER_CC1E); + + /* Get the TIMx CCER register value */ + tmpccer = TIMx->CCER; + + /* 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 &= (uint32_t)(~((uint32_t)TIM_CCMR1_OC1M)); + tmpccmrx &= (uint32_t)(~((uint32_t)TIM_CCMR1_CC1S)); + /* Select the Output Compare Mode */ + tmpccmrx |= TIM_OCInitStruct->TIM_OCMode; + + /* Reset the Output Polarity level */ + tmpccer &= (uint32_t)(~((uint32_t)TIM_CCER_CC1P)); + /* Set the Output Compare Polarity */ + tmpccer |= TIM_OCInitStruct->TIM_OCPolarity; + + /* Set the Output State */ + tmpccer |= TIM_OCInitStruct->TIM_OutputState; + + if ((TIMx == TIM1) || (TIMx == TIM8)) + { + assert_param(IS_TIM_OUTPUTN_STATE(TIM_OCInitStruct->TIM_OutputNState)); + assert_param(IS_TIM_OCN_POLARITY(TIM_OCInitStruct->TIM_OCNPolarity)); + assert_param(IS_TIM_OCNIDLE_STATE(TIM_OCInitStruct->TIM_OCNIdleState)); + assert_param(IS_TIM_OCIDLE_STATE(TIM_OCInitStruct->TIM_OCIdleState)); + + /* Reset the Output N Polarity level */ + tmpccer &= (uint32_t)(~((uint32_t)TIM_CCER_CC1NP)); + /* Set the Output N Polarity */ + tmpccer |= TIM_OCInitStruct->TIM_OCNPolarity; + + /* Reset the Output N State */ + tmpccer &= (uint32_t)(~((uint32_t)TIM_CCER_CC1NE)); + /* Set the Output N State */ + tmpccer |= TIM_OCInitStruct->TIM_OutputNState; + + /* Reset the Ouput Compare and Output Compare N IDLE State */ + tmpcr2 &= (uint32_t)(~((uint32_t)TIM_CR2_OIS1)); + tmpcr2 &= (uint32_t)(~((uint32_t)TIM_CR2_OIS1N)); + /* Set the Output Idle state */ + tmpcr2 |= TIM_OCInitStruct->TIM_OCIdleState; + /* Set the Output N Idle state */ + tmpcr2 |= TIM_OCInitStruct->TIM_OCNIdleState; + } + /* Write to TIMx CR2 */ + TIMx->CR2 = tmpcr2; + + /* Set the Capture Compare Register value */ + if (((TIMx->CCMR1)&TIM_CCMR1_OC1PE) != TIM_CCMR1_OC1PE) + { + TIMx->CCR1 = TIM_OCInitStruct->TIM_Pulse; + } + else if (((TIMx->CCMR1)&TIM_CCMR1_OC1PE) == TIM_CCMR1_OC1PE) + { + TIMx->CCR1 = TIM_OCInitStruct->TIM_Pulse; + TIMx->EGR |= TIM_EGR_UG; + TIMx->SR &= (uint32_t)~((uint32_t)TIM_SR_UIF); + } + + /* Write to TIMx CCMR1 */ + TIMx->CCMR1 = tmpccmrx; + + /* Write to TIMx CCER */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Initializes the TIMx Channel2 according to the specified + * parameters in the TIM_OCInitStruct. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select + * the TIM peripheral. + * @param TIM_OCInitStruct: pointer to a TIM_OCInitTypeDef structure + * that contains the configuration information for the specified TIM + * peripheral. + * + * @retval None + */ +void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct) +{ + uint32_t tmpccmrx = 0, tmpccer = 0, tmpcr2 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST5_PERIPH(TIMx)); + assert_param(IS_TIM_OC_MODE(TIM_OCInitStruct->TIM_OCMode)); + assert_param(IS_TIM_OUTPUT_STATE(TIM_OCInitStruct->TIM_OutputState)); + assert_param(IS_TIM_OC_POLARITY(TIM_OCInitStruct->TIM_OCPolarity)); + + /* Disable the Channel 2: Reset the CC2E Bit */ + TIMx->CCER &= (uint32_t)(~((uint32_t)TIM_CCER_CC2E)); + + /* Get the TIMx CCER register value */ + tmpccer = TIMx->CCER; + + /* 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 &= (uint32_t)(~((uint32_t)TIM_CCMR1_OC2M)); + tmpccmrx &= (uint32_t)(~((uint32_t)TIM_CCMR1_CC2S)); + + /* Select the Output Compare Mode */ + tmpccmrx |= (uint32_t)(TIM_OCInitStruct->TIM_OCMode << 8); + + /* Reset the Output Polarity level */ + tmpccer &= (uint32_t)(~((uint32_t)TIM_CCER_CC2P)); + /* Set the Output Compare Polarity */ + tmpccer |= (uint32_t)(TIM_OCInitStruct->TIM_OCPolarity << 4); + + /* Set the Output State */ + tmpccer |= (uint32_t)(TIM_OCInitStruct->TIM_OutputState << 4); + + if ((TIMx == TIM1) || (TIMx == TIM8)) + { + /* Check the parameters */ + assert_param(IS_TIM_OUTPUTN_STATE(TIM_OCInitStruct->TIM_OutputNState)); + assert_param(IS_TIM_OCN_POLARITY(TIM_OCInitStruct->TIM_OCNPolarity)); + assert_param(IS_TIM_OCNIDLE_STATE(TIM_OCInitStruct->TIM_OCNIdleState)); + assert_param(IS_TIM_OCIDLE_STATE(TIM_OCInitStruct->TIM_OCIdleState)); + + /* Reset the Output N Polarity level */ + tmpccer &= (uint32_t)(~((uint32_t)TIM_CCER_CC2NP)); + /* Set the Output N Polarity */ + tmpccer |= (uint32_t)(TIM_OCInitStruct->TIM_OCNPolarity << 4); + + /* Reset the Output N State */ + tmpccer &= (uint32_t)(~((uint32_t)TIM_CCER_CC2NE)); + /* Set the Output N State */ + tmpccer |= (uint32_t)(TIM_OCInitStruct->TIM_OutputNState << 4); + + /* Reset the Output Compare N IDLE State */ + tmpcr2 &= (uint32_t)(~((uint32_t)TIM_CR2_OIS2)); + tmpcr2 &= (uint32_t)(~((uint32_t)TIM_CR2_OIS2N)); + /* Set the Output Idle state */ + tmpcr2 |= (uint32_t)(TIM_OCInitStruct->TIM_OCIdleState << 2); + /* Set the Output N Idle state */ + tmpcr2 |= (uint32_t)(TIM_OCInitStruct->TIM_OCNIdleState << 2); + } + /* Write to TIMx CR2 */ + TIMx->CR2 = tmpcr2; + + /* Set the Capture Compare Register value */ + if (((TIMx->CCMR1)&TIM_CCMR1_OC2PE) != TIM_CCMR1_OC2PE) + { + TIMx->CCR2 = TIM_OCInitStruct->TIM_Pulse; + } + else if (((TIMx->CCMR1)&TIM_CCMR1_OC2PE) == TIM_CCMR1_OC2PE) + { + TIMx->CCR2 = TIM_OCInitStruct->TIM_Pulse; + TIMx->EGR |= TIM_EGR_UG; + TIMx->SR &= (uint32_t)~((uint32_t)TIM_SR_UIF); + } + + /* Write to TIMx CCMR1 */ + TIMx->CCMR1 = tmpccmrx; + + /* Write to TIMx CCER */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Initializes the TIMx Channel3 according to the specified + * parameters in the TIM_OCInitStruct. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_OCInitStruct: pointer to a TIM_OCInitTypeDef structure + * that contains the configuration information for the specified TIM + * peripheral. + * @retval None + */ +void TIM_OC3Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct) +{ + uint32_t tmpccmrx = 0, tmpccer = 0, tmpcr2 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_OC_MODE(TIM_OCInitStruct->TIM_OCMode)); + assert_param(IS_TIM_OUTPUT_STATE(TIM_OCInitStruct->TIM_OutputState)); + assert_param(IS_TIM_OC_POLARITY(TIM_OCInitStruct->TIM_OCPolarity)); + + /* Disable the Channel 3: Reset the CC3E Bit */ + TIMx->CCER &= (uint32_t)(~((uint32_t)TIM_CCER_CC3E)); + + /* Get the TIMx CCER register value */ + tmpccer = TIMx->CCER; + + /* 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 &= (uint32_t)(~((uint32_t)TIM_CCMR2_OC3M)); + tmpccmrx &= (uint32_t)(~((uint32_t)TIM_CCMR2_CC3S)); + /* Select the Output Compare Mode */ + tmpccmrx |= TIM_OCInitStruct->TIM_OCMode; + + /* Reset the Output Polarity level */ + tmpccer &= (uint32_t)(~((uint32_t)TIM_CCER_CC3P)); + /* Set the Output Compare Polarity */ + tmpccer |= (uint32_t)(TIM_OCInitStruct->TIM_OCPolarity << 8); + + /* Set the Output State */ + tmpccer |= (uint32_t)(TIM_OCInitStruct->TIM_OutputState << 8); + + if ((TIMx == TIM1) || (TIMx == TIM8)) + { + assert_param(IS_TIM_OUTPUTN_STATE(TIM_OCInitStruct->TIM_OutputNState)); + assert_param(IS_TIM_OCN_POLARITY(TIM_OCInitStruct->TIM_OCNPolarity)); + assert_param(IS_TIM_OCNIDLE_STATE(TIM_OCInitStruct->TIM_OCNIdleState)); + assert_param(IS_TIM_OCIDLE_STATE(TIM_OCInitStruct->TIM_OCIdleState)); + + /* Reset the Output N Polarity level */ + tmpccer &= (uint32_t)(~((uint32_t)TIM_CCER_CC3NP)); + /* Set the Output N Polarity */ + tmpccer |= (uint32_t)(TIM_OCInitStruct->TIM_OCNPolarity << 8); + + /* Reset the Output N State */ + tmpccer &= (uint32_t)(~((uint32_t)TIM_CCER_CC3NE)); + /* Set the Output N State */ + tmpccer |= (uint32_t)(TIM_OCInitStruct->TIM_OutputNState << 8); + + /* Reset the Ouput Compare and Output Compare N IDLE State */ + tmpcr2 &= (uint32_t)(~((uint32_t)TIM_CR2_OIS3)); + tmpcr2 &= (uint32_t)(~((uint32_t)TIM_CR2_OIS3N)); + /* Set the Output Idle state */ + tmpcr2 |= (uint32_t)(TIM_OCInitStruct->TIM_OCIdleState << 4); + /* Set the Output N Idle state */ + tmpcr2 |= (uint32_t)(TIM_OCInitStruct->TIM_OCNIdleState << 4); + } + /* Write to TIMx CR2 */ + TIMx->CR2 = tmpcr2; + + /* Set the Capture Compare Register value */ + if (((TIMx->CCMR2)&TIM_CCMR2_OC3PE) != TIM_CCMR2_OC3PE) + { + TIMx->CCR3 = TIM_OCInitStruct->TIM_Pulse; + } + else if (((TIMx->CCMR2)&TIM_CCMR2_OC3PE) == TIM_CCMR2_OC3PE) + { + TIMx->CCR3 = TIM_OCInitStruct->TIM_Pulse; + TIMx->EGR |= TIM_EGR_UG; + TIMx->SR &= (uint32_t)~((uint32_t)TIM_SR_UIF); + } + + /* Write to TIMx CCMR2 */ + TIMx->CCMR2 = tmpccmrx; + + /* Write to TIMx CCER */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Initializes the TIMx Channel4 according to the specified + * parameters in the TIM_OCInitStruct. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_OCInitStruct: pointer to a TIM_OCInitTypeDef structure + * that contains the configuration information for the specified TIM + * peripheral. + * @retval None + */ +void TIM_OC4Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct) +{ + uint32_t tmpccmrx = 0, tmpccer = 0, tmpcr2 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_OC_MODE(TIM_OCInitStruct->TIM_OCMode)); + assert_param(IS_TIM_OUTPUT_STATE(TIM_OCInitStruct->TIM_OutputState)); + assert_param(IS_TIM_OC_POLARITY(TIM_OCInitStruct->TIM_OCPolarity)); + + /* Disable the Channel 4: Reset the CC4E Bit */ + TIMx->CCER &= (uint32_t)(~((uint32_t)TIM_CCER_CC4E)); + + /* Get the TIMx CCER register value */ + tmpccer = TIMx->CCER; + + /* 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 &= (uint32_t)(~((uint32_t)TIM_CCMR2_OC4M)); + tmpccmrx &= (uint32_t)(~((uint32_t)TIM_CCMR2_CC4S)); + + /* Select the Output Compare Mode */ + tmpccmrx |= (uint32_t)(TIM_OCInitStruct->TIM_OCMode << 8); + + /* Reset the Output Polarity level */ + tmpccer &= (uint32_t)(~((uint32_t)TIM_CCER_CC4P)); + /* Set the Output Compare Polarity */ + tmpccer |= (uint32_t)(TIM_OCInitStruct->TIM_OCPolarity << 12); + + /* Set the Output State */ + tmpccer |= (uint32_t)(TIM_OCInitStruct->TIM_OutputState << 12); + + if ((TIMx == TIM1) || (TIMx == TIM8)) + { + assert_param(IS_TIM_OCIDLE_STATE(TIM_OCInitStruct->TIM_OCIdleState)); + + /* Reset the Ouput Compare IDLE State */ + tmpcr2 &= (uint32_t)(~((uint32_t)TIM_CR2_OIS4)); + /* Set the Output Idle state */ + tmpcr2 |= (uint32_t)(TIM_OCInitStruct->TIM_OCIdleState << 6); + } + /* Write to TIMx CR2 */ + TIMx->CR2 = tmpcr2; + + /* Set the Capture Compare Register value */ + if (((TIMx->CCMR2)&TIM_CCMR2_OC4PE) != TIM_CCMR2_OC4PE) + { + TIMx->CCR4 = TIM_OCInitStruct->TIM_Pulse; + } + else if (((TIMx->CCMR2)&TIM_CCMR2_OC4PE) == TIM_CCMR2_OC4PE) + { + TIMx->CCR4 = TIM_OCInitStruct->TIM_Pulse; + TIMx->EGR |= TIM_EGR_UG; + TIMx->SR &= (uint32_t)~((uint32_t)TIM_SR_UIF); + } + + /* Write to TIMx CCMR2 */ + TIMx->CCMR2 = tmpccmrx; + + /* Write to TIMx CCER */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Initializes the TIMx Channel5 according to the specified + * parameters in the TIM_OCInitStruct. + * @param TIMx: where x can be 1 or 8 to select the TIM peripheral. + * @param TIM_OCInitStruct: pointer to a TIM_OCInitTypeDef structure + * that contains the configuration information for the specified TIM + * peripheral. + * @retval None + */ +void TIM_OC5Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct) +{ + uint32_t tmpccmrx = 0, tmpccer = 0, tmpcr2 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_TIM_OC_MODE(TIM_OCInitStruct->TIM_OCMode)); + assert_param(IS_TIM_OUTPUT_STATE(TIM_OCInitStruct->TIM_OutputState)); + assert_param(IS_TIM_OC_POLARITY(TIM_OCInitStruct->TIM_OCPolarity)); + + /* Disable the Channel 5: Reset the CC5E Bit */ + TIMx->CCER &= (uint32_t)(~((uint32_t)TIM_CCER_CC5E)); + + /* Get the TIMx CCER register value */ + tmpccer = TIMx->CCER; + + /* Get the TIMx CR2 register value */ + tmpcr2 = TIMx->CR2; + + /* Get the TIMx CCMR3 register value */ + tmpccmrx = TIMx->CCMR3; + + /* Reset the Output Compare mode Bits */ + tmpccmrx &= (uint32_t)(~((uint32_t)TIM_CCMR3_OC5M)); + /* Select the Output Compare Mode */ + tmpccmrx |= TIM_OCInitStruct->TIM_OCMode; + + /* Reset the Output Polarity level */ + tmpccer &= (uint32_t)(~((uint32_t)TIM_CCER_CC5P)); + /* Set the Output Compare Polarity */ + tmpccer |= (uint32_t)(TIM_OCInitStruct->TIM_OCPolarity << 16); + + /* Set the Output State */ + tmpccer |= (uint32_t)(TIM_OCInitStruct->TIM_OutputState << 16); + + /* Check the parameters */ + assert_param(IS_TIM_OCIDLE_STATE(TIM_OCInitStruct->TIM_OCIdleState)); + + /* Reset the Ouput Compare IDLE State */ + tmpcr2 &= (uint32_t)(~((uint32_t)TIM_CR2_OIS5)); + /* Set the Output Idle state */ + tmpcr2 |= (uint32_t)(TIM_OCInitStruct->TIM_OCIdleState << 8); + + /* Write to TIMx CR2 */ + TIMx->CR2 = tmpcr2; + + /* Set the Capture Compare Register value */ + if (((TIMx->CCMR3)&TIM_CCMR3_OC5PE) != TIM_CCMR3_OC5PE) + { + TIMx->CCR5 = TIM_OCInitStruct->TIM_Pulse; + } + else if (((TIMx->CCMR3)&TIM_CCMR3_OC5PE) == TIM_CCMR3_OC5PE) + { + TIMx->CCR5 = TIM_OCInitStruct->TIM_Pulse; + TIMx->EGR |= TIM_EGR_UG; + TIMx->SR &= (uint32_t)~((uint32_t)TIM_SR_UIF); + } + + + /* Write to TIMx CCMR3 */ + TIMx->CCMR3 = tmpccmrx; + + /* Write to TIMx CCER */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Initializes the TIMx Channel6 according to the specified + * parameters in the TIM_OCInitStruct. + * @param TIMx: where x can be 1 or 8 to select the TIM peripheral. + * @param TIM_OCInitStruct: pointer to a TIM_OCInitTypeDef structure + * that contains the configuration information for the specified TIM + * peripheral. + * @retval None + */ +void TIM_OC6Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct) +{ + uint32_t tmpccmrx = 0, tmpccer = 0, tmpcr2 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_TIM_OC_MODE(TIM_OCInitStruct->TIM_OCMode)); + assert_param(IS_TIM_OUTPUT_STATE(TIM_OCInitStruct->TIM_OutputState)); + assert_param(IS_TIM_OC_POLARITY(TIM_OCInitStruct->TIM_OCPolarity)); + + /* Disable the Channel 6: Reset the CC6E Bit */ + TIMx->CCER &= (uint32_t)(~((uint32_t)TIM_CCER_CC6E)); + + /* Get the TIMx CCER register value */ + tmpccer = TIMx->CCER; + + /* Get the TIMx CR2 register value */ + tmpcr2 = TIMx->CR2; + + /* Get the TIMx CCMR3 register value */ + tmpccmrx = TIMx->CCMR3; + + /* Reset the Output Compare mode Bits */ + tmpccmrx &= (uint32_t)(~((uint32_t)TIM_CCMR3_OC6M)); + /* Select the Output Compare Mode */ + tmpccmrx |= (uint32_t)(TIM_OCInitStruct->TIM_OCMode << 8); + + /* Reset the Output Polarity level */ + tmpccer &= (uint32_t)(~((uint32_t)TIM_CCER_CC6P)); + /* Set the Output Compare Polarity */ + tmpccer |= (uint32_t)(TIM_OCInitStruct->TIM_OCPolarity << 20); + + /* Set the Output State */ + tmpccer |= (uint32_t)(TIM_OCInitStruct->TIM_OutputState << 20); + + /* Check the parameters */ + assert_param(IS_TIM_OCIDLE_STATE(TIM_OCInitStruct->TIM_OCIdleState)); + + /* Reset the Ouput Compare IDLE State */ + tmpcr2 &= (uint32_t)(~((uint32_t)TIM_CR2_OIS6)); + /* Set the Output Idle state */ + tmpcr2 |= (uint32_t)(TIM_OCInitStruct->TIM_OCIdleState << 10); + + /* Write to TIMx CR2 */ + TIMx->CR2 = tmpcr2; + + /* Set the Capture Compare Register value */ + if (((TIMx->CCMR3)&TIM_CCMR3_OC6PE) != TIM_CCMR3_OC6PE) + { + TIMx->CCR6 = TIM_OCInitStruct->TIM_Pulse; + } + else if (((TIMx->CCMR3)&TIM_CCMR3_OC6PE) == TIM_CCMR3_OC6PE) + { + TIMx->CCR6 = TIM_OCInitStruct->TIM_Pulse; + TIMx->EGR |= TIM_EGR_UG; + TIMx->SR &= (uint32_t)~((uint32_t)TIM_SR_UIF); + } + + /* Write to TIMx CCMR3 */ + TIMx->CCMR3 = tmpccmrx; + + /* Write to TIMx CCER */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Group channel 5 and channel 1, 2 or 3 + * @param TIMx: where x can be 1 or 8 to select the TIM peripheral. + * @param TIM_Group_Channel5 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 None + */ +void TIM_GroupChannel5(TIM_TypeDef* TIMx, uint32_t TIM_Group_Channel5) +{ + /* Check parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_TIM_GROUPCH5(TIM_Group_Channel5)); + + /* Clear GC5Cx bit fields */ + TIMx->CCR5 &= ~(TIM_CCR5_GC5C3 | TIM_CCR5_GC5C2 | TIM_CCR5_GC5C1); + + /* Set GC5Cx bit fields */ + TIMx->CCR5 |= TIM_Group_Channel5; +} + +/** + * @brief Fills each TIM_OCInitStruct member with its default value. + * @param TIM_OCInitStruct: pointer to a TIM_OCInitTypeDef structure which will + * be initialized. + * @retval None + */ +void TIM_OCStructInit(TIM_OCInitTypeDef* TIM_OCInitStruct) +{ + /* Set the default configuration */ + TIM_OCInitStruct->TIM_OCMode = TIM_OCMode_Timing; + TIM_OCInitStruct->TIM_OutputState = TIM_OutputState_Disable; + TIM_OCInitStruct->TIM_OutputNState = TIM_OutputNState_Disable; + TIM_OCInitStruct->TIM_Pulse = 0x0000000; + TIM_OCInitStruct->TIM_OCPolarity = TIM_OCPolarity_High; + TIM_OCInitStruct->TIM_OCNPolarity = TIM_OCNPolarity_High; + TIM_OCInitStruct->TIM_OCIdleState = TIM_OCIdleState_Reset; + TIM_OCInitStruct->TIM_OCNIdleState = TIM_OCNIdleState_Reset; +} + +/** + * @brief Selects the TIM Output Compare Mode. + * @note This function disables the selected channel before changing the Output + * Compare Mode. + * User has to enable this channel using TIM_CCxCmd and TIM_CCxNCmd functions. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13 or 14 to select + * the TIM peripheral. + * @param TIM_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 + * @param TIM_OCMode: specifies the TIM Output Compare Mode. + * This parameter can be one of the following values: + * @arg TIM_OCMode_Timing + * @arg TIM_OCMode_Active + * @arg TIM_OCMode_Inactive + * @arg TIM_OCMode_Toggle + * @arg TIM_OCMODE_Forced_Inactive + * @arg TIM_OCMODE_Forced_Active + * @arg TIM_OCMode_PWM1 + * @arg TIM_OCMode_PWM2 + * @arg TIM_OCMode_Combined_PWM1 + * @arg TIM_OCMode_Combined_PWM2 + * @arg TIM_OCMode_Asymmetric_PWM1 + * @arg TIM_OCMode_Asymmetric_PWM2 + * @retval None + */ +void TIM_SelectOCxM(TIM_TypeDef* TIMx, uint32_t TIM_Channel, uint32_t TIM_OCMode) +{ + uint32_t tmp = 0; + uint32_t tmp1 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST4_PERIPH(TIMx)); + assert_param(IS_TIM_OC_MODE(TIM_OCMode)); + + /* Check the parameters - TIM_Channel */ + if ((TIMx == TIM1) || (TIMx == TIM8)) + { + assert_param(IS_TIM_CHANNEL(TIM_Channel)); + } + else if ((TIMx == TIM2) || (TIMx == TIM3) || + (TIMx == TIM4) || (TIMx == TIM5)) + { + assert_param(IS_TIM_2_TO_5_CHANNEL(TIM_Channel)); + } + else if ((TIMx == TIM9) || (TIMx == TIM12)) + { + assert_param(IS_TIM_9_AND_12_CHANNEL(TIM_Channel)); + } + else/*if((TIMx == TIM10) || (TIMx == TIM11) || + (TIMx == TIM13) || (TIMx == TIM14))*/ + { + assert_param(IS_TIM_10_11_13_14_CHANNEL(TIM_Channel)); + } + + tmp = (uint32_t) TIMx; + tmp += CCMR_OFFSET; + + tmp1 = CCER_CCE_SET << (uint32_t)TIM_Channel; + + /* Disable the Channel: Reset the CCxE Bit */ + TIMx->CCER &= (uint32_t) ~tmp1; + + if ((TIM_Channel == TIM_Channel_1) || (TIM_Channel == TIM_Channel_3) || (TIM_Channel == TIM_Channel_5)) + { + if ((TIM_Channel == TIM_Channel_1) || (TIM_Channel == TIM_Channel_3)) + { + tmp += (TIM_Channel >> 1); + } + else /* if(TIM_Channel == TIM_Channel_5) */ + { + tmp += ((uint32_t)0x0000003C); + } + + /* Reset the OCxM bits in the CCMRx register */ + *(__IO uint32_t *) tmp &= (uint32_t)~((uint32_t)TIM_CCMR1_OC1M); + + /* Configure the OCxM bits in the CCMRx register */ + *(__IO uint32_t *) tmp |= TIM_OCMode; + } + else + { + if ((TIM_Channel == TIM_Channel_2) || (TIM_Channel == TIM_Channel_4)) + { + tmp += (uint32_t)(TIM_Channel - (uint32_t)4) >> (uint32_t)1; + } + else /* if(TIM_Channel == TIM_Channel_6) */ + { + tmp += ((uint32_t)0x0000003C); + } + + /* Reset the OCxM bits in the CCMRx register */ + *(__IO uint32_t *) tmp &= (uint32_t)~((uint32_t)TIM_CCMR1_OC2M); + + /* Configure the OCxM bits in the CCMRx register */ + *(__IO uint32_t *) tmp |= (uint32_t)(TIM_OCMode << 8); + } +} + +/** + * @brief Sets the TIMx Capture Compare1 Register value + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13 or 14 + * to select the TIM peripheral. + * @param Compare1: specifies the Capture Compare1 register new value. + * @retval None + */ +void TIM_SetCompare1(TIM_TypeDef* TIMx, uint32_t Compare1) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST4_PERIPH(TIMx)); + + /* Set the Capture Compare1 Register value */ + TIMx->CCR1 = Compare1; +} + +/** + * @brief Sets the TIMx Capture Compare2 Register value + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select + * the TIM peripheral. + * @param Compare2: specifies the Capture Compare2 register new value. + * @retval None + */ +void TIM_SetCompare2(TIM_TypeDef* TIMx, uint32_t Compare2) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST5_PERIPH(TIMx)); + + /* Set the Capture Compare2 Register value */ + TIMx->CCR2 = Compare2; +} + +/** + * @brief Sets the TIMx Capture Compare3 Register value + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param Compare3: specifies the Capture Compare3 register new value. + * @retval None + */ +void TIM_SetCompare3(TIM_TypeDef* TIMx, uint32_t Compare3) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + + /* Set the Capture Compare3 Register value */ + TIMx->CCR3 = Compare3; +} + +/** + * @brief Sets the TIMx Capture Compare4 Register value + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param Compare4: specifies the Capture Compare4 register new value. + * @retval None + */ +void TIM_SetCompare4(TIM_TypeDef* TIMx, uint32_t Compare4) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + + /* Set the Capture Compare4 Register value */ + TIMx->CCR4 = Compare4; +} + +/** + * @brief Sets the TIMx Capture Compare5 Register value + * @param TIMx: where x can be 1 or 8 to select the TIM peripheral. + * @param Compare5: specifies the Capture Compare5 register new value. + * @retval None + */ +void TIM_SetCompare5(TIM_TypeDef* TIMx, uint32_t Compare5) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + + /* Set the Capture Compare5 Register value */ + TIMx->CCR5 = Compare5; +} + +/** + * @brief Sets the TIMx Capture Compare6 Register value + * @param TIMx: where x can be 1 or 8 to select the TIM peripheral. + * @param Compare6: specifies the Capture Compare6 register new value. + * @retval None + */ +void TIM_SetCompare6(TIM_TypeDef* TIMx, uint32_t Compare6) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + + /* Set the Capture Compare6 Register value */ + TIMx->CCR6 = Compare6; +} + +/** + * @brief Forces the TIMx output 1 waveform to active or inactive level. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13 or 14 to select the + * TIM peripheral. + * @param TIM_ForcedAction: specifies the forced Action to be set to the output waveform. + * This parameter can be one of the following values: + * @arg TIM_ForcedAction_Active : Force active level on OC1REF + * @arg TIM_ForcedAction_InActive: Force inactive level on OC1REF. + * @retval None + */ +void TIM_ForcedOC1Config(TIM_TypeDef* TIMx, uint32_t TIM_ForcedAction) +{ + uint32_t tmpccmr1 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST4_PERIPH(TIMx)); + assert_param(IS_TIM_FORCED_ACTION(TIM_ForcedAction)); + + tmpccmr1 = TIMx->CCMR1; + + /* Reset the OC1M Bits */ + tmpccmr1 &= (uint32_t)~((uint32_t)TIM_CCMR1_OC1M); + + /* Configure The Forced output Mode */ + tmpccmr1 |= TIM_ForcedAction; + + /* Write to TIMx CCMR1 register */ + TIMx->CCMR1 = tmpccmr1; +} + +/** + * @brief Forces the TIMx output 2 waveform to active or inactive level. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM peripheral. + * @param TIM_ForcedAction: specifies the forced Action to be set to the output waveform. + * This parameter can be one of the following values: + * @arg TIM_ForcedAction_Active : Force active level on OC2REF + * @arg TIM_ForcedAction_InActive: Force inactive level on OC2REF. + * @retval None + */ +void TIM_ForcedOC2Config(TIM_TypeDef* TIMx, uint32_t TIM_ForcedAction) +{ + uint32_t tmpccmr1 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST5_PERIPH(TIMx)); + assert_param(IS_TIM_FORCED_ACTION(TIM_ForcedAction)); + tmpccmr1 = TIMx->CCMR1; + + /* Reset the OC2M Bits */ + tmpccmr1 &= (uint32_t)~((uint32_t)TIM_CCMR1_OC2M); + + /* Configure The Forced output Mode */ + tmpccmr1 |= (uint32_t)(TIM_ForcedAction << 8); + + /* Write to TIMx CCMR1 register */ + TIMx->CCMR1 = tmpccmr1; +} + +/** + * @brief Forces the TIMx output 3 waveform to active or inactive level. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_ForcedAction: specifies the forced Action to be set to the output waveform. + * This parameter can be one of the following values: + * @arg TIM_ForcedAction_Active : Force active level on OC3REF + * @arg TIM_ForcedAction_InActive: Force inactive level on OC3REF. + * @retval None + */ +void TIM_ForcedOC3Config(TIM_TypeDef* TIMx, uint32_t TIM_ForcedAction) +{ + uint32_t tmpccmr2 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_FORCED_ACTION(TIM_ForcedAction)); + tmpccmr2 = TIMx->CCMR2; + + /* Reset the OC3M Bits */ + tmpccmr2 &= (uint32_t)~((uint32_t)TIM_CCMR2_OC3M); + + /* Configure The Forced output Mode */ + tmpccmr2 |= TIM_ForcedAction; + + /* Write to TIMx CCMR2 register */ + TIMx->CCMR2 = tmpccmr2; +} + +/** + * @brief Forces the TIMx output 4 waveform to active or inactive level. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_ForcedAction: specifies the forced Action to be set to the output waveform. + * This parameter can be one of the following values: + * @arg TIM_ForcedAction_Active : Force active level on OC4REF + * @arg TIM_ForcedAction_InActive: Force inactive level on OC4REF. + * @retval None + */ +void TIM_ForcedOC4Config(TIM_TypeDef* TIMx, uint32_t TIM_ForcedAction) +{ + uint32_t tmpccmr2 = 0; + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_FORCED_ACTION(TIM_ForcedAction)); + tmpccmr2 = TIMx->CCMR2; + + /* Reset the OC4M Bits */ + tmpccmr2 &= (uint32_t)~((uint32_t)TIM_CCMR2_OC4M); + + /* Configure The Forced output Mode */ + tmpccmr2 |= (uint32_t)(TIM_ForcedAction << 8); + + /* Write to TIMx CCMR2 register */ + TIMx->CCMR2 = tmpccmr2; +} + +/** + * @brief Forces the TIMx output 5 waveform to active or inactive level. + * @param TIMx: where x can be 1 or 8 to select the TIM peripheral. + * @param TIM_ForcedAction: specifies the forced Action to be set to the output waveform. + * This parameter can be one of the following values: + * @arg TIM_ForcedAction_Active : Force active level on OC5REF + * @arg TIM_ForcedAction_InActive: Force inactive level on OC5REF. + * @retval None + */ +void TIM_ForcedOC5Config(TIM_TypeDef* TIMx, uint32_t TIM_ForcedAction) +{ + uint32_t tmpccmr3 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_TIM_FORCED_ACTION(TIM_ForcedAction)); + tmpccmr3 = TIMx->CCMR3; + + /* Reset the OC5M Bits */ + tmpccmr3 &= (uint32_t)~((uint32_t)TIM_CCMR3_OC5M); + + /* Configure The Forced output Mode */ + tmpccmr3 |= TIM_ForcedAction; + + /* Write to TIMx CCMR3 register */ + TIMx->CCMR3 = tmpccmr3; +} + +/** + * @brief Forces the TIMx output 6 waveform to active or inactive level. + * @param TIMx: where x can be 1 or 8 to select the TIM peripheral. + * @param TIM_ForcedAction: specifies the forced Action to be set to the output waveform. + * This parameter can be one of the following values: + * @arg TIM_ForcedAction_Active : Force active level on OC6REF + * @arg TIM_ForcedAction_InActive: Force inactive level on OC6REF. + * @retval None + */ +void TIM_ForcedOC6Config(TIM_TypeDef* TIMx, uint32_t TIM_ForcedAction) +{ + uint32_t tmpccmr3 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_TIM_FORCED_ACTION(TIM_ForcedAction)); + tmpccmr3 = TIMx->CCMR3; + + /* Reset the OC6M Bits */ + tmpccmr3 &= (uint32_t)~((uint32_t)TIM_CCMR3_OC6M); + + /* Configure The Forced output Mode */ + tmpccmr3 |= (uint32_t)(TIM_ForcedAction << 8); + + /* Write to TIMx CCMR3 register */ + TIMx->CCMR3 = tmpccmr3; +} + +/** + * @brief Sets or Resets the TIM peripheral Capture Compare Preload Control bit. + * @param TIMx: where x can be 1 or 8 to select the TIMx peripheral + * @param NewState: new state of the Capture Compare Preload Control bit + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void TIM_CCPreloadControl(TIM_TypeDef* TIMx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Set the CCPC Bit */ + TIMx->CR2 |= TIM_CR2_CCPC; + } + else + { + /* Reset the CCPC Bit */ + TIMx->CR2 &= (uint32_t)~((uint32_t)TIM_CR2_CCPC); + } +} + + +/** + * @brief Enables or disables the TIMx peripheral Preload register on CCR1. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13 and 14 to + * select the TIM peripheral. + * @param TIM_OCPreload: new state of the TIMx peripheral Preload register + * This parameter can be one of the following values: + * @arg TIM_OCPreload_Enable + * @arg TIM_OCPreload_Disable + * @retval None + */ +void TIM_OC1PreloadConfig(TIM_TypeDef* TIMx, uint32_t TIM_OCPreload) +{ + uint32_t tmpccmr1 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST4_PERIPH(TIMx)); + assert_param(IS_TIM_OCPRELOAD_STATE(TIM_OCPreload)); + + tmpccmr1 = TIMx->CCMR1; + + /* Reset the OC1PE Bit */ + tmpccmr1 &= (uint32_t)~((uint32_t)TIM_CCMR1_OC1PE); + + /* Enable or Disable the Output Compare Preload feature */ + tmpccmr1 |= TIM_OCPreload; + + /* Write to TIMx CCMR1 register */ + TIMx->CCMR1 = tmpccmr1; +} + +/** + * @brief Enables or disables the TIMx peripheral Preload register on CCR2. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 and 12 to select the + * TIM peripheral. + * @param TIM_OCPreload: new state of the TIMx peripheral Preload register + * This parameter can be one of the following values: + * @arg TIM_OCPreload_Enable + * @arg TIM_OCPreload_Disable + * @retval None + */ +void TIM_OC2PreloadConfig(TIM_TypeDef* TIMx, uint32_t TIM_OCPreload) +{ + uint32_t tmpccmr1 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST5_PERIPH(TIMx)); + assert_param(IS_TIM_OCPRELOAD_STATE(TIM_OCPreload)); + + tmpccmr1 = TIMx->CCMR1; + + /* Reset the OC2PE Bit */ + tmpccmr1 &= (uint32_t)~((uint32_t)TIM_CCMR1_OC2PE); + + /* Enable or Disable the Output Compare Preload feature */ + tmpccmr1 |= (uint32_t)(TIM_OCPreload << 8); + + /* Write to TIMx CCMR1 register */ + TIMx->CCMR1 = tmpccmr1; +} + +/** + * @brief Enables or disables the TIMx peripheral Preload register on CCR3. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_OCPreload: new state of the TIMx peripheral Preload register + * This parameter can be one of the following values: + * @arg TIM_OCPreload_Enable + * @arg TIM_OCPreload_Disable + * @retval None + */ +void TIM_OC3PreloadConfig(TIM_TypeDef* TIMx, uint32_t TIM_OCPreload) +{ + uint32_t tmpccmr2 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_OCPRELOAD_STATE(TIM_OCPreload)); + + tmpccmr2 = TIMx->CCMR2; + + /* Reset the OC3PE Bit */ + tmpccmr2 &= (uint32_t)~((uint32_t)TIM_CCMR2_OC3PE); + + /* Enable or Disable the Output Compare Preload feature */ + tmpccmr2 |= TIM_OCPreload; + + /* Write to TIMx CCMR2 register */ + TIMx->CCMR2 = tmpccmr2; +} + +/** + * @brief Enables or disables the TIMx peripheral Preload register on CCR4. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_OCPreload: new state of the TIMx peripheral Preload register + * This parameter can be one of the following values: + * @arg TIM_OCPreload_Enable + * @arg TIM_OCPreload_Disable + * @retval None + */ +void TIM_OC4PreloadConfig(TIM_TypeDef* TIMx, uint32_t TIM_OCPreload) +{ + uint32_t tmpccmr2 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_OCPRELOAD_STATE(TIM_OCPreload)); + + tmpccmr2 = TIMx->CCMR2; + + /* Reset the OC4PE Bit */ + tmpccmr2 &= (uint32_t)~((uint32_t)TIM_CCMR2_OC4PE); + + /* Enable or Disable the Output Compare Preload feature */ + tmpccmr2 |= (uint32_t)(TIM_OCPreload << 8); + + /* Write to TIMx CCMR2 register */ + TIMx->CCMR2 = tmpccmr2; +} + +/** + * @brief Enables or disables the TIMx peripheral Preload register on CCR5. + * @param TIMx: where x can be 1 or 8 to select the TIM peripheral. + * @param TIM_OCPreload: new state of the TIMx peripheral Preload register + * This parameter can be one of the following values: + * @arg TIM_OCPreload_Enable + * @arg TIM_OCPreload_Disable + * @retval None + */ +void TIM_OC5PreloadConfig(TIM_TypeDef* TIMx, uint32_t TIM_OCPreload) +{ + uint32_t tmpccmr3 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_TIM_OCPRELOAD_STATE(TIM_OCPreload)); + + tmpccmr3 = TIMx->CCMR3; + + /* Reset the OC5PE Bit */ + tmpccmr3 &= (uint32_t)~((uint32_t)TIM_CCMR3_OC5PE); + + /* Enable or Disable the Output Compare Preload feature */ + tmpccmr3 |= TIM_OCPreload; + + /* Write to TIMx CCMR3 register */ + TIMx->CCMR3 = tmpccmr3; +} + +/** + * @brief Enables or disables the TIMx peripheral Preload register on CCR6. + * @param TIMx: where x can be 1 or 8 to select the TIM peripheral. + * @param TIM_OCPreload: new state of the TIMx peripheral Preload register + * This parameter can be one of the following values: + * @arg TIM_OCPreload_Enable + * @arg TIM_OCPreload_Disable + * @retval None + */ +void TIM_OC6PreloadConfig(TIM_TypeDef* TIMx, uint32_t TIM_OCPreload) +{ + uint32_t tmpccmr3 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_TIM_OCPRELOAD_STATE(TIM_OCPreload)); + + tmpccmr3 = TIMx->CCMR3; + + /* Reset the OC6PE Bit */ + tmpccmr3 &= (uint32_t)~((uint32_t)TIM_CCMR3_OC6PE); + + /* Enable or Disable the Output Compare Preload feature */ + tmpccmr3 |= (uint32_t)(TIM_OCPreload << 8); + + /* Write to TIMx CCMR3 register */ + TIMx->CCMR3 = tmpccmr3; +} + +/** + * @brief Configures the TIMx Output Compare 1 Fast feature. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13 or 14 + * to select the TIM peripheral. + * @param TIM_OCFast: new state of the Output Compare Fast Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCFast_Enable : TIM output compare fast enable + * @arg TIM_OCFast_Disable: TIM output compare fast disable + * @retval None + */ +void TIM_OC1FastConfig(TIM_TypeDef* TIMx, uint32_t TIM_OCFast) +{ + uint32_t tmpccmr1 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST4_PERIPH(TIMx)); + assert_param(IS_TIM_OCFAST_STATE(TIM_OCFast)); + + /* Get the TIMx CCMR1 register value */ + tmpccmr1 = TIMx->CCMR1; + + /* Reset the OC1FE Bit */ + tmpccmr1 &= (uint32_t)~((uint32_t)TIM_CCMR1_OC1FE); + + /* Enable or Disable the Output Compare Fast Bit */ + tmpccmr1 |= TIM_OCFast; + + /* Write to TIMx CCMR1 */ + TIMx->CCMR1 = tmpccmr1; +} + +/** + * @brief Configures the TIMx Output Compare 2 Fast feature. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select + * the TIM peripheral. + * @param TIM_OCFast: new state of the Output Compare Fast Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCFast_Enable : TIM output compare fast enable + * @arg TIM_OCFast_Disable: TIM output compare fast disable + * @retval None + */ +void TIM_OC2FastConfig(TIM_TypeDef* TIMx, uint32_t TIM_OCFast) +{ + uint32_t tmpccmr1 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST5_PERIPH(TIMx)); + assert_param(IS_TIM_OCFAST_STATE(TIM_OCFast)); + + /* Get the TIMx CCMR1 register value */ + tmpccmr1 = TIMx->CCMR1; + + /* Reset the OC2FE Bit */ + tmpccmr1 &= (uint32_t)~((uint32_t)TIM_CCMR1_OC2FE); + + /* Enable or Disable the Output Compare Fast Bit */ + tmpccmr1 |= (uint32_t)(TIM_OCFast << 8); + + /* Write to TIMx CCMR1 */ + TIMx->CCMR1 = tmpccmr1; +} + +/** + * @brief Configures the TIMx Output Compare 3 Fast feature. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_OCFast: new state of the Output Compare Fast Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCFast_Enable : TIM output compare fast enable + * @arg TIM_OCFast_Disable: TIM output compare fast disable + * @retval None + */ +void TIM_OC3FastConfig(TIM_TypeDef* TIMx, uint32_t TIM_OCFast) +{ + uint32_t tmpccmr2 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_OCFAST_STATE(TIM_OCFast)); + + /* Get the TIMx CCMR2 register value */ + tmpccmr2 = TIMx->CCMR2; + + /* Reset the OC3FE Bit */ + tmpccmr2 &= (uint32_t)~((uint32_t)TIM_CCMR2_OC3FE); + + /* Enable or Disable the Output Compare Fast Bit */ + tmpccmr2 |= TIM_OCFast; + + /* Write to TIMx CCMR2 */ + TIMx->CCMR2 = tmpccmr2; +} + +/** + * @brief Configures the TIMx Output Compare 4 Fast feature. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_OCFast: new state of the Output Compare Fast Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCFast_Enable : TIM output compare fast enable + * @arg TIM_OCFast_Disable: TIM output compare fast disable + * @retval None + */ +void TIM_OC4FastConfig(TIM_TypeDef* TIMx, uint32_t TIM_OCFast) +{ + uint32_t tmpccmr2 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_OCFAST_STATE(TIM_OCFast)); + + /* Get the TIMx CCMR2 register value */ + tmpccmr2 = TIMx->CCMR2; + + /* Reset the OC4FE Bit */ + tmpccmr2 &= (uint32_t)~((uint32_t)TIM_CCMR2_OC4FE); + + /* Enable or Disable the Output Compare Fast Bit */ + tmpccmr2 |= (uint32_t)(TIM_OCFast << 8); + + /* Write to TIMx CCMR2 */ + TIMx->CCMR2 = tmpccmr2; +} + +/** + * @brief Configures the TIMx Output Compare 5 Fast feature. + * @param TIMx: where x can be 1 or 8 to select the TIM peripheral. + * @param TIM_OCFast: new state of the Output Compare Fast Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCFast_Enable : TIM output compare fast enable + * @arg TIM_OCFast_Disable: TIM output compare fast disable + * @retval None + */ +void TIM_OC5FastConfig(TIM_TypeDef* TIMx, uint32_t TIM_OCFast) +{ + uint32_t tmpccmr3 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_OCFAST_STATE(TIM_OCFast)); + + /* Get the TIMx CCMR3 register value */ + tmpccmr3 = TIMx->CCMR3; + + /* Reset the OC5FE Bit */ + tmpccmr3 &= (uint32_t)~((uint32_t)TIM_CCMR3_OC5FE); + + /* Enable or Disable the Output Compare Fast Bit */ + tmpccmr3 |= TIM_OCFast; + + /* Write to TIMx CCMR3 */ + TIMx->CCMR3 = tmpccmr3; +} + +/** + * @brief Configures the TIMx Output Compare 6 Fast feature. + * @param TIMx: where x can be 1 or 8 to select the TIM peripheral. + * @param TIM_OCFast: new state of the Output Compare Fast Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCFast_Enable : TIM output compare fast enable + * @arg TIM_OCFast_Disable: TIM output compare fast disable + * @retval None + */ +void TIM_OC6FastConfig(TIM_TypeDef* TIMx, uint32_t TIM_OCFast) +{ + uint32_t tmpccmr3 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_OCFAST_STATE(TIM_OCFast)); + + /* Get the TIMx CCMR3 register value */ + tmpccmr3 = TIMx->CCMR3; + + /* Reset the OC6FE Bit */ + tmpccmr3 &= (uint32_t)~((uint32_t)TIM_CCMR3_OC6FE); + + /* Enable or Disable the Output Compare Fast Bit */ + tmpccmr3 |= (uint32_t)(TIM_OCFast << 8); + + /* Write to TIMx CCMR3 */ + TIMx->CCMR3 = tmpccmr3; +} + +/** + * @brief Clears or safeguards the OCREF1 signal on an external event + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_OCClear: new state of the Output Compare Clear Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCClear_Enable : TIM Output clear enable + * @arg TIM_OCClear_Disable: TIM Output clear disable + * @retval None + */ +void TIM_ClearOC1Ref(TIM_TypeDef* TIMx, uint32_t TIM_OCClear) +{ + uint32_t tmpccmr1 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_OCCLEAR_STATE(TIM_OCClear)); + + tmpccmr1 = TIMx->CCMR1; + + /* Reset the OC1CE Bit */ + tmpccmr1 &= (uint32_t)~((uint32_t)TIM_CCMR1_OC1CE); + + /* Enable or Disable the Output Compare Clear Bit */ + tmpccmr1 |= TIM_OCClear; + + /* Write to TIMx CCMR1 register */ + TIMx->CCMR1 = tmpccmr1; +} + +/** + * @brief Clears or safeguards the OCREF2 signal on an external event + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_OCClear: new state of the Output Compare Clear Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCClear_Enable : TIM Output clear enable + * @arg TIM_OCClear_Disable: TIM Output clear disable + * @retval None + */ +void TIM_ClearOC2Ref(TIM_TypeDef* TIMx, uint32_t TIM_OCClear) +{ + uint32_t tmpccmr1 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_OCCLEAR_STATE(TIM_OCClear)); + + tmpccmr1 = TIMx->CCMR1; + + /* Reset the OC2CE Bit */ + tmpccmr1 &= (uint32_t)~((uint32_t)TIM_CCMR1_OC2CE); + + /* Enable or Disable the Output Compare Clear Bit */ + tmpccmr1 |= (uint32_t)(TIM_OCClear << 8); + + /* Write to TIMx CCMR1 register */ + TIMx->CCMR1 = tmpccmr1; +} + +/** + * @brief Clears or safeguards the OCREF3 signal on an external event + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_OCClear: new state of the Output Compare Clear Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCClear_Enable : TIM Output clear enable + * @arg TIM_OCClear_Disable: TIM Output clear disable + * @retval None + */ +void TIM_ClearOC3Ref(TIM_TypeDef* TIMx, uint32_t TIM_OCClear) +{ + uint32_t tmpccmr2 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_OCCLEAR_STATE(TIM_OCClear)); + + tmpccmr2 = TIMx->CCMR2; + + /* Reset the OC3CE Bit */ + tmpccmr2 &= (uint32_t)~((uint32_t)TIM_CCMR2_OC3CE); + + /* Enable or Disable the Output Compare Clear Bit */ + tmpccmr2 |= TIM_OCClear; + + /* Write to TIMx CCMR2 register */ + TIMx->CCMR2 = tmpccmr2; +} + +/** + * @brief Clears or safeguards the OCREF4 signal on an external event + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_OCClear: new state of the Output Compare Clear Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCClear_Enable : TIM Output clear enable + * @arg TIM_OCClear_Disable: TIM Output clear disable + * @retval None + */ +void TIM_ClearOC4Ref(TIM_TypeDef* TIMx, uint32_t TIM_OCClear) +{ + uint32_t tmpccmr2 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_OCCLEAR_STATE(TIM_OCClear)); + + tmpccmr2 = TIMx->CCMR2; + + /* Reset the OC4CE Bit */ + tmpccmr2 &= (uint32_t)~((uint32_t)TIM_CCMR2_OC4CE); + + /* Enable or Disable the Output Compare Clear Bit */ + tmpccmr2 |= (uint32_t)(TIM_OCClear << 8); + + /* Write to TIMx CCMR2 register */ + TIMx->CCMR2 = tmpccmr2; +} + +/** + * @brief Clears or safeguards the OCREF5 signal on an external event + * @param TIMx: where x can be 1 or 8 to select the TIM peripheral. + * @param TIM_OCClear: new state of the Output Compare Clear Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCClear_Enable : TIM Output clear enable + * @arg TIM_OCClear_Disable: TIM Output clear disable + * @retval None + */ +void TIM_ClearOC5Ref(TIM_TypeDef* TIMx, uint32_t TIM_OCClear) +{ + uint32_t tmpccmr3 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_TIM_OCCLEAR_STATE(TIM_OCClear)); + + tmpccmr3 = TIMx->CCMR3; + + /* Reset the OC5CE Bit */ + tmpccmr3 &= (uint32_t)~((uint32_t)TIM_CCMR3_OC5CE); + + /* Enable or Disable the Output Compare Clear Bit */ + tmpccmr3 |= TIM_OCClear; + + /* Write to TIMx CCMR3 register */ + TIMx->CCMR3 = tmpccmr3; +} + +/** + * @brief Clears or safeguards the OCREF6 signal on an external event + * @param TIMx: where x can be 1 or 8 to select the TIM peripheral. + * @param TIM_OCClear: new state of the Output Compare Clear Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCClear_Enable : TIM Output clear enable + * @arg TIM_OCClear_Disable: TIM Output clear disable + * @retval None + */ +void TIM_ClearOC6Ref(TIM_TypeDef* TIMx, uint32_t TIM_OCClear) +{ + uint32_t tmpccmr3 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_TIM_OCCLEAR_STATE(TIM_OCClear)); + + tmpccmr3 = TIMx->CCMR3; + + /* Reset the OC6CE Bit */ + tmpccmr3 &= (uint32_t)~((uint32_t)TIM_CCMR3_OC6CE); + + /* Enable or Disable the Output Compare Clear Bit */ + tmpccmr3 |= (uint32_t)(TIM_OCClear << 8); + + /* Write to TIMx CCMR3 register */ + TIMx->CCMR3 = tmpccmr3; +} + +/** + * @brief Configures the TIMx channel 1 polarity. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13 + * or 14 to select the TIM peripheral. + * @param TIM_OCPolarity: specifies the OC1 Polarity + * This parmeter can be one of the following values: + * @arg TIM_OCPolarity_High: Output Compare active high + * @arg TIM_OCPolarity_Low : Output Compare active low + * @retval None + */ +void TIM_OC1PolarityConfig(TIM_TypeDef* TIMx, uint32_t TIM_OCPolarity) +{ + uint32_t tmpccer = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST4_PERIPH(TIMx)); + assert_param(IS_TIM_OC_POLARITY(TIM_OCPolarity)); + + tmpccer = TIMx->CCER; + + /* Set or Reset the CC1P Bit */ + tmpccer &= (uint32_t)~((uint32_t)TIM_CCER_CC1P); + tmpccer |= TIM_OCPolarity; + + /* Write to TIMx CCER register */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Configures the TIMx Channel 1N polarity. + * @param TIMx: where x can be 1 or 8 to select the TIM peripheral. + * @param TIM_OCNPolarity: specifies the OC1N Polarity + * This parmeter can be one of the following values: + * @arg TIM_OCNPolarity_High: Output Compare active high + * @arg TIM_OCNPolarity_Low : Output Compare active low + * @retval None + */ +void TIM_OC1NPolarityConfig(TIM_TypeDef* TIMx, uint32_t TIM_OCNPolarity) +{ + uint32_t tmpccer = 0; + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_TIM_OCN_POLARITY(TIM_OCNPolarity)); + + tmpccer = TIMx->CCER; + + /* Set or Reset the CC1NP Bit */ + tmpccer &= (uint32_t)~((uint32_t)TIM_CCER_CC1NP); + tmpccer |= TIM_OCNPolarity; + + /* Write to TIMx CCER register */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Configures the TIMx channel 2 polarity. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to + * select the TIM peripheral. + * @param TIM_OCPolarity: specifies the OC2 Polarity + * This parmeter can be one of the following values: + * @arg TIM_OCPolarity_High: Output Compare active high + * @arg TIM_OCPolarity_Low : Output Compare active low + * @retval None + */ +void TIM_OC2PolarityConfig(TIM_TypeDef* TIMx, uint32_t TIM_OCPolarity) +{ + uint32_t tmpccer = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST5_PERIPH(TIMx)); + assert_param(IS_TIM_OC_POLARITY(TIM_OCPolarity)); + + tmpccer = TIMx->CCER; + + /* Set or Reset the CC2P Bit */ + tmpccer &= (uint32_t)~((uint32_t)TIM_CCER_CC2P); + tmpccer |= (uint32_t)(TIM_OCPolarity << 4); + + /* Write to TIMx CCER register */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Configures the TIMx Channel 2N polarity. + * @param TIMx: where x can be 1 or 8 to select the TIM peripheral. + * @param TIM_OCNPolarity: specifies the OC2N Polarity + * This parmeter can be one of the following values: + * @arg TIM_OCNPolarity_High: Output Compare active high + * @arg TIM_OCNPolarity_Low : Output Compare active low + * @retval None + */ +void TIM_OC2NPolarityConfig(TIM_TypeDef* TIMx, uint32_t TIM_OCNPolarity) +{ + uint32_t tmpccer = 0; + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_TIM_OCN_POLARITY(TIM_OCNPolarity)); + + tmpccer = TIMx->CCER; + + /* Set or Reset the CC2NP Bit */ + tmpccer &= (uint32_t)~((uint32_t)TIM_CCER_CC2NP); + tmpccer |= (uint32_t)(TIM_OCNPolarity << 4); + + /* Write to TIMx CCER register */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Configures the TIMx channel 3 polarity. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select + * the TIM peripheral. + * @param TIM_OCPolarity: specifies the OC3 Polarity + * This parmeter can be one of the following values: + * @arg TIM_OCPolarity_High: Output Compare active high + * @arg TIM_OCPolarity_Low : Output Compare active low + * @retval None + */ +void TIM_OC3PolarityConfig(TIM_TypeDef* TIMx, uint32_t TIM_OCPolarity) +{ + uint32_t tmpccer = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_OC_POLARITY(TIM_OCPolarity)); + + tmpccer = TIMx->CCER; + + /* Set or Reset the CC3P Bit */ + tmpccer &= (uint32_t)~((uint32_t)TIM_CCER_CC3P); + tmpccer |= (uint32_t)(TIM_OCPolarity << 8); + + /* Write to TIMx CCER register */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Configures the TIMx Channel 3N polarity. + * @param TIMx: where x can be 1 or 8 to select the TIM peripheral. + * @param TIM_OCNPolarity: specifies the OC3N Polarity + * This parmeter can be one of the following values: + * @arg TIM_OCNPolarity_High: Output Compare active high + * @arg TIM_OCNPolarity_Low: Output Compare active low + * @retval None + */ +void TIM_OC3NPolarityConfig(TIM_TypeDef* TIMx, uint32_t TIM_OCNPolarity) +{ + uint32_t tmpccer = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_TIM_OCN_POLARITY(TIM_OCNPolarity)); + + tmpccer = TIMx->CCER; + + /* Set or Reset the CC3NP Bit */ + tmpccer &= (uint32_t)~((uint32_t)TIM_CCER_CC3NP); + tmpccer |= (uint32_t)(TIM_OCNPolarity << 8); + + /* Write to TIMx CCER register */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Configures the TIMx channel 4 polarity. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select + * the TIM peripheral. + * @param TIM_OCPolarity: specifies the OC4 Polarity + * This parmeter can be one of the following values: + * @arg TIM_OCPolarity_High: Output Compare active high + * @arg TIM_OCPolarity_Low : Output Compare active low + * @retval None + */ +void TIM_OC4PolarityConfig(TIM_TypeDef* TIMx, uint32_t TIM_OCPolarity) +{ + uint32_t tmpccer = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_OC_POLARITY(TIM_OCPolarity)); + + tmpccer = TIMx->CCER; + + /* Set or Reset the CC4P Bit */ + tmpccer &= (uint32_t)~((uint32_t)TIM_CCER_CC4P); + tmpccer |= (uint32_t)(TIM_OCPolarity << 12); + + /* Write to TIMx CCER register */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Configures the TIMx channel 5 polarity. + * @param TIMx: where x can be 1 or 8 to select the TIM peripheral. + * @param TIM_OCPolarity: specifies the OC5 Polarity + * This parmeter can be one of the following values: + * @arg TIM_OCPolarity_High: Output Compare active high + * @arg TIM_OCPolarity_Low : Output Compare active low + * @retval None + */ +void TIM_OC5PolarityConfig(TIM_TypeDef* TIMx, uint32_t TIM_OCPolarity) +{ + uint32_t tmpccer = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_TIM_OC_POLARITY(TIM_OCPolarity)); + + tmpccer = TIMx->CCER; + + /* Set or Reset the CC5P Bit */ + tmpccer &= (uint32_t)~((uint32_t)TIM_CCER_CC5P); + tmpccer |= (uint32_t)(TIM_OCPolarity << 16); + + /* Write to TIMx CCER register */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Configures the TIMx channel 6 polarity. + * @param TIMx: where x can be 1 or 8 to select the TIM peripheral. + * @param TIM_OCPolarity: specifies the OC6 Polarity + * This parmeter can be one of the following values: + * @arg TIM_OCPolarity_High: Output Compare active high + * @arg TIM_OCPolarity_Low : Output Compare active low + * @retval None + */ +void TIM_OC6PolarityConfig(TIM_TypeDef* TIMx, uint32_t TIM_OCPolarity) +{ + uint32_t tmpccer = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_TIM_OC_POLARITY(TIM_OCPolarity)); + + tmpccer = TIMx->CCER; + + /* Set or Reset the CC6P Bit */ + tmpccer &= (uint32_t)~((uint32_t)TIM_CCER_CC6P); + tmpccer |= (uint32_t)(TIM_OCPolarity << 20); + + /* Write to TIMx CCER register */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Selects the OCReference Clear source. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_OCReferenceClear: specifies the OCReference Clear source. + * This parameter can be one of the following values: + * @arg TIM_OCReferenceClear_ETRF : The internal OCreference clear input is connected to ETRF. + * @arg TIM_OCReferenceClear_OCREFCLR: The internal OCreference clear input is connected to OCREF_CLR input. + * @retval None + */ +void TIM_SelectOCREFClear(TIM_TypeDef* TIMx, uint32_t TIM_OCReferenceClear) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(TIM_OCREFERENCECECLEAR_SOURCE(TIM_OCReferenceClear)); + + /* Set the TIM_OCReferenceClear source */ + TIMx->SMCR &= (uint32_t)~((uint32_t)TIM_SMCR_OCCS); + TIMx->SMCR |= TIM_OCReferenceClear; +} + +/** + * @brief Enables or disables the TIM Capture Compare Channel x. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13 or 14 to select + * the TIM peripheral. + * @param TIM_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 + * @param TIM_CCx: specifies the TIM Channel CCxE bit new state. + * This parameter can be: TIM_CCx_Enable or TIM_CCx_Disable . + * @retval None + */ +void TIM_CCxCmd(TIM_TypeDef* TIMx, uint32_t TIM_Channel, uint32_t TIM_CCx) +{ + uint32_t tmp = 0; + + /* Check the parameters */ + assert_param(IS_TIM_CCX(TIM_CCx)); + + /* Check the parameters - TIM_Channel */ + if ((TIMx == TIM1) || (TIMx == TIM8)) + { + assert_param(IS_TIM_CHANNEL(TIM_Channel)); + } + else if ((TIMx == TIM2) || (TIMx == TIM3) || + (TIMx == TIM4) || (TIMx == TIM5)) + { + assert_param(IS_TIM_2_TO_5_CHANNEL(TIM_Channel)); + } + else if ((TIMx == TIM9) || (TIMx == TIM12)) + { + assert_param(IS_TIM_9_AND_12_CHANNEL(TIM_Channel)); + } + else/*if((TIMx == TIM10) || (TIMx == TIM11) || + (TIMx == TIM13) || (TIMx == TIM14))*/ + { + assert_param(IS_TIM_10_11_13_14_CHANNEL(TIM_Channel)); + } + + tmp = CCER_CCE_SET << TIM_Channel; + + /* Reset the CCxE Bit */ + TIMx->CCER &= (uint32_t)~ tmp; + + /* Set or reset the CCxE Bit */ + TIMx->CCER |= (uint32_t)(TIM_CCx << TIM_Channel); +} + +/** + * @brief Enables or disables the TIM Capture Compare Channel xN. + * @param TIMx: where x can be 1 or 8 to select the TIM peripheral. + * @param TIM_Channel: specifies the TIM Channel + * This parmeter 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 + * @param TIM_CCxN: specifies the TIM Channel CCxNE bit new state. + * This parameter can be: TIM_CCxN_Enable or TIM_CCxN_Disable. + * @retval None + */ +void TIM_CCxNCmd(TIM_TypeDef* TIMx, uint32_t TIM_Channel, uint32_t TIM_CCxN) +{ + uint32_t tmp = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_TIM_COMPLEMENTARY_CHANNEL(TIM_Channel)); + assert_param(IS_TIM_CCXN(TIM_CCxN)); + + tmp = CCER_CCNE_SET << TIM_Channel; + + /* Reset the CCxNE Bit */ + TIMx->CCER &= (uint32_t) ~tmp; + + /* Set or reset the CCxNE Bit */ + TIMx->CCER |= (uint32_t)(TIM_CCxN << TIM_Channel); +} + +/** + * @brief Selects the TIM peripheral Commutation event. + * @param TIMx: where x can be 1 or 8 to select the TIMx peripheral + * @param NewState: new state of the Commutation event. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void TIM_SelectCOM(TIM_TypeDef* TIMx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Set the COM Bit */ + TIMx->CR2 |= TIM_CR2_CCUS; + } + else + { + /* Reset the COM Bit */ + TIMx->CR2 &= (uint32_t)~((uint32_t)TIM_CR2_CCUS); + } +} + +/** + * @} + */ +/** + * @brief Initializes the TIM peripheral according to the specified + * parameters in the TIM_ICInitStruct. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13 or 14 + * to select the TIM peripheral. + * @param TIM_ICInitStruct: pointer to a TIM_ICInitTypeDef structure + * that contains the configuration information for the specified TIM + * peripheral. + * @retval None + */ +void TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST4_PERIPH(TIMx)); + assert_param(IS_TIM_CHANNEL(TIM_ICInitStruct->TIM_Channel)); + assert_param(IS_TIM_IC_SELECTION(TIM_ICInitStruct->TIM_ICSelection)); + assert_param(IS_TIM_IC_PRESCALER(TIM_ICInitStruct->TIM_ICPrescaler)); + assert_param(IS_TIM_IC_FILTER(TIM_ICInitStruct->TIM_ICFilter)); + assert_param(IS_TIM_IC_POLARITY(TIM_ICInitStruct->TIM_ICPolarity)); + + if (TIM_ICInitStruct->TIM_Channel == TIM_Channel_1) + { + assert_param(IS_TIM_LIST4_PERIPH(TIMx)); + /* TI1 Configuration */ + TI1_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, + TIM_ICInitStruct->TIM_ICSelection, + TIM_ICInitStruct->TIM_ICFilter); + /* Set the Input Capture Prescaler value */ + TIM_SetIC1Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); + } + else if (TIM_ICInitStruct->TIM_Channel == TIM_Channel_2) + { + assert_param(IS_TIM_LIST5_PERIPH(TIMx)); + /* TI2 Configuration */ + TI2_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, + TIM_ICInitStruct->TIM_ICSelection, + TIM_ICInitStruct->TIM_ICFilter); + /* Set the Input Capture Prescaler value */ + TIM_SetIC2Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); + } + else if (TIM_ICInitStruct->TIM_Channel == TIM_Channel_3) + { + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + /* TI3 Configuration */ + TI3_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, + TIM_ICInitStruct->TIM_ICSelection, + TIM_ICInitStruct->TIM_ICFilter); + /* Set the Input Capture Prescaler value */ + TIM_SetIC3Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); + } + else + { + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + /* TI4 Configuration */ + TI4_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, + TIM_ICInitStruct->TIM_ICSelection, + TIM_ICInitStruct->TIM_ICFilter); + /* Set the Input Capture Prescaler value */ + TIM_SetIC4Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); + } +} + +/** + * @brief Fills each TIM_ICInitStruct member with its default value. + * @param TIM_ICInitStruct: pointer to a TIM_ICInitTypeDef structure which will + * be initialized. + * @retval None + */ +void TIM_ICStructInit(TIM_ICInitTypeDef* TIM_ICInitStruct) +{ + /* Set the default configuration */ + TIM_ICInitStruct->TIM_Channel = TIM_Channel_1; + TIM_ICInitStruct->TIM_ICPolarity = TIM_ICPolarity_Rising; + TIM_ICInitStruct->TIM_ICSelection = TIM_ICSelection_DirectTI; + TIM_ICInitStruct->TIM_ICPrescaler = TIM_ICPSC_DIV1; + TIM_ICInitStruct->TIM_ICFilter = 0x00; +} + +/** + * @brief Configures the TIM peripheral according to the specified + * parameters in the TIM_ICInitStruct to measure an external PWM signal. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM peripheral. + * @param TIM_ICInitStruct: pointer to a TIM_ICInitTypeDef structure + * that contains the configuration information for the specified TIM + * peripheral. + * @retval None + */ +void TIM_PWMIConfig(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct) +{ + uint32_t icoppositepolarity = TIM_ICPolarity_Rising; + uint32_t icoppositeselection = TIM_ICSelection_DirectTI; + + /* Check the parameters */ + assert_param(IS_TIM_LIST5_PERIPH(TIMx)); + + /* Select the Opposite Input Polarity */ + if (TIM_ICInitStruct->TIM_ICPolarity == TIM_ICPolarity_Rising) + { + icoppositepolarity = TIM_ICPolarity_Falling; + } + else + { + icoppositepolarity = TIM_ICPolarity_Rising; + } + + /* Select the Opposite Input */ + if (TIM_ICInitStruct->TIM_ICSelection == TIM_ICSelection_DirectTI) + { + icoppositeselection = TIM_ICSelection_IndirectTI; + } + else + { + icoppositeselection = TIM_ICSelection_DirectTI; + } + + if (TIM_ICInitStruct->TIM_Channel == TIM_Channel_1) + { + /* TI1 Configuration */ + TI1_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, TIM_ICInitStruct->TIM_ICSelection, + TIM_ICInitStruct->TIM_ICFilter); + /* Set the Input Capture Prescaler value */ + TIM_SetIC1Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); + /* TI2 Configuration */ + TI2_Config(TIMx, icoppositepolarity, icoppositeselection, TIM_ICInitStruct->TIM_ICFilter); + /* Set the Input Capture Prescaler value */ + TIM_SetIC2Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); + } + else + { + /* TI2 Configuration */ + TI2_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, TIM_ICInitStruct->TIM_ICSelection, + TIM_ICInitStruct->TIM_ICFilter); + /* Set the Input Capture Prescaler value */ + TIM_SetIC2Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); + /* TI1 Configuration */ + TI1_Config(TIMx, icoppositepolarity, icoppositeselection, TIM_ICInitStruct->TIM_ICFilter); + /* Set the Input Capture Prescaler value */ + TIM_SetIC1Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); + } +} + +/** + * @brief Gets the TIMx Input Capture 1 value. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13 or 14 + * to select the TIM peripheral. + * @retval Capture Compare 1 Register value. + */ +uint32_t TIM_GetCapture1(TIM_TypeDef* TIMx) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST4_PERIPH(TIMx)); + + /* Get the Capture 1 Register value */ + return TIMx->CCR1; +} + +/** + * @brief Gets the TIMx Input Capture 2 value. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the + * TIM peripheral. + * @retval Capture Compare 2 Register value. + */ +uint32_t TIM_GetCapture2(TIM_TypeDef* TIMx) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST5_PERIPH(TIMx)); + + /* Get the Capture 2 Register value */ + return TIMx->CCR2; +} + +/** + * @brief Gets the TIMx Input Capture 3 value. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @retval Capture Compare 3 Register value. + */ +uint32_t TIM_GetCapture3(TIM_TypeDef* TIMx) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + + /* Get the Capture 3 Register value */ + return TIMx->CCR3; +} + +/** + * @brief Gets the TIMx Input Capture 4 value. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @retval Capture Compare 4 Register value. + */ +uint32_t TIM_GetCapture4(TIM_TypeDef* TIMx) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + + /* Get the Capture 4 Register value */ + return TIMx->CCR4; +} + +/** + * @brief Gets the TIMx Input Capture 5 value. + * @param TIMx: where x can be 1 or 8 to select the TIM peripheral. + * @retval Capture Compare 5 Register value. + */ +uint32_t TIM_GetCapture5(TIM_TypeDef* TIMx) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + + /* Get the Capture 5 Register value */ + return TIMx->CCR5; +} + +/** + * @brief Gets the TIMx Input Capture 6 value. + * @param TIMx: where x can be 1 or 8 to select the TIM peripheral. + * @retval Capture Compare 6 Register value. + */ +uint32_t TIM_GetCapture6(TIM_TypeDef* TIMx) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + + /* Get the Capture 6 Register value */ + return TIMx->CCR6; +} + +/** + * @brief Sets the TIMx Input Capture 1 prescaler. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13 or 14 + * to select the TIM peripheral. + * @param TIM_ICPSC: specifies the Input Capture1 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 + */ +void TIM_SetIC1Prescaler(TIM_TypeDef* TIMx, uint32_t TIM_ICPSC) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST4_PERIPH(TIMx)); + assert_param(IS_TIM_IC_PRESCALER(TIM_ICPSC)); + + /* Reset the IC1PSC Bits */ + TIMx->CCMR1 &= (uint32_t)~((uint32_t)TIM_CCMR1_IC1PSC); + + /* Set the IC1PSC value */ + TIMx->CCMR1 |= TIM_ICPSC; +} + +/** + * @brief Sets the TIMx Input Capture 2 prescaler. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM peripheral. + * @param TIM_ICPSC: specifies the Input Capture2 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 + */ +void TIM_SetIC2Prescaler(TIM_TypeDef* TIMx, uint32_t TIM_ICPSC) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST5_PERIPH(TIMx)); + assert_param(IS_TIM_IC_PRESCALER(TIM_ICPSC)); + + /* Reset the IC2PSC Bits */ + TIMx->CCMR1 &= (uint32_t)~((uint32_t)TIM_CCMR1_IC2PSC); + + /* Set the IC2PSC value */ + TIMx->CCMR1 |= (uint32_t)(TIM_ICPSC << 8); +} + +/** + * @brief Sets the TIMx Input Capture 3 prescaler. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_ICPSC: specifies the Input Capture3 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 + */ +void TIM_SetIC3Prescaler(TIM_TypeDef* TIMx, uint32_t TIM_ICPSC) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_IC_PRESCALER(TIM_ICPSC)); + + /* Reset the IC3PSC Bits */ + TIMx->CCMR2 &= (uint32_t)~((uint32_t)TIM_CCMR2_IC3PSC); + + /* Set the IC3PSC value */ + TIMx->CCMR2 |= TIM_ICPSC; +} + +/** + * @brief Sets the TIMx Input Capture 4 prescaler. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_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 + */ +void TIM_SetIC4Prescaler(TIM_TypeDef* TIMx, uint32_t TIM_ICPSC) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_IC_PRESCALER(TIM_ICPSC)); + + /* Reset the IC4PSC Bits */ + TIMx->CCMR2 &= (uint32_t)~((uint32_t)TIM_CCMR2_IC4PSC); + + /* Set the IC4PSC value */ + TIMx->CCMR2 |= (uint32_t)(TIM_ICPSC << 8); +} + +/** + * @} + */ + +/** + * @brief Enables or disables the specified TIM interrupts. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 or 14 + * to select the TIMx peripheral. + * @param TIM_IT: specifies the TIM interrupts sources to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg TIM_IT_Update : TIM update Interrupt source + * @arg TIM_IT_CC1 : TIM Capture Compare 1 Interrupt source + * @arg TIM_IT_CC2 : TIM Capture Compare 2 Interrupt source + * @arg TIM_IT_CC3 : TIM Capture Compare 3 Interrupt source + * @arg TIM_IT_CC4 : TIM Capture Compare 4 Interrupt source + * @arg TIM_IT_COM : TIM Commutation Interrupt source + * @arg TIM_IT_Trigger: TIM Trigger Interrupt source + * @arg TIM_IT_Break : TIM Break Interrupt source + * + * @note TIM2, TIM3, TIM4 and TIM5 can generate TIM_IT_Update, TIM_IT_CC1, + * TIM_IT_CC2, TIM_IT_CC3, TIM_IT_CC4 and TIM_IT_Trigger interrupt. + * @note TIM6 and TIM7 can only generate an update interrupt. + * @note TIM9 and TIM12 can generate TIM_IT_Update, TIM_IT_CC1, TIM_IT_CC2 and + * TIM_IT_Trigger interrupt. + * @note TIM10, TIM11, TIM13 and TIM14 can generate TIM_IT_Update and TIM_IT_CC1 + * interrupt. + * + * @note TIM_IT_Break is used only with TIM1 and TIM8. + * @note TIM_IT_COM is used only with TIM1 and TIM8. + * + * @param NewState: new state of the TIM interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void TIM_ITConfig(TIM_TypeDef* TIMx, uint32_t TIM_IT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_TIM_IT(TIM_IT)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the Interrupt sources */ + TIMx->DIER |= TIM_IT; + } + else + { + /* Disable the Interrupt sources */ + TIMx->DIER &= (uint32_t)~TIM_IT; + } +} + +/** + * @brief Configures the TIMx event to be generate by software. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 or 14 + * to select the TIMx peripheral. + * @param TIM_EventSource: specifies the event source. + * This parameter can be one or more 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 + * + * @note TIM2, TIM3, TIM4 and TIM5 can generate Update, CC1, CC2, CC3, CC4 and trigger event. + * @note TIM6 and TIM7 can only generate an update event. + * @note TIM9 and TIM12 can generate Update, CC1, CC2 and trigger event. + * @note TIM10, TIM11, TIM13 and TIM14 can generate Update and CC1 event. + * @note TIM_EventSource_COM and TIM_EventSource_Break are used only with TIM1 and TIM8. + * + * @retval None + */ +void TIM_GenerateEvent(TIM_TypeDef* TIMx, uint32_t TIM_EventSource) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_TIM_EVENT_SOURCE(TIM_EventSource)); + + /* Set the event sources */ + TIMx->EGR = TIM_EventSource; +} + +/** + * @brief Checks whether the specified TIM flag is set or not. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 or 14 + * to select the TIMx peripheral. + * @param TIM_FLAG: specifies the flag to check. + * This parameter can be one of the following values: + * @arg TIM_FLAG_Update : TIM update Flag + * @arg TIM_FLAG_CC1 : TIM Capture Compare 1 Flag + * @arg TIM_FLAG_CC2 : TIM Capture Compare 2 Flag + * @arg TIM_FLAG_CC3 : TIM Capture Compare 3 Flag + * @arg TIM_FLAG_CC4 : TIM Capture Compare 4 Flag + * @arg TIM_FLAG_CC5 : TIM Capture Compare 5 Flag + * @arg TIM_FLAG_CC6 : TIM Capture Compare 6 Flag + * @arg TIM_FLAG_COM : TIM Commutation Flag + * @arg TIM_FLAG_Trigger: TIM Trigger Flag + * @arg TIM_FLAG_Break : TIM Break Flag + * @arg TIM_FLAG_CC1OF : TIM Capture Compare 1 overcapture Flag + * @arg TIM_FLAG_CC2OF : TIM Capture Compare 2 overcapture Flag + * @arg TIM_FLAG_CC3OF : TIM Capture Compare 3 overcapture Flag + * @arg TIM_FLAG_CC4OF : TIM Capture Compare 4 overcapture Flag + * + * @note TIM2, TIM3, TIM4 and TIM5 can have Update, CC1, CC2, CC3, CC4, trigger, + * CC1OF, CC2OF, CC3OF and CC4OF flag. + * @note TIM6 and TIM7 can have only one update flag. + * @note TIM9 and TIM12 can have Update, CC1, CC2, trigger, CC1OF and CC2OF flag. + * @note TIM10, TIM11, TIM13 and TIM14 can have Update, CC1 and CC1OF flag. + * @note TIM_FLAG_Break, TIM_FLAG_COM, TIM_FLAG_CC5 and TIM_FLAG_CC6 are used only + * with TIM1 and TIM8. + * + * @retval The new state of TIM_FLAG (SET or RESET). + */ +FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint32_t TIM_FLAG) +{ + ITStatus bitstatus = RESET; + + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_TIM_GET_FLAG(TIM_FLAG)); + + if ((TIMx->SR & TIM_FLAG) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + return bitstatus; +} + +/** + * @brief Clears the TIMx's pending flags. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 or 14 + * to select the TIMx peripheral. + * @param TIM_FLAG: specifies the flag bit to clear. + * This parameter can be any combination of the following values: + * @arg TIM_FLAG_Update : TIM update Flag + * @arg TIM_FLAG_CC1 : TIM Capture Compare 1 Flag + * @arg TIM_FLAG_CC2 : TIM Capture Compare 2 Flag + * @arg TIM_FLAG_CC3 : TIM Capture Compare 3 Flag + * @arg TIM_FLAG_CC4 : TIM Capture Compare 4 Flag + * @arg TIM_FLAG_CC5 : TIM Capture Compare 5 Flag + * @arg TIM_FLAG_CC6 : TIM Capture Compare 6 Flag + * @arg TIM_FLAG_COM : TIM Commutation Flag + * @arg TIM_FLAG_Trigger: TIM Trigger Flag + * @arg TIM_FLAG_Break : TIM Break Flag + * @arg TIM_FLAG_CC1OF : TIM Capture Compare 1 overcapture Flag + * @arg TIM_FLAG_CC2OF : TIM Capture Compare 2 overcapture Flag + * @arg TIM_FLAG_CC3OF : TIM Capture Compare 3 overcapture Flag + * @arg TIM_FLAG_CC4OF : TIM Capture Compare 4 overcapture Flag + * + * @note TIM2, TIM3, TIM4 and TIM5 can have Update, CC1, CC2, CC3, CC4, trigger, + * CC1OF, CC2OF, CC3OF and CC4OF flag. + * @note TIM6 and TIM7 can have only one update flag. + * @note TIM9 and TIM12 can have Update, CC1, CC2, trigger, CC1OF and CC2OF flag. + * @note TIM10, TIM11, TIM13 and TIM14 can have Update, CC1 and CC1OF flag. + * @note TIM_FLAG_Break, TIM_FLAG_COM, TIM_FLAG_CC5 and TIM_FLAG_CC6 are used only + * with TIM1 and TIM8. + * + * @retval None + */ +void TIM_ClearFlag(TIM_TypeDef* TIMx, uint32_t TIM_FLAG) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_TIM_CLEAR_FLAG(TIM_FLAG)); + + /* Clear the flags */ + TIMx->SR = (uint32_t)~TIM_FLAG; +} + +/** + * @brief Checks whether the TIM interrupt has occurred or not. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 or 14 + * to select the TIMx peripheral. + * @param TIM_IT: specifies the TIM interrupt source to check. + * This parameter can be one of the following values: + * @arg TIM_IT_Update : TIM update Interrupt source + * @arg TIM_IT_CC1 : TIM Capture Compare 1 Interrupt source + * @arg TIM_IT_CC2 : TIM Capture Compare 2 Interrupt source + * @arg TIM_IT_CC3 : TIM Capture Compare 3 Interrupt source + * @arg TIM_IT_CC4 : TIM Capture Compare 4 Interrupt source + * @arg TIM_IT_COM : TIM Commutation Interrupt source + * @arg TIM_IT_Trigger: TIM Trigger Interrupt source + * @arg TIM_IT_Break : TIM Break Interrupt source + * + * @note TIM2, TIM3, TIM4 and TIM5 can generate TIM_IT_Update, TIM_IT_CC1, + * TIM_IT_CC2, TIM_IT_CC3, TIM_IT_CC4 and TIM_IT_Trigger interrupt. + * @note TIM6 and TIM7 can only generate an update interrupt. + * @note TIM9 and TIM12 can generate TIM_IT_Update, TIM_IT_CC1, TIM_IT_CC2 and + * TIM_IT_Trigger interrupt. + * @note TIM10, TIM11, TIM13 and TIM14 can generate TIM_IT_Update and TIM_IT_CC1 + * interrupt. + * + * @note TIM_IT_Break is used only with TIM1 and TIM8. + * @note TIM_IT_COM is used only with TIM1 and TIM8. + * + * @retval The new state of the TIM_IT(SET or RESET). + */ +ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint32_t TIM_IT) +{ + ITStatus bitstatus = RESET; + uint32_t itstatus = 0x0, itenable = 0x0; + + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_TIM_GET_IT(TIM_IT)); + + itstatus = TIMx->SR & TIM_IT; + + itenable = TIMx->DIER & TIM_IT; + if ((itstatus != (uint32_t)RESET) && (itenable != (uint32_t)RESET)) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + return bitstatus; +} + +/** + * @brief Clears the TIMx's interrupt pending bits. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 or 14 + * to select the TIMx peripheral. + * @param TIM_IT: specifies the pending bit to clear. + * This parameter can be any combination of the following values: + * @arg TIM_IT_Update : TIM1 update Interrupt source + * @arg TIM_IT_CC1 : TIM Capture Compare 1 Interrupt source + * @arg TIM_IT_CC2 : TIM Capture Compare 2 Interrupt source + * @arg TIM_IT_CC3 : TIM Capture Compare 3 Interrupt source + * @arg TIM_IT_CC4 : TIM Capture Compare 4 Interrupt source + * @arg TIM_IT_COM : TIM Commutation Interrupt source + * @arg TIM_IT_Trigger: TIM Trigger Interrupt source + * @arg TIM_IT_Break : TIM Break Interrupt source + * + * @note TIM2, TIM3, TIM4 and TIM5 can generate TIM_IT_Update, TIM_IT_CC1, + * TIM_IT_CC2, TIM_IT_CC3, TIM_IT_CC4 and TIM_IT_Trigger interrupt. + * @note TIM6 and TIM7 can only generate an update interrupt. + * @note TIM9 and TIM12 can generate TIM_IT_Update, TIM_IT_CC1, TIM_IT_CC2 and + * TIM_IT_Trigger interrupt. + * @note TIM10, TIM11, TIM13 and TIM14 can generate TIM_IT_Update and TIM_IT_CC1 + * interrupt. + * + * @note TIM_IT_Break is used only with TIM1 and TIM8. + * @note TIM_IT_COM is used only with TIM1 and TIM8. + * + * @retval None + */ +void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint32_t TIM_IT) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_TIM_IT(TIM_IT)); + + /* Clear the IT pending Bit */ + TIMx->SR = (uint32_t)~TIM_IT; +} + +/** + * @brief Configures the TIMx's DMA interface. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_DMABase: DMA Base address. + * 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_DCR + * @arg TIM_DMABase_OR + * @arg TIM_DMABase_CCMR3 + * @arg TIM_DMABase_CCR5 + * @arg TIM_DMABase_CCR6 + * @arg TIM_DMABase_AF1 + * @arg TIM_DMABase_AF2 + * @arg TIM_DMABase_TISEL + * @param TIM_DMABurstLength: DMA Burst length. This parameter can be one value + * between: TIM_DMABurstLength_1Transfer and TIM_DMABurstLength_18Transfers. + * @retval None + */ +void TIM_DMAConfig(TIM_TypeDef* TIMx, uint32_t TIM_DMABase, uint32_t TIM_DMABurstLength) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_DMA_BASE(TIM_DMABase)); + assert_param(IS_TIM_DMA_LENGTH(TIM_DMABurstLength)); + + /* Set the DMA Base and the DMA Burst Length */ + TIMx->DCR = TIM_DMABase | TIM_DMABurstLength; +} + +/** + * @brief Enables or disables the TIMx's DMA Requests. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 6, 7 or 8 to select the TIM peripheral. + * @param TIM_DMASource: specifies the DMA Request sources. + * This parameter can be any combination 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 NewState: new state of the DMA Request sources. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void TIM_DMACmd(TIM_TypeDef* TIMx, uint32_t TIM_DMASource, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST6_PERIPH(TIMx)); + assert_param(IS_TIM_DMA_SOURCE(TIM_DMASource)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the DMA sources */ + TIMx->DIER |= TIM_DMASource; + } + else + { + /* Disable the DMA sources */ + TIMx->DIER &= (uint32_t)~TIM_DMASource; + } +} + +/** + * @brief Selects the TIMx peripheral Capture Compare DMA source. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the + * TIM peripheral. + * @param NewState: new state of the Capture Compare DMA source + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void TIM_SelectCCDMA(TIM_TypeDef* TIMx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Set the CCDS Bit */ + TIMx->CR2 |= TIM_CR2_CCDS; + } + else + { + /* Reset the CCDS Bit */ + TIMx->CR2 &= (uint32_t)~((uint32_t)TIM_CR2_CCDS); + } +} + +/** + * @} + */ + +/** + * @brief Configures the TIMx internal Clock + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to + * select the TIM peripheral. + * @retval None + */ +void TIM_InternalClockConfig(TIM_TypeDef* TIMx) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST5_PERIPH(TIMx)); + + /* Disable slave mode to clock the prescaler directly with the internal clock */ + TIMx->SMCR &= (uint32_t)(~((uint32_t)TIM_SMCR_SMS)); +} + +/** + * @brief Configures the TIMx Internal Trigger as External Clock + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select + * the TIM peripheral. + * @param TIM_ITRSource: 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 + * @retval None + */ +void TIM_ITRxExternalClockConfig(TIM_TypeDef* TIMx, uint32_t TIM_InputTriggerSource) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST5_PERIPH(TIMx)); + assert_param(IS_TIM_INTERNAL_TRIGGER_SELECTION(TIM_InputTriggerSource)); + + /* Select the Internal Trigger */ + TIM_SelectInputTrigger(TIMx, TIM_InputTriggerSource); + + /* Select the External clock mode1 */ + TIMx->SMCR |= TIM_SlaveMode_External1; +} + +/** + * @brief Configures the TIMx Trigger as External Clock + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the + * TIM peripheral. + * @param TIM_TIxExternalCLKSource: Trigger source. + * This parameter can be one of the following values: + * @arg TIM_TIxExternalCLK1Source_TI1ED: TI1 Edge Detector + * @arg TIM_TIxExternalCLK1Source_TI1 : Filtered Timer Input 1 + * @arg TIM_TIxExternalCLK1Source_TI2 : Filtered Timer Input 2 + * @param TIM_ICPolarity: specifies the TIx Polarity. + * This parameter can be one of the following values: + * @arg TIM_ICPolarity_Rising + * @arg TIM_ICPolarity_Falling + * @param ICFilter: specifies the filter value. + * This parameter must be a value between 0x0 and 0xF. + * @retval None + */ +void TIM_TIxExternalClockConfig(TIM_TypeDef* TIMx, uint32_t TIM_TIxExternalCLKSource, + uint32_t TIM_ICPolarity, uint32_t ICFilter) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST5_PERIPH(TIMx)); + assert_param(IS_TIM_IC_POLARITY(TIM_ICPolarity)); + assert_param(IS_TIM_IC_FILTER(ICFilter)); + + /* Configure the Timer Input Clock Source */ + if (TIM_TIxExternalCLKSource == TIM_TIxExternalCLK1Source_TI2) + { + TI2_Config(TIMx, TIM_ICPolarity, TIM_ICSelection_DirectTI, ICFilter); + } + else + { + TI1_Config(TIMx, TIM_ICPolarity, TIM_ICSelection_DirectTI, ICFilter); + } + + /* Select the Trigger source */ + TIM_SelectInputTrigger(TIMx, TIM_TIxExternalCLKSource); + + /* Select the External clock mode1 */ + TIMx->SMCR |= TIM_SlaveMode_External1; +} + +/** + * @brief Configures the External clock Mode1 + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_ExtTRGPrescaler: The external Trigger Prescaler. + * This parameter can be one of the following values: + * @arg TIM_ExtTRGPSC_OFF : ETRP Prescaler OFF. + * @arg TIM_ExtTRGPSC_DIV2: ETRP frequency divided by 2. + * @arg TIM_ExtTRGPSC_DIV4: ETRP frequency divided by 4. + * @arg TIM_ExtTRGPSC_DIV8: ETRP frequency divided by 8. + * @param TIM_ExtTRGPolarity: The external Trigger Polarity. + * This parameter can be one of the following values: + * @arg TIM_ExtTRGPolarity_Inverted : active low or falling edge active. + * @arg TIM_ExtTRGPolarity_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_ETRClockMode1Config(TIM_TypeDef* TIMx, uint32_t TIM_ExtTRGPrescaler, uint32_t TIM_ExtTRGPolarity, + uint32_t ExtTRGFilter) +{ + uint32_t tmpsmcr = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_EXT_PRESCALER(TIM_ExtTRGPrescaler)); + assert_param(IS_TIM_EXT_POLARITY(TIM_ExtTRGPolarity)); + assert_param(IS_TIM_EXT_FILTER(ExtTRGFilter)); + + /* Configure the ETR Clock source */ + TIM_ETRConfig(TIMx, TIM_ExtTRGPrescaler, TIM_ExtTRGPolarity, ExtTRGFilter); + + /* Get the TIMx SMCR register value */ + tmpsmcr = TIMx->SMCR; + + /* Reset the SMS Bits */ + tmpsmcr &= (uint32_t)(~((uint32_t)TIM_SMCR_SMS)); + + /* Select the External clock mode1 */ + tmpsmcr |= TIM_SlaveMode_External1; + + /* Select the Trigger selection : ETRF */ + tmpsmcr &= (uint32_t)(~((uint32_t)TIM_SMCR_TS)); + tmpsmcr |= TIM_TS_ETRF; + + /* Write to TIMx SMCR */ + TIMx->SMCR = tmpsmcr; +} + +/** + * @brief Configures the External clock Mode2 + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_ExtTRGPrescaler: The external Trigger Prescaler. + * This parameter can be one of the following values: + * @arg TIM_ExtTRGPSC_OFF : ETRP Prescaler OFF. + * @arg TIM_ExtTRGPSC_DIV2: ETRP frequency divided by 2. + * @arg TIM_ExtTRGPSC_DIV4: ETRP frequency divided by 4. + * @arg TIM_ExtTRGPSC_DIV8: ETRP frequency divided by 8. + * @param TIM_ExtTRGPolarity: The external Trigger Polarity. + * This parameter can be one of the following values: + * @arg TIM_ExtTRGPolarity_Inverted : active low or falling edge active. + * @arg TIM_ExtTRGPolarity_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_ETRClockMode2Config(TIM_TypeDef* TIMx, uint32_t TIM_ExtTRGPrescaler, + uint32_t TIM_ExtTRGPolarity, uint32_t ExtTRGFilter) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_EXT_PRESCALER(TIM_ExtTRGPrescaler)); + assert_param(IS_TIM_EXT_POLARITY(TIM_ExtTRGPolarity)); + assert_param(IS_TIM_EXT_FILTER(ExtTRGFilter)); + + /* Configure the ETR Clock source */ + TIM_ETRConfig(TIMx, TIM_ExtTRGPrescaler, TIM_ExtTRGPolarity, ExtTRGFilter); + + /* Enable the External clock mode2 */ + TIMx->SMCR |= TIM_SMCR_ECE; +} + +/** + * @} + */ +/** + * @brief Selects the Input Trigger source + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to + * select the TIM peripheral. + * @param TIM_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_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 + * + * @note TIM9 and TIM12 don't include TIM_TS_ETRF. + * + * @retval None + */ +void TIM_SelectInputTrigger(TIM_TypeDef* TIMx, uint32_t TIM_InputTriggerSource) +{ + uint32_t tmpsmcr = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST5_PERIPH(TIMx)); + assert_param(IS_TIM_TRIGGER_SELECTION(TIM_InputTriggerSource)); + + /* Get the TIMx SMCR register value */ + tmpsmcr = TIMx->SMCR; + + /* Reset the TS Bits */ + tmpsmcr &= (uint32_t)(~((uint32_t)TIM_SMCR_TS)); + + /* Set the Input Trigger source */ + tmpsmcr |= TIM_InputTriggerSource; + + /* Write to TIMx SMCR */ + TIMx->SMCR = tmpsmcr; +} + +/** + * @brief Selects the TIMx Trigger Output Mode. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 6, 7 or 8 to select the TIM peripheral. + * @param TIM_TRGOSource: specifies the Trigger Output source. + * This parameter can be one of the following values: + * + * - For all TIMx + * @arg TIM_TRGOSource_Reset : The UG bit in the TIM_EGR register is used as the trigger output (TRGO). + * @arg TIM_TRGOSource_Enable: The Counter Enable CEN is used as the trigger output (TRGO). + * @arg TIM_TRGOSource_Update: The update event is selected as the trigger output (TRGO). + * + * - For all TIMx except TIM6 and TIM7 + * @arg TIM_TRGOSource_OC1 : The trigger output sends a positive pulse when the CC1IF flag + * is to be set, as soon as a capture or compare match occurs (TRGO). + * @arg TIM_TRGOSource_OC1Ref: OC1REF signal is used as the trigger output (TRGO). + * @arg TIM_TRGOSource_OC2Ref: OC2REF signal is used as the trigger output (TRGO). + * @arg TIM_TRGOSource_OC3Ref: OC3REF signal is used as the trigger output (TRGO). + * @arg TIM_TRGOSource_OC4Ref: OC4REF signal is used as the trigger output (TRGO). + * + * @retval None + */ +void TIM_SelectOutputTrigger(TIM_TypeDef* TIMx, uint32_t TIM_TRGOSource) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST6_PERIPH(TIMx)); + assert_param(IS_TIM_TRGO_SOURCE(TIM_TRGOSource)); + + /* Reset the MMS Bits */ + TIMx->CR2 &= (uint32_t)~((uint32_t)TIM_CR2_MMS); + + /* Select the TRGO source */ + TIMx->CR2 |= TIM_TRGOSource; +} + +/** + * @brief Selects the TIMx Trigger Output Mode. + * @param TIMx: where x can be 1 or 8 to select the TIM peripheral. + * @param TIM_TRGOSource: specifies the Trigger Output source. + * This parameter can be one of the following values: + * @arg TIM_TRGO2Source_Reset : TIMx_EGR.UG bit is used as trigger output (TRGO2) + * @arg TIM_TRGO2Source_Enable : TIMx_CR1.CEN bit is used as trigger output (TRGO2) + * @arg TIM_TRGO2Source_Update : Update event is used as trigger output (TRGO2) + * @arg TIM_TRGO2Source_OC1 : Capture or a compare match 1 is used as trigger output (TRGO2) + * @arg TIM_TRGO2Source_OC1Ref : OC1REF signal is used as trigger output (TRGO2) + * @arg TIM_TRGO2Source_OC2Ref : OC2REF signal is used as trigger output (TRGO2) + * @arg TIM_TRGO2Source_OC3Ref : OC3REF signal is used as trigger output (TRGO2) + * @arg TIM_TRGO2Source_OC4Ref : OC4REF signal is used as trigger output (TRGO2) + * @arg TIM_TRGO2Source_OC5Ref : OC5REF signal is used as trigger output (TRGO2) + * @arg TIM_TRGO2Source_OC6Ref : OC6REF signal is used as trigger output (TRGO2) + * @arg TIM_TRGO2Source_OC4Ref_RisingFalling : OC4REF rising or falling edges generate pulses on TRGO2 + * @arg TIM_TRGO2Source_OC6Ref_RisingFalling : OC6REF rising or falling edges generate pulses on TRGO2 + * @arg TIM_TRGO2Source_OC4Ref_Rising_OC6Ref_Rising : OC4REF or OC6REF rising edges generate pulses on TRGO2 + * @arg TIM_TRGO2Source_OC4Ref_Rising_OC6Ref_Falling: OC4REF rising or OC6REF falling edges generate pulses on TRGO2 + * @arg TIM_TRGO2Source_OC5Ref_Rising_OC6Ref_Rising : OC5REF or OC6REF rising edges generate pulses on TRGO2 + * @arg TIM_TRGO2Source_OC5Ref_Rising_OC6Ref_Falling: OC5REF or OC6REF rising edges generate pulses on TRGO2 + * + * @retval None + */ +void TIM_SelectOutputTrigger2(TIM_TypeDef* TIMx, uint32_t TIM_TRGO2Source) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_TIM_TRGO2_SOURCE(TIM_TRGO2Source)); + + /* Reset the MMS Bits */ + TIMx->CR2 &= (uint32_t)~((uint32_t)TIM_CR2_MMS2); + + /* Select the TRGO source */ + TIMx->CR2 |= TIM_TRGO2Source; +} + +/** + * @brief Selects the TIMx Slave Mode. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM peripheral. + * @param TIM_SlaveMode: specifies the Timer Slave Mode. + * This parameter can be one of the following values: + * @arg TIM_SlaveMode_Reset : Rising edge of the selected trigger signal (TRGI) re-initializes + * the counter and triggers an update of the registers. + * @arg TIM_SlaveMode_Gated : The counter clock is enabled when the trigger signal (TRGI) is high. + * @arg TIM_SlaveMode_Trigger : The counter starts at a rising edge of the trigger TRGI. + * @arg TIM_SlaveMode_External1: Rising edges of the selected trigger (TRGI) clock the counter. + * @retval None + */ +void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint32_t TIM_SlaveMode) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST5_PERIPH(TIMx)); + assert_param(IS_TIM_SLAVE_MODE(TIM_SlaveMode)); + + /* Reset the SMS Bits */ + TIMx->SMCR &= (uint32_t)~((uint32_t)TIM_SMCR_SMS); + + /* Select the Slave Mode */ + TIMx->SMCR |= TIM_SlaveMode; +} + +/** + * @brief Sets or Resets the TIMx Master/Slave Mode. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM peripheral. + * @param TIM_MasterSlaveMode: specifies the Timer Master Slave Mode. + * This parameter can be one of the following values: + * @arg TIM_MasterSlaveMode_Enable : synchronization between the current timer + * and its slaves (through TRGO). + * @arg TIM_MasterSlaveMode_Disable: No action + * @retval None + */ +void TIM_SelectMasterSlaveMode(TIM_TypeDef* TIMx, uint32_t TIM_MasterSlaveMode) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST5_PERIPH(TIMx)); + assert_param(IS_TIM_MSM_STATE(TIM_MasterSlaveMode)); + + /* Reset the MSM Bit */ + TIMx->SMCR &= (uint32_t)~((uint32_t)TIM_SMCR_MSM); + + /* Set or Reset the MSM Bit */ + TIMx->SMCR |= TIM_MasterSlaveMode; +} + +/** + * @brief Configures the TIMx External Trigger (ETR). + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_ExtTRGPrescaler: The external Trigger Prescaler. + * This parameter can be one of the following values: + * @arg TIM_ExtTRGPSC_OFF : ETRP Prescaler OFF. + * @arg TIM_ExtTRGPSC_DIV2: ETRP frequency divided by 2. + * @arg TIM_ExtTRGPSC_DIV4: ETRP frequency divided by 4. + * @arg TIM_ExtTRGPSC_DIV8: ETRP frequency divided by 8. + * @param TIM_ExtTRGPolarity: The external Trigger Polarity. + * This parameter can be one of the following values: + * @arg TIM_ExtTRGPolarity_Inverted: active low or falling edge active. + * @arg TIM_ExtTRGPolarity_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_ETRConfig(TIM_TypeDef* TIMx, uint32_t TIM_ExtTRGPrescaler, uint32_t TIM_ExtTRGPolarity, + uint32_t ExtTRGFilter) +{ + uint32_t tmpsmcr = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_EXT_PRESCALER(TIM_ExtTRGPrescaler)); + assert_param(IS_TIM_EXT_POLARITY(TIM_ExtTRGPolarity)); + assert_param(IS_TIM_EXT_FILTER(ExtTRGFilter)); + + tmpsmcr = TIMx->SMCR; + + /* Reset the ETR Bits */ + tmpsmcr &= SMCR_ETR_MASK; + + /* Set the Prescaler, the Filter value and the Polarity */ + tmpsmcr |= (uint32_t)(TIM_ExtTRGPrescaler | (uint32_t)(TIM_ExtTRGPolarity | (uint32_t)(ExtTRGFilter << (uint32_t)8))); + + /* Write to TIMx SMCR */ + TIMx->SMCR = tmpsmcr; +} + +/** + * @} + */ +/** + * @brief Configures the TIMx Encoder Interface. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_EncoderMode: specifies the TIMx Encoder Mode. + * This parameter can be one of the following values: + * @arg TIM_EncoderMode_TI1 : counts up/down on TI2FP2 edge depending on TI1FP1 level. + * @arg TIM_EncoderMode_TI2 : counts up/down on TI1FP1 edge depending on TI2FP2 level. + * @arg TIM_EncoderMode_TI12: Counter counts on both TI1FP1 and TI2FP2 edges depending + * on the level of the other input. + * @param TIM_IC1Polarity: specifies the IC1 Polarity + * This parmeter can be one of the following values: + * @arg TIM_ICPolarity_Falling: IC Falling edge. + * @arg TIM_ICPolarity_Rising : IC Rising edge. + * @param TIM_IC2Polarity: specifies the IC2 Polarity + * This parmeter can be one of the following values: + * @arg TIM_ICPolarity_Falling: IC Falling edge. + * @arg TIM_ICPolarity_Rising : IC Rising edge. + * @retval None + */ +void TIM_EncoderInterfaceConfig(TIM_TypeDef* TIMx, uint32_t TIM_EncoderMode, + uint32_t TIM_IC1Polarity, uint32_t TIM_IC2Polarity) +{ + uint32_t tmpsmcr = 0; + uint32_t tmpccmr1 = 0; + uint32_t tmpccer = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_ENCODER_MODE(TIM_EncoderMode)); + assert_param(IS_TIM_IC_POLARITY(TIM_IC1Polarity)); + assert_param(IS_TIM_IC_POLARITY(TIM_IC2Polarity)); + + /* Get the TIMx SMCR register value */ + tmpsmcr = TIMx->SMCR; + + /* Get the TIMx CCMR1 register value */ + tmpccmr1 = TIMx->CCMR1; + + /* Get the TIMx CCER register value */ + tmpccer = TIMx->CCER; + + /* Set the encoder Mode */ + tmpsmcr &= (uint32_t)(~((uint32_t)TIM_SMCR_SMS)); + tmpsmcr |= TIM_EncoderMode; + + /* Select the Capture Compare 1 and the Capture Compare 2 as input */ + tmpccmr1 &= (uint32_t)(((uint32_t)~((uint32_t)TIM_CCMR1_CC1S)) & (uint32_t)(~((uint32_t)TIM_CCMR1_CC2S))); + tmpccmr1 |= TIM_CCMR1_CC1S_0 | TIM_CCMR1_CC2S_0; + + /* Set the TI1 and the TI2 Polarities */ + tmpccer &= (uint32_t)~((uint32_t)(TIM_CCER_CC1P | TIM_CCER_CC1NP)) & (uint32_t)~((uint32_t)(TIM_CCER_CC2P | TIM_CCER_CC2NP)); + tmpccer |= (uint32_t)(TIM_IC1Polarity | (uint32_t)(TIM_IC2Polarity << (uint32_t)4)); + + /* Write to TIMx SMCR */ + TIMx->SMCR = tmpsmcr; + + /* Write to TIMx CCMR1 */ + TIMx->CCMR1 = tmpccmr1; + + /* Write to TIMx CCER */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Enables or disables the TIMx's Hall sensor interface. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param NewState: new state of the TIMx Hall sensor interface. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void TIM_SelectHallSensor(TIM_TypeDef* TIMx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Set the TI1S Bit */ + TIMx->CR2 |= TIM_CR2_TI1S; + } + else + { + /* Reset the TI1S Bit */ + TIMx->CR2 &= (uint32_t)~((uint32_t)TIM_CR2_TI1S); + } +} + +/** + * @} + */ + +/** + * @brief Configures the TIM2 or TIM11 OR register Remapping input Capabilities. + * @param TIMx: where x can be 2 or 11 to select the TIM peripheral. + * @param TIM_Remap: specifies the TIM input reampping source. + * This parameter can be one of the following values: + * + * - For TIM2 + * @arg TIM2_ITR1ConnectTIM8Trgo: TIM8 TRGO is connected to TIM2_ITR1 input + * @arg TIM2_ITR1ConnectPTPTrgo : PTP TRGO is connected to TIM2_ITR1 input + * @arg TIM2_ITR1ConnectOTGFSSOF: OTG FS SOF is connected to TIM2_ITR1 input + * @arg TIM2_ITR1ConnectOTGHSSOF: OTG HS SOF is connected to TIM2_ITR1 input + * + * - For TIM11 + * @arg TIM11_IT1ConnectGPIO_0 : TIM11 GPIO is connected to TIM11_TI1 input + * @arg TIM11_IT1ConnectGPIO_1 : TIM11 GPIO is connected to TIM11_TI1 input + * @arg TIM11_IT1ConnectHSE_RTC: HSE RTC clock is connected to TIM11_TI1 input + * @arg TIM11_IT1ConnectGPIO_3 : TIM11 GPIO is connected to TIM11_TI1 input + * + * @retval None + */ +void TIM_RemapConfig(TIM_TypeDef* TIMx, uint32_t TIM_Remap) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST7_PERIPH(TIMx)); + + /* Check the parameters - TIM_Remap */ + if (TIMx == TIM2) + { + assert_param(IS_TIM2_ITR1REMAP(TIM_Remap)); + } + else + { + assert_param(IS_TIM11_ITR1REMAP(TIM_Remap)); + } + + /* Clear the Timer ITR1_RMP or IT1_RMP remapping configuration */ + if (TIMx == TIM2) + { + TIMx->OR &= (uint32_t)(~(3 << (uint32_t)10)); + } + else + { + TIMx->OR &= (uint32_t)(~(3 << (uint32_t)0)); + } + + /* Set the Timer remapping configuration */ + if (TIMx == TIM2) + { + TIMx->OR = (uint32_t)(TIM_Remap << (uint32_t)10); + } + else + { + TIMx->OR = TIM_Remap; + } +} + +/** + * @brief Configures the TIMx ETRSEL[3:0] bits of AF1 register Remapping input Capabilities. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_ETRSel_Remap: specifies the TIM etrsel input reampping source. + * This parameter can be one of the following values: + * + * - For TIM1 and TIM8 + * @arg TIM_ETR_GPIO : ETR input is connected to GPIO + * @arg TIM_ETR_COMP1 : ETR input is connected to COMP1_OUT + * @arg TIM_ETR_COMP2 : ETR input is connected to COMP2_OUT + * @arg TIM_ETR_COMP3 : ETR input is connected to COMP3_OUT + * @arg TIM_ETR_COMP4 : ETR input is connected to COMP4_OUT + * @arg TIM_ETR_COMP5 : ETR input is connected to COMP5_OUT + * @arg TIM_ETR_COMP6 : ETR input is connected to COMP6_OUT + * @arg TIM_ETR_ADC1_AWD1: ETR input is connected to ADC1 analog watchdog 1 + * @arg TIM_ETR_ADC1_AWD2: ETR input is connected to ADC1 analog watchdog 2 + * @arg TIM_ETR_ADC1_AWD3: ETR input is connected to ADC1 analog watchdog 3 + * @arg TIM_ETR_ADC2_AWD1: ETR input is connected to ADC2 analog watchdog 1 + * @arg TIM_ETR_ADC2_AWD2: ETR input is connected to ADC2 analog watchdog 2 + * @arg TIM_ETR_ADC2_AWD3: ETR input is connected to ADC2 analog watchdog 3 + * @arg TIM_ETR_ADC3_AWD1: ETR input is connected to ADC3 analog watchdog 1 + * @arg TIM_ETR_ADC3_AWD2: ETR input is connected to ADC3 analog watchdog 2 + * @arg TIM_ETR_ADC3_AWD3: ETR input is connected to ADC3 analog watchdog 3 + * + * - For TIM2, TIM3, TIM4 and TIM5 + * @arg TIM_ETR_GPIO: ETR input is connected to GPIO + * @arg TIM_ETR_1 : ETR input is connected to ETR[ 1] + * @arg TIM_ETR_2 : ETR input is connected to ETR[ 2] + * @arg TIM_ETR_3 : ETR input is connected to ETR[ 3] + * @arg TIM_ETR_4 : ETR input is connected to ETR[ 4] + * @arg TIM_ETR_5 : ETR input is connected to ETR[ 5] + * @arg TIM_ETR_6 : ETR input is connected to ETR[ 6] + * @arg TIM_ETR_7 : ETR input is connected to ETR[ 7] + * @arg TIM_ETR_8 : ETR input is connected to ETR[ 8] + * @arg TIM_ETR_9 : ETR input is connected to ETR[ 9] + * @arg TIM_ETR_10 : ETR input is connected to ETR[10] + * @arg TIM_ETR_11 : ETR input is connected to ETR[11] + * @arg TIM_ETR_12 : ETR input is connected to ETR[12] + * @arg TIM_ETR_13 : ETR input is connected to ETR[13] + * @arg TIM_ETR_14 : ETR input is connected to ETR[14] + * @arg TIM_ETR_15 : ETR input is connected to ETR[15] + * + * @retval None + */ +void TIM_ETRSelRemapConfig(TIM_TypeDef* TIMx, uint32_t TIM_ETRSel_Remap) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + + /* Check the parameters - TIM_ETRSel_Remap */ + if ((TIMx == TIM1) || (TIMx == TIM8)) + { + assert_param(IS_TIM_ETRSEL_LIST1_REMAP(TIM_ETRSel_Remap)); + } + else + { + if ((TIMx == TIM2) || (TIMx == TIM3) || (TIMx == TIM4) || (TIMx == TIM5)) + { + assert_param(IS_TIM_ETRSEL_LIST2_REMAP(TIM_ETRSel_Remap)); + } + } + + /* Clear the Timer ETRSEL remapping configuration */ + TIMx->AF1 &= (uint32_t)(~TIM_AF1_ETRSEL); + + /* Set the Timer ETRSEL remapping configuration */ + TIMx->AF1 |= TIM_ETRSel_Remap; +} + +/** + * @brief Configures the TIMx OCRSEL[2:0] bits of AF2 register Remapping input Capabilities. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_OCRSel_Remap: specifies the TIM ocrsel input reampping source. + * This parameter can be one of the following values: + * + * - For TIM1 and TIM8 + * @arg TIM_OCR_COMP1: OCxref clear source select COMP1_OUT + * @arg TIM_OCR_COMP2: OCxref clear source select COMP2_OUT + * @arg TIM_OCR_COMP3: OCxref clear source select COMP3_OUT + * @arg TIM_OCR_COMP4: OCxref clear source select COMP4_OUT + * @arg TIM_OCR_COMP5: OCxref clear source select COMP5_OUT + * @arg TIM_OCR_COMP6: OCxref clear source select COMP6_OUT + * + * - For TIM2, TIM3, TIM4 and TIM5 + * @arg TIM_OCR_CLEAR_0: OCxref clear source select ocrefcr[0] + * @arg TIM_OCR_CLEAR_1: OCxref clear source select ocrefcr[1] + * @arg TIM_OCR_CLEAR_2: OCxref clear source select ocrefcr[2] + * @arg TIM_OCR_CLEAR_3: OCxref clear source select ocrefcr[3] + * @arg TIM_OCR_CLEAR_4: OCxref clear source select ocrefcr[4] + * @arg TIM_OCR_CLEAR_5: OCxref clear source select ocrefcr[5] + * @arg TIM_OCR_CLEAR_6: OCxref clear source select ocrefcr[6] + * @arg TIM_OCR_CLEAR_7: OCxref clear source select ocrefcr[7] + * + * @retval None + */ +void TIM_OCRSelRemapConfig(TIM_TypeDef* TIMx, uint32_t TIM_OCRSel_Remap) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + + /* Check the parameters - TIM_OCRSel_Remap */ + if ((TIMx == TIM1) || (TIMx == TIM8)) + { + assert_param(IS_TIM_OCRSEL_LIST1_REMAP(TIM_OCRSel_Remap)); + } + else + { + if ((TIMx == TIM2) || (TIMx == TIM3) || (TIMx == TIM4) || (TIMx == TIM5)) + { + assert_param(IS_TIM_OCRSEL_LIST2_REMAP(TIM_OCRSel_Remap)); + } + } + + /* Clear the Timer OCRSEL remapping configuration */ + if ((TIMx == TIM1) || (TIMx == TIM8)) + { + TIMx->AF2 &= (uint32_t)(~(7 << (uint32_t)0)); + } + else + { + if ((TIMx == TIM2) || (TIMx == TIM3) || (TIMx == TIM4) || (TIMx == TIM5)) + { + TIMx->AF2 &= (uint32_t)(~(TIM_AF2_OCRSEL)); + } + } + + /* Set the Timer OCRSEL remapping configuration */ + TIMx->AF2 |= TIM_OCRSel_Remap; +} + +/** + * @brief Configures the TIMx TIxSEL[2:0] bits of TISEL register Remapping input Capabilities. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIxSEL: where x can be 1, 2, 3 or 4 to select the TIM TISEL. + * @param TIM_TISel_Channel: specifies the TIM tisel input channel select. + * This parameter can be one of the following values: + * + * - For TIM1 and TIM8 + * @arg TIM_TISel_Channel1 + * + * - For TIM2, TIM3, TIM4 and TIM5 + * @arg TIM_TISel_Channel1 + * @arg TIM_TISel_Channel2 + * @arg TIM_TISel_Channel3 + * @arg TIM_TISel_Channel4 + * + * @param TIM_TISel_Remap: specifies the TIM tisel input reampping source. + * This parameter can be one of the following values: + * + * - For TIM1 and TIM8 + * @arg TIM_TI1_CH1 : TIM_CH1 input select GPIO + * @arg TIM_TI1_COMP1: TIM_CH1 input select COMP1_OUT + * @arg TIM_TI1_COMP2: TIM_CH1 input select COMP2_OUT + * @arg TIM_TI1_COMP3: TIM_CH1 input select COMP3_OUT + * @arg TIM_TI1_COMP4: TIM_CH1 input select COMP4_OUT + * @arg TIM_TI1_COMP5: TIM_CH1 input select COMP5_OUT + * @arg TIM_TI1_COMP6: TIM_CH1 input select COMP6_OUT + * + * - For TIM2, TIM3, TIM4 and TIM5 + * @arg TIM_TI_CH : TIM_CH input select GPIO + * @arg TIM_TI_I1 : TIM_CH input select ti_i[ 1] + * @arg TIM_TI_I2 : TIM_CH input select ti_i[ 2] + * @arg TIM_TI_I3 : TIM_CH input select ti_i[ 3] + * @arg TIM_TI_I4 : TIM_CH input select ti_i[ 4] + * @arg TIM_TI_I5 : TIM_CH input select ti_i[ 5] + * @arg TIM_TI_I6 : TIM_CH input select ti_i[ 6] + * @arg TIM_TI_I7 : TIM_CH input select ti_i[ 7] + * @arg TIM_TI_I8 : TIM_CH input select ti_i[ 8] + * @arg TIM_TI_I9 : TIM_CH input select ti_i[ 9] + * @arg TIM_TI_I10: TIM_CH input select ti_i[10] + * @arg TIM_TI_I11: TIM_CH input select ti_i[11] + * @arg TIM_TI_I12: TIM_CH input select ti_i[12] + * @arg TIM_TI_I13: TIM_CH input select ti_i[13] + * @arg TIM_TI_I14: TIM_CH input select ti_i[14] + * @arg TIM_TI_I15: TIM_CH input select ti_i[15] + * + * @retval None + */ +void TIM_TISelRemapConfig(TIM_TypeDef* TIMx, uint32_t TIM_TISel_Channel, uint32_t TIM_TISel_Remap) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + + /* Check the parameters - TIM_TISel_Remap */ + if ((TIMx == TIM1) || (TIMx == TIM8)) + { + assert_param(IS_TIM_TISEL_LIST1_REMAP(TIM_TISel_Remap)); + } + else + { + if ((TIMx == TIM2) || (TIMx == TIM3) || (TIMx == TIM4) || (TIMx == TIM5)) + { + assert_param(IS_TIM_TISEL_LIST2_REMAP(TIM_TISel_Remap)); + } + } + + /* Clear the Timer TISEL remapping configuration */ + if ((TIMx == TIM1) || (TIMx == TIM8)) + { + TIMx->TISEL &= (uint32_t)(~(7 << (uint32_t)TIM_TISel_Channel1)); + } + else + { + if ((TIMx == TIM2) || (TIMx == TIM3) || (TIMx == TIM4) || (TIMx == TIM5)) + { + TIMx->TISEL &= (uint32_t)(~(TIM_TISEL_TI1SEL << TIM_TISel_Channel)); + } + } + + /* Set the Timer TIxSEL remapping configuration */ + if ((TIMx == TIM1) || (TIMx == TIM8)) + { + TIMx->TISEL |= (uint32_t)((TIM_TISel_Remap << (uint32_t)TIM_TISel_Channel1)); + } + else + { + if ((TIMx == TIM2) || (TIMx == TIM3) || (TIMx == TIM4) || (TIMx == TIM5)) + { + TIMx->TISEL |= (uint32_t)((TIM_TISel_Remap << TIM_TISel_Channel)); + } + } +} + +/** + * @} + */ + +/** + * @brief Configure the TI1 as Input. + * @param TIMx: where x can from 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13 or 14 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 + * @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 + */ +static void TI1_Config(TIM_TypeDef* TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection, + uint32_t TIM_ICFilter) +{ + uint32_t tmpccmr1 = 0, tmpccer = 0; + + /* Disable the Channel 1: Reset the CC1E Bit */ + TIMx->CCER &= (uint32_t)~((uint32_t)TIM_CCER_CC1E); + tmpccmr1 = TIMx->CCMR1; + tmpccer = TIMx->CCER; + + /* Select the Input and set the filter */ + tmpccmr1 &= (uint32_t)(((uint32_t)~((uint32_t)TIM_CCMR1_CC1S)) & ((uint32_t)~((uint32_t)TIM_CCMR1_IC1F))); + tmpccmr1 |= (uint32_t)(TIM_ICSelection | (uint32_t)(TIM_ICFilter << (uint32_t)4)); + + /* Select the Polarity and set the CC1E Bit */ + tmpccer &= (uint32_t)~((uint32_t)(TIM_CCER_CC1P | TIM_CCER_CC1NP)); + tmpccer |= (uint32_t)(TIM_ICPolarity | (uint32_t)TIM_CCER_CC1E); + + /* Write to TIMx CCMR1 and CCER registers */ + TIMx->CCMR1 = tmpccmr1; + TIMx->CCER = tmpccer; +} + +/** + * @brief Configure the TI2 as Input. + * @param TIMx: where x can from 1, 2, 3, 4, 5, 8, 9 or 12 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 + * @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 + */ +static void TI2_Config(TIM_TypeDef* TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection, + uint32_t TIM_ICFilter) +{ + uint32_t tmpccmr1 = 0, tmpccer = 0, tmp = 0; + + /* Disable the Channel 2: Reset the CC2E Bit */ + TIMx->CCER &= (uint32_t)~((uint32_t)TIM_CCER_CC2E); + tmpccmr1 = TIMx->CCMR1; + tmpccer = TIMx->CCER; + tmp = (uint32_t)(TIM_ICPolarity << 4); + + /* Select the Input and set the filter */ + tmpccmr1 &= (uint32_t)(((uint32_t)~((uint32_t)TIM_CCMR1_CC2S)) & ((uint32_t)~((uint32_t)TIM_CCMR1_IC2F))); + tmpccmr1 |= (uint32_t)(TIM_ICFilter << 12); + tmpccmr1 |= (uint32_t)(TIM_ICSelection << 8); + + /* Select the Polarity and set the CC2E Bit */ + tmpccer &= (uint32_t)~((uint32_t)(TIM_CCER_CC2P | TIM_CCER_CC2NP)); + tmpccer |= (uint32_t)(tmp | (uint32_t)TIM_CCER_CC2E); + + /* Write to TIMx CCMR1 and CCER registers */ + TIMx->CCMR1 = tmpccmr1 ; + TIMx->CCER = tmpccer; +} + +/** + * @brief Configure the TI3 as Input. + * @param TIMx: where x can from 1, 2, 3, 4, 5 or 8 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 + * @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 + */ +static void TI3_Config(TIM_TypeDef* TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection, + uint32_t TIM_ICFilter) +{ + uint32_t tmpccmr2 = 0, tmpccer = 0, tmp = 0; + + /* Disable the Channel 3: Reset the CC3E Bit */ + TIMx->CCER &= (uint32_t)~((uint32_t)TIM_CCER_CC3E); + tmpccmr2 = TIMx->CCMR2; + tmpccer = TIMx->CCER; + tmp = (uint32_t)(TIM_ICPolarity << 8); + + /* Select the Input and set the filter */ + tmpccmr2 &= (uint32_t)(((uint32_t)~((uint32_t)TIM_CCMR2_CC3S)) & ((uint32_t)~((uint32_t)TIM_CCMR2_IC3F))); + tmpccmr2 |= (uint32_t)(TIM_ICSelection | (uint32_t)(TIM_ICFilter << (uint32_t)4)); + + /* Select the Polarity and set the CC3E Bit */ + tmpccer &= (uint32_t)~((uint32_t)(TIM_CCER_CC3P | TIM_CCER_CC3NP)); + tmpccer |= (uint32_t)(tmp | (uint32_t)TIM_CCER_CC3E); + + /* Write to TIMx CCMR2 and CCER registers */ + TIMx->CCMR2 = tmpccmr2; + TIMx->CCER = tmpccer; +} + +/** + * @brief Configure the TI4 as Input. + * @param TIMx: where x can from 1, 2, 3, 4, 5 or 8 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 + * @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. + * @retval None + */ +static void TI4_Config(TIM_TypeDef* TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection, + uint32_t TIM_ICFilter) +{ + uint32_t tmpccmr2 = 0, tmpccer = 0, tmp = 0; + + /* Disable the Channel 4: Reset the CC4E Bit */ + TIMx->CCER &= (uint32_t)~((uint32_t)TIM_CCER_CC4E); + tmpccmr2 = TIMx->CCMR2; + tmpccer = TIMx->CCER; + tmp = (uint32_t)(TIM_ICPolarity << 12); + + /* Select the Input and set the filter */ + tmpccmr2 &= (uint32_t)((uint32_t)(~(uint32_t)TIM_CCMR2_CC4S) & ((uint32_t)~((uint32_t)TIM_CCMR2_IC4F))); + tmpccmr2 |= (uint32_t)(TIM_ICSelection << 8); + tmpccmr2 |= (uint32_t)(TIM_ICFilter << 12); + + /* Select the Polarity and set the CC4E Bit */ + tmpccer &= (uint32_t)~((uint32_t)(TIM_CCER_CC4P)); + tmpccer |= (uint32_t)(tmp | (uint32_t)TIM_CCER_CC4E); + + /* Write to TIMx CCMR2 and CCER registers */ + TIMx->CCMR2 = tmpccmr2; + TIMx->CCER = tmpccer; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_uart.c b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_uart.c new file mode 100644 index 00000000000..f30398bc1cd --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_uart.c @@ -0,0 +1,2391 @@ +/** + ****************************************************************************** + * @file ft32f4xx_uart.c + * @author FMD AE + * @brief This file provides firmware functions to manage the following + * functionalities of the Universal Asynchronous Receiver Transmitter + * Peripheral (UART) and the Low-Power Universal Asynchronous Receiver + * Transmitter Peripheral (LPUART). + * + Initialization and de-initialization functions + * + Normal command and configuration functions + * + Fractional baudrate function + * + Break command functions + * + Receiver time-out and transmitter timeguard functions + * + Multidrop mode command function + * + IrDA mode function + * + LIN mode functions + * + Data transfers functions + * + DMA transfers management functions + * + Low-Power SLEEP and STOP wakeup management functions + * + Interrupts and flags management functions + * @version V1.0.0 + * @date 2025-03-28 + * + @verbatim + * + * [..] + * The functionalities supported by different UART and LPUART are listed in following: + * + * Table 1. UART / LPUART feature. + * +---------------------------------------------------------+ + * | Functionalities | UART4 | UART5 | UART7 | LPUART | + * |---------------------------------------------------------+ + * | DMA Communication | X | X | X | X | + * |---------------------------------------------------------+ + * | IrDA mode | X | X | X | - | + * |---------------------------------------------------------+ + * | Low-Power wakeup | X | X | X | X | + * |---------------------------------------------------------+ + * | LIN mode | X | X | X | - | + * |---------------------------------------------------------+ + * | Fractional baudrate | X | X | - | - | + * |---------------------------------------------------------+ + * | Timeguard and Time-out | X | X | X | - | + * |---------------------------------------------------------+ + * | Multidrop mode | X | X | X | X | + * |---------------------------------------------------------+ + * + * [+] X - Supported + * [+] - - Not supported + * [+] Low-Power wakeup: UART can wakeup from SLEEP mode. + * LPUART can wakeup from SLEEP and STOP mode. + * + @endverbatim + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx_uart.h" +#include "ft32f4xx_rcc.h" + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @defgroup UART_Private_Constants UART Private Constants + * @{ + */ +/*!< UART and LPUART CR register mode field Mask ((~(uint32_t)0xFFFFFF5F)) */ +#define CR_CLEAR_MODE_MASK ((uint32_t)(USART_CR_TXDIS | USART_CR_RXDIS)) /*!< UART CR mode fields of parameters set by UART_Init API */ + +/*!< UART and LPUART MR register normal Mask ((~(uint32_t)0xFF740100)) */ +#define MR_CLEAR_NORMAL_MASK ((uint32_t)(USART_MR_INVDATA | USART_MR_OVER | \ + USART_MR_MODE9 | \ + USART_MR_MSBF | USART_MR_CHMODE | \ + USART_MR_NBSTOP | USART_MR_PAR | \ + USART_MR_CHRL | \ + USART_MR_USCLKS | USART_MR_USART_MODE))/*!< UART MR normal fields of parameters set by UART_Init API */ + +/** + * @} + */ + +/** @defgroup UART and LPUAR init and de-init functions + * @brief None + * +@verbatim + =============================================================================== + ##### Init and DeInit Functions ##### + =============================================================================== + [..] This subsection provides a set of functions about UART and LPUART + initialization and de-initialization. + + [..] Most UART and LPUART configurations can be set in the UART_init() function. + However, After UART_Init() function, user can use others configurations + (cfg) functions to change UART and LPUART configurational. The command (Cmd) + functions can execute control operations under different configurations. + + [..] The configuration procedure of UART_Init() function is as follows: + (++) Check the parameters + (++) Enable UARTx and LPUART work clock and configuration clock. + (++) UART and LPUART CR configuration + (#) Configure the UART_Mode: + (-) transmitter disable + (-) transmitter enable + (-) receiver disable + (-) receiver enable + (++) UART and LPUART MR configuration + (#) Normal configuration: + (-) Inverted data + (-) Oversampling mode + (-) 9-bit character length + (-) Bit order + (-) channel mode + (-) Number of STOP bits + (-) Parity type + (-) Character length + (-) Clock selection + (-) UART mode of operation + (++) UART BRGR configuration except fractional part + (++) UART IF configuration + (++) UART LINMR configuration: + (-) Synchronization disable + (-) DMA mode + (-) Data length control + (-) Wakeup signal type + (-) Frame slot mode disable + (-) Data length mode + (-) Checksum type + (-) Checksum disable + (-) Parity disable + (-) LIN node action + + [..] + + (#) The UART and LPUART init API's : + (++) UART_Init() + + (#) The UART and LPUART Struct init API's : + (++) UART_StructInit() + + (#) The UART and LPUART de-init API's : + (++) UART_DeInit() +@endverbatim + * @{ + */ + +/** + * @brief Initialize the UART and LPUART peripheral according to the specified + * parameters in the UART_InitStruct. + * @param UARTx: Select UART peripheral from among UART4, UART5, UART7 and LPUART. + * @param UART_InitStruct: pointer to a UART_InitTypeDef structure that contains + * the configuration information for the specified UART peripheral. + * @retval None + */ +void UART_Init(USART_TypeDef* UARTx, UART_InitTypeDef* UART_InitStruct) +{ + uint32_t clock_divider = 0, frac_divider = 0, apbclock = 0, tmpreg = 0; + + RCC_ClocksTypeDef RCC_ClocksStatus; + + /*---------------------------- Check the Parameter -------------------------*/ + /* Check UART PERIPH */ + if ((UART_InitStruct->UART_OperationMode == UART_MODE_OPERATION_IrDA) || + (UART_InitStruct->UART_OperationMode == UART_MODE_OPERATION_LIN_MASTER) || + (UART_InitStruct->UART_OperationMode == UART_MODE_OPERATION_LIN_SLAVE)) + { + assert_param(IS_UART_457_PERIPH(UARTx)); + } + else if (UART_InitStruct->UART_OperationMode == UART_MODE_OPERATION_NORMAL) + { + assert_param(IS_UART_ALL_PERIPH(UARTx)); + } + + if (UART_InitStruct->UART_INVData == UART_INVDATA_ENABLE) + { + assert_param(IS_UART_457_PERIPH(UARTx)); + } + else + { + assert_param(IS_UART_ALL_PERIPH(UARTx)); + } + + /* Check normal parameter*/ + assert_param(IS_UART_BAUDRATE(UART_InitStruct->UART_BaudRate)); + assert_param(IS_UART_CHAR_LENGTH(UART_InitStruct->UART_WordLength)); + assert_param(IS_UART_STOPBITS(UART_InitStruct->UART_StopBits)); + assert_param(IS_UART_PARITY(UART_InitStruct->UART_Parity)); + assert_param(IS_UART_MODE(UART_InitStruct->UART_Mode)); + assert_param(IS_UART_CLOCK_SELECT(UART_InitStruct->UART_CLKSelect)); + assert_param(IS_UART_MODE_OPERATION(UART_InitStruct->UART_OperationMode)); + assert_param(IS_UART_BIT_ORDER(UART_InitStruct->UART_BitOrder)); + assert_param(IS_UART_CHANNEL_MODE(UART_InitStruct->UART_ChannelMode)); + assert_param(IS_UART_OVERSAMPLING(UART_InitStruct->UART_OverSampling)); + assert_param(IS_UART_INVDATA(UART_InitStruct->UART_INVData)); + + /* Check IrDA mode parameter */ + if (UART_InitStruct->UART_OperationMode == UART_MODE_OPERATION_IrDA) + { + assert_param(IS_UART_IF(UART_InitStruct->UART_IrDAFilter)); + assert_param(IS_UART_FIDIRATIO(UART_InitStruct->UART_FiDiRatio)); + } + + /* Check LIN mode parameter*/ + if ((UART_InitStruct->UART_OperationMode == UART_MODE_OPERATION_LIN_MASTER) || + (UART_InitStruct->UART_OperationMode == UART_MODE_OPERATION_LIN_SLAVE)) + { + assert_param(IS_UART_SYNC_DISABLE(UART_InitStruct->UART_SYNCDisable)); + assert_param(IS_UART_PDC_MODE_LINMR(UART_InitStruct->UART_PDCMode)); + assert_param(IS_UART_DLC(UART_InitStruct->UART_DataLengthControl)); + assert_param(IS_UART_WKUP_TYPE(UART_InitStruct->UART_WkupType)); + assert_param(IS_UART_FRAME_SLOT_DISABLE(UART_InitStruct->UART_FrameSlotDisable)); + assert_param(IS_UART_DATA_LENGTH_MODE(UART_InitStruct->UART_DataLengthMode)); + assert_param(IS_UART_CHECKSUM_TYPE(UART_InitStruct->UART_CheckSumType)); + assert_param(IS_UART_CHECKSUM_DISABLE(UART_InitStruct->UART_CheckSumDisable)); + assert_param(IS_UART_PARITY_DISABLE(UART_InitStruct->UART_ParityDisable)); + assert_param(IS_UART_NODE_ACTIVE(UART_InitStruct->UART_NodeAction)); + } + + /*--------------------------- Enable The Peripheral ------------------------*/ + if (UARTx == UART4) + { + RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE); + } + else if (UARTx == UART5) + { + RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5, ENABLE); + } + else if (UARTx == UART7) + { + RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART7, ENABLE); + } + else if (UARTx == LPUART) + { + RCC_APB1PeriphClockCmd(RCC_APB1Periph_LPUART, ENABLE); + } + + /*---------------------- UART and LPUART CR Configuration ------------------*/ + tmpreg = UARTx->CR; + + /* Configure the UART_Mode */ + /* Configure the TXDIS and RXDIS bits */ + UARTx->CR |= ((uint32_t)(CR_CLEAR_MODE_MASK)); + /* Configure the TXEN and RXEN bits */ + tmpreg |= UART_InitStruct->UART_Mode; + + /* Write to UART and LPUART CR */ + UARTx->CR = tmpreg; + + /*---------------------- UART and LPUART MR Configuration ------------------*/ + tmpreg = UARTx->MR; + + /* Normal configuration */ + /* Set the [23:23]_INVDATA ascording to UART_INVData value */ + /* Set the [19:19]_OVER ascording to UART_OverSampling value */ + /* Set the [17:17]_MODE9 ascording to UART_WordLength value */ + /* Set the [16:16]_MSBF ascording to UART_BitOrder value */ + /* Set the [15:14]_CHMODE ascording to UART_ChannelMode value */ + /* Set the [13:12]_NBSTOP ascording to UART_StopBits value */ + /* Set the [11: 9]_PAR ascording to UART_Parity value */ + /* Set the [ 7: 6]_CHRL ascording to UART_WordLength value */ + /* Set the [ 5: 4]_USCLKS ascording to UART_CLKSelect value */ + /* Set the [ 3: 0]_USART_MODE ascording to UART_OperationMode value */ + /* Clear the normal cfg bits */ + tmpreg &= (uint32_t)~((uint32_t)MR_CLEAR_NORMAL_MASK); + /* Configure the normal cfg bits */ + tmpreg |= (uint32_t)UART_InitStruct->UART_INVData | + UART_InitStruct->UART_OverSampling | + UART_InitStruct->UART_WordLength | + UART_InitStruct->UART_BitOrder | + UART_InitStruct->UART_ChannelMode | + UART_InitStruct->UART_StopBits | + UART_InitStruct->UART_Parity | + UART_InitStruct->UART_CLKSelect | + UART_InitStruct->UART_OperationMode ; + + /* Write to UART and LPUART MR */ + UARTx->MR = tmpreg; + + /*---------------------------- USART FIDI Configuration -----------------------*/ + if (UART_InitStruct->UART_OperationMode == UART_MODE_OPERATION_IrDA) + { + UARTx->FIDI = (uint32_t)UART_InitStruct->UART_FiDiRatio; + } + + /*---------------------- UART and LPUART BRGR Configuration ----------------*/ + tmpreg = UARTx->BRGR; + + /* Configure the UART and LPUART Baud Rate */ + RCC_GetClocksFreq(&RCC_ClocksStatus); + + if (UARTx == UART4) + { + apbclock = RCC_ClocksStatus.PCLK_Frequency ; + } + else if (UARTx == UART5) + { + apbclock = RCC_ClocksStatus.PCLK_Frequency ; + } + else if (UARTx == UART7) + { + apbclock = RCC_ClocksStatus.PCLK_Frequency ; + } + else if (UARTx == LPUART) + { + apbclock = RCC_ClocksStatus.LPUARTCLK_Frequency; + } + + /* Determine the integer part and fraction part disable (fractional part can configure in UART_FracDivider_Cfg()) */ + /* BaudRate not equal 0*/ + if ((UART_InitStruct->UART_BaudRate) > 0) + { + /* x16 Oversample in Async mode */ + if (UART_InitStruct->UART_OverSampling == UART_OVERSAMPLING_16) + { + clock_divider = (uint32_t)(((apbclock) / ((UART_InitStruct->UART_BaudRate) * 16))); + frac_divider = 0; + } + /* x8 Oversample in Async mode */ + else if (UART_InitStruct->UART_OverSampling == UART_OVERSAMPLING_8) + { + clock_divider = (uint32_t)(((apbclock) / ((UART_InitStruct->UART_BaudRate) * 8))); + frac_divider = 0; + } + } + /* BaudRate equal 0*/ + else if ((UART_InitStruct->UART_BaudRate) == 0) + { + clock_divider = 0; + frac_divider = 0; + } + + /* Write to UART and LPUART BRGR */ + UARTx->BRGR = (((uint32_t)(clock_divider)) | ((uint32_t)(frac_divider) << 16U)); + + /*---------------------- UART and LPUART IF Configuration -------------------*/ + /* Write to UART and LPUART IF in IrDA mode */ + if (UART_InitStruct->UART_OperationMode == UART_MODE_OPERATION_IrDA) + { + UARTx->IF = (uint16_t)UART_InitStruct->UART_IrDAFilter; + } + + /*---------------------- UART and LPUART LINMR Configuration ----------------*/ + tmpreg = 0; + + if ((UART_InitStruct->UART_OperationMode == UART_MODE_OPERATION_LIN_MASTER) || + (UART_InitStruct->UART_OperationMode == UART_MODE_OPERATION_LIN_SLAVE)) + { + /* Set the [17:17]_SYNCDIS ascording to UART_SYNCDisable value */ + /* Set the [16:16]_PDCM ascording to UART_PDCMode value */ + /* Set the [15: 8]_DLC ascording to UART_DataLengthControl value */ + /* Set the [ 7: 7]_WKUPTYP ascording to UART_WkupType value */ + /* Set the [ 6: 6]_FSDIS ascording to UART_FrameSlotDisable value */ + /* Set the [ 5: 5]_DLM ascording to UART_DataLengthMode value */ + /* Set the [ 4: 4]_CHKTYP ascording to UART_CheckSumType value */ + /* Set the [ 3: 3]_CHKDIS ascording to UART_CheckSumDisable value */ + /* Set the [ 2: 2]_PARDIS ascording to UART_ParityDisable value */ + /* Set the [ 1: 0]_NACT ascording to UART_NodeAction value */ + tmpreg |= (uint32_t)UART_InitStruct-> UART_SYNCDisable | + UART_InitStruct-> UART_PDCMode | + ((UART_InitStruct-> UART_DataLengthControl << (uint32_t)8)) | + UART_InitStruct-> UART_WkupType | + UART_InitStruct-> UART_FrameSlotDisable | + UART_InitStruct-> UART_DataLengthMode | + UART_InitStruct-> UART_CheckSumType | + UART_InitStruct-> UART_CheckSumDisable | + UART_InitStruct-> UART_ParityDisable | + ((UART_InitStruct-> UART_NodeAction << (uint32_t)0)) ; + + /* Write to UART and LPUART LINMR*/ + UARTx->LINMR = tmpreg; + } +} + +/** + * @brief Configure each UART_InitStruct member with its default value. + * @param UART_InitStruct: pointer to a UART_InitTypeDef structure + * which will be initialized. + * @retval None + */ +void UART_StructInit(UART_InitTypeDef* UART_InitStruct) +{ + /* UART_InitStruct members default value */ + UART_InitStruct->UART_BaudRate = 9600 ; + UART_InitStruct->UART_FiDiRatio = 174 ; + UART_InitStruct->UART_IrDAFilter = 0 ; + UART_InitStruct->UART_WordLength = UART_CHAR_LENGTH_8BIT ; + UART_InitStruct->UART_StopBits = UART_STOPBITS_1 ; + UART_InitStruct->UART_Parity = UART_PARITY_NONE ; + UART_InitStruct->UART_Mode = UART_MODE_TX | UART_MODE_RX ; + UART_InitStruct->UART_CLKSelect = UART_CLOCK_SELECT_MCK ; + UART_InitStruct->UART_OperationMode = UART_MODE_OPERATION_NORMAL ; + UART_InitStruct->UART_BitOrder = UART_BIT_ORDER_LSBF ; + UART_InitStruct->UART_ChannelMode = UART_CHANNEL_MODE_NORMAL ; + UART_InitStruct->UART_OverSampling = UART_OVERSAMPLING_16 ; + UART_InitStruct->UART_INVData = UART_INVDATA_DISABLE ; + UART_InitStruct->UART_SYNCDisable = UART_SYNC_DISABLE_NONE ; + UART_InitStruct->UART_PDCMode = UART_PDC_MODE_LINMR_NOTWRITE ; + UART_InitStruct->UART_DataLengthControl = 0 ; + UART_InitStruct->UART_WkupType = UART_WKUP_TYPE_LIN_2_0 ; + UART_InitStruct->UART_FrameSlotDisable = UART_FRAME_SLOT_DISABLE_NONE ; + UART_InitStruct->UART_DataLengthMode = UART_DATA_LENGTH_MODE_DLC ; + UART_InitStruct->UART_CheckSumType = UART_CHECKSUM_TYPE_ENHANCED ; + UART_InitStruct->UART_CheckSumDisable = UART_CHECKSUM_DISABLE_NONE ; + UART_InitStruct->UART_ParityDisable = UART_PARITY_DISABLE_NONE ; + UART_InitStruct->UART_NodeAction = UART_NODE_ACTIVE_PUBLISH ; +} + +/** + * @brief De-Initialize the UARTx peripheral to their default reset value. + * @param UARTx: Select UART peripheral from among UART4, UART5, UART7 and LPUART. + * @retval None + */ +void UART_DeInit(USART_TypeDef* UARTx) +{ + /* Check the parameters */ + assert_param(IS_UART_ALL_PERIPH(UARTx)); + + /* UARTx reset operation */ + if (UARTx == UART4) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART4, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART4, DISABLE); + } + else if (UARTx == UART5) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART5, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART5, DISABLE); + } + else if (UARTx == UART7) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART7, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART7, DISABLE); + } + else if (UARTx == LPUART) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_LPUART, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_LPUART, DISABLE); + } +} + +/** + * @} + */ + +/** @defgroup UART and LPUART normal cmd and cfg functions + * @brief UART and LPUART normal command and configuration functions + * +@verbatim + =============================================================================== + ##### Normal Command And Configuration Functions ##### + =============================================================================== + [..] This subsection provides a set of normal command and configuration + function. + + [..] + + (#) The Normal cmd API's : + (++) UART_Cmd() + (++) UART_RSTSTA_Cmd() + (++) UART_TXDIS_Cmd() + (++) UART_TXEN_Cmd() + (++) UART_RXDIS_Cmd() + (++) UART_RXEN_Cmd() + (++) UART_RSTTX_Cmd() + (++) UART_RSTRX_Cmd() + + (#) The Normal cfg API's : + (++) UART_InvData_Cfg() + (++) UART_OverSampling8_Cfg() + (++) UART_DataLength9_Cfg() + (++) UART_MSBFirst_Cfg() + (++) UART_ChannelMode_Cfg() + (++) UART_StopBit_Cfg() + (++) UART_Parity_Cfg() + (++) UART_DataLength_Cfg() + (++) UART_CLKSelect_Cfg() + (++) UART_OperationMode_Cfg() + + (#) The Normal read API's : + (++) None +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the specified UART peripheral. + * @param UARTx: Select UART peripheral from among UART4, UART5, UART7 and LPUART. + * @param NewState: new state of the UARTx peripheral. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void UART_Cmd(USART_TypeDef* UARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_UART_ALL_PERIPH(UARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected UART by setting the UARTxEN bit in the RCC_APB1ENR register */ + if (UARTx == UART4) + { + RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE); + } + else if (UARTx == UART5) + { + RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5, ENABLE); + } + else if (UARTx == UART7) + { + RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART7, ENABLE); + } + else if (UARTx == LPUART) + { + RCC_APB1PeriphClockCmd(RCC_APB1Periph_LPUART, ENABLE); + } + } + else + { + /* Disable the selected UART by clearing the UARTxEN bit in the RCC_APB1ENR register */ + if (UARTx == UART4) + { + RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, DISABLE); + } + else if (UARTx == UART5) + { + RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5, DISABLE); + } + else if (UARTx == UART7) + { + RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART7, DISABLE); + } + else if (UARTx == LPUART) + { + RCC_APB1PeriphClockCmd(RCC_APB1Periph_LPUART, DISABLE); + } + } +} + +/** + * @brief Reset status bits. + * @param UARTx: Select UART peripheral from among UART4, UART5, UART7 and LPUART. + * @param NewState: new state of the UARTx reset status bits. + * This parameter can be: + * @arg ENABLE : Resets the status bits PARE, FRAME, OVER, LINBE, + * LINISFE, LINIPE, LINCE, LINSNRE, LINSTE, LINHTE, + * LINID, LINTC, LINBK and RXBRK in US_CSR. + * @arg DISABLE: No effect + * @retval None + */ +void UART_RSTSTA_Cmd(USART_TypeDef* UARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_UART_ALL_PERIPH(UARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* The status bits reset by setting RSTSTA bit in the CR register */ + UARTx->CR |= USART_CR_RSTSTA; + } + else + { + /* No effect */ + UARTx->CR &= (uint32_t)~((uint32_t)USART_CR_RSTSTA); + } +} + +/** + * @brief Transmitter disable. + * @param UARTx: Select UART peripheral from among UART4, UART5, UART7 and LPUART. + * @param NewState: new state of the UARTx transmitter disable. + * This parameter can be: + * @arg ENABLE : Disable the transmitter. + * @arg DISABLE: No effect + * @retval None + */ +void UART_TXDIS_Cmd(USART_TypeDef* UARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_UART_ALL_PERIPH(UARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* The transmitter disable by setting TXDIS bit in the CR register */ + UARTx->CR |= USART_CR_TXDIS; + } + else + { + /* No effect */ + UARTx->CR &= (uint32_t)~((uint32_t)USART_CR_TXDIS); + } +} + +/** + * @brief Transmitter enable. + * @param UARTx: Select UART peripheral from among UART4, UART5, UART7 and LPUART. + * @param NewState: new state of the UARTx transmitter enable. + * This parameter can be: + * @arg ENABLE : Enable the transmitter if TXDIS is 0. + * @arg DISABLE: No effect + * @retval None + */ +void UART_TXEN_Cmd(USART_TypeDef* UARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_UART_ALL_PERIPH(UARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* The transmitter enable by setting TXEN bit in the CR register */ + UARTx->CR |= USART_CR_TXEN; + } + else + { + /* No effect */ + UARTx->CR &= (uint32_t)~((uint32_t)USART_CR_TXEN); + } +} + +/** + * @brief Receiver disable. + * @param UARTx: Select UART peripheral from among UART4, UART5, UART7 and LPUART. + * @param NewState: new state of the UARTx receiver disable. + * This parameter can be: + * @arg ENABLE : Disable the receiver. + * @arg DISABLE: No effect + * @retval None + */ +void UART_RXDIS_Cmd(USART_TypeDef* UARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_UART_ALL_PERIPH(UARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* The receiver disable by setting RXDIS bit in the CR register */ + UARTx->CR |= USART_CR_RXDIS; + } + else + { + /* No effect */ + UARTx->CR &= (uint32_t)~((uint32_t)USART_CR_RXDIS); + } +} + +/** + * @brief Receiver enable. + * @param UARTx: Select UART peripheral from among UART4, UART5, UART7 and LPUART. + * @param NewState: new state of the UARTx receiver enable. + * This parameter can be: + * @arg ENABLE : Enable the receiver if RXDIS is 0. + * @arg DISABLE: No effect + * @retval None + */ +void UART_RXEN_Cmd(USART_TypeDef* UARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_UART_ALL_PERIPH(UARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* The receiver enable by setting RXEN bit in the CR register */ + UARTx->CR |= USART_CR_RXEN; + } + else + { + /* No effect */ + UARTx->CR &= (uint32_t)~((uint32_t)USART_CR_RXEN); + } +} + +/** + * @brief Reset transmitter + * @param UARTx: Select UART peripheral from among UART4, UART5, UART7 and LPUART. + * @param NewState: new state of the UARTx reset transmitter. + * This parameter can be: + * @arg ENABLE : Resets the transmitter. + * @arg DISABLE: No effect + * @retval None + */ +void UART_RSTTX_Cmd(USART_TypeDef* UARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_UART_ALL_PERIPH(UARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* The transmitter reset by setting RSTTX bit in the CR register */ + UARTx->CR |= USART_CR_RSTTX; + } + else + { + /* No effect */ + UARTx->CR &= (uint32_t)~((uint32_t)USART_CR_RSTTX); + } +} + +/** + * @brief Reset receiver + * @param UARTx: Select UART peripheral from among UART4, UART5, UART7 and LPUART. + * @param NewState: new state of the UARTx reset receiver. + * This parameter can be: + * @arg ENABLE : Resets the receiver. + * @arg DISABLE: No effect + * @retval None + */ +void UART_RSTRX_Cmd(USART_TypeDef* UARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_UART_ALL_PERIPH(UARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* The receiver reset by setting RSTRX bit in the CR register */ + UARTx->CR |= USART_CR_RSTRX; + } + else + { + /* No effect */ + UARTx->CR &= (uint32_t)~((uint32_t)USART_CR_RSTRX); + } +} + +/** + * @brief Inverted data + * @param UARTx: Select UART peripheral from among UART4, UART5 and UART7 (Except LPUART). + * @param NewState: new state of the UARTx inverted data. + * This parameter can be: + * @arg ENABLE : The data field transmitted on TXD line is inverted + * compared to the value writted on US_THR register or + * the content read in US_RHR is inverted compared to + * what is received on TXD line. + * @arg DISABLE: The data field transmitted on TXD line is the same + * as one written in US_THR register or content read in + * US_RHR is the same as RXD line. Normal mode of operation. + * @retval None + */ +void UART_InvData_Cfg(USART_TypeDef* UARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_UART_457_PERIPH(UARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the invert data function by setting INVDATA bit in the MR register */ + UARTx->MR |= USART_MR_INVDATA; + } + else + { + /* Disable the invert data function by clearing INVDATA bit in the MR register */ + UARTx->MR &= (uint32_t)~((uint32_t)USART_MR_INVDATA); + } +} + +/** + * @brief Oversampling mode + * @param UARTx: Select UART peripheral from among UART4, UART5, UART7 and LPUART. + * @param NewState: new state of the UARTx oversampling mode. + * This parameter can be: + * @arg ENABLE : 8x oversampling. + * @arg DISABLE: 16x oversampling. + * @retval None + */ +void UART_OverSampling8_Cfg(USART_TypeDef* UARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_UART_ALL_PERIPH(UARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the 8x oversampling function by setting OVER bit in the MR register */ + UARTx->MR |= USART_MR_OVER; + } + else + { + /* Disable the 8x oversampling function by clearing OVER bit in the MR register */ + UARTx->MR &= (uint32_t)~((uint32_t)USART_MR_OVER); + } +} + +/** + * @brief 9-bit character length + * @param UARTx: Select UART peripheral from among UART4, UART5, UART7 and LPUART. + * @param NewState: new state of the UARTx 9-bit character length. + * This parameter can be: + * @arg ENABLE : 9-bit character length. + * @arg DISABLE: UART_Char_Length defines character length. + * @retval None + */ +void UART_DataLength9_Cfg(USART_TypeDef* UARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_UART_ALL_PERIPH(UARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable 9-bit character length by setting MODE9 bit in the MR register */ + UARTx->MR |= USART_MR_MODE9; + } + else + { + /* Disable 9-bit character length by clearing MODE9 bit in the MR register */ + UARTx->MR &= (uint32_t)~((uint32_t)USART_MR_MODE9); + } +} + +/** + * @brief Bit order + * @param UARTx: Select UART peripheral from among UART4, UART5, UART7 and LPUART. + * @param NewState: new state of the UARTx bit order. + * This parameter can be: + * @arg ENABLE : Most significant bit is sent/received first. + * @arg DISABLE: Least significant bit is sent/received first. + * @retval None + */ +void UART_MSBFirst_Cfg(USART_TypeDef* UARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_UART_ALL_PERIPH(UARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable most significant bit is sent/received by setting MSBF bit in the MR register */ + UARTx->MR |= USART_MR_MSBF; + } + else + { + /* Enable least significant bit is sent/received by setting MSBF bit in the MR register */ + UARTx->MR &= (uint32_t)~((uint32_t)USART_MR_MSBF); + } +} + +/** + * @brief Channel mode + * @param UARTx: Select UART peripheral from among UART4, UART5, UART7 and LPUART. + * @param UART_ChannelMode: channel mode; + * This parameter can be one of the following values: + * UART_CHANNEL_MODE_NORMAL - Normal mode + * UART_CHANNEL_MODE_AUTOMATIC - Automatic mode + * UART_CHANNEL_MODE_LOCAL_LOOPBACK - Local loopback mode + * UART_CHANNEL_MODE_REMOTE_LOOPBACK - Remote loopbak mode + * @retval None + */ +void UART_ChannelMode_Cfg(USART_TypeDef* UARTx, uint32_t UART_ChannelMode) +{ + /* Check the parameters */ + assert_param(IS_UART_ALL_PERIPH(UARTx)); + assert_param(IS_UART_CHANNEL_MODE(UART_ChannelMode)); + + /* Clear the channel mode by clearing the CHMODE[15:14] bits in the MR register */ + UARTx->MR &= (uint32_t)~((uint32_t)USART_MR_CHMODE); + + /* Set the channel mode by setting the CHMODE[15:14] bits in the MR register */ + UARTx->MR |= (uint32_t)((uint32_t)UART_ChannelMode); +} + +/** + * @brief Number of stop bits + * @param UARTx: Select UART peripheral from among UART4, UART5, UART7 and LPUART. + * @param UART_StopBits: number of stop bits, + * This parameter can be one of the following values: + * UART_STOPBITS_1 - 1 stop bit + * UART_STOPBITS_1_5 - 1.5 stop bit (SYNC = 0) or reserved (SYNC = 1) + * UART_STOPBITS_2 - 2 stop bits + * @retval None + */ +void UART_StopBit_Cfg(USART_TypeDef* UARTx, uint32_t UART_StopBits) +{ + /* Check the parameters */ + assert_param(IS_UART_ALL_PERIPH(UARTx)); + assert_param(IS_UART_STOPBITS(UART_StopBits)); + + /* Clear the number of stop bits by clearing the NBSTOP[13:12] bits in the MR register */ + UARTx->MR &= (uint32_t)~((uint32_t)USART_MR_NBSTOP); + + /* Set the number of stop bits by setting the NBSTOP[13:12] bits in the MR register */ + UARTx->MR |= (uint32_t)((uint32_t)UART_StopBits); +} + +/** + * @brief Parity type + * @param UARTx: Select UART peripheral from among UART4, UART5, UART7 and LPUART. + * @param UART_Parity: Parity type + * This parameter can be one of the following values: + * UART_PARITY_EVEN - Even parity + * UART_PARITY_ODD - Odd parity + * UART_PARITY_SPACE - Parity forced to 0 (space) + * UART_PARITY_MARK - Parity forced to 1 (mark) + * UART_PARITY_NONE - No parity + * UART_PARITY_MULTIDROP - Multidrop mode + * @retval None + */ +void UART_Parity_Cfg(USART_TypeDef* UARTx, uint32_t UART_Parity) +{ + /* Check the parameters */ + assert_param(IS_UART_ALL_PERIPH(UARTx)); + assert_param(IS_UART_PARITY(UART_Parity)); + + /* Clear the parity type by clearing the PAR[11:9] bits in the MR register */ + UARTx->MR &= (uint32_t)~((uint32_t)USART_MR_PAR); + + /* Set the parity type by setting the PAR[11:9] bits in the MR register */ + UARTx->MR |= (uint32_t)((uint32_t)UART_Parity); +} + +/** + * @brief Character length + * @param UARTx: Select UART peripheral from among UART4, UART5, UART7 and LPUART. + * @param UART_WordLength: character length + * This parameter can be one of the following values: + * UART_CHAR_LENGTH_5BIT - character length is 5 bits + * UART_CHAR_LENGTH_6BIT - character length is 6 bits + * UART_CHAR_LENGTH_7BIT - character length is 7 bits + * UART_CHAR_LENGTH_8BIT - character length is 8 bits + * @retval None + */ +void UART_DataLength_Cfg(USART_TypeDef* UARTx, uint32_t UART_WordLength) +{ + /* Check the parameters */ + assert_param(IS_UART_ALL_PERIPH(UARTx)); + assert_param(IS_UART_CHAR_LENGTH(UART_WordLength)); + + /* Clear the character length by clearing the CHRL[7:6] bits in the MR register */ + UARTx->MR &= (uint32_t)~((uint32_t)USART_MR_CHRL); + + /* Set the character length by setting the CHRL[7:6] bits in the MR register */ + UARTx->MR |= (uint32_t)((uint32_t)UART_WordLength); +} + +/** + * @brief Clock selection + * @param UARTx: Select UART peripheral from among UART4, UART5, UART7 and LPUART. + * @param UART_CLKSelect: clock selection + * This parameter can be one of the following values: + * UART_CLOCK_SELECT_MCK - MCK + * UART_CLOCK_SELECT_MCKDIV8 - MCK / 8 + * @retval None + */ +void UART_CLKSelect_Cfg(USART_TypeDef* UARTx, uint32_t UART_CLKSelect) +{ + /* Check the parameters */ + assert_param(IS_UART_ALL_PERIPH(UARTx)); + assert_param(IS_UART_CLOCK_SELECT(UART_CLKSelect)); + + /* Clear the clock select by clearing the USCLKS[5:4] bits in the MR register */ + UARTx->MR &= (uint32_t)~((uint32_t)USART_MR_USCLKS); + + /* Set the clock select by setting the USCLKS[5:4] bits in the MR register */ + UARTx->MR |= (uint32_t)((uint32_t)UART_CLKSelect); +} + +/** + * @brief UART mode of operation + * @param UARTx: Select UART peripheral from among UART4, UART5, UART7 and LPUART. + * @param UART_OperationMode: UART mode of operation + * This parameter can be one of the following values: + * UART_MODE_OPERATION_NORMAL - Normal mode + * UART_MODE_OPERATION_IrDA - IrDA + * UART_MODE_OPERATION_LIN_MASTER - LIN master + * UART_MODE_OPERATION_LIN_SLAVE - LIN slave + * @retval None + */ +void UART_OperationMode_Cfg(USART_TypeDef* UARTx, uint32_t UART_OperationMode) +{ + /* Check the parameters */ + assert_param(IS_UART_ALL_PERIPH(UARTx)); + assert_param(IS_UART_MODE_OPERATION(UART_OperationMode)); + + /* Clear the UART mode of operation by clearing the USART_MODE[3:0] bits in the MR register */ + UARTx->MR &= (uint32_t)~((uint32_t)USART_MR_USART_MODE); + + /* Set the UART mode of operation by setting the USART_MODE[3:0] bits in the MR register */ + UARTx->MR |= (uint32_t)((uint32_t)UART_OperationMode); +} + +/** + * @} + */ + +/** @defgroup UART fractional baudrate function + * @brief UART fractional part of baudrate function + * +@verbatim + =============================================================================== + ##### Fractional Baudrate Functions ##### + =============================================================================== + [..] This subsection provides a function, which can configure fractional part + of baudrate. + + [..] + + (#) The fractional part of baudrate API's : + (++) UART_FracDivider_Cfg() +@endverbatim + * @{ + */ + +/** + * @brief UART fractional part of BaudRate + * @param UARTx: Select UART peripheral from among UART4, UART5 and UART7 (Except LPUART). + * @param UART_BaudRate: user confige baudrate + * @note This function has to be called after calling UART_Init() function + * in order to have correct fractional part baudrate Divider value. + * @retval None + */ +void UART_FracDivider_Cfg(USART_TypeDef* UARTx, uint32_t UART_BaudRate) +{ + double clock_divider = 0, frac_divider = 0, apbclock = 0; + + RCC_ClocksTypeDef RCC_ClocksStatus; + + /* Check the parameters */ + assert_param(IS_UART_457_PERIPH(UARTx)); + assert_param(IS_UART_BAUDRATE(UART_BaudRate)); + + RCC_GetClocksFreq(&RCC_ClocksStatus); + + /* Get UARTx work clock*/ + apbclock = RCC_ClocksStatus.PCLK_Frequency; + + /* BaudRate not equal 0*/ + if (UART_BaudRate > 0) + { + /* Async mode x16 Oversample*/ + if (((UARTx->MR)&USART_MR_OVER) == UART_OVERSAMPLING_16) + { + clock_divider = (uint32_t)(((apbclock) / ((UART_BaudRate) * 16))); + frac_divider = (uint32_t)(((apbclock) / ((UART_BaudRate) * 16) - clock_divider) * 8); + } + /* Async mode x8 Oversample*/ + if (((UARTx->MR)&USART_MR_OVER) == UART_OVERSAMPLING_8) + { + clock_divider = (uint32_t)(((apbclock) / ((UART_BaudRate) * 8))); + frac_divider = (uint32_t)(((apbclock) / ((UART_BaudRate) * 8) - clock_divider) * 8); + } + } + + /* Clear the UART fractional part by clearing the FP[18:16] bits in the BRGR register */ + UARTx->BRGR &= (uint32_t)~((uint32_t)USART_BRGR_FP); + + /* Set the UART fractional part by setting the FP[18:16] bits in the BRGR register */ + UARTx->BRGR |= (((uint32_t)frac_divider) << 16U); +} + +/** + * @} + */ + +/** @defgroup UART and LPUART BREAK command functions + * @brief None + * +@verbatim + =============================================================================== + ##### Break Command Functions ##### + =============================================================================== + [..] This subsection provides a set of BREAK command functions. + + [..] + + (#) The stop break command API's : + (++) UART_STPBRK_Cmd() + + (#) The start break command API's : + (++) UART_STTBRK_Cmd() +@endverbatim + * @{ + */ + +/** + * @brief Stop break. + * @param UARTx: Select UART peripheral from among UART4, UART5, UART7 and LPUART. + * @param NewState: new state of the UARTx stop break. + * This parameter can be: + * @arg ENABLE : Stops transmission of break after a minimum of one character length and + * transmits a high level during 12-bit periods. + * @arg DISABLE: No effect + * @retval None + */ +void UART_STPBRK_Cmd(USART_TypeDef* UARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_UART_ALL_PERIPH(UARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Stops transmission of break after a minimum of one character by setting + STPBRK bit in the CR register */ + UARTx->CR |= USART_CR_STPBRK; + } + else + { + /* No effect */ + UARTx->CR &= (uint32_t)~((uint32_t)USART_CR_STPBRK); + } +} + +/** + * @brief Start break. + * @param UARTx: Select UART peripheral from among UART4, UART5, UART7 and LPUART. + * @param NewState: new state of the UARTx start break. + * This parameter can be: + * @arg ENABLE : Starts transmission of break after the character present in US_THR and + * the transmit shift register have been transmitted. No effect if a break + * is already being transmitted. + * @arg DISABLE: No effect + * @retval None + */ +void UART_STTBRK_Cmd(USART_TypeDef* UARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_UART_ALL_PERIPH(UARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Starts transmission of break after the characters present in US_THR and the transmit + shift register have been transmitted by setting STTBRK bit in the CR register */ + UARTx->CR |= USART_CR_STTBRK; + } + else + { + /* No effect */ + UARTx->CR &= (uint32_t)~((uint32_t)USART_CR_STTBRK); + } +} + +/** + * @} + */ + +/** @defgroup UART receiver time-out and transmitter timeguard functions + * @brief Receiver time-out cfg and cmd functions. + * Transmitter timeguard cfg function. + * +@verbatim + =============================================================================== + ##### Receiver Time-out And Transmitter Timeguard Functions ##### + =============================================================================== + [..] This subsection provides a set of receiver time-out and transmitter + timeguard functions. + + [..] + + (#) The receiver time-out cfg API's : + (++) UART_Receiver_TimeOut_Cfg() + + (#) The receiver time-out cmd API's : + (++) UART_RETTO_After_Timeout_Cmd() + (++) UART_STTTO_After_Timeout_Cmd() + + (#) The transmitter timeguard cfg API's : + (++) UART_Transmitter_TimeGuard_Cfg() +@endverbatim + * @{ + */ + +/** + * @brief Receiver time-out value + * @param UARTx: Select UART peripheral from among UART4, UART5 and UART7 (Except LPUART). + * @param UART_ReceiverTimeOut: Time-out value + * 0 : The receiver time-out is disabled. + * 1 - 65535 : The receiver time-out is enabled and time-out + * delay is TO * bit period. + * 1 - 131071: The receiver time-out is enabled and time-out + * delay is TO * bit period. + * @note This function has to be called before calling UART_Init() function + * in order to have correct receiver time-out value. + * @retval None + */ +void UART_Receiver_TimeOut_Cfg(USART_TypeDef* UARTx, uint32_t UART_ReceiverTimeOut) +{ + /* Check the parameters */ + assert_param(IS_UART_457_PERIPH(UARTx)); + assert_param(IS_UART_TIMEOUT(UART_ReceiverTimeOut)); + + /* Clear the time-out value of receiver by clearing the TO[16:0] bits in the RTOR register */ + UARTx->RTOR &= (uint32_t)~((uint32_t)USART_RTOR_TO); + + /* Set the time-out value of receiver setting the TO[16:0] bits in the RTOR register */ + UARTx->RTOR |= (uint32_t)((uint32_t)UART_ReceiverTimeOut); +} + +/** + * @brief Rearm Time-out. + * @param UARTx: Select UART peripheral from among UART4, UART5 and UART7 (Except LPUART). + * @param NewState: new state of the UARTx rearm Time-out. + * This parameter can be: + * @arg ENABLE : Restart Time-out + * @arg DISABLE: No effect + * @retval None + */ +void UART_RETTO_After_Timeout_Cmd(USART_TypeDef* UARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_UART_457_PERIPH(UARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Restart time-out by setting RETTO bit in the CR register */ + UARTx->CR |= USART_CR_RETTO; + } + else + { + /* No effect */ + UARTx->CR &= (uint32_t)~((uint32_t)USART_CR_RETTO); + } +} + +/** + * @brief Start time-out. + * @param UARTx: Select UART peripheral from among UART4, UART5 and UART7 (Except LPUART). + * @param NewState: new state of the UARTx start time-out. + * This parameter can be: + * @arg ENABLE : Starts waiting for a character before clocking the time-out counter. + * Resets the status bit TIMEOUT in US_CSR. + * @arg DISABLE: No effect + * @retval None + */ +void UART_STTTO_After_Timeout_Cmd(USART_TypeDef* UARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_UART_457_PERIPH(UARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Starts waiting for a character before clocking the time-out counter by setting + STTTO bit in the CR register */ + UARTx->CR |= USART_CR_STTTO; + } + else + { + /* No effect */ + UARTx->CR &= (uint32_t)~((uint32_t)USART_CR_STTTO); + } +} + +/** + * @brief Transmitter timeguard value + * @param UARTx: Select UART peripheral from among UART4, UART5 and UART7 (Except LPUART). + * @param UART_TransmitterTimeGuard: timeguard value + * 0 : The transmitter timeguard value is disabled. + * 1 - 255: The transmitter timeguard is enabled and the + * timeguard delay is TG * bit period. + * @note This function has to be called before calling UART_Init() function + * in order to have correct transmitter timeguard value. + * @retval None + */ +void UART_Transmitter_TimeGuard_Cfg(USART_TypeDef* UARTx, uint32_t UART_TransmitterTimeGuard) +{ + /* Check the parameters */ + assert_param(IS_UART_457_PERIPH(UARTx)); + assert_param(IS_UART_TIMGUARD(UART_TransmitterTimeGuard)); + + /* Clear the timeguard value of transmitter by clearing the TG[7:0] bits in the TTGR register */ + UARTx->TTGR &= (uint32_t)~((uint32_t)USART_TTGR_TG); + + /* Set the timeguard value of transmitter setting the TG[7:0] bits in the TTGR register */ + UARTx->TTGR |= (uint32_t)((uint32_t)UART_TransmitterTimeGuard); +} + +/** + * @} + */ + +/** @defgroup UART and LPUART multidrop mode cmd function + * @brief Multidrop mode command function. + * +@verbatim + =============================================================================== + ##### Multidrop Mode Command Function ##### + =============================================================================== + [..] This subsection provides the multidrop mode command function. + + [..] + + (#) The multidrop mode command API's : + (++) UART_SENDAInMultidropMode_Cmd() + +@endverbatim + * @{ + */ + +/** + * @brief Send address. + * @param UARTx: Select UART peripheral from among UART4, UART5, UART7 and LPUART. + * @param NewState: new state of the UARTx send address. + * This parameter can be: + * @arg ENABLE : In multidrop mode only, the next character written to + * the US_THR is sent with address bit set. + * @arg DISABLE: No effect + * @retval None + */ +void UART_SENDAInMultidropMode_Cmd(USART_TypeDef* UARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_UART_ALL_PERIPH(UARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* In multidrop mode only, the next character writted to the US_THR is sent with + address bit set by setting SENDA bit in the CR register */ + UARTx->CR |= USART_CR_SENDA; + } + else + { + /* No effect */ + UARTx->CR &= (uint32_t)~((uint32_t)USART_CR_SENDA); + } +} + +/** + * @} + */ + +/** @defgroup UART IrDA mode cfg functions + * @brief UART IrDA mode mode configuration function + * +@verbatim + =============================================================================== + ##### IrDA Mode Functions ##### + =============================================================================== + [..] This subsection provides a IrDA mode function. + + [..] + + (#) The IrDA mode cfg API's : + (++) UART_IrDAFilter_Cfg() + +@endverbatim + * @{ + */ + +/** + * @brief IrDA Filter + * @param UARTx: Select UART peripheral from among UART4, UART5 and UART7 (Except LPUART). + * @param UART_IrDAFilter: The IRDA_FILTER value must be defined to meet the + * following criteria: + * tMCK * (IDA_FILTER + 3) < 1.41us + * @retval None + */ +void UART_IrDAFilter_Cfg(USART_TypeDef* UARTx, uint32_t UART_IrDAFilter) +{ + /* Check the parameters */ + assert_param(IS_UART_457_PERIPH(UARTx)); + assert_param(IS_UART_IF(UART_IrDAFilter)); + + /* Clear the IrDA filter value by clearing the IRDA_FILTER[7:0] bits in the IF register */ + UARTx->IF &= (uint32_t)~((uint32_t)USART_IF_IRDA_FILTER); + + /* Set the IrDA filter value by setting the IRDA_FILTER[7:0] bits in the IF register */ + UARTx->IF |= (uint32_t)((uint32_t)UART_IrDAFilter); +} + +/** + * @} + */ + +/** @defgroup UART LIN mode cmd, cfg, and read functions + * @brief UART LIN mode mode command, configuration and read functions + * +@verbatim + =============================================================================== + ##### LIN Mode Functions ##### + =============================================================================== + [..] This subsection provides a set of LIN mode functions. + + [..] + + (#) The LIN mode cmd API's : + (++) UART_LINWKUP_Cmd() + (++) UART_LINABT_Cmd() + + (#) The LIN mode cfg API's : + (++) UART_Write_LINIR_In_LIN_Master() + (++) UART_SYNCDisable_Cfg() + (++) UART_PDCMode_Cfg() + (++) UART_DataLengthControl_Cfg() + (++) UART_WkupType_Cfg() + (++) UART_FrameSlotDisable_Cfg() + (++) UART_DataLengthMode_Cfg() + (++) UART_CheckSumType_Cfg() + (++) UART_CheckSumDisable_Cfg() + (++) UART_ParityDisable_Cfg() + (++) UART_NodeAction_Cfg() + + (#) The LIN mode read API's : + (++) UART_Read_LINIR_In_LIN_Slave() + (++) UART_LINBaudRate() +@endverbatim + * @{ + */ + +/** + * @brief Send LIN Wakeup Signal. + * @param UARTx: Select UART peripheral from among UART4, UART5 and UART7 (Except LPUART). + * @param NewState: new state of the UARTx send LIN wakeup signal. + * This parameter can be: + * @arg ENABLE : Sends a wakeup signal on LIN bus + * @arg DISABLE: No effect + * @retval None + */ +void UART_LINWKUP_Cmd(USART_TypeDef* UARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_UART_457_PERIPH(UARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Send a wakeup signal on LIN bus by setting LINWKUP bit in the CR register */ + UARTx->CR |= USART_CR_LINWKUP; + } + else + { + /* No effect */ + UARTx->CR &= (uint32_t)~((uint32_t)USART_CR_LINWKUP); + } +} + +/** + * @brief Abort LIN Transmission. + * @param UARTx: Select UART peripheral from among UART4, UART5 and UART7 (Except LPUART). + * @param NewState: new state of the UARTx abort LIN transmission. + * This parameter can be: + * @arg ENABLE : Abort LIN transmission + * @arg DISABLE: No effect + * @retval None + */ +void UART_LINABT_Cmd(USART_TypeDef* UARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_UART_457_PERIPH(UARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Abort LIN transmission by setting LINABT bit in the CR register */ + UARTx->CR |= USART_CR_LINABT; + } + else + { + /* No effect */ + UARTx->CR &= (uint32_t)~((uint32_t)USART_CR_LINABT); + } +} + +/** + * @brief Write identifier character in LIN master mode + * @param UARTx: Select UART peripheral from among UART4, UART5 and UART7 (Except LPUART). + * @param UART_LINIR_Data: if UART_OperationMode = 0xA (Master node configure), + * UART_LINIR_Data is read-write and its value is the + * identifier character to be transmitted. + * @note This function has to be called after calling UART_Init() function + * in order to have correct identifer value in LIN master mode. + * @retval None + */ +void UART_Write_LINIR_In_LIN_Master(USART_TypeDef* UARTx, uint32_t UART_LINIR_Data) +{ + /* Check the parameters */ + assert_param(IS_UART_457_PERIPH(UARTx)); + assert_param(IS_UART_LINIR_WR(UART_LINIR_Data)); + + /* Clear the identifier value to be transmitted in LIN master node by clearing + the IDCHR[7:0] bits in the LINIR register */ + UARTx->LINIR &= (uint32_t)~((uint32_t)USART_LINIR_IDCHR); + + /* Set the identifier value to be transmitted in LIN master node by setting + the IDCHR[7:0] bits in the LINIR register */ + UARTx->LINIR |= (uint32_t)((uint32_t)UART_LINIR_Data); +} + +/** + * @brief Synchronization disable in LIN mode + * @param UARTx: Select UART peripheral from among UART4, UART5 and UART7 (Except LPUART). + * @param NewState: new state of the UARTx LIN synchronization disable, + * applicable if UART operates in LIN mode. + * This parameter can be: + * @arg ENABLE : The synchronization procedure is not performed in LIN + * slave node configure. + * @arg DISABLE: The synchronization procedure is performed in LIN + * slave node configure. + * @retval None + */ +void UART_SYNCDisable_Cfg(USART_TypeDef* UARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_UART_457_PERIPH(UARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the synchronization procedure's disable by setting SYNCDIS bit in the LINMR register */ + UARTx->LINMR |= USART_LINMR_SYNCDIS; + } + else + { + /* Disable the synchronization procedure's disable by clearing SYNCDIS bit in the LINMR register */ + UARTx->LINMR &= (uint32_t)~((uint32_t)USART_LINMR_SYNCDIS); + } +} + +/** + * @brief DMA mode in LIN mode + * @param UARTx: Select UART peripheral from among UART4, UART5 and UART7 (Except LPUART). + * @param NewState: new state of the UARTx LIN DMA mode, applicable if UART + * operates in LIN mode. + * This parameter can be: + * @arg ENABLE : The LIN mode register US_LINMR (excepting that flag) + * is written by the DMA. + * @arg DISABLE: The LIN mode register US_LINMR is not written by the DMA. + * @retval None + */ +void UART_PDCMode_Cfg(USART_TypeDef* UARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_UART_457_PERIPH(UARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the DMA written of LINMR by setting PDCM bit in the LINMR register */ + UARTx->LINMR |= USART_LINMR_PDCM; + } + else + { + /* Disable the DMA written of LINMR by clearing PDCM bit in the LINMR register */ + UARTx->LINMR &= (uint32_t)~((uint32_t)USART_LINMR_PDCM); + } +} + +/** + * @brief Data length control in LIN mode + * @param UARTx: Select UART peripheral from among UART4, UART5 and UART7 (Except LPUART). + * @param UART_DataLengthControl: (0 - 255) Defines the response data length + * if UART_DataLengthMode = 0, in that case + * the response data length is equal to + * UART_DataLengthControl + 1 bytes; + * @retval None + */ +void UART_DataLengthControl_Cfg(USART_TypeDef* UARTx, uint32_t UART_DataLengthControl) +{ + /* Check the parameters */ + assert_param(IS_UART_457_PERIPH(UARTx)); + assert_param(IS_UART_DLC(UART_DataLengthControl)); + + /* Clear the response data length value of LIN mode (UART_DataLengthMode = 0) + by clearing the DLC[15:8] bits in the LINMR register */ + UARTx->LINMR &= (uint32_t)~((uint32_t)USART_LINMR_DLC); + + /* Set the response data length value of LIN mode (UART_DataLengthMode = 0) + by setting the DLC[15:8] bits in the LINMR register */ + UARTx->LINMR |= (uint32_t)((uint32_t)UART_DataLengthControl << 8U); +} + +/** + * @brief Wakeup signal type in LIN mode + * @param UARTx: Select UART peripheral from among UART4, UART5 and UART7 (Except LPUART). + * @param NewState: new state of the UARTx LIN wakeup signal type. + * This parameter can be: + * @arg ENABLE : Setting the bit LINWKUP in the control register send + * a LIN 1.3 wakeup signal. + * @arg DISABLE: Setting the bit LINWKUP in the control register send + * a LIN 2.0 wakeup signal. + * @retval None + */ +void UART_WkupType_Cfg(USART_TypeDef* UARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_UART_457_PERIPH(UARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the LIN 1.3 wakeup signal as the wakeup type to send by setting WKUPTYP + bit in the LINMR register */ + UARTx->LINMR |= USART_LINMR_WKUPTYP; + } + else + { + /* Disable the LIN 1.3 wakeup signal as the wakeup type to send by clearing WKUPTYP + bit in the LINMR register */ + UARTx->LINMR &= (uint32_t)~((uint32_t)USART_LINMR_WKUPTYP); + } +} + +/** + * @brief Frame slot mode disable in LIN mode + * @param UARTx: Select UART peripheral from among UART4, UART5 and UART7 (Except LPUART). + * @param NewState: new state of the UARTx LIN frame slot mode disable. + * This parameter can be: + * @arg ENABLE : The frame slot mode is disabled. + * @arg DISABLE: The frame slot mode is enabled. + * @retval None + */ +void UART_FrameSlotDisable_Cfg(USART_TypeDef* UARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_UART_457_PERIPH(UARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the frame slot mode's disable by setting FSDIS bit in the LINMR register */ + UARTx->LINMR |= USART_LINMR_FSDIS; + } + else + { + /* Disable the frame slot mode's disable by clearing FSDIS bit in the LINMR register */ + UARTx->LINMR &= (uint32_t)~((uint32_t)USART_LINMR_FSDIS); + } +} + +/** + * @brief Data length mode in LIN mode + * @param UARTx: Select UART peripheral from among UART4, UART5 and UART7 (Except LPUART). + * @param NewState: new state of the UARTx LIN data length mode. + * This parameter can be: + * @arg ENABLE : The response data length is defined by the bits 5 + * and 6 of the identifier (IDCHR in US_LINIR). + * @arg DISABLE: The response data length is defined by the field + * DLC of US_LINMR register. + * @retval None + */ +void UART_DataLengthMode_Cfg(USART_TypeDef* UARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_UART_457_PERIPH(UARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the response data length is defined by the bits 5 and 6 of the identifier + (IDCHR in US_LINIR) by setting DLM bit in the LINMR register */ + UARTx->LINMR |= USART_LINMR_DLM; + } + else + { + /* Disable the response data length is defined by the bits 5 and 6 of the identifier + (IDCHR in US_LINIR) by clearing DLM bit in the LINMR register */ + UARTx->LINMR &= (uint32_t)~((uint32_t)USART_LINMR_DLM); + } +} + +/** + * @brief Checksum type in LIN mode + * @param UARTx: Select UART peripheral from among UART4, UART5 and UART7 (Except LPUART). + * @param NewState: new state of the UARTx LIN checksum type. + * This parameter can be: + * @arg ENABLE : LIN 1.3 "Classic" checksum. + * @arg DISABLE: LIN 2.0 "Enhanced" checksum. + * @retval None + */ +void UART_CheckSumType_Cfg(USART_TypeDef* UARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_UART_457_PERIPH(UARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the LIN 1.3 "Classic" checksum type by setting CHKTYP bit in the LINMR register */ + UARTx->LINMR |= USART_LINMR_CHKTYP; + } + else + { + /* Disable the LIN 1.3 "Classic" checksum type by clearing CHKTYP bit in the LINMR register */ + UARTx->LINMR &= (uint32_t)~((uint32_t)USART_LINMR_CHKTYP); + } +} + +/** + * @brief Checksum disable in LIN mode + * @param UARTx: Select UART peripheral from among UART4, UART5 and UART7 (Except LPUART). + * @param NewState: new state of the UARTx LIN checksum disable. + * This parameter can be: + * @arg ENABLE : Whatever the node configuration is, the checksum is + * not computed/sent and it is not checked. + * @arg DISABLE: In Master node configuration, the cheksum is computed + * and sent automatically. In Slave node configure, the + * checksum is checked automatically. + * @retval None + */ +void UART_CheckSumDisable_Cfg(USART_TypeDef* UARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_UART_457_PERIPH(UARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the checksum's disable by setting CHKDIS bit in the LINMR register */ + UARTx->LINMR |= USART_LINMR_CHKDIS; + } + else + { + /* Disable the checksum's disable by clearing CHKDIS bit in the LINMR register */ + UARTx->LINMR &= (uint32_t)~((uint32_t)USART_LINMR_CHKDIS); + } +} + +/** + * @brief Parity disable in LIN mode + * @param UARTx: Select UART peripheral from among UART4, UART5 and UART7 (Except LPUART). + * @param NewState: new state of the UARTx LIN parity disable. + * This parameter can be: + * @arg ENABLE : Whatever the node configuration is, the identifier + * parity is not computed/sent and it is not checked. + * @arg DISABLE: In Master node configuration, the identifier parity + * is computed and sent automatically. In Master node + * and Slave node configuration, the parity is checked + * automatically. + * @retval None + */ +void UART_ParityDisable_Cfg(USART_TypeDef* UARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_UART_457_PERIPH(UARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the identifier parity's disable by setting PARDIS bit in the LINMR register */ + UARTx->LINMR |= USART_LINMR_PARDIS; + } + else + { + /* Disable the identifier parity's disable by clearing PARDIS bit in the LINMR register */ + UARTx->LINMR &= (uint32_t)~((uint32_t)USART_LINMR_PARDIS); + } +} + +/** + * @brief LIN node action + * @param UARTx: Select UART peripheral from among UART4, UART5 and UART7 (Except LPUART). + * @param UART_NodeAction: LIN node action + * This parameter can be one of the following values: + * UART_NODE_ACTIVE_PUBLISH - PUBLISH ; The UART transmits the response. + * UART_NODE_ACTIVE_SUBSCRIBE - SUBSCRIBE; The UART receives the response. + * UART_NODE_ACTIVE_IGNORE - IGNORE ; The UART does not transmits and + * does not receives the response. + * @retval None + */ +void UART_NodeAction_Cfg(USART_TypeDef* UARTx, uint32_t UART_NodeAction) +{ + /* Check the parameters */ + assert_param(IS_UART_457_PERIPH(UARTx)); + assert_param(IS_UART_NODE_ACTIVE(UART_NodeAction)); + + /* Clear the LIN node action by clearing the NACT[1:0] bits in the LINMR register */ + UARTx->LINMR &= (uint32_t)~((uint32_t)USART_LINMR_NACT); + + /* Set the LIN node action by setting the NACT[1:0] bits in the LINMR register */ + UARTx->LINMR |= (uint32_t)((uint32_t)UART_NodeAction); +} + +/** + * @brief Returns the identifier character by the UARTx peripheral. + * @param UARTx: Select UART peripheral from among UART4, UART5 and UART7 (Except LPUART). + * @note If UART_OperationMode = 0xB (Slave node configuration), IDCHR[7:0] + * in US_LINIR is read-only and its value is the last identifier character + * that has been received. + * @retval The last identifier character. + */ +uint32_t UART_Read_LINIR_In_LIN_Slave(USART_TypeDef* UARTx) +{ + /* Check the parameters */ + assert_param(IS_UART_457_PERIPH(UARTx)); + + /* Return the last identifier character if operation in slave node configuration*/ + return (uint32_t)((UARTx->LINIR)); +} + +/** + * @brief Returns the baud rate value after the synchronization process completion + * by the UARTx peripheral. + * @param UARTx: Select UART peripheral from among UART4, UART5 and UART7 (Except LPUART). + * @note The return value [18:16] bits is LINFP[18:16], which means fractional part + * after synchronization. + * @note The return value [15: 0] bits is LINCD[15: 0], which means clock driver + * after synchronization. + * @retval The baud rate value after the synchronization process completion. + */ +uint32_t UART_LINBaudRate(USART_TypeDef* UARTx) +{ + /* Check the parameters */ + assert_param(IS_UART_457_PERIPH(UARTx)); + + /* Return the baud rate value after the synchronization process completion */ + return (uint32_t)((UARTx->LINBRR)); +} + +/** + * @} + */ + +/** @defgroup UART and LPUART Transfers functions + * @brief UART and LPUART Transmit and Receive functions + * +@verbatim + =============================================================================== + ##### Data Transfers Functions ##### + =============================================================================== + [..] This subsection provides a set of functions allowing to manage the UART + and LPUART data transfers. + + [..] + + (#) The UART and LPUART data transmit API's : + (++) UART_Transmit() + + (#) The UART and LPUART data receive API's : + (++) UART_Receive() +@endverbatim + * @{ + */ + +/** + * @brief Transmits single data through the UARTx peripheral. + * @param UARTx: Select UART peripheral from among UART4, UART5, UART7 and LPUART. + * @param Data: the data to transmit. + * @retval None + */ +void UART_Transmit(USART_TypeDef* UARTx, uint16_t Data) +{ + /* Check the parameters */ + assert_param(IS_UART_ALL_PERIPH(UARTx)); + assert_param(IS_UART_DATA(Data)); + + /* Transmit Data */ + UARTx->THR = (Data & (uint16_t)0x01FF); +} + +/** + * @brief Returns the most recent received data by the UARTx peripheral. + * @param UARTx: Select UART peripheral from among UART4, UART5, UART7 and LPUART. + * @retval The received data. + */ +uint16_t UART_Receive(USART_TypeDef* UARTx) +{ + /* Check the parameters */ + assert_param(IS_UART_ALL_PERIPH(UARTx)); + + /* Received Data */ + return (uint16_t)(UARTx->RHR & (uint16_t)0x01FF); +} + +/** + * @} + */ + +/** @defgroup UART and LPUART DMA Transfers functions + * @brief UART and LPUART DMA Transmit and Receive enable functions + * +@verbatim + =============================================================================== + ##### DMA Transfer Management Functions ##### + =============================================================================== + [..] This subsection provides a set of functions about DMA Tx/Rx enable functions. + + [..] + + (#) The UART and LPUART DMA enable transmitter API's : + (++) UART_DMATxEnable_Cmd() + + (#) The UART and LPUART DMA enable receiver API's : + (++) UART_DMARxEnable_Cmd() +@endverbatim + * @{ + */ + +/** + * @brief DMA enable transmitter + * @param UARTx: Select UART peripheral from among UART4, UART5, UART7 and LPUART. + * @param NewState: new state of the UARTx DMA enable transmitter. + * This parameter can be: + * @arg ENABLE : DMA mode is enable for transmission. + * @arg DISABLE: DMA mode is disable for transmission. + * @retval None + */ +void UART_DMATxEnable_Cmd(USART_TypeDef* UARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_UART_ALL_PERIPH(UARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the transmission function of DMA mode by setting DMAT bit in the CR register */ + UARTx->CR |= USART_CR_DMAT_EN; + } + else + { + /* Disable the transmission function of DMA mode by clearing DMAT bit in the CR register */ + UARTx->CR &= (uint32_t)~((uint32_t)USART_CR_DMAT_EN); + } +} + +/** + * @brief DMA enable receiver + * @param UARTx: Select UART peripheral from among UART4, UART5, UART7 and LPUART. + * @param NewState: new state of the UARTx DMA enable receiver. + * This parameter can be: + * @arg ENABLE : DMA mode is enable for reception. + * @arg DISABLE: DMA mode is disable for reception. + * @retval None + */ +void UART_DMARxEnable_Cmd(USART_TypeDef* UARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_UART_ALL_PERIPH(UARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the reception function of DMA mode by setting DMAR bit in the CR register */ + UARTx->CR |= USART_CR_DMAR_EN; + } + else + { + /* Disable the reception function of DMA mode by clearing DMAR bit in the CR register */ + UARTx->CR &= (uint32_t)~((uint32_t)USART_CR_DMAR_EN); + } +} + +/** + * @} + */ + +/** @defgroup UART and LPUART low-power management functions + * @brief UART low-power sleep wakeup functions + * LPUART low-power sleep or stop wakeup functions + * +@verbatim + =============================================================================== + ##### Low-Power SLEEP and STOP Wakeup Management Functions ##### + =============================================================================== + [..] This subsection provides a set of functions about UART and LPUART + low-power wakeup management functions. + + [..] + + (#) The UART and LPUART Low-Power SLEEP wakeup configurations API's : + (++) UART_LowPowerSleepWkupConfig() + + (#) The LPUART Low-Power STOP wakeup configurations API's : + (++) LPUART_LowPowerStopWkupConfig() +@endverbatim + * @{ + */ + +/** + * @brief UART and LPUART Low-Power SLEEP wakeup configurations + * @param UARTx: Select UART peripheral from among UART4, UART5, UART7 and LPUART. + * @param NewState: new state of the UARTx Low-Power SLEEP wakeup configurations. + * This parameter can be: + * @arg ENABLE : Enable UARTx module clock in SLEEP mode. + * @arg DISABLE: Disable UARTx module clock in SLEEP mode. + * @retval None + */ +void UART_LowPowerSleepWkupConfig(USART_TypeDef* UARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_UART_ALL_PERIPH(UARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (UARTx == UART4) + { + if (NewState != DISABLE) + { + /* Enable the UART4 module clock in SLEEP mode by setting UART4LPEN bit in the + RCC_APB1LPENR register */ + RCC_APB1PeriphLpenCmd(RCC_APB1PeriphLpen_UART4, ENABLE); + } + else + { + /* Disable the UART4 module clock in SLEEP mode by clearing UART4LPEN bit in the + RCC_APB1LPENR register */ + RCC_APB1PeriphLpenCmd(RCC_APB1PeriphLpen_UART4, DISABLE); + } + } + else if (UARTx == UART5) + { + if (NewState != DISABLE) + { + /* Enable the UART5 module clock in SLEEP mode by setting UART5LPEN bit in the + RCC_APB1LPENR register */ + RCC_APB1PeriphLpenCmd(RCC_APB1PeriphLpen_UART5, ENABLE); + } + else + { + /* Disable the UART5 module clock in SLEEP mode by clearing UART5LPEN bit in the + RCC_APB1LPENR register */ + RCC_APB1PeriphLpenCmd(RCC_APB1PeriphLpen_UART5, DISABLE); + } + } + else if (UARTx == UART7) + { + if (NewState != DISABLE) + { + /* Enable the UART7 module clock in SLEEP mode by setting UART7LPEN bit in the + RCC_APB1LPENR register */ + RCC_APB1PeriphLpenCmd(RCC_APB1PeriphLpen_UART7, ENABLE); + } + else + { + /* Disable the UART7 module clock in SLEEP mode by clearing UART7LPEN bit in the + RCC_APB1LPENR register */ + RCC_APB1PeriphLpenCmd(RCC_APB1PeriphLpen_UART7, DISABLE); + } + } + else if (UARTx == LPUART) + { + if (NewState != DISABLE) + { + /* Enable the LPUART module clock in SLEEP mode by setting LPUARTLPEN bit in the + RCC_APB1LPENR register */ + RCC_APB1PeriphLpenCmd(RCC_APB1PeriphLpen_LPUART, ENABLE); + } + else + { + /* Disable the LPUART module clock in SLEEP mode by clearing LPUARTLPEN bit in the + RCC_APB1LPENR register */ + RCC_APB1PeriphLpenCmd(RCC_APB1PeriphLpen_LPUART, DISABLE); + } + } +} + +/** + * @brief LPUART Low-Power STOP wakeup configurations + * @param UARTx: UART peripheral only for LPUART. + * @param NewState: new state of the LPUART Low-Power STOP wakeup configurations. + * This parameter can be: + * @arg ENABLE : LSE as LPUART clock in STOP mode. + * @arg DISABLE: PCLK as LPUART clock in STOP mode. + * @retval None + */ +void LPUART_LowPowerStopWkupConfig(USART_TypeDef* UARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_UART_LP_PERIPH(UARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* LSE as LPUART clock in STOP mode by setting LPUARTSEL bit in the RCC_CCIPR register */ + RCC_LPUARTCLKConfig(RCC_LPUARTCLK_LSE); + } + else + { + /* PCLK as LPUART clock in STOP mode by clearing LPUARTSEL bit in the RCC_CCIPR register */ + RCC_LPUARTCLKConfig(RCC_LPUARTCLK_PCLK); + } +} + +/** + * @} + */ + +/** @defgroup UART and LPUART Transfers functions + * @brief UART and LPUART Transmit and Receive functions + * +@verbatim + =============================================================================== + ##### Interrupts And Flags Management Functions ##### + =============================================================================== + [..] This subsection provides a set of functions, which is about the UART + and LPUART interrupts and the flags management. + + [..] + + (#) The UART and LPUART interrupts enable API's : + (++) UART_ITConfig() + + (#) The UART and LPUART flags status check API's : + (++) UART_GetFlagStatus() + + (#) The UART and LPUART flags clear API's : + (++) UART_ClearFlag() + + (#) The UART and LPUART interrupt mask check API's : + (++) UART_GetITStatus() + + (#) The UART and LPUART interrupt disable API's : + (++) UART_ITDisableConfig() +@endverbatim + * @{ + */ + +/** + * @brief Enables the specified UART and LPUART interrupts. + * @param UARTx: Select UART peripheral from among UART4, UART5, UART7 and LPUART. + * @param UART_IT: specifies the UART interrupt sources to be enabled or disabled. + * This parameter can be one of the following values: + * @arg UART_IT_TXEMPTY: UART transmitter empty interruption + * @arg UART_IT_TIMEOUT: UART receiver time-out interruption + * @arg UART_IT_PARE : UART parity error interruption + * @arg UART_IT_FRAME : UART framing error interruption + * @arg UART_IT_OVER : UART overrun error interruption + * @arg UART_IT_RXBRK : UART break receive/end of break interruption + * @arg UART_IT_TXRDY : UART transmitter ready interruption + * @arg UART_IT_RXRDY : UART receiver ready interruption + * @arg UART_IT_LINHTE : UART LIN header timeout error interruption + * @arg UART_IT_LINSTE : UART LIN synch tolerance eror interruption + * @arg UART_IT_LINSNRE: UART LIN slave not response error interruption + * @arg UART_IT_LINCE : UART LIN checksum error interruption + * @arg UART_IT_LINIPE : UART LIN identifier parity error interruption + * @arg UART_IT_LINISFE: UART LIN inconsistent synch field error interruption + * @arg UART_IT_LINBE : UART LIN bit error interruption + * @arg UART_IT_LINTC : UART LIN transfer completed interruption + * @arg UART_IT_LINID : UART LIN identifier sent or LIN identifier received interruption + * @arg UART_IT_LINBK : UART LIN break sent or LIN break received interruption + * The following values are only available for UART4, UART5 and UART7, not for LPUART: + * @arg UART_IT_TIMEOUT + * @arg UART_IT_LINHTE + * @arg UART_IT_LINSTE + * @arg UART_IT_LINSNRE + * @arg UART_IT_LINCE + * @arg UART_IT_LINIPE + * @arg UART_IT_LINISFE + * @arg UART_IT_LINBE + * @arg UART_IT_LINTC + * @arg UART_IT_LINID + * @arg UART_IT_LINBK + * @param NewState: new state of the specified UARTx interrupts. + * This parameter can be: + * @arg ENABLE : Enable corresponding interrupt. + * @arg DISABLE: No effect. + * @retval None + * @retval None + */ +void UART_ITConfig(USART_TypeDef* UARTx, uint32_t UART_IT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_UART_ALL_PERIPH(UARTx)); + assert_param(IS_UART_ENABLE_IT(UART_IT)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + UARTx->IER |= (uint32_t)((uint32_t)UART_IT); + } + else + { + UARTx->IER &= (uint32_t)~((uint32_t)UART_IT); + } +} + +/** + * @brief Checks whether the specified UART flag is set or not. + * @param UARTx: Select UART peripheral from among UART4, UART5, UART7 and LPUART. + * @param UART_FLAG: specifies the flag to check. + * This parameter can be one of the following values: + * @arg UART_FLAG_TXEMPTY: transmitter empty + * @arg UART_FLAG_TIMEOUT: receiver time-out + * @arg UART_FLAG_PARE : parity error + * @arg UART_FLAG_FRAME : framing error + * @arg UART_FLAG_OVER : overrun error + * @arg UART_FLAG_RXBRK : break receive/end of break + * @arg UART_FLAG_TXRDY : transmitter ready + * @arg UART_FLAG_RXRDY : receiver ready + * @arg UART_FLAG_LINHTE : LIN header timeout error + * @arg UART_FLAG_LINSTE : LIN synch tolerance eror + * @arg UART_FLAG_LINSNRE: LIN slave not response error + * @arg UART_FLAG_LINCE : LIN checksum error + * @arg UART_FLAG_LINIPE : LIN identifier parity error + * @arg UART_FLAG_LINISFE: LIN inconsistent synch field error + * @arg UART_FLAG_LINBE : LIN bit error + * @arg UART_FLAG_LINBLS : LIN bus line status + * @arg UART_FLAG_LINTC : LIN transfer completed + * @arg UART_FLAG_LINID : LIN identifier sent or LIN identifier received + * @arg UART_FLAG_LINBK : LIN break sent or LIN break received + * The following values are only available for UART4, UART5 and UART7, not for LPUART: + * @arg UART_FLAG_TIMEOUT + * @arg UART_FLAG_LINHTE + * @arg UART_FLAG_LINSTE + * @arg UART_FLAG_LINSNRE + * @arg UART_FLAG_LINCE + * @arg UART_FLAG_LINIPE + * @arg UART_FLAG_LINISFE + * @arg UART_FLAG_LINBE + * @arg UART_FLAG_LINBLS + * @arg UART_FLAG_LINTC + * @arg UART_FLAG_LINID + * @arg UART_FLAG_LINBK + * @retval The new state of UART_FLAG (SET or RESET). + */ +FlagStatus UART_GetFlagStatus(USART_TypeDef* UARTx, uint32_t UART_FLAG) +{ + FlagStatus bitstatus = RESET; + + /* Check the parameters */ + assert_param(IS_UART_ALL_PERIPH(UARTx)); + assert_param(IS_UART_GET_FLAG(UART_FLAG)); + + if ((UARTx->CSR & UART_FLAG) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + return bitstatus; +} + +/** + * @brief Clears the UARTx's pending flags. + * @param UARTx: Select UART peripheral from among UART4, UART5, UART7 and LPUART. + * @param UART_FLAG: specifies the flag to clear. + * This parameter can be any combination of the following values: + * @arg UART_CLEAR_TXEMPTY: transmitter empty interrupt clear + * @arg UART_CLEAR_TIMEOUT: receiver time-out interrupt clear + * @arg UART_CLEAR_PARE : parity error interrupt clear + * @arg UART_CLEAR_FRAME : framing error interrupt clear + * @arg UART_CLEAR_OVER : overrun error interrupt clear + * @arg UART_CLEAR_RXBRK : break receive/end of break interrupt clear + * @arg UART_CLEAR_TXRDY : transmitter ready interrupt clear + * @arg UART_CLEAR_RXRDY : receiver ready interrupt clear + * @arg UART_CLEAR_LINHTE : LIN header timeout error interrupt clear + * @arg UART_CLEAR_LINSTE : LIN synch tolerance eror interrupt clear + * @arg UART_CLEAR_LINSNRE: LIN slave not response error interrupt clear + * @arg UART_CLEAR_LINCE : LIN checksum error interrupt clear + * @arg UART_CLEAR_LINIPE : LIN identifier parity error interrupt clear + * @arg UART_CLEAR_LINISFE: LIN inconsistent synch field error interrupt clear + * @arg UART_CLEAR_LINBE : LIN bit error interrupt clear + * @arg UART_CLEAR_LINTC : LIN transfer completed interrupt clear + * @arg UART_CLEAR_LINID : LIN identifier sent or LIN identifier received interrupt clear + * @arg UART_CLEAR_LINBK : LIN break sent or LIN break received interrupt clear + * The following values are only available for UART4, UART5 and UART7, not for LPUART: + * @arg UART_CLEAR_TIMEOUT + * @arg UART_CLEAR_LINHTE + * @arg UART_CLEAR_LINSTE + * @arg UART_CLEAR_LINSNRE + * @arg UART_CLEAR_LINCE + * @arg UART_CLEAR_LINIPE + * @arg UART_CLEAR_LINISFE + * @arg UART_CLEAR_LINBE + * @arg UART_CLEAR_LINTC + * @arg UART_CLEAR_LINID + * @arg UART_CLEAR_LINBK + * @note LINBLS LIN bus line status bit is cleared when LINRX pin is 0. + * @note TXEMPTY flag bit also can be cleared by a write to the US_THR register (UART_Transmit()). + * @note TXRDY flag bit also can be cleared by a write to the US_THR register (UART_Transmit()). + * @note RXRDY flag bit also can be cleared by a read to the US_RHR register (UART_Receive()). + * @retval None + */ +void UART_ClearFlag(USART_TypeDef* UARTx, uint32_t UART_FLAG) +{ + /* Check the parameters */ + assert_param(IS_UART_ALL_PERIPH(UARTx)); + assert_param(IS_UART_CLEAR_FLAG(UART_FLAG)); + + UARTx->CR |= (uint32_t)UART_FLAG; +} + +/** + * @brief Checks whether the specified UART interrupt has enabled or disabled. + * @param UARTx: Select UART peripheral from among UART4, UART5, UART7 and LPUART. + * @param UART_IT: specifies the UART interrupt source to check. + * This parameter can be one of the following values: + * @arg UART_MASK_TXEMPTY: transmitter empty interrupt mask + * @arg UART_MASK_TIMEOUT: receiver time-out interrupt mask + * @arg UART_MASK_PARE : parity error interrupt mask + * @arg UART_MASK_FRAME : framing error interrupt mask + * @arg UART_MASK_OVER : overrun error interrupt mask + * @arg UART_MASK_RXBRK : break receive/end of break interrupt mask + * @arg UART_MASK_TXRDY : transmitter ready interrupt mask + * @arg UART_MASK_RXRDY : receiver ready interrupt mask + * @arg UART_MASK_LINHTE : LIN header timeout error interrupt mask + * @arg UART_MASK_LINSTE : LIN synch tolerance eror interrupt mask + * @arg UART_MASK_LINSNRE: LIN slave not response error interrupt mask + * @arg UART_MASK_LINCE : LIN checksum error interrupt mask + * @arg UART_MASK_LINIPE : LIN identifier parity error interrupt mask + * @arg UART_MASK_LINISFE: LIN inconsistent synch field error interrupt mask + * @arg UART_MASK_LINBE : LIN bit error interrupt mask + * @arg UART_MASK_LINTC : LIN transfer completed interrupt mask + * @arg UART_MASK_LINID : LIN identifier sent or LIN identifier received interrupt mask + * @arg UART_MASK_LINBK : LIN break sent or LIN break received interrupt mask + * The following values are only available for UART4, UART5 and UART7, not for LPUART: + * @arg UART_MASK_TIMEOUT + * @arg UART_MASK_LINHTE + * @arg UART_MASK_LINSTE + * @arg UART_MASK_LINSNRE + * @arg UART_MASK_LINCE + * @arg UART_MASK_LINIPE + * @arg UART_MASK_LINISFE + * @arg UART_MASK_LINBE + * @arg UART_MASK_LINTC + * @arg UART_MASK_LINID + * @arg UART_MASK_LINBK + * @retval The new state of UART_IT (SET or RESET). + */ +ITStatus UART_GetITStatus(USART_TypeDef* UARTx, uint32_t UART_IT) +{ + ITStatus bitstatus = RESET; + + /* Check the parameters */ + assert_param(IS_UART_ALL_PERIPH(UARTx)); + assert_param(IS_UART_GET_IT(UART_IT)); + + if ((UARTx->IMR & UART_IT) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + + return bitstatus; +} + +/** + * @brief UARTx's interrupt disable configure. + * @param UARTx: Select UART peripheral from among UART4, UART5, UART7 and LPUART. + * @param UART_IT: specifies the interrupt pending bit to clear. + * This parameter can be one of the following values: + * @arg UART_DIS_TXEMPTY: transmitter empty interrupt disable + * @arg UART_DIS_TIMEOUT: receiver time-out interrupt disable + * @arg UART_DIS_PARE : parity error interrupt disable + * @arg UART_DIS_FRAME : framing error interrupt disable + * @arg UART_DIS_OVER : overrun error interrupt disable + * @arg UART_DIS_RXBRK : break receive/end of break interrupt disable + * @arg UART_DIS_TXRDY : transmitter ready interrupt disable + * @arg UART_DIS_RXRDY : receiver ready interrupt disable + * @arg UART_DIS_LINHTE : LIN header timeout error interrupt disable + * @arg UART_DIS_LINSTE : LIN synch tolerance eror interrupt disable + * @arg UART_DIS_LINSNRE: LIN slave not response error interrupt disable + * @arg UART_DIS_LINCE : LIN checksum error interrupt disable + * @arg UART_DIS_LINIPE : LIN identifier parity error interrupt disable + * @arg UART_DIS_LINISFE: LIN inconsistent synch field error interrupt disable + * @arg UART_DIS_LINBE : LIN bit error interrupt disable + * @arg UART_DIS_LINTC : LIN transfer completed interrupt disable + * @arg UART_DIS_LINID : LIN identifier sent or LIN identifier received interrupt disable + * @arg UART_DIS_LINBK : LIN break sent or LIN break received interrupt disable + * The following values are only available for UART4, UART5 and UART7, not for LPUART: + * @arg UART_DIS_TIMEOUT + * @arg UART_DIS_LINHTE + * @arg UART_DIS_LINSTE + * @arg UART_DIS_LINSNRE + * @arg UART_DIS_LINCE + * @arg UART_DIS_LINIPE + * @arg UART_DIS_LINISFE + * @arg UART_DIS_LINBE + * @arg UART_DIS_LINTC + * @arg UART_DIS_LINID + * @arg UART_DIS_LINBK + * @param NewState: new state of the specified UARTx interrupts. + * This parameter can be: + * @arg ENABLE : Disable corresponding interrupt. + * @arg DISABLE: No effect. + * @retval None + */ +void UART_ITDisableConfig(USART_TypeDef* UARTx, uint32_t UART_IT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_UART_ALL_PERIPH(UARTx)); + assert_param(IS_UART_CLEAR_IT(UART_IT)); + + if (NewState != DISABLE) + { + UARTx->IDR |= (uint32_t)((uint32_t)UART_IT); + } + else + { + UARTx->IDR &= (uint32_t)~((uint32_t)UART_IT); + } +} + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_usart.c b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_usart.c new file mode 100644 index 00000000000..aab557cf412 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_usart.c @@ -0,0 +1,3188 @@ +/** + ****************************************************************************** + * @file ft32f4xx_usart.c + * @author FMD AE + * @brief This file provides firmware functions to manage the following + * functionalities of the Universal Synchronous/Asynchronous Receiver Transmitter + * Peripheral (USART). + * + Initialization and de-initialization functions + * + Normal command and configuration functions + * + Fractional baudrate function + * + Break command functions + * + Receiver time-out and transmitter timeguard functions + * + Multidrop mode command function + * + RS485 mode + * + MODEM mode + * + SPI mode functions + * + ISO7816 mode functions + * + IrDA mode function + * + LIN mode functions + * + Write protection register mode functions + * + Data transfers functions + * + DMA transfers management functions + * + Low-Power SLEEP wakeup management function + * + Interrupts and flags management functions + * @version V1.0.0 + * @date 2025-03-21 + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx_usart.h" +#include "ft32f4xx_rcc.h" + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @defgroup USART_Private_Constants USART Private Constants + * @{ + */ +/*!< USART CR register mode field Mask ((~(uint32_t)0xFFFFFF5F)) */ +#define CR_CLEAR_MODE_MASK ((uint32_t)(USART_CR_TXDIS | USART_CR_RXDIS)) /*!< USART CR mode fields of parameters set by USART_Init API */ + +/*!< USART CR register hardware field Mask ((~(uint32_t)0xFFF9FFFF)) */ +#define CR_CLEAR_HARDWARE_MASK ((uint32_t)(USART_CR_RTSDIS | USART_CR_DTRDIS)) /*!< USART CR hardware fields of parameters set by USART_Init API */ + +/*!< USART MR register SPI mode Mask ((~(uint32_t)0xFFEEFEFF)) */ +#define MR_CLEAR_SPI_MASK ((uint32_t)(USART_MR_WRDBT | USART_MR_CPOL | \ + USART_MR_CPHA)) /*!< USART MR SPI mode fields of parameters set by USART_Init API */ + +/*!< USART MR register ISO7816 mode Mask ((~(uint32_t)0xF8CFFFFF)) */ +#define MR_CLEAR_ISO7816_MASK ((uint32_t)(USART_MR_MAX_ITERATION | USART_MR_DSNACK | \ + USART_MR_INACK)) /*!< USART MR ISO7816 mode fields of parameters set by USART_Init API */ + +/*!< USART MR register normal Mask ((~(uint32_t)0xFF700000)) */ +#define MR_CLEAR_NORMAL_MASK ((uint32_t)(USART_MR_INVDATA | USART_MR_OVER | \ + USART_MR_CLKO | USART_MR_MODE9 | \ + USART_MR_MSBF | USART_MR_CHMODE | \ + USART_MR_NBSTOP | USART_MR_PAR | \ + USART_MR_SYNC | USART_MR_CHRL | \ + USART_MR_USCLKS | USART_MR_USART_MODE))/*!< USART MR normal fields of parameters set by USART_Init API */ + +/** + * @} + */ + +/** @defgroup USART init and de-init functions + * @brief None + * +@verbatim + =============================================================================== + ##### Init and DeInit Functions ##### + =============================================================================== + [..] This subsection provides a set of functions about USART initialization + and de-initialization. + + [..] Most USART configurations can be set in the USART_init() function. + However, After USART_Init() function, user can use others configurations + (cfg) functions to change USART configurational. The command (Cmd) + functions can execute control operations under different configurations. + + [..] The configuration procedure of USART_Init() function is as follows: + (++) Check the parameters + (++) Enable USARTx work clock and configuration clock. + (++) USART CR configuration + (#) Configure the USART_Mode: + (-) transmitter disable + (-) transmitter enable + (-) receiver disable + (-) receiver enable + (#) Configure the USART RTS and DTR pins in RS485, MODEM and SPI mode: + (-) Request to send disable + (-) Request to send enable + (-) Data teriminal ready disable + (-) Data teriminal ready enable + (++) USART MR configuration + (#) Special configuration for SPI mode: + (-) Wait read data before transfer + (-) SPI clock polarity + (-) SPI clock phase + (#) Special configuration for ISO7816 protocol T = 0 mode: + (-) Maximum number of automatic iteration + (-) Disable successive NACK + (-) Inhibit non acknowledge + (#) Normal configuration: + (-) Inverted data + (-) Oversampling mode + (-) Clock output select + (-) 9-bit character length + (-) Bit order + (-) channel mode + (-) Number of STOP bits + (-) Parity type + (-) Synchronous mode select + (-) Character length + (-) Clock selection + (-) USART mode of operation + (++) USART FIDI configuration + (++) USART BRGR configuration except fractional part + (++) USART IF configuration + (++) USART LINMR configuration: + (-) Synchronization disable + (-) DMA mode + (-) Data length control + (-) Wakeup signal type + (-) Frame slot mode disable + (-) Data length mode + (-) Checksum type + (-) Checksum disable + (-) Parity disable + (-) LIN node action + + [..] + + (#) The USART init API's : + (++) USART_Init() + + (#) The USART Struct init API's : + (++) USART_StructInit() + + (#) The USART de-init API's : + (++) USART_DeInit() +@endverbatim + * @{ + */ + +/** + * @brief Initialize the USARTx peripheral according to the specified + * parameters in the USART_InitStruct. + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param USART_InitStruct: pointer to a USART_InitTypeDef structure that contains + * the configuration information for the specified USART peripheral. + * @retval None + */ +void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct) +{ + uint32_t clock_divider = 0, frac_divider = 0, apbclock = 0, tmpreg = 0; + + RCC_ClocksTypeDef RCC_ClocksStatus; + + /*------------------------------ Check The Parameter ------------------------*/ + /* Check the normal parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + + if ((USARTx == USART1) || (USARTx == USART6)) + { + assert_param(IS_USART_BAUDRATE(USART_InitStruct->USART_BaudRate)); + } + else if ((USARTx == USART2) || (USARTx == USART3)) + { + assert_param(IS_USART_BAUDRATE_APB1(USART_InitStruct->USART_BaudRate)); + } + + assert_param(IS_USART_CHAR_LENGTH(USART_InitStruct->USART_WordLength)); + assert_param(IS_USART_CLOCK_OUTPUT(USART_InitStruct->USART_ClockOutput)); + assert_param(IS_USART_STOPBITS(USART_InitStruct->USART_StopBits)); + assert_param(IS_USART_PARITY(USART_InitStruct->USART_Parity)); + assert_param(IS_USART_MODE(USART_InitStruct->USART_Mode)); + assert_param(IS_USART_CLOCK_SELECT(USART_InitStruct->USART_CLKSelect)); + assert_param(IS_USART_MODE_OPERATION(USART_InitStruct->USART_OperationMode)); + assert_param(IS_USART_HARDWARE_FLOW_CONTROL(USART_InitStruct->USART_HardwareFlowControl)); + assert_param(IS_USART_SYNC_MODE(USART_InitStruct->USART_Sync)); + assert_param(IS_USART_BIT_ORDER(USART_InitStruct->USART_BitOrder)); + assert_param(IS_USART_CHANNEL_MODE(USART_InitStruct->USART_ChannelMode)); + assert_param(IS_USART_OVERSAMPLING(USART_InitStruct->USART_OverSampling)); + assert_param(IS_USART_INVDATA(USART_InitStruct->USART_INVData)); + + /* Check ISO7816 mode special parameter */ + if ((USART_InitStruct->USART_OperationMode == USART_MODE_OPERATION_ISO7816_T_0) || + (USART_InitStruct->USART_OperationMode == USART_MODE_OPERATION_ISO7816_T_1)) + { + assert_param(IS_USART_FIDIRATIO(USART_InitStruct->USART_FiDiRatio)); + assert_param(IS_USART_ISO7816_T0_INACK(USART_InitStruct->USART_InhibitNACK)); + assert_param(IS_USART_ISO7816_T0_DSNACK(USART_InitStruct->USART_DisSuccessiveNACK)); + assert_param(IS_USART_ISO7816_T0_MAX_ITERATION(USART_InitStruct->USART_MAXIteration)); + } + + /* Check IrDA mode special parameter */ + if (USART_InitStruct->USART_OperationMode == USART_MODE_OPERATION_IrDA) + { + assert_param(IS_USART_IF(USART_InitStruct->USART_IrDAFilter)); + assert_param(IS_USART_FIDIRATIO(USART_InitStruct->USART_FiDiRatio)); + } + + /* Check SPI mode special parameter */ + if ((USART_InitStruct->USART_OperationMode == USART_MODE_OPERATION_SPI_MASTER) || + (USART_InitStruct->USART_OperationMode == USART_MODE_OPERATION_SPI_SLAVE)) + { + assert_param(IS_USART_WRDBT(USART_InitStruct->USART_WRDBT)); + assert_param(IS_USART_POLARITY(USART_InitStruct->USART_CLKPolarity)); + assert_param(IS_USART_PHASE(USART_InitStruct->USART_CLKPhase)); + } + + /* Check LIN mode special parameter */ + if ((USART_InitStruct->USART_OperationMode == USART_MODE_OPERATION_LIN_MASTER) || + (USART_InitStruct->USART_OperationMode == USART_MODE_OPERATION_LIN_SLAVE)) + { + assert_param(IS_USART_SYNC_DISABLE(USART_InitStruct->USART_SYNCDisable)); + assert_param(IS_USART_PDC_MODE_LINMR(USART_InitStruct->USART_PDCMode)); + assert_param(IS_USART_DLC(USART_InitStruct->USART_DataLengthControl)); + assert_param(IS_USART_WKUP_TYPE(USART_InitStruct->USART_WkupType)); + assert_param(IS_USART_FRAME_SLOT_DISABLE(USART_InitStruct->USART_FrameSlotDisable)); + assert_param(IS_USART_DATA_LENGTH_MODE(USART_InitStruct->USART_DataLengthMode)); + assert_param(IS_USART_CHECKSUM_TYPE(USART_InitStruct->USART_CheckSumType)); + assert_param(IS_USART_CHECKSUM_DISABLE(USART_InitStruct->USART_CheckSumDisable)); + assert_param(IS_USART_PARITY_DISABLE(USART_InitStruct->USART_ParityDisable)); + assert_param(IS_USART_NODE_ACTIVE(USART_InitStruct->USART_NodeAction)); + } + + /*----------------------------- Enable The Peripheral -----------------------*/ + if (USARTx == USART1) + { + RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); + } + else if (USARTx == USART2) + { + RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART2, ENABLE); + } + else if (USARTx == USART3) + { + RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART3, ENABLE); + } + else if (USARTx == USART6) + { + RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART6, ENABLE); + } + + /*---------------------------- USART CR Configuration -----------------------*/ + tmpreg = USARTx->CR; + + /* Configure the USART_Mode */ + /* Configure the TXDIS and RXDIS bits */ + USARTx->CR |= ((uint32_t)(CR_CLEAR_MODE_MASK)); + /* Configure the TXEN and RXEN bits */ + tmpreg |= USART_InitStruct->USART_Mode; + + /* Configure the USART RTS in SPI mode and DTR in MODEM mode */ + if ((USART_InitStruct->USART_OperationMode == USART_MODE_OPERATION_MODEM) || + (USART_InitStruct->USART_OperationMode == USART_MODE_OPERATION_SPI_MASTER) || + (USART_InitStruct->USART_OperationMode == USART_MODE_OPERATION_SPI_SLAVE)) + { + /* Configure the hardware flow control bits RTSDIS and DTRDIS */ + USARTx->CR |= ((uint32_t)(CR_CLEAR_HARDWARE_MASK)); + /* Configure the hardware flow control bits RTSEN and DTREN */ + tmpreg |= USART_InitStruct->USART_HardwareFlowControl; + } + + /* Write to USART CR */ + USARTx->CR = tmpreg; + + /*---------------------------- USART MR Configuration -----------------------*/ + tmpreg = USARTx->MR; + + /* Normal configuration */ + /* Set the [23:23]_INVDATA ascording to USART_INVData value */ + /* Set the [19:19]_OVER ascording to USART_OverSampling value */ + /* Set the [18:18]_CLKO ascording to USART_ClockOutput value */ + /* Set the [17:17]_MODE9 ascording to USART_WordLength value */ + /* Set the [16:16]_MSBF ascording to USART_BitOrder value */ + /* Set the [15:14]_CHMODE ascording to USART_ChannelMode value */ + /* Set the [13:12]_NBSTOP ascording to USART_StopBits value */ + /* Set the [11: 9]_PAR ascording to USART_Parity value */ + /* Set the [ 8: 8]_SYNC ascording to USART_Sync value */ + /* Set the [ 7: 6]_CHRL ascording to USART_WordLength value */ + /* Set the [ 5: 4]_USCLKS ascording to USART_CLKSelect value */ + /* Set the [ 3: 0]_USART_MODE ascording to USART_OperationMode value */ + /* Clear the normal cfg bits */ + tmpreg &= (uint32_t)~((uint32_t)MR_CLEAR_NORMAL_MASK); + /* Configure the normal cfg bits */ + tmpreg |= (uint32_t)USART_InitStruct->USART_INVData | + USART_InitStruct->USART_OverSampling | + USART_InitStruct->USART_ClockOutput | + USART_InitStruct->USART_WordLength | + USART_InitStruct->USART_BitOrder | + USART_InitStruct->USART_ChannelMode | + USART_InitStruct->USART_StopBits | + USART_InitStruct->USART_Parity | + USART_InitStruct->USART_Sync | + USART_InitStruct->USART_CLKSelect | + USART_InitStruct->USART_OperationMode ; + + /* Special configuration for SPI mode */ + /* Set the [20:20]_WRDBT(SPI) ascording to USART_WRDBT value */ + /* Set the [16:16]_CPOL(SPI) ascording to USART_CLKPolarity value */ + /* Set the [ 8: 8]_CPHA(SPI) ascording to USART_CLKPhase value */ + if ((USART_InitStruct->USART_OperationMode == USART_MODE_OPERATION_SPI_MASTER) || + (USART_InitStruct->USART_OperationMode == USART_MODE_OPERATION_SPI_SLAVE)) + { + /* Clear the SPI mode cfg bits WRDBT, CPOL and CPHA bits */ + tmpreg &= (uint32_t)~((uint32_t)MR_CLEAR_SPI_MASK); + /* Configure the SPI mode cfg bits WRDBT, CPOL and CPHA bits */ + tmpreg |= (uint32_t)USART_InitStruct->USART_WRDBT | + USART_InitStruct->USART_CLKPolarity | + USART_InitStruct->USART_CLKPhase ; + } + + /* Special configuration for ISO7816 protocol T = 0 mode */ + /* Set the [26:24]_MAX_ITERATION ascording to USART_MAXIteration value */ + /* Set the [21:21]_DSNACK ascording to USART_DisSuccessiveNACK value */ + /* Set the [20:20]_INACK ascording to USART_InhibitNACK value */ + if (USART_InitStruct->USART_OperationMode == USART_MODE_OPERATION_ISO7816_T_0) + { + /* Clear the ISO7816 mode cfg bits MAX_ITERATION, DSNACK and INACK bits */ + tmpreg &= (uint32_t)~((uint32_t)MR_CLEAR_ISO7816_MASK); + /* Configure the ISO7816 mode cfg bits MAX_ITERATION, DSNACK and INACK bits */ + tmpreg |= (uint32_t)USART_InitStruct->USART_MAXIteration | + USART_InitStruct->USART_DisSuccessiveNACK | + USART_InitStruct->USART_InhibitNACK ; + } + + /* Write to USART MR */ + USARTx->MR = tmpreg; + + /*---------------------------- USART FIDI Configuration -----------------------*/ + if ((USART_InitStruct->USART_OperationMode == USART_MODE_OPERATION_ISO7816_T_0) || + (USART_InitStruct->USART_OperationMode == USART_MODE_OPERATION_ISO7816_T_1) || + (USART_InitStruct->USART_OperationMode == USART_MODE_OPERATION_IrDA)) + { + USARTx->FIDI = (uint32_t)USART_InitStruct->USART_FiDiRatio; + } + + /*---------------------------- USART BRGR Configuration -----------------------*/ + tmpreg = USARTx->BRGR; + + /* Configure the USART Baud Rate */ + RCC_GetClocksFreq(&RCC_ClocksStatus); + + if (USARTx == USART1) + { + apbclock = RCC_ClocksStatus.P2CLK_Frequency; + } + else if (USARTx == USART2) + { + apbclock = RCC_ClocksStatus.PCLK_Frequency ; + } + else if (USARTx == USART3) + { + apbclock = RCC_ClocksStatus.PCLK_Frequency ; + } + else if (USARTx == USART6) + { + apbclock = RCC_ClocksStatus.P2CLK_Frequency; + } + + /* Determine the integer part and fraction part disable (fractional part can configure in USART_FracDivider_Cfg()) */ + /* BaudRate not equal 0*/ + if ((USART_InitStruct->USART_BaudRate) > 0) + { + /* Non ISO7816 Mode*/ + if (!((USART_InitStruct->USART_OperationMode == USART_MODE_OPERATION_ISO7816_T_0) || + (USART_InitStruct->USART_OperationMode == USART_MODE_OPERATION_ISO7816_T_1))) + { + /* Async mode*/ + if (!((USART_InitStruct->USART_Sync == USART_SYNC_MODE_SYNC) || + (USART_InitStruct->USART_OperationMode == USART_MODE_OPERATION_SPI_MASTER) || + (USART_InitStruct->USART_OperationMode == USART_MODE_OPERATION_SPI_SLAVE))) + { + /* x16 Oversample*/ + if (USART_InitStruct->USART_OverSampling == USART_OVERSAMPLING_16) + { + clock_divider = (uint32_t)(((apbclock) / ((USART_InitStruct->USART_BaudRate) * 16))); + frac_divider = 0; + } + /* x8 Oversample*/ + else if (USART_InitStruct->USART_OverSampling == USART_OVERSAMPLING_8) + { + clock_divider = (uint32_t)(((apbclock) / ((USART_InitStruct->USART_BaudRate) * 8))); + frac_divider = 0; + } + } + /* Sync mode or SPI mode*/ + else if ((USART_InitStruct->USART_Sync == USART_SYNC_MODE_SYNC) || + (USART_InitStruct->USART_OperationMode == USART_MODE_OPERATION_SPI_MASTER) || + (USART_InitStruct->USART_OperationMode == USART_MODE_OPERATION_SPI_SLAVE)) + { + clock_divider = (uint32_t)((apbclock) / ((USART_InitStruct->USART_BaudRate))); + } + } + /* ISO7816 Mode*/ + else if (((USART_InitStruct->USART_OperationMode == USART_MODE_OPERATION_ISO7816_T_0) || + (USART_InitStruct->USART_OperationMode == USART_MODE_OPERATION_ISO7816_T_1))) + { + clock_divider = (uint32_t)((apbclock) / ((USART_InitStruct->USART_BaudRate) * + (USART_InitStruct->USART_FiDiRatio))); + } + } + /* BaudRate equal 0*/ + else if ((USART_InitStruct->USART_BaudRate) == 0) + { + clock_divider = 0; + frac_divider = 0; + } + + /* Write to USART BRGR */ + USARTx->BRGR = (((uint32_t)(clock_divider)) | ((uint32_t)(frac_divider) << 16U)); + + /*---------------------------- USART IF Configuration -----------------------*/ + /* Write to USART IF in IrDA mode */ + if (USART_InitStruct->USART_OperationMode == USART_MODE_OPERATION_IrDA) + { + USARTx->IF = (uint16_t)USART_InitStruct->USART_IrDAFilter; + } + + /*---------------------------- USART LINMR Configuration --------------------*/ + tmpreg = 0; + + if ((USART_InitStruct->USART_OperationMode == USART_MODE_OPERATION_LIN_MASTER) || + (USART_InitStruct->USART_OperationMode == USART_MODE_OPERATION_LIN_SLAVE)) + { + /* Set the [17:17]_SYNCDIS ascording to USART_SYNCDisable value */ + /* Set the [16:16]_PDCM ascording to USART_PDCMode value */ + /* Set the [15: 8]_DLC ascording to USART_DataLengthControl value */ + /* Set the [ 7: 7]_WKUPTYP ascording to USART_WkupType value */ + /* Set the [ 6: 6]_FSDIS ascording to USART_FrameSlotDisable value */ + /* Set the [ 5: 5]_DLM ascording to USART_DataLengthMode value */ + /* Set the [ 4: 4]_CHKTYP ascording to USART_CheckSumType value */ + /* Set the [ 3: 3]_CHKDIS ascording to USART_CheckSumDisable value */ + /* Set the [ 2: 2]_PARDIS ascording to USART_ParityDisable value */ + /* Set the [ 1: 0]_NACT ascording to USART_NodeAction value */ + tmpreg |= (uint32_t)USART_InitStruct-> USART_SYNCDisable | + USART_InitStruct-> USART_PDCMode | + ((USART_InitStruct-> USART_DataLengthControl << (uint32_t)8)) | + USART_InitStruct-> USART_WkupType | + USART_InitStruct-> USART_FrameSlotDisable | + USART_InitStruct-> USART_DataLengthMode | + USART_InitStruct-> USART_CheckSumType | + USART_InitStruct-> USART_CheckSumDisable | + USART_InitStruct-> USART_ParityDisable | + ((USART_InitStruct-> USART_NodeAction << (uint32_t)0)) ; + + /* Write to USART LINMR*/ + USARTx->LINMR = tmpreg; + } +} + +/** + * @brief Configure each USART_InitStruct member with its default value. + * @param USART_InitStruct: pointer to a USART_InitTypeDef structure + * which will be initialized. + * @retval None + */ +void USART_StructInit(USART_InitTypeDef* USART_InitStruct) +{ + /* USART_InitStruct members default value */ + USART_InitStruct->USART_BaudRate = 9600 ; + USART_InitStruct->USART_FiDiRatio = 174 ; + USART_InitStruct->USART_IrDAFilter = 0 ; + USART_InitStruct->USART_WordLength = USART_CHAR_LENGTH_8BIT ; + USART_InitStruct->USART_ClockOutput = USART_CLOCK_OUTPUT_DISABLE ; + USART_InitStruct->USART_StopBits = USART_STOPBITS_1 ; + USART_InitStruct->USART_Parity = USART_PARITY_NONE ; + USART_InitStruct->USART_Mode = USART_MODE_TX | USART_MODE_RX ; + USART_InitStruct->USART_CLKSelect = USART_CLOCK_SELECT_MCK ; + USART_InitStruct->USART_OperationMode = USART_MODE_OPERATION_NORMAL ; + USART_InitStruct->USART_HardwareFlowControl = USART_HardwareFlowControl_None ; + USART_InitStruct->USART_Sync = USART_SYNC_MODE_ASYNC ; + USART_InitStruct->USART_BitOrder = USART_BIT_ORDER_LSBF ; + USART_InitStruct->USART_ChannelMode = USART_CHANNEL_MODE_NORMAL ; + USART_InitStruct->USART_WRDBT = USART_WRDBT_DISABLE ; + USART_InitStruct->USART_OverSampling = USART_OVERSAMPLING_16 ; + USART_InitStruct->USART_CLKPolarity = USART_POLARITY_LOW ; + USART_InitStruct->USART_CLKPhase = USART_PHASE_2EDGE ; + USART_InitStruct->USART_INVData = USART_INVDATA_DISABLE ; + USART_InitStruct->USART_InhibitNACK = USART_ISO7816_T0_INACK_DISABLE ; + USART_InitStruct->USART_DisSuccessiveNACK = USART_ISO7816_T0_DSNACK_DISABLE ; + USART_InitStruct->USART_MAXIteration = USART_ISO7816_T0_MAX_ITERATION_0; + USART_InitStruct->USART_SYNCDisable = USART_SYNC_DISABLE_NONE ; + USART_InitStruct->USART_PDCMode = USART_PDC_MODE_LINMR_NOTWRITE ; + USART_InitStruct->USART_DataLengthControl = 0 ; + USART_InitStruct->USART_WkupType = USART_WKUP_TYPE_LIN_2_0 ; + USART_InitStruct->USART_FrameSlotDisable = USART_FRAME_SLOT_DISABLE_NONE ; + USART_InitStruct->USART_DataLengthMode = USART_DATA_LENGTH_MODE_DLC ; + USART_InitStruct->USART_CheckSumType = USART_CHECKSUM_TYPE_ENHANCED ; + USART_InitStruct->USART_CheckSumDisable = USART_CHECKSUM_DISABLE_NONE ; + USART_InitStruct->USART_ParityDisable = USART_PARITY_DISABLE_NONE ; + USART_InitStruct->USART_NodeAction = USART_NODE_ACTIVE_PUBLISH ; +} + +/** + * @brief De-Initialize the USARTx peripheral to their default reset value. + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @retval None + */ +void USART_DeInit(USART_TypeDef* USARTx) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + + /* USARTx reset operation */ + if (USARTx == USART1) + { + RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, DISABLE); + } + else if (USARTx == USART2) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART2, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART2, DISABLE); + } + else if (USARTx == USART3) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART3, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART3, DISABLE); + } + else if (USARTx == USART6) + { + RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART6, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART6, DISABLE); + } +} + +/** + * @} + */ + +/** @defgroup USART normal cmd and cfg functions + * @brief USART normal command and configuration functions + * +@verbatim + =============================================================================== + ##### Normal Command And Configuration Functions ##### + =============================================================================== + [..] This subsection provides a set of normal command and configuration + function. + + [..] + + (#) The Normal cmd API's : + (++) USART_Cmd() + (++) USART_RTSDIS_Cmd() + (++) USART_RTSEN_Cmd() + (++) USART_DTRDIS_Cmd() + (++) USART_DTREN_Cmd() + (++) USART_RSTSTA_Cmd() + (++) USART_TXDIS_Cmd() + (++) USART_TXEN_Cmd() + (++) USART_RXDIS_Cmd() + (++) USART_RXEN_Cmd() + (++) USART_RSTTX_Cmd() + (++) USART_RSTRX_Cmd() + + (#) The Normal cfg API's : + (++) USART_InvData_Cfg() + (++) USART_OverSampling8_Cfg() + (++) USART_ClkOutput_Cfg() + (++) USART_DataLength9_Cfg() + (++) USART_MSBFirst_Cfg() + (++) USART_ChannelMode_Cfg() + (++) USART_StopBit_Cfg() + (++) USART_Parity_Cfg() + (++) USART_SYNCMode_Cfg() + (++) USART_DataLength_Cfg() + (++) USART_CLKSelect_Cfg() + (++) USART_OperationMode_Cfg() + + (#) The Normal read API's : + (++) None +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the specified USART peripheral. + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param NewState: new state of the USARTx peripheral. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected USART by setting the USARTxEN bit in the RCC_APB1ENR/APB2ENR register */ + if (USARTx == USART1) + { + RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); + } + else if (USARTx == USART2) + { + RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART2, ENABLE); + } + else if (USARTx == USART3) + { + RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART3, ENABLE); + } + else if (USARTx == USART6) + { + RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART6, ENABLE); + } + } + else + { + /* Disable the selected USART by clearing the USARTxEN bit in the RCC_APB1ENR/APB2ENR register */ + if (USARTx == USART1) + { + RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, DISABLE); + } + else if (USARTx == USART2) + { + RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART2, DISABLE); + } + else if (USARTx == USART3) + { + RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART3, DISABLE); + } + else if (USARTx == USART6) + { + RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART6, DISABLE); + } + } +} + +/** + * @brief Request to send disable. + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param NewState: new state of the USARTx request to send disable. + * This parameter can be: + * @arg ENABLE : Drives the pin RTS to 1 + * @arg DISABLE: No effect + * @retval None + */ +void USART_RTSDIS_Cmd(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Request to send disable by setting RTSDIS bit in the CR register */ + USARTx->CR |= USART_CR_RTSDIS; + } + else + { + /* No effect */ + USARTx->CR &= (uint32_t)~((uint32_t)USART_CR_RTSDIS); + } +} + +/** + * @brief Request to send enable. + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param NewState: new state of the USARTx request to send enable. + * This parameter can be: + * @arg ENABLE : Drives the pin RTS to 0 + * @arg DISABLE: No effect + * @retval None + */ +void USART_RTSEN_Cmd(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Request to send enable by setting RTSEN bit in the CR register */ + USARTx->CR |= USART_CR_RTSEN; + } + else + { + /* No effect */ + USARTx->CR &= (uint32_t)~((uint32_t)USART_CR_RTSEN); + } +} + +/** + * @brief Data terminal ready disable. + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param NewState: new state of the USARTx data terminal ready disable. + * This parameter can be: + * @arg ENABLE : Drives the pin DTR to 1 + * @arg DISABLE: No effect + * @retval None + */ +void USART_DTRDIS_Cmd(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Data terminal ready disable by setting DTRDIS bit in the CR register */ + USARTx->CR |= USART_CR_DTRDIS; + } + else + { + /* No effect */ + USARTx->CR &= (uint32_t)~((uint32_t)USART_CR_DTRDIS); + } +} + +/** + * @brief Data terminal ready enable. + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param NewState: new state of the USARTx data terminal ready enable. + * This parameter can be: + * @arg ENABLE : Drives the pin DTR to 0 + * @arg DISABLE: No effect + * @retval None + */ +void USART_DTREN_Cmd(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Data terminal ready enable by setting DTREN bit in the CR register */ + USARTx->CR |= USART_CR_DTREN; + } + else + { + /* No effect */ + USARTx->CR &= (uint32_t)~((uint32_t)USART_CR_DTREN); + } +} + +/** + * @brief Reset status bits. + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param NewState: new state of the USARTx reset status bits. + * This parameter can be: + * @arg ENABLE : Resets the status bits PARE, FRAME, OVER, LINBE, + * LINISFE, LINIPE, LINCE, LINSNRE, LINSTE, LINHTE, + * LINID, LINTC, LINBK and RXBRK in US_CSR. + * @arg DISABLE: No effect + * @retval None + */ +void USART_RSTSTA_Cmd(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* The status bits reset by setting RSTSTA bit in the CR register */ + USARTx->CR |= USART_CR_RSTSTA; + } + else + { + /* No effect */ + USARTx->CR &= (uint32_t)~((uint32_t)USART_CR_RSTSTA); + } +} + +/** + * @brief Transmitter disable. + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param NewState: new state of the USARTx transmitter disable. + * This parameter can be: + * @arg ENABLE : Disable the transmitter. + * @arg DISABLE: No effect + * @retval None + */ +void USART_TXDIS_Cmd(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* The transmitter disable by setting TXDIS bit in the CR register */ + USARTx->CR |= USART_CR_TXDIS; + } + else + { + /* No effect */ + USARTx->CR &= (uint32_t)~((uint32_t)USART_CR_TXDIS); + } +} + +/** + * @brief Transmitter enable. + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param NewState: new state of the USARTx transmitter enable. + * This parameter can be: + * @arg ENABLE : Enable the transmitter if TXDIS is 0. + * @arg DISABLE: No effect + * @retval None + */ +void USART_TXEN_Cmd(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* The transmitter enable by setting TXEN bit in the CR register */ + USARTx->CR |= USART_CR_TXEN; + } + else + { + /* No effect */ + USARTx->CR &= (uint32_t)~((uint32_t)USART_CR_TXEN); + } +} + +/** + * @brief Receiver disable. + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param NewState: new state of the USARTx receiver disable. + * This parameter can be: + * @arg ENABLE : Disable the receiver. + * @arg DISABLE: No effect + * @retval None + */ +void USART_RXDIS_Cmd(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* The receiver disable by setting RXDIS bit in the CR register */ + USARTx->CR |= USART_CR_RXDIS; + } + else + { + /* No effect */ + USARTx->CR &= (uint32_t)~((uint32_t)USART_CR_RXDIS); + } +} + +/** + * @brief Receiver enable. + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param NewState: new state of the USARTx receiver enable. + * This parameter can be: + * @arg ENABLE : Enable the receiver if RXDIS is 0. + * @arg DISABLE: No effect + * @retval None + */ +void USART_RXEN_Cmd(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* The receiver enable by setting RXEN bit in the CR register */ + USARTx->CR |= USART_CR_RXEN; + } + else + { + /* No effect */ + USARTx->CR &= (uint32_t)~((uint32_t)USART_CR_RXEN); + } +} + +/** + * @brief Reset transmitter + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param NewState: new state of the USARTx reset transmitter. + * This parameter can be: + * @arg ENABLE : Resets the transmitter. + * @arg DISABLE: No effect + * @retval None + */ +void USART_RSTTX_Cmd(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* The transmitter reset by setting RSTTX bit in the CR register */ + USARTx->CR |= USART_CR_RSTTX; + } + else + { + /* No effect */ + USARTx->CR &= (uint32_t)~((uint32_t)USART_CR_RSTTX); + } +} + +/** + * @brief Reset receiver + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param NewState: new state of the USARTx reset receiver. + * This parameter can be: + * @arg ENABLE : Resets the receiver. + * @arg DISABLE: No effect + * @retval None + */ +void USART_RSTRX_Cmd(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* The receiver reset by setting RSTRX bit in the CR register */ + USARTx->CR |= USART_CR_RSTRX; + } + else + { + /* No effect */ + USARTx->CR &= (uint32_t)~((uint32_t)USART_CR_RSTRX); + } +} + +/** + * @brief Inverted data + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param NewState: new state of the USARTx inverted data. + * This parameter can be: + * @arg ENABLE : The data field transmitted on TXD line is inverted + * compared to the value writted on US_THR register or + * the content read in US_RHR is inverted compared to + * what is received on TXD line (or ISO7816 IO line). + * @arg DISABLE: The data field transmitted on TXD line is the same + * as one written in US_THR register or content read in + * US_RHR is the same as RXD line. Normal mode of operation. + * @retval None + */ +void USART_InvData_Cfg(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the invert data function by setting INVDATA bit in the MR register */ + USARTx->MR |= USART_MR_INVDATA; + } + else + { + /* Disable the invert data function by clearing INVDATA bit in the MR register */ + USARTx->MR &= (uint32_t)~((uint32_t)USART_MR_INVDATA); + } +} + +/** + * @brief Oversampling mode + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param NewState: new state of the USARTx oversampling mode. + * This parameter can be: + * @arg ENABLE : 8x oversampling. + * @arg DISABLE: 16x oversampling. + * @retval None + */ +void USART_OverSampling8_Cfg(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the 8x oversampling function by setting OVER bit in the MR register */ + USARTx->MR |= USART_MR_OVER; + } + else + { + /* Disable the 8x oversampling function by clearing OVER bit in the MR register */ + USARTx->MR &= (uint32_t)~((uint32_t)USART_MR_OVER); + } +} + +/** + * @brief Clock output select + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param NewState: new state of the USARTx clock output select. + * This parameter can be: + * @arg ENABLE : The USART drives the SCK pin if USART_CLKSelect does + * not select the external clock SCK. + * @arg DISABLE: The USART does not drive the SCK pin. + * @retval None + */ +void USART_ClkOutput_Cfg(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the USART drives the SCK pin if USART_CLKSelect does not select the + external clock SCK by setting CLKO bit in the MR register */ + USARTx->MR |= USART_MR_CLKO; + } + else + { + /* Disable the USART drives the SCK pin if USART_CLKSelect does not select the + external clock SCK by clearing CLKO bit in the MR register */ + USARTx->MR &= (uint32_t)~((uint32_t)USART_MR_CLKO); + } +} + +/** + * @brief 9-bit character length + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param NewState: new state of the USARTx 9-bit character length. + * This parameter can be: + * @arg ENABLE : 9-bit character length. + * @arg DISABLE: USART_Char_Length defines character length. + * @retval None + */ +void USART_DataLength9_Cfg(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable 9-bit character length by setting MODE9 bit in the MR register */ + USARTx->MR |= USART_MR_MODE9; + } + else + { + /* Disable 9-bit character length by clearing MODE9 bit in the MR register */ + USARTx->MR &= (uint32_t)~((uint32_t)USART_MR_MODE9); + } +} + +/** + * @brief Bit order + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param NewState: new state of the USARTx bit order. + * This parameter can be: + * @arg ENABLE : Most significant bit is sent/received first. + * @arg DISABLE: Least significant bit is sent/received first. + * @retval None + */ +void USART_MSBFirst_Cfg(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable most significant bit is sent/received by setting MSBF bit in the MR register */ + USARTx->MR |= USART_MR_MSBF; + } + else + { + /* Enable least significant bit is sent/received by setting MSBF bit in the MR register */ + USARTx->MR &= (uint32_t)~((uint32_t)USART_MR_MSBF); + } +} + +/** + * @brief Channel mode + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param USART_ChannelMode: channel mode + * This parameter can be one of the following values: + * USART_CHANNEL_MODE_NORMAL - Normal mode + * USART_CHANNEL_MODE_AUTOMATIC - Automatic mode + * USART_CHANNEL_MODE_LOCAL_LOOPBACK - Local loopback mode + * USART_CHANNEL_MODE_REMOTE_LOOPBACK - Remote loopbak mode + * @retval None + */ +void USART_ChannelMode_Cfg(USART_TypeDef* USARTx, uint32_t USART_ChannelMode) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_USART_CHANNEL_MODE(USART_ChannelMode)); + + /* Clear the channel mode by clearing the CHMODE[15:14] bits in the MR register */ + USARTx->MR &= (uint32_t)~((uint32_t)USART_MR_CHMODE); + + /* Set the channel mode by setting the CHMODE[15:14] bits in the MR register */ + USARTx->MR |= (uint32_t)((uint32_t)USART_ChannelMode); +} + +/** + * @brief Number of stop bits + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param USART_StopBits: number of stop bits, + * This parameter can be one of the following values: + * USART_STOPBITS_1 - 1 stop bit + * USART_STOPBITS_1_5 - 1.5 stop bit (SYNC = 0) or reserved (SYNC = 1) + * USART_STOPBITS_2 - 2 stop bits + * @retval None + */ +void USART_StopBit_Cfg(USART_TypeDef* USARTx, uint32_t USART_StopBits) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_USART_STOPBITS(USART_StopBits)); + + /* Clear the number of stop bits by clearing the NBSTOP[13:12] bits in the MR register */ + USARTx->MR &= (uint32_t)~((uint32_t)USART_MR_NBSTOP); + + /* Set the number of stop bits by setting the NBSTOP[13:12] bits in the MR register */ + USARTx->MR |= (uint32_t)((uint32_t)USART_StopBits); +} + +/** + * @brief Parity type + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param USART_Parity: Parity type + * This parameter can be one of the following values: + * USART_PARITY_EVEN - Even parity + * USART_PARITY_ODD - Odd parity + * USART_PARITY_SPACE - Parity forced to 0 (space) + * USART_PARITY_MARK - Parity forced to 1 (mark) + * USART_PARITY_NONE - No parity + * USART_PARITY_MULTIDROP - Multidrop mode + * @retval None + */ +void USART_Parity_Cfg(USART_TypeDef* USARTx, uint32_t USART_Parity) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_USART_PARITY(USART_Parity)); + + /* Clear the parity type by clearing the PAR[11:9] bits in the MR register */ + USARTx->MR &= (uint32_t)~((uint32_t)USART_MR_PAR); + + /* Set the parity type by setting the PAR[11:9] bits in the MR register */ + USARTx->MR |= (uint32_t)((uint32_t)USART_Parity); +} + +/** + * @brief Synchronous mode select + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param NewState: new state of the USARTx synchronous mode select. + * This parameter can be: + * @arg ENABLE : USART operates in synchronous mode. + * @arg DISABLE: USART operated in asynchronous mode. + * @retval None + */ +void USART_SYNCMode_Cfg(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the USART operates in sync mode by setting SYNC bit in the MR register */ + USARTx->MR |= USART_MR_SYNC; + } + else + { + /* Disable the USART operates in sync mode by clearing SYNC bit in the MR register */ + USARTx->MR &= (uint32_t)~((uint32_t)USART_MR_SYNC); + } +} + +/** + * @brief Character length + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param USART_WordLength: character length + * This parameter can be one of the following values: + * USART_CHAR_LENGTH_5BIT - character length is 5 bits + * USART_CHAR_LENGTH_6BIT - character length is 6 bits + * USART_CHAR_LENGTH_7BIT - character length is 7 bits + * USART_CHAR_LENGTH_8BIT - character length is 8 bits + * @retval None + */ +void USART_DataLength_Cfg(USART_TypeDef* USARTx, uint32_t USART_WordLength) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_USART_CHAR_LENGTH(USART_WordLength)); + + /* Clear the character length by clearing the CHRL[7:6] bits in the MR register */ + USARTx->MR &= (uint32_t)~((uint32_t)USART_MR_CHRL); + + /* Set the character length by setting the CHRL[7:6] bits in the MR register */ + USARTx->MR |= (uint32_t)((uint32_t)USART_WordLength); +} + +/** + * @brief Clock selection + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param USART_CLKSelect: clock selection + * This parameter can be one of the following values: + * USART_CLOCK_SELECT_MCK - MCK + * USART_CLOCK_SELECT_MCKDIV8 - MCK / 8 + * USART_CLOCK_SELECT_SCK - SCK + * @retval None + */ +void USART_CLKSelect_Cfg(USART_TypeDef* USARTx, uint32_t USART_CLKSelect) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_USART_CLOCK_SELECT(USART_CLKSelect)); + + /* Clear the clock select by clearing the USCLKS[5:4] bits in the MR register */ + USARTx->MR &= (uint32_t)~((uint32_t)USART_MR_USCLKS); + + /* Set the clock select by setting the USCLKS[5:4] bits in the MR register */ + USARTx->MR |= (uint32_t)((uint32_t)USART_CLKSelect); +} + +/** + * @brief USART mode of operation + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param USART_OperationMode: USART mode of operation + * This parameter can be one of the following values: + * USART_MODE_OPERATION_NORMAL - Normal mode + * USART_MODE_OPERATION_RS485 - RS485 mode + * USART_MODE_OPERATION_MODEM - Modem mode + * USART_MODE_OPERATION_ISO7816_T_0 - ISO7816 protocol: T = 0 + * USART_MODE_OPERATION_ISO7816_T_1 - ISO7816 protocol: T = 1 + * USART_MODE_OPERATION_IrDA - IrDA + * USART_MODE_OPERATION_LIN_MASTER - LIN master + * USART_MODE_OPERATION_LIN_SLAVE - LIN slave + * USART_MODE_OPERATION_SPI_MASTER - SPI master + * USART_MODE_OPERATION_SPI_SLAVE - SPI slave + * + * @retval None + */ +void USART_OperationMode_Cfg(USART_TypeDef* USARTx, uint32_t USART_OperationMode) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_USART_MODE_OPERATION(USART_OperationMode)); + + /* Clear the USART mode of operation by clearing the USART_MODE[3:0] bits in the MR register */ + USARTx->MR &= (uint32_t)~((uint32_t)USART_MR_USART_MODE); + + /* Set the USART mode of operation by setting the USART_MODE[3:0] bits in the MR register */ + USARTx->MR |= (uint32_t)((uint32_t)USART_OperationMode); +} + +/** + * @} + */ + +/** @defgroup USART fractional baudrate function + * @brief USART fractional part of baudrate function + * +@verbatim + =============================================================================== + ##### Fractional Baudrate Functions ##### + =============================================================================== + [..] This subsection provides a function, which can configure fractional part + of baudrate. + + [..] + + (#) The fractional part of baudrate API's : + (++) USART_FracDivider_Cfg() +@endverbatim + * @{ + */ + +/** + * @brief USART fractional part of BaudRate + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param USART_BaudRate: user confige baudrate + * @note This function has to be called after calling USART_Init() function + * in order to have correct fractional part baudrate Divider value. + * @retval None + */ +void USART_FracDivider_Cfg(USART_TypeDef* USARTx, uint32_t USART_BaudRate) +{ + double clock_divider = 0, frac_divider = 0, apbclock = 0; + + RCC_ClocksTypeDef RCC_ClocksStatus; + + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + + if ((USARTx == USART1) || (USARTx == USART6)) + { + assert_param(IS_USART_BAUDRATE(USART_BaudRate)); + } + else if ((USARTx == USART2) || (USARTx == USART3)) + { + assert_param(IS_USART_BAUDRATE_APB1(USART_BaudRate)); + } + + RCC_GetClocksFreq(&RCC_ClocksStatus); + + /* Get USARTx work clock*/ + if (USARTx == USART1) + { + apbclock = RCC_ClocksStatus.P2CLK_Frequency; + } + else if (USARTx == USART2) + { + apbclock = RCC_ClocksStatus.PCLK_Frequency ; + } + else if (USARTx == USART3) + { + apbclock = RCC_ClocksStatus.PCLK_Frequency ; + } + else if (USARTx == USART6) + { + apbclock = RCC_ClocksStatus.P2CLK_Frequency; + } + + /* BaudRate not equal 0*/ + if (USART_BaudRate > 0) + { + /* Non ISO7816 Mode*/ + if (!((((USARTx->MR)&USART_MR_USART_MODE) == USART_MODE_OPERATION_ISO7816_T_0) || + (((USARTx->MR)&USART_MR_USART_MODE) == USART_MODE_OPERATION_ISO7816_T_1))) + { + /* Async mode*/ + if (((USARTx->MR)&USART_MR_SYNC) == USART_SYNC_MODE_ASYNC) + { + /* x16 Oversample*/ + if (((USARTx->MR)&USART_MR_OVER) == USART_OVERSAMPLING_16) + { + clock_divider = (uint32_t)(((apbclock) / ((USART_BaudRate) * 16))); + frac_divider = (uint32_t)(((apbclock) / ((USART_BaudRate) * 16) - clock_divider) * 8); + } + /* x8 Oversample*/ + if (((USARTx->MR)&USART_MR_OVER) == USART_OVERSAMPLING_8) + { + clock_divider = (uint32_t)(((apbclock) / ((USART_BaudRate) * 8))); + frac_divider = (uint32_t)(((apbclock) / ((USART_BaudRate) * 8) - clock_divider) * 8); + } + } + } + } + + /* Clear the USART fractional part by clearing the FP[18:16] bits in the BRGR register */ + USARTx->BRGR &= (uint32_t)~((uint32_t)USART_BRGR_FP); + + /* Set the USART fractional part by setting the FP[18:16] bits in the BRGR register */ + USARTx->BRGR |= (((uint32_t)frac_divider) << 16U); +} + +/** + * @} + */ + +/** @defgroup USART BREAK command functions + * @brief None + * +@verbatim + =============================================================================== + ##### Break Command Functions ##### + =============================================================================== + [..] This subsection provides a set of BREAK command functions. + + [..] + + (#) The stop break command API's : + (++) USART_STPBRK_Cmd() + + (#) The start break command API's : + (++) USART_STTBRK_Cmd() +@endverbatim + * @{ + */ + +/** + * @brief Stop break. + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param NewState: new state of the USARTx stop break. + * This parameter can be: + * @arg ENABLE : Stops transmission of break after a minimum of one character length and + * transmits a high level during 12-bit periods. + * @arg DISABLE: No effect + * @retval None + */ +void USART_STPBRK_Cmd(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Stops transmission of break after a minimum of one character by setting STPBRK + bit in the CR register */ + USARTx->CR |= USART_CR_STPBRK; + } + else + { + /* No effect */ + USARTx->CR &= (uint32_t)~((uint32_t)USART_CR_STPBRK); + } +} + +/** + * @brief Start break. + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param NewState: new state of the USARTx start break. + * This parameter can be: + * @arg ENABLE : Starts transmission of break after the character present in US_THR and + * the transmit shift register have been transmitted. No effect if a break + * is already being transmitted. + * @arg DISABLE: No effect + * @retval None + */ +void USART_STTBRK_Cmd(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Starts transmission of the break after the characters present in US_THR and the transmit + shift register have been transmitted by setting STTBRK bit in the CR register */ + USARTx->CR |= USART_CR_STTBRK; + } + else + { + /* No effect */ + USARTx->CR &= (uint32_t)~((uint32_t)USART_CR_STTBRK); + } +} + +/** + * @} + */ + +/** @defgroup USART receiver time-out and transmitter timeguard functions + * @brief Receiver time-out cfg and cmd functions. + * Transmitter timeguard cfg function. + * +@verbatim + =============================================================================== + ##### Receiver Time-out And Transmitter Timeguard Functions ##### + =============================================================================== + [..] This subsection provides a set of receiver time-out and transmitter + timeguard functions. + + [..] + + (#) The receiver time-out cfg API's : + (++) USART_Receiver_TimeOut_Cfg() + + (#) The receiver time-out cmd API's : + (++) USART_RETTO_After_Timeout_Cmd() + (++) USART_STTTO_After_Timeout_Cmd() + + (#) The transmitter timeguard cfg API's : + (++) USART_Transmitter_TimeGuard_Cfg() +@endverbatim + * @{ + */ + +/** + * @brief Receiver time-out value + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param USART_ReceiverTimeOut: Time-out value + * 0 : The receiver time-out is disabled. + * 1 - 65535 : The receiver time-out is enabled and time-out + * delay is TO * bit period. + * 1 - 131071: The receiver time-out is enabled and time-out + * delay is TO * bit period. + * @note This function has to be called before calling USART_Init() function + * in order to have correct receiver time-out value. + * @retval None + */ +void USART_Receiver_TimeOut_Cfg(USART_TypeDef* USARTx, uint32_t USART_ReceiverTimeOut) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_USART_TIMEOUT(USART_ReceiverTimeOut)); + + /* Clear the time-out value of receiver by clearing the TO[16:0] bits in the RTOR register */ + USARTx->RTOR &= (uint32_t)~((uint32_t)USART_RTOR_TO); + + /* Set the time-out value of receiver setting the TO[16:0] bits in the RTOR register */ + USARTx->RTOR |= (uint32_t)((uint32_t)USART_ReceiverTimeOut); +} + +/** + * @brief Rearm Time-out. + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param NewState: new state of the USARTx rearm Time-out. + * This parameter can be: + * @arg ENABLE : Restart Time-out + * @arg DISABLE: No effect + * @retval None + */ +void USART_RETTO_After_Timeout_Cmd(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Restart Time-out by setting RETTO bit in the CR register */ + USARTx->CR |= USART_CR_RETTO; + } + else + { + /* No effect */ + USARTx->CR &= (uint32_t)~((uint32_t)USART_CR_RETTO); + } +} + +/** + * @brief Start time-out. + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param NewState: new state of the USARTx start time-out. + * This parameter can be: + * @arg ENABLE : Starts waiting for a character before clocking the time-out counter. + * Resets the status bit TIMEOUT in US_CSR. + * @arg DISABLE: No effect + * @retval None + */ +void USART_STTTO_After_Timeout_Cmd(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Starts waiting for a character before clocking the time-out counter by setting + STTTO bit in the CR register */ + USARTx->CR |= USART_CR_STTTO; + } + else + { + /* No effect */ + USARTx->CR &= (uint32_t)~((uint32_t)USART_CR_STTTO); + } +} + +/** + * @brief Transmitter timeguard value + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param USART_TransmitterTimeGuard: timeguard value + * 0 : The transmitter timeguard value is disabled. + * 1 - 255: The transmitter timeguard is enabled and the + * timeguard delay is TG * bit period. + * @note This function has to be called before calling USART_Init() function + * in order to have correct transmitter timeguard value. + * @retval None + */ +void USART_Transmitter_TimeGuard_Cfg(USART_TypeDef* USARTx, uint32_t USART_TransmitterTimeGuard) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_USART_TIMGUARD(USART_TransmitterTimeGuard)); + + /* Clear the timeguard value of transmitter by clearing the TG[7:0] bits in the TTGR register */ + USARTx->TTGR &= (uint32_t)~((uint32_t)USART_TTGR_TG); + + /* Set the timeguard value of transmitter setting the TG[7:0] bits in the TTGR register */ + USARTx->TTGR |= (uint32_t)((uint32_t)USART_TransmitterTimeGuard); +} + +/** + * @} + */ + +/** @defgroup USART multidrop mode cmd function + * @brief Multidrop mode command function. + * +@verbatim + =============================================================================== + ##### Multidrop Mode Command Function ##### + =============================================================================== + [..] This subsection provides the multidrop mode command function. + + [..] + + (#) The multidrop mode command API's : + (++) USART_SENDAInMultidropMode_Cmd() + +@endverbatim + * @{ + */ + +/** + * @brief Send address. + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param NewState: new state of the USARTx send address. + * This parameter can be: + * @arg ENABLE : In multidrop mode only, the next character written to + * the US_THR is sent with address bit set. + * @arg DISABLE: No effect + * @retval None + */ +void USART_SENDAInMultidropMode_Cmd(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* In multidrop mode only, the next character writted to the US_THR is sent + with the address bit set by setting SENDA bit in the CR register */ + USARTx->CR |= USART_CR_SENDA; + } + else + { + /* No effect */ + USARTx->CR &= (uint32_t)~((uint32_t)USART_CR_SENDA); + } +} + +/** + * @} + */ + +/** @defgroup USART SPI mode cmd, cfg, and read functions + * @brief USART SPI mode mode command, configuration and read functions + * +@verbatim + =============================================================================== + ##### SPI Mode Functions ##### + =============================================================================== + [..] This subsection provides a set of SPI mode functions. + + [..] + + (#) The SPI mode cmd API's : + (++) USART_RCS_Cmd() + (++) USART_FCS_Cmd() + + (#) The SPI mode cfg API's : + (++) USART_WRDBT_Cfg() + (++) USART_CLKPolarity_Cfg() + (++) USART_CLKPhase_Cfg() + + (#) The SPI mode read API's : + (++) None +@endverbatim + * @{ + */ + +/** + * @brief Release SPI chip select + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param NewState: new state of the USARTx release SPI chip select. + * This parameter can be: + * @arg ENABLE : Releases the slave select lin NSS (RTS pin). + * Applicable if USARTx operates in SPI Master. + * @arg DISABLE: No effect + * @retval None + */ +void USART_RCS_Cmd(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Release the slave slect line (RTS pin) by setting RCS bit in + the CR(SPI_MODE) register */ + USARTx->CR |= USART_CR_RCS; + } + else + { + /* No effect */ + USARTx->CR &= (uint32_t)~((uint32_t)USART_CR_RCS); + } +} + +/** + * @brief Force SPI chip select + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param NewState: new state of the USARTx force SPI chip select. + * This parameter can be: + * @arg ENABLE : Forces the slave select lin NSS (RTS pin) to 0, + * even if USART is no transmitting, in order to + * address SPI slave devices supporting the CSAAT + * mode (Chip Select Active After Transfer). + * Applicable if USARTx operates in SPI Master. + * @arg DISABLE: No effect + * @retval None + */ +void USART_FCS_Cmd(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Force the slave slect line (RTS pin) by setting FCS bit in the + CR(SPI_MODE) register */ + USARTx->CR |= USART_CR_FCS; + } + else + { + /* No effect */ + USARTx->CR &= (uint32_t)~((uint32_t)USART_CR_FCS); + } +} + +/** + * @brief Wait read data before transfre + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param NewState: new state of the USARTx wait read data before transfer. + * This parameter can be: + * @arg ENABLE : The character transmission starts when a character + * is written and only if RXRDY flag is cleared (Receiver + * Holding register has been read). + * @arg DISABLE: The character transmission starts as soon as a character + * is written into US_THR register (assuming TXRDY was set). + * @retval None + */ +void USART_WRDBT_Cfg(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the transmission after read data by setting WRDBT bit in the MR register */ + USARTx->MR |= USART_MR_WRDBT; + } + else + { + /* Disable the transmission after read data by clearing WRDBT bit in the MR register */ + USARTx->MR &= (uint32_t)~((uint32_t)USART_MR_WRDBT); + } +} + +/** + * @brief SPI clock polarity + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param NewState: new state of the USARTx spi operates clock polarity, + * applicable if USART operates in SPI mode (slave or master). + * This parameter can be: + * @arg ENABLE : The inactive status value of SPCK is logic level one. + * @arg DISABLE: The inactive status value of SPCK is logic level zero. + * @retval None + */ +void USART_CLKPolarity_Cfg(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the spi clock polarity by setting CPOL bit in the MR register */ + USARTx->MR |= USART_MR_CPOL; + } + else + { + /* Disable the spi clock polarity by clearing CPOL bit in the MR register */ + USARTx->MR &= (uint32_t)~((uint32_t)USART_MR_CPOL); + } +} + +/** + * @brief SPI clock phase + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param NewState: new state of the USARTx spi operates clock phase, + * applicable if USART operates in SPI mode (slave or master). + * This parameter can be: + * @arg ENABLE : Data is captured on the leading edge of SPCK and + * changed on the following edge of SPCK. + * @arg DISABLE: Data is changeded on the leading edge of SPCK and + * captured on the following edge of SPCK. + * @retval None + */ +void USART_CLKPhase_Cfg(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the spi clock phase by setting CPHA bit in the MR register */ + USARTx->MR |= USART_MR_CPHA; + } + else + { + /* Disable the spi clock phase by clearing CPHA bit in the MR register */ + USARTx->MR &= (uint32_t)~((uint32_t)USART_MR_CPHA); + } +} + +/** + * @} + */ + +/** @defgroup USART ISO7816 mode cmd, cfg, and read functions + * @brief USART ISO7816 mode mode command, configuration and read functions + * +@verbatim + =============================================================================== + ##### ISO7816 Mode Functions ##### + =============================================================================== + [..] This subsection provides a set of ISO7816 mode functions. + + [..] + + (#) The ISO7816 mode cmd API's : + (++) USART_RSTNACK_Cmd() + (++) USART_RSTIT_Cmd() + + (#) The ISO7816 mode cfg API's : + (++) USART_MaxIteration_Cfg() + (++) USART_DsNack_Cfg() + (++) USART_INack_Cfg() + (++) USART_FiDiRatio_Cfg() + + (#) The ISO7816 mode read API's : + (++) USART_GetNumberOfError() +@endverbatim + * @{ + */ + +/** + * @brief Reset non acknowledge. + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param NewState: new state of the USARTx reset non acknowledge. + * This parameter can be: + * @arg ENABLE : Reset NACK in US_CSR + * @arg DISABLE: No effect + * @retval None + */ +void USART_RSTNACK_Cmd(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Reset the NACK in US_CSR by setting RSTNACK bit in the CR register */ + USARTx->CR |= USART_CR_RSTNACK; + } + else + { + /* No effect */ + USARTx->CR &= (uint32_t)~((uint32_t)USART_CR_RSTNACK); + } +} + +/** + * @brief Reset iterations. + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param NewState: new state of the USARTx reset iterations. + * This parameter can be: + * @arg ENABLE : Reset ITERATION in US_CSR (No effect if the ISO7816 is not enabled). + * @arg DISABLE: No effect + * @retval None + */ +void USART_RSTIT_Cmd(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Reset the ITERATION in US_CSR by setting RSTIT bit in the CR register */ + USARTx->CR |= USART_CR_RSTIT; + } + else + { + /* No effect */ + USARTx->CR &= (uint32_t)~((uint32_t)USART_CR_RSTIT); + } +} + +/** + * @brief Maximum number of automatic iteration + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param USART_MAXIteration: Defines the maximum number of iterations in mode ISO7816, + * protocol T = 0 + * This parameter can be one of the following values: + * USART_ISO7816_T0_MAX_ITERATION_0 - USART max_iteration with 0 times + * USART_ISO7816_T0_MAX_ITERATION_1 - USART max_iteration with 1 times + * USART_ISO7816_T0_MAX_ITERATION_2 - USART max_iteration with 2 times + * USART_ISO7816_T0_MAX_ITERATION_3 - USART max_iteration with 4 times + * USART_ISO7816_T0_MAX_ITERATION_5 - USART max_iteration with 5 times + * USART_ISO7816_T0_MAX_ITERATION_6 - USART max_iteration with 6 times + * USART_ISO7816_T0_MAX_ITERATION_7 - USART max_iteration with 7 times + * @retval None + */ +void USART_MaxIteration_Cfg(USART_TypeDef* USARTx, uint32_t USART_MAXIteration) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_USART_ISO7816_T0_MAX_ITERATION(USART_MAXIteration)); + + /* Clear the maximum number of automatic iteration value by clearing the MAX_ITERATION[26:24] + bits in the MR register */ + USARTx->MR &= (uint32_t)~((uint32_t)USART_MR_MAX_ITERATION); + + /* Set the maximum number of automatic iteration value by setting the MAX_ITERATION[26:24] + bits in the MR register */ + USARTx->MR |= (uint32_t)((uint32_t)USART_MAXIteration); +} + +/** + * @brief Disable Successive NACK + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param NewState: new state of the USARTx disable successive NACK. + * This parameter can be: + * @arg ENABLE : Successive parity errors are counted up to the value + * specificed in the MAX_ITERATION field. + * @arg DISABLE: NACK is sent on the ISO line as soon as a parity error + * occurs in the received character (unless INACK is set). + * @retval None + */ +void USART_DsNack_Cfg(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the disable successive NACK function by setting DSNACK bit in the MR register */ + USARTx->MR |= USART_MR_DSNACK; + } + else + { + /* Disable the disable successive NACK function by clearing DSNACK bit in the MR register */ + USARTx->MR &= (uint32_t)~((uint32_t)USART_MR_DSNACK); + } +} + +/** + * @brief Inhibit non acknowledge + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param NewState: new state of the USARTx inhibit non acknowledge. + * This parameter can be: + * @arg ENABLE : The NACK is not generated. + * @arg DISABLE: The NACK is generated. + * @retval None + */ +void USART_INack_Cfg(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the inhibit non acknowledge function by setting INACK bit in the MR register */ + USARTx->MR |= USART_MR_INACK; + } + else + { + /* Disable the inhibit non acknowledge function by clearing INACK bit in the MR register */ + USARTx->MR &= (uint32_t)~((uint32_t)USART_MR_INACK); + } +} + +/** + * @brief Fi over Di ratio value + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param USART_FiDiRatio: user config Fi_Di_Ratio + * @param USART_BaudRate: user confige baudrate + * @note This function has to be called when user need to change Fi_Di_Ratio + * after USART_Init() function, CD fields of BRGR change as bellow: + * CD = MCK / (BaudRate * FiDiRatio). + * @retval None + */ +void USART_FiDiRatio_Cfg(USART_TypeDef* USARTx, uint32_t USART_FiDiRatio, uint32_t USART_BaudRate) +{ + uint32_t clock_divider = 0, apbclock = 0; + RCC_ClocksTypeDef RCC_ClocksStatus; + + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + + if ((USARTx == USART1) || (USARTx == USART6)) + { + assert_param(IS_USART_BAUDRATE(USART_BaudRate)); + } + else if ((USARTx == USART2) || (USARTx == USART3)) + { + assert_param(IS_USART_BAUDRATE_APB1(USART_BaudRate)); + } + + assert_param(IS_USART_FIDIRATIO(USART_FiDiRatio)); + + RCC_GetClocksFreq(&RCC_ClocksStatus); + + /* Get USARTx work clock*/ + if (USARTx == USART1) + { + apbclock = RCC_ClocksStatus.P2CLK_Frequency; + } + else if (USARTx == USART2) + { + apbclock = RCC_ClocksStatus.PCLK_Frequency ; + } + else if (USARTx == USART3) + { + apbclock = RCC_ClocksStatus.PCLK_Frequency ; + } + else if (USARTx == USART6) + { + apbclock = RCC_ClocksStatus.P2CLK_Frequency; + } + + /* BaudRate not equal 0*/ + if (USART_BaudRate > 0) + { + /* ISO7816 Mode*/ + if ((((USARTx->MR)&USART_MR_USART_MODE) == USART_MODE_OPERATION_ISO7816_T_0) || + (((USARTx->MR)&USART_MR_USART_MODE) == USART_MODE_OPERATION_ISO7816_T_1)) + { + clock_divider = (uint32_t)(((apbclock) / ((USART_BaudRate) * USART_FiDiRatio))); + } + } + + /* Clear the USART clock divider by clearing the CD[15:0] bits in the BRGR register */ + USARTx->BRGR &= (uint32_t)~((uint32_t)USART_BRGR_CD); + + /* Set the USART clock divider by setting the CD[15:0] bits in the BRGR register */ + USARTx->BRGR |= ((uint32_t)clock_divider); + + /* Clear the USART Fi_Di_Ration by clearing the FI_DI_RATIO[15:0] bits in the FIDI register */ + USARTx->FIDI &= (uint32_t)~((uint32_t)USART_FIDI_FI_DI_RATIO); + + /* Set the USART Fi_Di_Ration by setting the FI_DI_RATIO[15:0] bits in the FIDI register */ + USARTx->FIDI |= ((uint32_t)USART_FiDiRatio); +} + +/** + * @brief Returns the number of error by the USARTx peripheral. + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @note Total number of errors that occurred during an ISO7816 transfer. + * This register automatically clears when read. + * @retval The number of error. + */ +uint32_t USART_GetNumberOfError(USART_TypeDef* USARTx) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + + /* Return the number of errors that occured during an ISO7816 transfer */ + return (uint32_t)((USARTx->NER)); +} + +/** + * @} + */ + +/** @defgroup USART IrDA mode cfg functions + * @brief USART IrDA mode mode configuration function + * +@verbatim + =============================================================================== + ##### IrDA Mode Functions ##### + =============================================================================== + [..] This subsection provides a IrDA mode function. + + [..] + + (#) The IrDA mode cfg API's : + (++) USART_IrDAFilter_Cfg() + +@endverbatim + * @{ + */ + +/** + * @brief IrDA Filter + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param USART_IrDAFilter: The IRDA_FILTER value must be defined to meet the + * following criteria: + * tMCK * (IRDA_FILTER + 3) < 1.41us + * @retval None + */ +void USART_IrDAFilter_Cfg(USART_TypeDef* USARTx, uint32_t USART_IrDAFilter) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_USART_IF(USART_IrDAFilter)); + + /* Clear the IrDA filter value by clearing the IRDA_FILTER[7:0] bits in the IF register */ + USARTx->IF &= (uint32_t)~((uint32_t)USART_IF_IRDA_FILTER); + + /* Set the IrDA filter value by setting the IRDA_FILTER[7:0] bits in the IF register */ + USARTx->IF |= (uint32_t)((uint32_t)USART_IrDAFilter); +} + +/** + * @} + */ + +/** @defgroup USART LIN mode cmd, cfg, and read functions + * @brief USART LIN mode mode command, configuration and read functions + * +@verbatim + =============================================================================== + ##### LIN Mode Functions ##### + =============================================================================== + [..] This subsection provides a set of LIN mode functions. + + [..] + + (#) The LIN mode cmd API's : + (++) USART_LINWKUP_Cmd() + (++) USART_LINABT_Cmd() + + (#) The LIN mode cfg API's : + (++) USART_Write_LINIR_In_LIN_Master() + (++) USART_SYNCDisable_Cfg() + (++) USART_PDCMode_Cfg() + (++) USART_DataLengthControl_Cfg() + (++) USART_WkupType_Cfg() + (++) USART_FrameSlotDisable_Cfg() + (++) USART_DataLengthMode_Cfg() + (++) USART_CheckSumType_Cfg() + (++) USART_CheckSumDisable_Cfg() + (++) USART_ParityDisable_Cfg() + (++) USART_NodeAction_Cfg() + + (#) The LIN mode read API's : + (++) USART_Read_LINIR_In_LIN_Slave() + (++) USART_LINBaudRate() +@endverbatim + * @{ + */ + +/** + * @brief Send LIN Wakeup Signal. + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param NewState: new state of the USARTx send LIN wakeup signal. + * This parameter can be: + * @arg ENABLE : Sends a wakeup signal on LIN bus + * @arg DISABLE: No effect + * @retval None + */ +void USART_LINWKUP_Cmd(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Sends a wakeup signal on LIN bus by setting LINWKUP bit in the CR register */ + USARTx->CR |= USART_CR_LINWKUP; + } + else + { + /* No effect */ + USARTx->CR &= (uint32_t)~((uint32_t)USART_CR_LINWKUP); + } +} + +/** + * @brief Abort LIN Transmission. + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param NewState: new state of the USARTx abort LIN transmission. + * This parameter can be: + * @arg ENABLE : Abort LIN transmission + * @arg DISABLE: No effect + * @retval None + */ +void USART_LINABT_Cmd(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Abort the LIN transmission by setting LINABT bit in the CR register */ + USARTx->CR |= USART_CR_LINABT; + } + else + { + /* No effect */ + USARTx->CR &= (uint32_t)~((uint32_t)USART_CR_LINABT); + } +} + +/** + * @brief Write identifier character in LIN master mode + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param USART_LINIR_Data: if USART_OperationMode = 0xA (Master node configure), + * USART_LINIR_Data is read-write and its value is the + * identifier character to be transmitted. + * @note This function has to be called after calling USART_Init() function + * in order to have correct identifer value in LIN master mode. + * @retval None + */ +void USART_Write_LINIR_In_LIN_Master(USART_TypeDef* USARTx, uint32_t USART_LINIR_Data) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_USART_LINIR_WR(USART_LINIR_Data)); + + /* Clear the identifier value to be transmitted in LIN master node by clearing + the IDCHR[7:0] bits in the LINIR register */ + USARTx->LINIR &= (uint32_t)~((uint32_t)USART_LINIR_IDCHR); + + /* Set the identifier value to be transmitted in LIN master node by setting + the IDCHR[7:0] bits in the LINIR register */ + USARTx->LINIR |= (uint32_t)((uint32_t)USART_LINIR_Data); +} + +/** + * @brief Synchronization disable in LIN mode + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param NewState: new state of the USARTx LIN synchronization disable, + * applicable if USART operates in LIN mode. + * This parameter can be: + * @arg ENABLE : The synchronization procedure is not performed in LIN + * slave node configure. + * @arg DISABLE: The synchronization procedure is performed in LIN + * slave node configure. + * @retval None + */ +void USART_SYNCDisable_Cfg(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the synchronization procedure's disable by setting SYNCDIS bit in the LINMR register */ + USARTx->LINMR |= USART_LINMR_SYNCDIS; + } + else + { + /* Disable the synchronization procedure's disable by clearing SYNCDIS bit in the LINMR register */ + USARTx->LINMR &= (uint32_t)~((uint32_t)USART_LINMR_SYNCDIS); + } +} + +/** + * @brief DMA mode in LIN mode + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param NewState: new state of the USARTx LIN DMA mode, + * applicable if USART operates in LIN mode. + * This parameter can be: + * @arg ENABLE : The LIN mode register US_LINMR (excepting that flag) + * is written by the DMA. + * @arg DISABLE: The LIN mode register US_LINMR is not written by the DMA. + * @retval None + */ +void USART_PDCMode_Cfg(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the DMA written of LINMR by setting PDCM bit in the LINMR register */ + USARTx->LINMR |= USART_LINMR_PDCM; + } + else + { + /* Disable the DMA written of LINMR by clearing PDCM bit in the LINMR register */ + USARTx->LINMR &= (uint32_t)~((uint32_t)USART_LINMR_PDCM); + } +} + +/** + * @brief Data length control in LIN mode + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param USART_DataLengthControl: (0 - 255) Defines the response data length + * if USART_DataLengthMode = 0, in that case + * the response data length is equal to + * USART_DataLengthControl + 1 bytes; + * @retval None + */ +void USART_DataLengthControl_Cfg(USART_TypeDef* USARTx, uint32_t USART_DataLengthControl) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_USART_DLC(USART_DataLengthControl)); + + /* Clear the response data length value of LIN mode (USART_DataLengthMode = 0) + by clearing the DLC[15:8] bits in the LINMR register */ + USARTx->LINMR &= (uint32_t)~((uint32_t)USART_LINMR_DLC); + + /* Set the response data length value of LIN mode (USART_DataLengthMode = 0) + by setting the DLC[15:8] bits in the LINMR register */ + USARTx->LINMR |= (uint32_t)((uint32_t)USART_DataLengthControl << 8U); +} + +/** + * @brief Wakeup signal type in LIN mode + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param NewState: new state of the USARTx LIN wakeup signal type. + * This parameter can be: + * @arg ENABLE : Setting the bit LINWKUP in the control register send + * a LIN 1.3 wakeup signal. + * @arg DISABLE: Setting the bit LINWKUP in the control register send + * a LIN 2.0 wakeup signal. + * @retval None + */ +void USART_WkupType_Cfg(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the LIN 1.3 wakeup signal as the wakeup type to send by setting WKUPTYP + bit in the LINMR register */ + USARTx->LINMR |= USART_LINMR_WKUPTYP; + } + else + { + /* Disable the LIN 1.3 wakeup signal as the wakeup type to send by clearing WKUPTYP + bit in the LINMR register */ + USARTx->LINMR &= (uint32_t)~((uint32_t)USART_LINMR_WKUPTYP); + } +} + +/** + * @brief Frame slot mode disable in LIN mode + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param NewState: new state of the USARTx LIN frame slot mode disable. + * This parameter can be: + * @arg ENABLE : The frame slot mode is disabled. + * @arg DISABLE: The frame slot mode is enabled. + * @retval None + */ +void USART_FrameSlotDisable_Cfg(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the frame slot mode's disable by setting FSDIS bit in the LINMR register */ + USARTx->LINMR |= USART_LINMR_FSDIS; + } + else + { + /* Disable the frame slot mode's disable by clearing FSDIS bit in the LINMR register */ + USARTx->LINMR &= (uint32_t)~((uint32_t)USART_LINMR_FSDIS); + } +} + +/** + * @brief Data length mode in LIN mode + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param NewState: new state of the USARTx LIN data length mode. + * This parameter can be: + * @arg ENABLE : The response data length is defined by the bits 5 + * and 6 of the identifier (IDCHR in US_LINIR). + * @arg DISABLE: The response data length is defined by the field + * DLC of US_LINMR register. + * @retval None + */ +void USART_DataLengthMode_Cfg(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the response data length is defined by the bits 5 and 6 of the identifier + (IDCHR in US_LINIR) by setting DLM bit in the LINMR register */ + USARTx->LINMR |= USART_LINMR_DLM; + } + else + { + /* Disable the response data length is defined by the bits 5 and 6 of the identifier + (IDCHR in US_LINIR) by clearing DLM bit in the LINMR register */ + USARTx->LINMR &= (uint32_t)~((uint32_t)USART_LINMR_DLM); + } +} + +/** + * @brief Checksum type in LIN mode + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param NewState: new state of the USARTx LIN checksum type. + * This parameter can be: + * @arg ENABLE : LIN 1.3 "Classic" checksum. + * @arg DISABLE: LIN 2.0 "Enhanced" checksum. + * @retval None + */ +void USART_CheckSumType_Cfg(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the LIN 1.3 "Classic" checksum type by setting CHKTYP bit in the LINMR register */ + USARTx->LINMR |= USART_LINMR_CHKTYP; + } + else + { + /* Disable the LIN 1.3 "Classic" checksum type by clearing CHKTYP bit in the LINMR register */ + USARTx->LINMR &= (uint32_t)~((uint32_t)USART_LINMR_CHKTYP); + } +} + +/** + * @brief Checksum disable in LIN mode + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param NewState: new state of the USARTx LIN checksum disable. + * This parameter can be: + * @arg ENABLE : Whatever the node configuration is, the checksum is + * not computed/sent and it is not checked. + * @arg DISABLE: In Master node configuration, the cheksum is computed + * and sent automatically. In Slave node configure, the + * checksum is checked automatically. + * @retval None + */ +void USART_CheckSumDisable_Cfg(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the checksum's disable by setting CHKDIS bit in the LINMR register */ + USARTx->LINMR |= USART_LINMR_CHKDIS; + } + else + { + /* Disable the checksum's disable by clearing CHKDIS bit in the LINMR register */ + USARTx->LINMR &= (uint32_t)~((uint32_t)USART_LINMR_CHKDIS); + } +} + +/** + * @brief Parity disable in LIN mode + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param NewState: new state of the USARTx LIN parity disable. + * This parameter can be: + * @arg ENABLE : Whatever the node configuration is, the identifier + * parity is not computed/sent and it is not checked. + * @arg DISABLE: In Master node configuration, the identifier parity + * is computed and sent automatically. In Master node + * and Slave node configuration, the parity is checked + * automatically. + * @retval None + */ +void USART_ParityDisable_Cfg(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the identifier parity's disable by setting PARDIS bit in the LINMR register */ + USARTx->LINMR |= USART_LINMR_PARDIS; + } + else + { + /* Disable the identifier parity's disable by clearing PARDIS bit in the LINMR register */ + USARTx->LINMR &= (uint32_t)~((uint32_t)USART_LINMR_PARDIS); + } +} + +/** + * @brief LIN node action + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param USART_NodeAction: LIN node action + * This parameter can be one of the following values: + * USART_NODE_ACTIVE_PUBLISH - PUBLISH ; The USART transmits the response. + * USART_NODE_ACTIVE_SUBSCRIBE - SUBSCRIBE; The USART receives the response. + * USART_NODE_ACTIVE_IGNORE - IGNORE ; The USART does not transmits and + * does not receives the response. + * @retval None + */ +void USART_NodeAction_Cfg(USART_TypeDef* USARTx, uint32_t USART_NodeAction) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_USART_NODE_ACTIVE(USART_NodeAction)); + + /* Clear the LIN node action by clearing the NACT[1:0] bits in the LINMR register */ + USARTx->LINMR &= (uint32_t)~((uint32_t)USART_LINMR_NACT); + + /* Set the LIN node action by setting the NACT[1:0] bits in the LINMR register */ + USARTx->LINMR |= (uint32_t)((uint32_t)USART_NodeAction); +} + +/** + * @brief Returns the identifier character by the USARTx peripheral. + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @note If USART_OperationMode = 0xB (Slave node configuration), IDCHR[7:0] + * in US_LINIR is read-only and its value is the last identifier character + * that has been received. + * @retval The last identifier character. + */ +uint32_t USART_Read_LINIR_In_LIN_Slave(USART_TypeDef* USARTx) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + + /* Return the last identifier character if operation in slave node configuration*/ + return (uint32_t)((USARTx->LINIR)); +} + +/** + * @brief Returns the baud rate value after the synchronization process completion + * by the USARTx peripheral. + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @note The return value [18:16] bits is LINFP[18:16], which means fractional part + * after synchronization. + * @note The return value [15: 0] bits is LINCD[15: 0], which means clock driver + * after synchronization. + * @retval The baud rate value after the synchronization process completion. + */ +uint32_t USART_LINBaudRate(USART_TypeDef* USARTx) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + + /* Return the baud rate value after the synchronization process completion */ + return (uint32_t)((USARTx->LINBRR)); +} + +/** + * @} + */ + +/** @defgroup USART write protection register functions + * @brief USART write protection register mode functions + * +@verbatim + =============================================================================== + ##### Write Protection Register Mode Functions ##### + =============================================================================== + [..] This subsection provides a set of functions allowing to operate in write + protection register mode. + + [..] The protected register are: + (++) US_MR, which offset address is 0x0004 + (++) US_BRGR, which offset address is 0x0020 + (++) US_RTOR, which offset address is 0x0024 + (++) US_TTGR, which offset address is 0x0028 + (++) US_FIDI, which offset address is 0x0040 + (++) US_IF, which offset address is 0x004C + + [..] + + (#) The USART write protection register mode configure API's : + (++) USART_WriteProtectionRegisterConfig() + + (#) The USART write protection violation status (WPVS bit of US_WPSR) API's : + (++) USART_GetWriteProtectionRegisterStatus() + + (#) The USART get write protection violation source API's : + (++) USART_GetWriteProtectionRegisterSource() + + (#) The USART clear write protection register US_WPSR fields API's : + (++) USART_ClearWPSRField() +@endverbatim + * @{ + */ + +/** + * @brief Write protect enable + * @param USARTx_WP: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param NewState: new state of the USARTx write protect enable. + * This parameter can be: + * @arg ENABLE : Enables the write protect if WPKEY corresponds to 0x555341. + * @arg DISABLE: Disables the write protect if WPKEY corresponds to 0x555341. + * @retval None + */ +void USART_WriteProtectionRegisterConfig(USART_WP_TypeDef* USARTx_WP, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH_WP(USARTx_WP)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enables the write protect if WPKEY corresponds to 0x555341 by setting WPEN bit in the WPMR register */ + USARTx_WP->WPMR = (USART_WPMR_WPEN | (0x555341 << 8U)); + } + else + { + /* Disables the write protect if WPKEY corresponds to 0x555341 by clearing WPEN bit in the WPMR register */ + USARTx_WP->WPMR = 0x55534100; + } +} + +/** + * @brief Checks whether the USART write protect violation is set or not. + * @param USARTx_WP: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @retval The new state of write protect violation status. + */ +FlagStatus USART_GetWriteProtectionRegisterStatus(USART_WP_TypeDef* USARTx_WP) +{ + FlagStatus bitstatus = RESET; + + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH_WP(USARTx_WP)); + + if ((USARTx_WP->WPSR & USART_WPSR_WPVS) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + return bitstatus; +} + +/** + * @brief Returns the write protect violation source by the USARTx_WP peripheral. + * @param USARTx_WP: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @note When WPVS bit of WPSR register is active, this field indicates the + * write-protected register (through address offset or code) in which a + * write access has been attempted. + * @retval The write protect violation source. + */ +uint32_t USART_GetWriteProtectionRegisterSource(USART_WP_TypeDef* USARTx_WP) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH_WP(USARTx_WP)); + + /* Return the write protect violation source, which is WPVSRC[23:8] bits of US_WPSR */ + return (uint32_t)((USARTx_WP->WPSR) >> 8U); +} + +/** + * @brief Reading US_WPSR automatically clears all fields. + * @param USARTx_WP: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @retval US_WPSR value. + */ +uint32_t USART_ClearWPSRField(USART_WP_TypeDef* USARTx_WP) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH_WP(USARTx_WP)); + + /* Reading US_WPSR automatically clears all fields */ + return (uint32_t)(USARTx_WP->WPSR); +} + +/** + * @} + */ + +/** @defgroup USART Transfers functions + * @brief USART Transmit and Receive functions + * +@verbatim + =============================================================================== + ##### Data Transfers Functions ##### + =============================================================================== + [..] This subsection provides a set of functions allowing to manage the USART data transfers. + + [..] + + (#) The USART data transmit API's : + (++) USART_Transmit() + + (#) The USART data receive API's : + (++) USART_Receive() +@endverbatim + * @{ + */ + +/** + * @brief Transmits single data through the USARTx peripheral. + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param Data: the data to transmit. + * @retval None + */ +void USART_Transmit(USART_TypeDef* USARTx, uint16_t Data) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_USART_DATA(Data)); + + /* Transmit Data */ + USARTx->THR = (Data & (uint16_t)0x01FF); +} + +/** + * @brief Returns the most recent received data by the USARTx peripheral. + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @retval The received data. + */ +uint16_t USART_Receive(USART_TypeDef* USARTx) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + + /* Received Data */ + return (uint16_t)(USARTx->RHR & (uint16_t)0x01FF); +} + +/** + * @} + */ + +/** @defgroup USART DMA Transfers functions + * @brief USART DMA Transmit and Receive enable functions + * +@verbatim + =============================================================================== + ##### DMA Transfer Management Functions ##### + =============================================================================== + [..] This subsection provides a set of functions about DMA Tx/Rx enable functions. + + [..] + + (#) The USART DMA enable transmitter API's : + (++) USART_DMATxEnable_Cmd() + + (#) The USART DMA enable receiver API's : + (++) USART_DMARxEnable_Cmd() +@endverbatim + * @{ + */ + +/** + * @brief DMA enable transmitter + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param NewState: new state of the USARTx DMA enable transmitter. + * This parameter can be: + * @arg ENABLE : DMA mode is enable for transmission. + * @arg DISABLE: DMA mode is disable for transmission. + * @retval None + */ +void USART_DMATxEnable_Cmd(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the transmission function of DMA mode by setting DMAT bit in the CR register */ + USARTx->CR |= USART_CR_DMAT_EN; + } + else + { + /* Disable the transmission function of DMA mode by clearing DMAT bit in the CR register */ + USARTx->CR &= (uint32_t)~((uint32_t)USART_CR_DMAT_EN); + } +} + +/** + * @brief DMA enable receiver + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param NewState: new state of the USARTx DMA enable receiver. + * This parameter can be: + * @arg ENABLE : DMA mode is enable for reception. + * @arg DISABLE: DMA mode is disable for reception. + * @retval None + */ +void USART_DMARxEnable_Cmd(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the reception function of DMA mode by setting DMAR bit in the CR register */ + USARTx->CR |= USART_CR_DMAR_EN; + } + else + { + /* Disable the reception function of DMA mode by clearing DMAR bit in the CR register */ + USARTx->CR &= (uint32_t)~((uint32_t)USART_CR_DMAR_EN); + } +} + +/** + * @} + */ + +/** @defgroup USART low-power management functions + * @brief USART low-power sleep wakeup functions + * +@verbatim + =============================================================================== + ##### Low-Power SLEEP Wakeup Management Functions ##### + =============================================================================== + [..] This subsection provides a set of functions about USART low-power wakeup + management functions. + + [..] + + (#) The USART Low-Power SLEEP wakeup configurations API's : + (++) USART_LowPowerSleepWkupConfig() +@endverbatim + * @{ + */ + +/** + * @brief USART Low-Power SLEEP wakeup configurations + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param NewState: new state of the USARTx Low-Power SLEEP wakeup configurations. + * This parameter can be: + * @arg ENABLE : Enable USARTx module clock in SLEEP mode. + * @arg DISABLE: Disable USARTx module clock in SLEEP mode. + * @retval None + */ +void USART_LowPowerSleepWkupConfig(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (USARTx == USART1) + { + if (NewState != DISABLE) + { + /* Enable the USART1 module clock in SLEEP mode by setting USART1LPEN bit in the + RCC_APB2LPENR register */ + RCC_APB2PeriphLpenCmd(RCC_APB2PeriphLpen_USART1, ENABLE); + } + else + { + /* Disable the USART1 module clock in SLEEP mode by clearing USART1LPEN bit in the + RCC_APB2LPENR register */ + RCC_APB2PeriphLpenCmd(RCC_APB2PeriphLpen_USART1, DISABLE); + } + } + else if (USARTx == USART2) + { + if (NewState != DISABLE) + { + /* Enable the USART2 module clock in SLEEP mode by setting USART2LPEN bit in the + RCC_APB1LPENR register */ + RCC_APB1PeriphLpenCmd(RCC_APB1PeriphLpen_UART2, ENABLE); + } + else + { + /* Disable the USART2 module clock in SLEEP mode by clearing USART2LPEN bit in the + RCC_APB1LPENR register */ + RCC_APB1PeriphLpenCmd(RCC_APB1PeriphLpen_UART2, DISABLE); + } + } + else if (USARTx == USART3) + { + if (NewState != DISABLE) + { + /* Enable the USART3 module clock in SLEEP mode by setting UART3LPEN bit in the + RCC_APB1LPENR register */ + RCC_APB1PeriphLpenCmd(RCC_APB1PeriphLpen_UART3, ENABLE); + } + else + { + /* Disable the USART3 module clock in SLEEP mode by clearing UART3LPEN bit in the + RCC_APB1LPENR register */ + RCC_APB1PeriphLpenCmd(RCC_APB1PeriphLpen_UART3, DISABLE); + } + } + else if (USARTx == USART6) + { + if (NewState != DISABLE) + { + /* Enable the USART6 module clock in SLEEP mode by setting USART6LPEN bit in the + RCC_APB2LPENR register */ + RCC_APB2PeriphLpenCmd(RCC_APB2PeriphLpen_USART6, ENABLE); + } + else + { + /* Disable the USART6 module clock in SLEEP mode by clearing USART6LPEN bit in the + RCC_APB2LPENR register */ + RCC_APB2PeriphLpenCmd(RCC_APB2PeriphLpen_USART6, DISABLE); + } + } +} + +/** + * @} + */ + +/** @defgroup USART Transfers functions + * @brief USART Transmit and Receive functions + * +@verbatim + =============================================================================== + ##### Interrupts And Flags Management Functions ##### + =============================================================================== + [..] This subsection provides a set of functions, which is about the USART + interrupts and the flags management. + + [..] + + (#) The USART interrupts enable API's : + (++) USART_ITConfig() + + (#) The USART flags status check API's : + (++) USART_GetFlagStatus() + + (#) The USART flags clear API's : + (++) USART_ClearFlag() + + (#) The USART interrupt mask check API's : + (++) USART_GetITStatus() + + (#) The USART interrupt disable API's : + (++) USART_ITDisableConfig() +@endverbatim + * @{ + */ + +/** + * @brief Enables the specified USART interrupts. + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param USART_IT: specifies the USART interrupt sources to be enabled or disabled. + * This parameter can be one of the following values: + * @arg USART_IT_CTSIC : USART Clear to Send input interruption + * @arg USART_IT_DSRIC : USART Data Set Ready input change interruption + * @arg USART_IT_NACK : USART non acknowledge interruption + * @arg USART_IT_ITER : USART max number of repetitions reached interruption + * @arg USART_IT_TXEMPTY: USART transmitter empty interruption + * @arg USART_IT_TIMEOUT: USART receiver time-out interruption + * @arg USART_IT_PARE : USART parity error interruption + * @arg USART_IT_FRAME : USART framing error interruption + * @arg USART_IT_OVER : USART overrun error interruption + * @arg USART_IT_RXBRK : USART break receive/end of break interruption + * @arg USART_IT_TXRDY : USART transmitter ready interruption + * @arg USART_IT_RXRDY : USART receiver ready interruption + * @arg USART_IT_UNRE : USART LIN header timeout error interruption + * @arg USART_IT_LINHTE : USART LIN header timeout error interruption + * @arg USART_IT_LINSTE : USART LIN synch tolerance eror interruption + * @arg USART_IT_LINSNRE: USART LIN slave not response error interruption + * @arg USART_IT_LINCE : USART LIN checksum error interruption + * @arg USART_IT_LINIPE : USART LIN identifier parity error interruption + * @arg USART_IT_LINISFE: USART LIN inconsistent synch field error interruption + * @arg USART_IT_LINBE : USART LIN bit error interruption + * @arg USART_IT_LINTC : USART LIN transfer completed interruption + * @arg USART_IT_LINID : USART LIN identifier sent or LIN identifier received interruption + * @arg USART_IT_LINBK : USART LIN break sent or LIN break received interruption + * @param NewState: new state of the specified USARTx interrupts. + * This parameter can be: + * @arg ENABLE : Enable corresponding interrupt. + * @arg DISABLE: No effect. + * @retval None + * @retval None + */ +void USART_ITConfig(USART_TypeDef* USARTx, uint32_t USART_IT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_USART_ENABLE_IT(USART_IT)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + USARTx->IER |= (uint32_t)((uint32_t)USART_IT); + } + else + { + USARTx->IER &= (uint32_t)~((uint32_t)USART_IT); + } +} + +/** + * @brief Checks whether the specified USART flag is set or not. + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param USART_FLAG: specifies the flag to check. + * This parameter can be one of the following values: + * @arg USART_FLAG_CTS : image of CTS input + * @arg USART_FLAG_DSR : image of DSR input + * @arg USART_FLAG_CTSIC : Clear to Send input change flag + * @arg USART_FLAG_DSRIC : Data Set Ready input change flag + * @arg USART_FLAG_NACK : non acknowledge interrupt + * @arg USART_FLAG_ITER : max number of repetitions reached + * @arg USART_FLAG_TXEMPTY: transmitter empty + * @arg USART_FLAG_TIMEOUT: receiver time-out + * @arg USART_FLAG_PARE : parity error + * @arg USART_FLAG_FRAME : framing error + * @arg USART_FLAG_OVER : overrun error + * @arg USART_FLAG_RXBRK : break receive/end of break + * @arg USART_FLAG_TXRDY : transmitter ready + * @arg USART_FLAG_RXRDY : receiver ready + * @arg USART_FLAG_UNRE : underrun error + * @arg USART_FLAG_LINHTE : LIN header timeout error + * @arg USART_FLAG_LINSTE : LIN synch tolerance eror + * @arg USART_FLAG_LINSNRE: LIN slave not response error + * @arg USART_FLAG_LINCE : LIN checksum error + * @arg USART_FLAG_LINIPE : LIN identifier parity error + * @arg USART_FLAG_LINISFE: LIN inconsistent synch field error + * @arg USART_FLAG_LINBE : LIN bit error + * @arg USART_FLAG_LINBLS : LIN bus line status + * @arg USART_FLAG_LINTC : LIN transfer completed + * @arg USART_FLAG_LINID : LIN identifier sent or LIN identifier received + * @arg USART_FLAG_LINBK : LIN break sent or LIN break received + * @retval The new state of USART_FLAG (SET or RESET). + */ +FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint32_t USART_FLAG) +{ + FlagStatus bitstatus = RESET; + + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_USART_GET_FLAG(USART_FLAG)); + + if ((USARTx->CSR & USART_FLAG) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + return bitstatus; +} + +/** + * @brief Clears the USARTx's pending flags. + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param USART_FLAG: specifies the flag to clear. + * This parameter can be any combination of the following values: + * @arg USART_CLEAR_CTSIC : Clear to Send input interrupt clear + * @arg USART_CLEAR_DSRIC : Data Set Ready input change clear + * @arg USART_CLEAR_NACK : non acknowledge interrupt clear + * @arg USART_CLEAR_ITER : max number of repetitions reached interrupt clear + * @arg USART_CLEAR_TXEMPTY: transmitter empty interrupt clear + * @arg USART_CLEAR_TIMEOUT: receiver time-out interrupt clear + * @arg USART_CLEAR_PARE : parity error interrupt clear + * @arg USART_CLEAR_FRAME : framing error interrupt clear + * @arg USART_CLEAR_OVER : overrun error interrupt clear + * @arg USART_CLEAR_RXBRK : break receive/end of break interrupt clear + * @arg USART_CLEAR_TXRDY : transmitter ready interrupt clear + * @arg USART_CLEAR_RXRDY : receiver ready interrupt clear + * @arg USART_CLEAR_UNRE : underrun error interrupt clear + * @arg USART_CLEAR_LINHTE : LIN header timeout error interrupt clear + * @arg USART_CLEAR_LINSTE : LIN synch tolerance eror interrupt clear + * @arg USART_CLEAR_LINSNRE: LIN slave not response error interrupt clear + * @arg USART_CLEAR_LINCE : LIN checksum error interrupt clear + * @arg USART_CLEAR_LINIPE : LIN identifier parity error interrupt clear + * @arg USART_CLEAR_LINISFE: LIN inconsistent synch field error interrupt clear + * @arg USART_CLEAR_LINBE : LIN bit error interrupt clear + * @arg USART_CLEAR_LINTC : LIN transfer completed interrupt clear + * @arg USART_CLEAR_LINID : LIN identifier sent or LIN identifier received interrupt clear + * @arg USART_CLEAR_LINBK : LIN break sent or LIN break received interrupt clear + * @note CTS image of CTS input bit is cleared when CTS pin is 0. + * @note DST image of DSR input bit is cleared when DSR pin is 0. + * @note LINBLS LIN bus line status bit is cleared when LINRX pin is 0. + * @note TXEMPTY flag bit also can be cleared by a write to the US_THR register (USART_Transmit()). + * @note TXRDY flag bit also can be cleared by a write to the US_THR register (USART_Transmit()). + * @note RXRDY flag bit also can be cleared by a read to the US_RHR register (USART_Receive()). + * @retval None + */ +void USART_ClearFlag(USART_TypeDef* USARTx, uint32_t USART_FLAG) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_USART_CLEAR_FLAG(USART_FLAG)); + + USARTx->CR |= (uint32_t)USART_FLAG; +} + +/** + * @brief Checks whether the specified USART interrupt has enabled or disabled. + * @param USARTx: where x can be [1, 2, 3, 6] to select the USART peripheral. + * @param USART_IT: specifies the USART interrupt source to check. + * This parameter can be one of the following values: + * @arg USART_MASK_CTSIC : mask to Send input interrupt mask + * @arg USART_MASK_DSRIC : Data Set Ready input change mask + * @arg USART_MASK_NACK : non acknowledge interrupt mask + * @arg USART_MASK_ITER : max number of repetitions reached interrupt mask + * @arg USART_MASK_TXEMPTY: transmitter empty interrupt mask + * @arg USART_MASK_TIMEOUT: receiver time-out interrupt mask + * @arg USART_MASK_PARE : parity error interrupt mask + * @arg USART_MASK_FRAME : framing error interrupt mask + * @arg USART_MASK_OVER : overrun error interrupt mask + * @arg USART_MASK_RXBRK : break receive/end of break interrupt mask + * @arg USART_MASK_TXRDY : transmitter ready interrupt mask + * @arg USART_MASK_RXRDY : receiver ready interrupt mask + * @arg USART_MASK_UNRE : underrun error interrupt mask + * @arg USART_MASK_LINHTE : LIN header timeout error interrupt mask + * @arg USART_MASK_LINSTE : LIN synch tolerance eror interrupt mask + * @arg USART_MASK_LINSNRE: LIN slave not response error interrupt mask + * @arg USART_MASK_LINCE : LIN checksum error interrupt mask + * @arg USART_MASK_LINIPE : LIN identifier parity error interrupt mask + * @arg USART_MASK_LINISFE: LIN inconsistent synch field error interrupt mask + * @arg USART_MASK_LINBE : LIN bit error interrupt mask + * @arg USART_MASK_LINTC : LIN transfer completed interrupt mask + * @arg USART_MASK_LINID : LIN identifier sent or LIN identifier received interrupt mask + * @arg USART_MASK_LINBK : LIN break sent or LIN break received interrupt mask + * @retval The new state of USART_IT (SET or RESET). + */ +ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint32_t USART_IT) +{ + ITStatus bitstatus = RESET; + + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_USART_GET_IT(USART_IT)); + + if ((USARTx->IMR & USART_IT) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + + return bitstatus; +} + +/** + * @brief USARTx's interrupt disable configure. + * @param USARTx: where x can be [1, 2. 3, 6] to select the USART peripheral. + * @param USART_IT: specifies the interrupt pending bit to clear. + * This parameter can be one of the following values: + * @arg USART_DIS_CTSIC : disable to Send input interrupt disable + * @arg USART_DIS_DSRIC : Data Set Ready input change disable + * @arg USART_DIS_NACK : non acknowledge interrupt disable + * @arg USART_DIS_ITER : max number of repetitions reached interrupt disable + * @arg USART_DIS_TXEMPTY: transmitter empty interrupt disable + * @arg USART_DIS_TIMEOUT: receiver time-out interrupt disable + * @arg USART_DIS_PARE : parity error interrupt disable + * @arg USART_DIS_FRAME : framing error interrupt disable + * @arg USART_DIS_OVER : overrun error interrupt disable + * @arg USART_DIS_RXBRK : break receive/end of break interrupt disable + * @arg USART_DIS_TXRDY : transmitter ready interrupt disable + * @arg USART_DIS_RXRDY : receiver ready interrupt disable + * @arg USART_DIS_UNRE : underrun error interrupt disable + * @arg USART_DIS_LINHTE : LIN header timeout error interrupt disable + * @arg USART_DIS_LINSTE : LIN synch tolerance eror interrupt disable + * @arg USART_DIS_LINSNRE: LIN slave not response error interrupt disable + * @arg USART_DIS_LINCE : LIN checksum error interrupt disable + * @arg USART_DIS_LINIPE : LIN identifier parity error interrupt disable + * @arg USART_DIS_LINISFE: LIN inconsistent synch field error interrupt disable + * @arg USART_DIS_LINBE : LIN bit error interrupt disable + * @arg USART_DIS_LINTC : LIN transfer completed interrupt disable + * @arg USART_DIS_LINID : LIN identifier sent or LIN identifier received interrupt disable + * @arg USART_DIS_LINBK : LIN break sent or LIN break received interrupt disable + * @param NewState: new state of the specified USARTx interrupts. + * This parameter can be: + * @arg ENABLE : Disable corresponding interrupt. + * @arg DISABLE: No effect. + * @retval None + */ +void USART_ITDisableConfig(USART_TypeDef* USARTx, uint32_t USART_IT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_USART_CLEAR_IT(USART_IT)); + + if (NewState != DISABLE) + { + USARTx->IDR |= (uint32_t)((uint32_t)USART_IT); + } + else + { + USARTx->IDR &= (uint32_t)~((uint32_t)USART_IT); + } +} + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_usb_fs.c b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_usb_fs.c new file mode 100644 index 00000000000..c475e0bcffa --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_usb_fs.c @@ -0,0 +1,1451 @@ +/** + ****************************************************************************** + * @file ft32f4xx_usb_fs.c + * @author FMD XA + * @brief This file provides firmware functions to manage the following + * functionalities of the USB Peripheral Controller: + * + Initialization/de-initialization functions + * + Peripheral Control functions + * + Peripheral State functions + * @version V1.0.0 + * @data 2025-05-28 + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + (#) Fill parameters of Init structure in USB_OTG_CfgTypeDef structure. + + (#) Call USB_FS_CoreInit() API to initialize the USB Core peripheral. + + (#) The upper HCD/PCD driver will call the right routines for its internal processes. + @endverbatim +****************************************************************************** + */ +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx.h" +#include "ft32f4xx_rcc.h" +#include "ft32f4xx_usb_fs.h" + +volatile uint32_t delayCount; + +/** @addtogroup FT32F4xx_USB_FS_DRIVER + * @{ + */ + +#if defined (PCD_FS_MODULE_ENABLED) || defined (HCD_FS_MODULE_ENABLED) +#if defined (USB_OTG_FS) +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ +#if defined (USB_OTG_FS) +static USB_FS_StatusTypeDef USB_FS_CoreReset(void); + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup USB_Exported_Functions USB OTG FS Low Layer Exported Functions + * @{ + */ + +/** @defgroup USB_Exported_Functions_Group1 Initialization/de-initialization functions + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + ##### Initialization/de-initialization functions ##### + =============================================================================== + +@endverbatim + * @{ + */ + +void USB_FS_Delayms(uint32_t num) +{ + if(SysTick_Config(SystemCoreClock/1000)) + { + while (1); + } + uint32_t tickStart = delayCount; + while ((delayCount - tickStart) < num); +} + +/** + * @brief Initializes the USB OTG FS Core + * @param USB FS USB Instance + * @param cfg pointer to a USB_OTG_FS_CfgTypeDef structure that contains + * the configuration information for the specified USB_FS peripheral. + * @retval USB_FS status + */ +USB_FS_StatusTypeDef USB_FS_CoreInit(void) +{ + USB_FS_StatusTypeDef ret; + + + /* Init the UTMI interface */ + + /* Reset */ + ret = USB_FS_CoreReset(); + /* change srqxtune txvreftune otgtune compdistune */ + /* waiting for update */ + + return ret; +} + +/** + * @brief Reset the USB_FS Core + * @param USB_FS Selected device + * @retval USB_FS status + */ +static USB_FS_StatusTypeDef USB_FS_CoreReset(void) +{ + __IO uint32_t count = 0U; + + /* Core Soft Reset */ + count = 0U; + RCC_AHB2PeriphResetCmd(RCC_AHB2PeriphRst_USBOTGFS, ENABLE); + + USB_FS_Delayms(5U); /* update delay */ + + RCC_AHB2PeriphResetCmd(RCC_AHB2PeriphRst_USBOTGFS, DISABLE); + return USB_FS_OK; +} + + +/** + * @brief USB_FS_DevInit: Initializes the USB_OTG_FS controller registers + * for device mode + * @param USB_FS Selected device + * @param cfg pointer to a USB_OTG_FS_CfgTypeDef structure that contains + * the configuration information for the specified USB_FS peripheral. + * @retval USB_FS status + */ +USB_FS_StatusTypeDef USB_FS_DevInit(USB_OTG_FS_CfgTypeDef cfg) +{ + USB_FS_StatusTypeDef ret = USB_FS_OK ; + uint32_t i; + + for (i = 1U; i < cfg.endpoints; i++) + { + USB_FS->INDEX = i; + USB_FS->TXFIFO1 = 0U; + USB_FS->TXFIFO2 = 0U; + USB_FS->RXFIFO1 = 0U; + USB_FS->RXFIFO2 = 0U; + } + + /* initial ep0 */ + USB_FS_RstEP0Regs(); + + /* reset all ep register include flush fifo*/ + for (i = 1U; i < cfg.endpoints; i++) + { + if (USB_FS_RstEPRegs(i) != USB_FS_OK) + { + ret = USB_FS_ERROR; + } + } + + /* Clear all pending Device Interrupts */ + USB_FS_ClrEPInt(); + USB_FS->INTRTX1E = 0U; + USB_FS->INTRRX1E = 0U; + + USB_FS_ClrUSBInt(); + USB_FS->INTRUSBE = 0U; + + /* Enable the common interrupts */ + USB_FS_SetUSBInt(OTG_FS_INTRUSBE_SOFINTE | OTG_FS_INTRUSBE_RSTINTE | + OTG_FS_INTRUSBE_DISCINTE | OTG_FS_INTRUSBE_SREQINTE | + OTG_FS_INTRUSBE_VERRINTE); + + return ret; +} + +/** + * @brief USB_FS_IndexSel : select a endpoint + * @param epnum endpoint number + * This parameter can be a value from 1 to 15 + 15 means Flush all Tx FIFOs + * @retval USB_FS status + */ +USB_FS_StatusTypeDef USB_FS_IndexSel(uint8_t epnum) +{ + uint8_t reg; + + reg = USB_FS->INDEX; + + if (reg != epnum) + { + USB_FS->INDEX = epnum; + + do + { + reg = USB_FS->INDEX; + } + while(reg != epnum); + } + + return USB_FS_OK; +} + +/** + * @brief USB_FS_RstEP0Regs : reset endpoint 0 registers + * @param none + * @retval USB_FS status + */ +USB_FS_StatusTypeDef USB_FS_RstEP0Regs(void) +{ + uint8_t reg; + + /* reset endpoint0 register */ + (void)USB_FS_FlushEp0Fifo(); + + USB_FS->CSR0 = 0U; + USB_FS->NAKLMT0 = 0U; + + return USB_FS_OK; +} + +/** + * @brief USB_FS_RstEPRegs : reset endpoint registers + * @param epnum endpoint number + * This parameter can be a value from 1 to 15 + * @retval USB_FS status + */ +USB_FS_StatusTypeDef USB_FS_RstEPRegs(uint8_t epnum) +{ + uint8_t reg; + + //USB_FS_IndexSel(epnum); + /* reset tx register */ + /* flush tx fifo */ + USB_FS_FlushTxFifo(epnum); + /* reset the data tog to 0 */ + USB_FS->TXCSR1 |= OTG_FS_TXCSR1_CLRDT; + /* clear autoset, iso, mode, frcdatatog */ + USB_FS->TXCSR2 = OTG_FS_TXCSR2_MODE; + /* config max tx endpoint data packet size */ + USB_FS->TXMAXP = USB_OTG_FS_MAX_PACKET_SIZE / 8; + + /* flush tx fifo */ + USB_FS_FlushRxFifo(epnum); + /* reset the data tog to 0 */ + USB_FS->RXCSR1 |= OTG_FS_RXCSR1_CLRDT; + /* clear autoclr, iso, autoreq */ + USB_FS->RXCSR2 = 0U; + /* config max rx endpoint data packet size */ + USB_FS->RXMAXP = USB_OTG_FS_MAX_PACKET_SIZE / 8; + + + return USB_FS_OK; +} +/** + * @brief USB_FS_Get_VBusStatus : + * get vbus stattus + * @param epnum endpoint number + * This parameter can be a value from 1 to 15 + * @retval USB_FS VBus status + */ +uint32_t USB_FS_Get_VBusStatus(void) +{ + uint8_t power; + + power = USB_FS->POWER; + + switch ((power & VBUS_MASK) >> 4) + { + case 0: + return VBUS_BELOW_SESSION_END; + + case 1: + return VBUS_ABOVE_SESSION_END; + + case 3: + return VBUS_ABOVE_AVALID; + + case 7: + return VBUS_ABOVE_VBUS_VALID; + } + + return (VBUS_ERROR); +} + +/** + * @brief USB_FS_Read_RxCount + * get received data size + * @param none + * @retval data size + */ +uint16_t USB_FS_Read_RxCount(void) +{ + uint16_t count = 0; + uint16_t count1 = 0; + uint16_t count2 = 0; + + count1 = USB_FS->RXCOUNT1; + count2 = USB_FS->RXCOUNT2; + + count = ((count2 << 8) | count1); + + return count; +} + +/** + * @brief USB_FS_Read_Count0 + * get received data size of endpoint0 + * @param none + @retval endpoint0 received data size + */ +uint8_t USB_FS_Read_Count0(void) +{ + uint8_t count = 0; + + count = USB_FS->COUNT0; + + return count; +} + + + +/** + * @brief USB_FS_GetCurrentFrame + * Return Host Current Frame number + * @param USB_FS Selected device + * @retval current frame number + */ +uint32_t USB_FS_GetCurrentFrame(void) +{ + uint32_t framel = 0U; + uint32_t frameh = 0U; + uint32_t frame = 0U; + + framel = USB_FS->FRAME1; + frameh = ((USB_FS->FRAME2) << 8); + frame = (framel | frameh); + + return frame; +} + +/** + * @brief USB_FS_Enable_EP + * enable endpoint transfer + * @param epnum endpoint number + * This parameter can be a value from 1 to 15 + 15 means Flush all Tx FIFOs + * @retval none + */ +/* + * MGC_Enable_EP_DRC: + * Following a successful "SetConfig" operation, use MGC_Enable_EP_DRC + * to enable the endpoint registers in the DRC previosly bound by a + * ReturnEPMatch/SelectEP operation. Following this operation, live + * traffic can occur on the endpoint. Note that this can be called prior + * to "SetConfig". Either way, if SetConfig fails, the EPs previously + * bound must be released. + */ +void USB_FS_Enable_HEP(USB_OTG_FS_HEPTypeDef *hep) +{ + uint8_t epnum = (uint8_t)hep->epnum; + USB_FS_IndexSel(epnum); + + if (hep->ep_is_in == 1U) + { + if ((USB_FS->RXCSR1 & OTG_FS_RXCSR1_REQPKT) == 0U) + { + USB_FS->RXTYPE = (hep->epnum & 0x0f) | ((hep->ep_type & 0x03) << 4); /* set this endpoint */ + USB_FS->RXMAXP = (hep->max_packet / 8); + USB_FS->RXCSR1 = OTG_FS_RXCSR1_CLRDT; + } + } + else + { + if ((USB_FS->TXCSR1 & OTG_FS_TXCSR1_TXPKTRDY) == 0U) + { + USB_FS->TXTYPE = (hep->epnum & 0x0f) | ((hep->ep_type & 0x03) << 4); /* set this endpoint */ + USB_FS->TXMAXP = (hep->max_packet / 8); + USB_FS->TXCSR2 = OTG_FS_TXCSR2_MODE; + USB_FS->TXCSR1 = OTG_FS_TXCSR1_FFIFO; + USB_FS->TXCSR1 = OTG_FS_TXCSR1_FFIFO; + USB_FS->TXCSR1 = OTG_FS_TXCSR1_CLRDT; + } + } +} + + +void USB_FS_Enable_DEP(USB_OTG_FS_DEPTypeDef *dep) +{ + uint8_t epnum = (uint8_t)dep->num; + USB_FS_IndexSel(epnum); + + if (dep->is_in == 0U) + { + if ((USB_FS->RXCSR1 & OTG_FS_RXCSR1_REQPKT) == 0U) + { + USB_FS->RXTYPE = (dep->num & 0x0f) | ((dep->type & 0x03) << 4); /* set this endpoint */ + USB_FS->RXMAXP = (dep->maxpacket / 8); + + if (dep->type == EP_TYPE_ISOC) + { + USB_FS->RXCSR2 = OTG_FS_RXCSR2_AUTOCLR | OTG_FS_RXCSR2_ISO; + } + + USB_FS->RXCSR1 = OTG_FS_RXCSR1_CLRDT; + } + } + else + { + if ((USB_FS->TXCSR1 & OTG_FS_TXCSR1_TXPKTRDY) == 0U) + { + USB_FS->TXTYPE = (dep->num & 0x0f) | ((dep->type & 0x03) << 4); /* set this endpoint */ + USB_FS->RXMAXP = (dep->maxpacket / 8); + + if (dep->type == EP_TYPE_ISOC) + { + USB_FS->TXCSR2 = OTG_FS_TXCSR2_MODE | OTG_FS_TXCSR2_ISO; + } + else + { + USB_FS->TXCSR2 = OTG_FS_TXCSR2_MODE; + } + + USB_FS->TXCSR1 = OTG_FS_TXCSR1_FFIFO; + USB_FS->TXCSR1 = OTG_FS_TXCSR1_FFIFO; + USB_FS->TXCSR1 = OTG_FS_TXCSR1_CLRDT; + } + } +} + + + +/** + * @brief USB_FS_DEPStartXfer : setup and starts a transfer over an EP + * @param ep pointer to endpoint structure + * @retval none + */ +void USB_FS_DEPStartXfer(USB_OTG_FS_DEPTypeDef *dep) +{ + uint8_t epnum = (uint8_t)dep->num; + uint16_t pktcnt; + static uint8_t current_pid = 0; + USB_FS_IndexSel(epnum); + + /* tx endpoint */ + if (dep->is_in == 1U) + { + /* Zero Length Packet? */ + if (dep->xfer_len == 0U) + { + USB_FS->TXMAXP &= (~OTG_FS_TXMAXP_TXMAXPKT); + } + else + { + USB_FS->TXMAXP &= (~OTG_FS_TXMAXP_TXMAXPKT); + + USB_FS->TXMAXP = (OTG_FS_TXMAXP_TXMAXPKT & dep->xfer_len); + } + + if (current_pid == 0) + { + USB_FS->TXCSR1 = OTG_FS_TXCSR1_CLRDT; + current_pid = 1; + } + else + { + current_pid = 0; + } + + USB_FS_FIFOWrite(dep->xfer_buff, dep->num, (uint16_t)dep->xfer_len); + USB_FS->TXCSR1 = OTG_FS_TXCSR1_TXPKTRDY; + } + else /* rx endpoint */ + { + USB_FS->RXMAXP &= (~OTG_FS_RXMAXP_RXMAXPKT); + + if (dep->xfer_len > 0U) + { + dep->xfer_size = dep->xfer_len; + USB_FS->RXMAXP = (OTG_FS_RXMAXP_RXMAXPKT & dep->xfer_size); + } + + USB_FS->RXCSR1 = OTG_FS_RXCSR1_CLRDT; + } +} +/** + * @brief USB_FS_DEP0StartXfer : setup and starts a transfer over EP0 + * @param ep pointer to endpoint structure + * @retval none + */ +void USB_FS_DEP0StartXfer(USB_OTG_FS_DEPTypeDef *dep) +{ + USB_FS_IndexSel(0U); + uint32_t len = 0; + + /* tx endpoint */ + if (dep->is_in == 1U) + { + if (dep->xfer_len > dep->maxpacket) + { + dep->xfer_len = dep->maxpacket; + } + USB_FS_FIFOWrite(dep->xfer_buff, dep->num, (uint16_t)dep->xfer_len); + USB_FS->CSR0 |= OTG_FS_CSR0_TXPKTRDY; + + if (dep->xfer_len < 0x40U) + { + USB_FS->CSR0 |= OTG_FS_CSR0_DATAEND; + } + dep->xfer_buff += dep->xfer_len; + dep->xfer_count += dep->xfer_len; + } + else + { + dep->xfer_count = 0; + } +} + + +/** + * @brief USB_FS_FIFORead + * read receive fifo + * @param epnum endpoint number + * This parameter can be a value from 1 to 15 + 15 means Flush all Tx FIFOs + * @retval none + */ + +/* + * Fifo_Read uses the endpoint object to ensure sole access to FIFO, + * then updates the object with # of bytes read. ***IMPORTANT***, we + * assume only thread of execution is BGD interrupt process, which has + * preselected the INDEX reg. eP->FifoRemain always represents the + * number of remaining bytes in the fifo following a recv packet interrupt. + * eP->BytesRequested - eP->BytesProcessed always represents the remaining + * bytes to fill from the APP (EP0 or user). We use the smaller of those + * two and move the bytes, updating all relevant counters. A new recv + * packet operation won't be initiated by the DRC until the fifo count + * has gone to 0. + */ +void USB_FS_FIFORead(uint8_t *dst, uint8_t ep_num, uint16_t len) +{ + uint16_t readcount; + uint32_t fifo_addr; + /* Take the smaller of what's requested versus what's in the fifo */ + readcount = len; + //MIN((eP->BytesRequested - eP->BytesProcessed), eP->FifoRemain); + + if (readcount <= 0) /* if none to read or blown tracking ... */ + { + return; + } + +// dst += eP->BytesProcessed; /* user buffer offset for current rd*/ +// eP->BytesProcessed += readcount; /* apps & stack can monitor progress */ +// eP->FifoRemain -= readcount; + fifo_addr = ADDR_FIFO_EP0 + (ep_num << 2); /* blds absolute fifo addrs */ +// fifo_addr = ADDR_FIFO_EP0 + ep_num; /* blds absolute fifo addrs */ + + while (readcount != 0U) + { + *dst++ = *((uint8_t *)fifo_addr); + readcount = readcount - 1U; + } + +} + +/** + * @brief USB_FS_FIFOWrite + * write data to tx fifo + * @param epnum endpoint number + * This parameter can be a value from 1 to 15 + 15 means Flush all Tx FIFOs + * @retval USB_FS VBus status + */ +/* + * MGC_DRC_Fifo_Write uses the endpoint object to ensure sole access to FIFO, + * then updates the object with # of bytes written. MaxEPSize used to + * limit the write. MaxEPSize shall never be larger than the size of the + * configured fifo. + * + * 20-May-03: Setting eP->LastPacket universally for transmits. If + * a requested transmission is a multiple of the Max EP Size, then a 0-len + * packet is owed following the data packets. Otherwise, when processed + * = requested, we have a last-packet condition. + */ +void USB_FS_FIFOWrite(uint8_t *src, uint8_t ep_num, uint16_t len) +{ + uint16_t writecount; + uint32_t fifo_addr; + + writecount = len; + //MIN(eP->MaxEPSize, (eP->BytesRequested - eP->BytesProcessed)); + +// src += eP->BytesProcessed; /* user offset */ +// eP->BytesProcessed += writecount; /* apps & stack can monitor progress */ + +// if ((eP->BytesProcessed == eP->BytesRequested) & +// ((eP->BytesProcessed % eP->MaxEPSize) /* can't be a multiple */ +// || usb_pipebulk(eP->URBP->pipe) || +// (eP->Attr == 3) || (eP->Attr == 1))) +// { +// eP->LastPacket = 1; +// } + fifo_addr = ADDR_FIFO_EP0 + (ep_num << 2); /* blds absolute fifo addrs */ +// fifo_addr = ADDR_FIFO_EP0 + ep_num; /* blds absolute fifo addrs */ + + while (writecount) + { + *((uint8_t *)fifo_addr) = *src++; + writecount--; + } +} + + + +/** + * @brief USB_FS_SetEPInt + * unmask or mask endpoint interrupt + * @param epnum endpoint number + * This parameter can be a value from 1 to 15 + * @retval USB_FS status + */ +void USB_FS_SetEPInt(uint8_t cfg) +{ + uint8_t reg; + + /* Set INT enable registers */ + reg = cfg & 0xff; /* endpoints 0 .. 7 */ + USB_FS->INTRTX1E |= reg; + USB_FS->INTRRX1E |= reg; +} + +/** + * @brief USB_FS_SetUSBInt + * unmask or mask usb interrupt + * @param none + * @retval USB_FS status + */ +void USB_FS_SetUSBInt(uint8_t cfg) +{ + uint8_t reg; + + /* Set INT enable registers */ + reg = cfg & 0xff; + USB_FS->INTRUSBE = reg; +} +/** + * @brief USB_FS_ClrUSBInt + * clear usb interrupts + * @retval none + */ + +void USB_FS_ClrUSBInt(void) +{ + uint8_t temp; + + /* flush pending interrupts */ + temp = USB_FS->INTRUSB; +} +/** + * @brief USB_FS_ClrEPInt + * clear endpoint interrupts + * @retval none + */ + +void USB_FS_ClrEPInt(void) +{ + uint8_t temp; + + /* flush pending interrupts */ + temp = USB_FS->INTRTX1; + temp = USB_FS->INTRRX1; +} + +/** + * @brief Activate EP0 for Setup transactions + * @param USB_FS Selected device + */ +void USB_FS_ActivateSetup(void) +{ + /* Set the MPS of the IN EP0 to 64 bytes */ + USB_FS->CSR0 |= (OTG_FS_CSR0_SETUPPKT | OTG_FS_TXCSR1_TXPKTRDY); +} + + +/** + * @brief Initialize a host transfer + * @param epnum Endpoint number + * This parameter can be a value from 1 to 15 + * @param dev_address Current device address + * This parameter can be a value from 0 to 255 + * @param speed Current device speed + * @param interval : for iso/interrupt interval + * for bulk: nakmit + * @param ep_type Endpoint Type + * This parameter can be one of these values: + * @arg EP_TYPE_CTRL: Control type + * @arg EP_TYPE_ISOC: Isochronous type + * @arg EP_TYPE_BULK: Bulk type + * @arg EP_TYPE_INTR: Interrupt type + * @param mps Max Packet Size + * @retval USB_FS state + */ +USB_FS_StatusTypeDef USB_FS_HEP_Init(uint8_t epnum, uint8_t dev_address, + uint8_t ep_type, uint8_t interval, + uint16_t xfersize) +{ + USB_FS_StatusTypeDef ret = USB_FS_OK; + uint8_t HostCoreSpeed; + uint8_t ep_num; + uint8_t ep_dir; + + ep_num = epnum & 0x7FU; + + ret = USB_FS_IndexSel(ep_num); + /* Clear old interrupt conditions for this host channel. */ + USB_FS_ClrUSBInt(); + USB_FS_ClrEPInt(); + USB_FS_SetEPInt(1 << ep_num); + + HostCoreSpeed = USB_FS_GetSpeed(); + + USB_FS_SetAddress(dev_address); + + if (ep_num != 0U) + { + if ((epnum & 0x80U) == 0x80U) /* in rx */ + { + USB_FS->RXTYPE = (ep_num | (ep_type << 4)); + USB_FS->RXINTERVAL = interval; + USB_FS->RXMAXP = (xfersize / 8); + } + else + { + USB_FS->TXTYPE = (ep_num | (ep_type << 4)); + USB_FS->TXINTERVAL = interval; + USB_FS->TXMAXP = (xfersize / 8); + } + } + + return ret; +} + + +/** + * @brief Start a transfer over a host endpoint + * @param endpoint pointer to host endpoint structure + * @retval none + */ +void USB_FS_HEP_StartXfer(USB_OTG_FS_HEPTypeDef *hep) +{ + uint8_t ep_num = (uint32_t)hep->epnum; + __IO uint32_t tmpreg; + uint16_t maxpacket = 0U; + + (void)USB_FS_IndexSel(ep_num); + + switch (hep->ep_type) + { + case EP_TYPE_BULK: + maxpacket = USB_OTG_FS_MAX_BULK_PACKET_SIZE; + break; + + case EP_TYPE_INTR: + if ((USB_FS->DEVCTL & 0x40U) != 0) + { + maxpacket = USB_OTG_FS_MAX_INTR_PACKET_SIZE; + } + else + { + maxpacket = USB_OTG_LS_MAX_INTR_PACKET_SIZE; + } + + break; + + case EP_TYPE_ISOC: + maxpacket = USB_OTG_FS_MAX_ISOC_PACKET_SIZE; + break; + + default: + break; + } + + if (hep->xfer_len > maxpacket) + { + hep->XferSize = maxpacket; + } + else + { + hep->XferSize = hep->xfer_len; + } + + if (hep->ep_is_in == 1U) /* in rx */ + { + USB_FS->RXTYPE = (ep_num | (hep->ep_type << 4)); + USB_FS->RXMAXP = ((maxpacket + 7U) / 8U); + USB_FS->RXCSR1 |= OTG_FS_RXCSR1_CLRDT; + USB_FS->RXCSR1 |= OTG_FS_RXCSR1_REQPKT; + } + else + { + USB_FS->TXTYPE = (ep_num | (hep->ep_type << 4)); + USB_FS->TXMAXP = ((maxpacket + 7U) / 8U);; + USB_FS->TXCSR1 |= OTG_FS_TXCSR1_CLRDT; + USB_FS->TXCSR2 |= OTG_FS_TXCSR2_MODE; + } + + if ((hep->ep_is_in == 0U) & (hep->xfer_len > 0U)) + { + /* Write packet into the Tx FIFO. */ + (void)USB_FS_FIFOWrite(hep->xfer_buff, ep_num, (uint16_t)hep->XferSize); + USB_FS->TXCSR1 = OTG_FS_TXCSR1_TXPKTRDY; + } +} + +/** + * @brief Start a transfer over a host endpoint 0 + * @param endpoint pointer to host endpoint structure + * @retval none + */ +void USB_FS_HEP0_StartXfer(USB_OTG_FS_HEPTypeDef *hep, uint8_t ctl_state) +{ + uint8_t ep_num = 0U; + + (void)USB_FS_IndexSel(ep_num); + + if (hep->data_pid == EP_PID_SETUP) + { + /* Write packet into the Tx FIFO. */ + (void)USB_FS_FIFOWrite(hep->xfer_buff, ep_num, (uint16_t)hep->xfer_len); + USB_FS->CSR0 = OTG_FS_CSR0_TXPKTRDY | OTG_FS_CSR0_SETUPPKT; + } + else if (ctl_state == CTRL_STATUS) + { + if (hep->ep_is_in == 0U) + { + USB_FS->CSR0 = OTG_FS_CSR0_TXPKTRDY | OTG_FS_CSR0_STATUSPKT; + } + else + { + USB_FS->CSR0 = OTG_FS_CSR0_REQPKT | OTG_FS_CSR0_STATUSPKT; + } + } + else if (ctl_state == CTRL_DATA) + { + if (hep->ep_is_in == 0U) + { + if (hep->xfer_len > 0U) + { + (void)USB_FS_FIFOWrite(hep->xfer_buff, ep_num, (uint16_t)hep->xfer_len); + } + + USB_FS->CSR0 = OTG_FS_CSR0_TXPKTRDY; + } + else + { + USB_FS->CSR0 = OTG_FS_CSR0_REQPKT; + } + } + else + { + /*...*/ + } +} + + +/** + * @brief USB_FS_FlushEp0Fifo : Flush EP0 FIFO + * @param none + * @retval USB_FS status + */ +USB_FS_StatusTypeDef USB_FS_FlushEp0Fifo(void) +{ + + /* Flush EP0 fifo */ + USB_FS->INDEX = 0U; + USB_FS->CSR02 = OTG_FS_CSR02_FFIFO; + + + return USB_FS_OK; +} + +/** + * @brief USB_FS_FlushTxFifo : Flush a Tx FIFO + * @param epnum endpoint number + * This parameter can be a value from 1 to 15 + 15 means Flush all Tx FIFOs + * @retval USB_FS status + */ +USB_FS_StatusTypeDef USB_FS_FlushTxFifo(uint8_t epnum) +{ + + /* Flush TX fifo */ + USB_FS->INDEX = epnum; + USB_FS->TXCSR1 |= OTG_FS_TXCSR1_FFIFO; + + + return USB_FS_OK; +} + +/** + * @brief USB_FS_FlushRxFifo : Flush Rx FIFO + * @param USB_FS Selected device + * @retval USB_FS status + */ +USB_FS_StatusTypeDef USB_FS_FlushRxFifo(uint8_t epnum) +{ + + /* Flush RX fifo */ + USB_FS->INDEX = epnum; + USB_FS->RXCSR1 |= OTG_FS_RXCSR1_FFIFO; + + return USB_FS_OK; +} + + +/** + * @brief Set Tx FIFO + * @param fifo The number of Tx fifo + * @param size Fifo size + * @retval none + */ +void USB_FS_SetTxFiFo(uint8_t epnum, uint8_t size, uint8_t address, uint8_t dpb) +{ + uint8_t fifo1, fifo2; + + /* + * usb_fs ram 1024bytes + * size and address are in the unit of 8 bytes + * max fifo size, 1024 bytes / 8 = 128 + * max address, 0x7ff8 / 8 = 0xfff (0x400-8) / 8 = 0x7F + */ + if ((size > 128) || (address > 0x7F)) + { + return; + } + + fifo1 = address; + fifo2 = ((dpb << 4 ) & (OTG_FS_TXFIFO2_TXDPB)); + fifo2 |= (usb_log2(size)) << 5; + + USB_FS->INDEX = (0x0F & epnum); + USB_FS->TXFIFO1 = fifo1; + USB_FS->TXFIFO2 = fifo2; + +} + +/** + * @brief Set Rx FIFO + * @param size Size of Rx fifo + * @retval none + */ +void USB_FS_SetRxFiFo(uint8_t epnum, uint8_t size, uint8_t address, uint8_t dpb) +{ + uint8_t fifo1, fifo2; + + /* + * usb_fs ram 1024bytes + * size and address are in the unit of 8 bytes + * max fifo size, 1024 bytes / 8 = 128 + * max address, 0x7ff8 / 8 = 0xfff (0x400-8) / 8 = 0x7F + */ + if ((size > 128) || (address > 0x7F)) + { + return; + } + + fifo1 = address; + fifo2 = ((dpb << 4 ) & (OTG_FS_TXFIFO2_TXDPB)); + fifo2 |= (usb_log2(size)) << 5; + + USB_FS->INDEX = (0x0F & epnum); + USB_FS->RXFIFO1 = fifo1; + USB_FS->RXFIFO2 = fifo2; + +} + +/** + * @brief Returns USB_FS core mode + * @param USB_FS Selected device + * @retval return core mode : Host or Device + * This parameter can be one of these values: + * 1 : Host + * 0 : Device + */ +uint8_t USB_FS_GetMode(void) +{ + return ((USB_FS->DEVCTL) & 0x4U); +} + +/** + * @brief Returns USB_FS core CID + * @retval return core ID : A-device or B-device + * This parameter can be one of these values: + * 0 : A-device + * 1 : B-device + */ +uint8_t USB_FS_GetCID(void) +{ + return ((USB_FS->DEVCTL) & 0x80U); +} + +/** + * @brief USB_FS_DrvSess : enabel or disable session + * @param state session state + * This parameter can be one of these values: + * 0 : disable session request + * 1 : enable session request + */ +void USB_FS_DrvSess(uint8_t state) +{ + __IO uint8_t session = 0U; + + session = USB_FS->DEVCTL; + + if (((session & OTG_FS_DEVCTL_SESSION) == 0U) & (state == 1U)) + { + USB_FS->DEVCTL = (OTG_FS_DEVCTL_SESSION | session); + } + + if (((session & OTG_FS_DEVCTL_SESSION) == OTG_FS_DEVCTL_SESSION) & (state == 0U)) + { + USB_FS->DEVCTL = ((~OTG_FS_DEVCTL_SESSION) & session); + } +} + +/** + * @brief Return Host Core speed + * @retval speed : Host speed + * This parameter can be one of these values: + * @arg HCD_SPEED_FULL: Full speed mode + * @arg HCD_SPEED_LOW: Low speed mode + */ +uint32_t USB_FS_GetSpeed(void) +{ + __IO uint8_t spd = 0U; + uint32_t speed; + spd = USB_FS->DEVCTL; + + if ((spd & OTG_FS_DEVCTL_FSDEV) == OTG_FS_DEVCTL_FSDEV) + { + speed = USB_FS_SPEED; + } + else if ((spd & OTG_FS_DEVCTL_LSDEV) == OTG_FS_DEVCTL_LSDEV) + { + speed = USB_LS_SPEED; + } + else + { + speed = 0xFU; + } + + return speed; +} + +/** + * @brief USB_FS_Set_Polling_Interval + * set polling interval value for iso or interrupt transfer. + * @param epdir endpoint transfer tx or rx + * 1: tx + * 0: rx + * @param interval: polling interval value + * @retval none + */ +void USB_FS_Set_Polling_Interval(uint8_t epdir, uint8_t interval) +{ + if ((epdir & 0x01) == FIFO_TX) + { + USB_FS->TXINTERVAL = (interval & 0xFF); + } + else + { + USB_FS->RXINTERVAL = (interval & 0xFF); + } +} + +/** + * @brief USB_FS_Set_NAKLMT + * set nak limit value + * @param epnum: endpoint number + * @param epdir endpoint transfer tx or rx + * 1: tx + * 0: rx + * @param interval: polling interval value + * @retval none + */ +void USB_FS_Set_NAKLMT(uint8_t epnum, uint8_t epdir, uint8_t naklmt) +{ + if (epnum != 0U) + { + if ((epdir & 0x01) == FIFO_TX) + { + USB_FS->TXINTERVAL = (naklmt & 0xFF); + } + else + { + USB_FS->RXINTERVAL = (naklmt & 0xFF); + } + } + else + { + USB_FS->NAKLMT0 = naklmt; + } +} + +/** + * @brief USB_FS_SetAddress : set device address + * @param address new device address to be assigned + * This parameter can be a value from 0 to 255 + * @retval none + */ +void USB_FS_SetAddress(uint8_t address) +{ + USB_FS->FADDR &= ~(OTG_FS_FADDR_FUNADDR); + USB_FS->FADDR = (address & OTG_FS_FADDR_FUNADDR); +} + +/** + * @brief USB_FS_GetAddress : get device address + * @retval device address + */ +uint8_t USB_FS_GetAddress(void) +{ + uint8_t address; + address = 0U; + + address = USB_FS->FADDR; + return address; +} + +/** + * @brief USB_FS_SetPower : Set power register + * @param configured value + * @retval none */ +void USB_FS_SetPower(uint8_t powercfg) +{ + uint8_t reg_power; + uint8_t temp; + reg_power = USB_FS->POWER; + temp = (reg_power | powercfg); + + USB_FS->POWER = temp; +} + +/** + * @brief USB_FS_GetPower : get power register + * @param none + * @retval power register value + */ +uint8_t USB_FS_GetPower(void) +{ + uint8_t reg_power; + reg_power = USB_FS->POWER; + + return reg_power; +} + +/** + * @brief USB_FS_ClrPower : Clear power register + * @param configured value + * @retval none + */ +void USB_FS_ClrPower(uint8_t powercfg) +{ + uint8_t reg_power; + uint8_t temp; + reg_power = USB_FS->POWER; + temp = (reg_power & (~powercfg)); + + USB_FS->POWER = temp; +} + +/** + * @brief USB_FS_SetDevctl : Set devctl register + * @param configured value + * @retval none + */ +void USB_FS_SetDevctl(uint8_t cfg) +{ + uint8_t reg_devctl; + uint8_t temp; + reg_devctl = USB_FS->DEVCTL; + temp = (reg_devctl | cfg); + + USB_FS->DEVCTL = temp; +} + +/** + * @brief USB_FS_GetDevctl : get devctl register + * @param none + * @retval Devctl register value + */ +uint8_t USB_FS_GetrDevctl(void) +{ + uint8_t reg_devctl; + reg_devctl = USB_FS->DEVCTL; + + return reg_devctl; +} + +/** + * @brief USB_FS_ClrDevctl : Clear devctl register + * @param configured value + * @retval none + */ +void USB_FS_ClrDevctl(uint8_t cfg) +{ + uint8_t reg_devctl; + uint8_t temp; + reg_devctl = USB_FS->DEVCTL; + temp = (reg_devctl & (~cfg)); + + USB_FS->DEVCTL = temp; +} + +/** + * @brief USB_FS_Exiting_Host : exit host mode + * @param toOTG cp + * @retval status + */ +int8_t USB_FS_Exiting_Host(uint8_t toOTG, USB_OTG_FS_CfgTypeDef *cfg) +{ + if (toOTG == A_SUSPEND) /* A_SUSPEND itself is not exiting host */ + { + return(0); + } + else if (toOTG == A_PERIPHERAL) /* Only way here is from a host(suspend) */ + { + return(1); + } + else if ((cfg->OTGState == A_HOST) || (cfg->OTGState == B_HOST)) + { + return(1); + } + else + { + return(0); + } +} +/** + * @brief USB_FS_Activate_Resume : set resume + * @param none + * @retval none + */ +void USB_FS_Activate_Resume(void) +{ + if ((USB_FS_GetPower() & OTG_FS_POWER_SUSPEND) == OTG_FS_POWER_SUSPEND) + { + USB_FS_SetPower(OTG_FS_POWER_RESUME); /* sets the RESUME bit */ + } +} + +/** + * @brief USB_FS_DeActivate_Resume : exit host mode + * @param none + * @retval none + */ +void USB_FS_DeActivate_Resume(void) +{ + USB_FS_ClrPower(OTG_FS_POWER_RESUME); /* clear the RESUME bit */ +} + +/** + * @brief USB_FS_ResetPort : Reset Host Port + * @param USB_FS Selected device + * @note (1)The application must wait at least 20 ms + * before clearing the reset bit. + */ +void USB_FS_ResetPort(void) +{ + __IO uint8_t temp_reg = 0U; + __IO uint32_t num = 20; + + temp_reg = USB_FS->POWER; + + temp_reg |= OTG_FS_POWER_RESET; + USB_FS->POWER = temp_reg; + + while(num--) /* update delay 20ms */ + { + SysTick->LOAD = SystemCoreClock / 1000; + SysTick->VAL = 0x00; + SysTick->CTRL = 0x00000005; + + while(!(SysTick->CTRL & 0x00010000)); + + SysTick->CTRL = 0x00000004; + } +// USB_FS_Delayms(20U); + temp_reg &= (~OTG_FS_POWER_RESET); + USB_FS->POWER = temp_reg; +} + +int32_t usb_log2(int32_t x) +{ + int32_t i; + + for (i = 0; x > 1; i++) + { + x = x / 2 ; + } + + return i; +} + +/** + * @brief USB_FS_HostInit : Initializes the USB controller registers + * for Host mode + * @param USB_FS Selected device + * @param cfg pointer to a USB_OTG_FS_CfgTypeDef structure that contains + * the configuration information for the specified USB_FS peripheral. + * @retval USB_FS status + */ +USB_FS_StatusTypeDef USB_FS_HostInit(USB_OTG_FS_CfgTypeDef cfg) +{ + USB_FS_StatusTypeDef ret = USB_FS_OK; + uint32_t i; + + /* initial ep0 */ + (void)USB_FS_RstEP0Regs(); + + /* reset all ep register include flush fifo*/ + for (i = 1U; i < cfg.endpoints; i++) + { + if (USB_FS_RstEPRegs(i) != USB_FS_OK) + { + ret = USB_FS_ERROR; + } + } + + /* Clear all pending Interrupts */ + USB_FS_ClrEPInt(); + OTG_FS->INTRTX1E = 0U; + OTG_FS->INTRRX1E = 0U; + + USB_FS_ClrUSBInt(); + OTG_FS->INTRUSBE = 0U; + + /* Enable VBUS driving */ + USB_FS_SetUSBInt(OTG_FS_INTRUSBE_CONNINTE); + (void)USB_FS_DrvSess(1U); + USB_FS_Delayms(200U); /* update delay*/ + + /* Enable the common interrupts */ + USB_FS_SetUSBInt(OTG_FS_INTRUSBE_SOFINTE | OTG_FS_INTRUSBE_RSTINTE | + OTG_FS_INTRUSBE_DISCINTE | OTG_FS_INTRUSBE_SREQINTE | + OTG_FS_INTRUSBE_VERRINTE); + return ret; +} + +/** + * @brief USB_FS_ReadInterrupts: return the USB interrupt status + * @retval global interrupt register + */ +uint32_t USB_FS_ReadInterrupts(void) +{ + uint32_t tmpreg = 0; + uint32_t tmpreg1 = 0; + uint32_t tmpreg2 = 0; + uint32_t tmpreg3 = 0; + + tmpreg1 = USB_FS->INTRUSB; + tmpreg1 &= USB_FS->INTRUSBE; + + tmpreg2 = USB_FS->INTRTX1; + tmpreg2 &= USB_FS->INTRTX1E; + + tmpreg3 = USB_FS->INTRRX1; + tmpreg3 &= USB_FS->INTRRX1E; + + tmpreg = ((tmpreg1) | (tmpreg2 << 8) | (tmpreg3 << 16)); + + return tmpreg; +} + +/** + * @brief USB_FS_SendStall: send STALL handshake to the endpoint + * @retval USB_FS status + */ +USB_FS_StatusTypeDef USB_FS_SendStall(USB_OTG_FS_DEPTypeDef *dep) +{ + if (dep->num == 0) /* endpoint0 */ + { + USB_FS_IndexSel(0U); + USB_FS->CSR0 |= OTG_FS_CSR0_SDSTALL; + } + else + { + USB_FS_IndexSel(dep->num); + + if (dep->is_in) /* tx */ + { + USB_FS->TXCSR1 |= OTG_FS_TXCSR1_SDSTALL; + } + else /* rx */ + { + USB_FS->RXCSR1 |= OTG_FS_RXCSR1_SDSTALL; + } + } + + return USB_FS_OK; +} + +/** + * @brief USB_FS_ClrStall: clear send STALL handshake to the endpoint + * @retval USB_FS status + */ +USB_FS_StatusTypeDef USB_FS_ClrStall(USB_OTG_FS_DEPTypeDef *dep) +{ + USB_FS_IndexSel(dep->num); + + if (dep->is_in) /* tx */ + { + USB_FS->TXCSR1 &= (~OTG_FS_TXCSR1_SDSTALL); + } + else /* rx */ + { + USB_FS->RXCSR1 &= (~OTG_FS_RXCSR1_SDSTALL); + } + + return USB_FS_OK; +} +/** + * @brief USB_FS_Enable_Suspend: entry suspend mode + * @retval none + */ +void USB_FS_Enable_Suspend(void) +{ + if ((USB_FS->DEVCTL & OTG_FS_DEVCTL_HSTMD) == OTG_FS_DEVCTL_HSTMD) + { + USB_FS_SetPower(OTG_FS_POWER_SUSPEND); + } + else + { + USB_FS_SetPower(OTG_FS_POWER_SUSPENDEN); + } +} + +/** + * @brief USB_FS_Disable_Suspend: exit suspend mode + * @retval none + */ +void USB_FS_Disable_Suspend(void) +{ + if ((USB_FS->DEVCTL & OTG_FS_DEVCTL_HSTMD) == OTG_FS_DEVCTL_HSTMD) + { + USB_FS_ClrPower(OTG_FS_POWER_SUSPEND); + } + else + { + USB_FS_ClrPower(OTG_FS_POWER_SUSPENDEN); + } +} + + +#endif /* defined (USB_OTG_FS) */ + +#endif /* defined (USB_OTG_FS) */ + + +#endif /* defined (PCD_MODULE_ENABLED) || defined (HCD_MODULE_ENABLED) */ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_usb_hs.c b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_usb_hs.c new file mode 100644 index 00000000000..85fd1259f26 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_usb_hs.c @@ -0,0 +1,2128 @@ +/** + ****************************************************************************** + * @file ft32f4xx_usb_hs.c + * @author FMD XA + * @brief This file provides firmware functions to manage the following + * functionalities of the USB Peripheral Controller: + * + Initialization/de-initialization functions + * + Peripheral Control functions + * + Peripheral State functions + * @version V1.0.0 + * @data 2025-03-20 + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + (#) Fill parameters of Init structure in USB_OTG_CfgTypeDef structure. + + (#) Call USB_HS_CoreInit() API to initialize the USB Core peripheral. + + (#) The upper HCD/PCD driver will call the right routines for its internal processes. + @endverbatim +****************************************************************************** + */ +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx.h" +#include "system_ft32f4xx.h" +#include "ft32f4xx_misc.h" +#include "ft32f4xx_usb_hs.h" + +/** @addtogroup FT32F4xx_USB_HS_DRIVER + * @{ + */ + +#if defined (PCD_MODULE_ENABLED) || defined (HCD_MODULE_ENABLED) +#if defined (USB_OTG_HS) +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ +#if defined (USB_OTG_HS) +static USB_HS_StatusTypeDef USB_HS_CoreReset(); + +volatile uint32_t delayCount_hs_ms; + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup USB_Exported_Functions USB OTG HS Low Layer Exported Functions + * @{ + */ + +/** @defgroup USB_Exported_Functions_Group1 Initialization/de-initialization functions + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + ##### Initialization/de-initialization functions ##### + =============================================================================== + +@endverbatim + * @{ + */ +void USB_HS_Delayms (uint32_t num) +{ + if(SysTick_Config(SystemCoreClock/1000)) + { + while (1); + } + uint32_t tickStart = delayCount_hs_ms; + while ((delayCount_hs_ms - tickStart) < num); +} +/** + * @brief Initializes the USB OTG HS Core + * @param USB HS USB Instance + * @param cfg pointer to a USB_OTG_HS_CfgTypeDef structure that contains + * the configuration information for the specified USB_HS peripheral. + * @retval USB_HS status + */ +USB_HS_StatusTypeDef USB_HS_CoreInit(USB_OTG_HS_CfgTypeDef cfg) +{ + USB_HS_StatusTypeDef ret; + #define W32_TRIM(ADDRESS) (*((volatile unsigned int *)(ADDRESS))) + uint32_t read_trim; + uint32_t otgtune; + uint32_t comptune; + uint32_t sqrxtune; + uint32_t txhstune; + uint32_t vregtune; + uint32_t txfslstune; + uint32_t txvreftune; + uint32_t txrisetune; + uint32_t txpretune; + + read_trim = W32_TRIM(0x1FFF0A24); + + otgtune = ((read_trim & 0x00000007) << 3); // bit5:3 + comptune = ((read_trim & 0x00000070) << 2); // bit8:6 + sqrxtune = ((read_trim & 0x00000700) << 1); // bit11:9 + txhstune = ((read_trim & 0x00003000) ); // bit13:12 + vregtune = ((read_trim & 0x00004000) ); // bit14 + txfslstune = ((read_trim & 0x000F0000) >> 1); // bit18:15 + txvreftune = ((read_trim & 0x00F00000) >> 1); // bit 22:19 + txrisetune = ((read_trim & 0x01000000) >> 1); // bit23 + txpretune = ((read_trim & 0x02000000) >> 1); // bit24 + + /* Init the UTMI interface */ + USB_HS->GUSBCFG &= ~(OTG_HS_GUSBCFG_TSDPS); + + /* Reset */ + ret = USB_HS_CoreReset(); + /* change srqxtune txvreftune otgtune compdistune */ + /* waiting for update */ + USB_HS_PKEY = 0x5057 ; + USB_HS_PKEY = 0x5948 ; + +//USB_HS_PREG = 0x0041B723; + USB_HS_PREG = (otgtune | comptune | sqrxtune | + txhstune | vregtune | txfslstune | + txvreftune | txrisetune | txpretune | + 0x03); + + *(uint32_t*)(0x40040E1C) |= 0x2000000; + + USB_HS_PKEY = 0x0; + + + if (cfg.dma_enable == 1U) + { + USB_HS->GAHBCFG |= OTG_HS_GAHBCFG_HBSTLEN_2 ; // INCR4 + USB_HS->GAHBCFG |= OTG_HS_GAHBCFG_DMAEN ; // enable dma mode + } + return ret; +} + + +/** + * @brief Set the USB turnaround time + * @param USB HS Instance + * @param hlck: AHB clock frequency + * @retval USB HS turnaround time in PHY clock number + */ + +void USB_HS_SetTurnaroundTime(uint32_t hclk, uint8_t speed) +{ + uint32_t UsbTrd; + + /* The USBTRD is configured according to the tables below, depending on AHB frequency + used by application. In the low AHB frequency range it is used to stretch enough the USB response + time to IN tokens, the USB turnaround time, so to compensate for the longer AHB read access + latency to the Data FIFO */ + if (speed == USBD_FS_SPEED) + { + if ((hclk >= 14200000U) && (hclk < 15000000U)) + { + /* hclk Clock Range between 14.2-15 MHz */ + UsbTrd = 0xFU; + } + else if ((hclk >= 15000000U) && (hclk < 16000000U)) + { + /* hclk Clock Range between 15-16 MHz */ + UsbTrd = 0xEU; + } + else if ((hclk >= 16000000U) && (hclk < 17200000U)) + { + /* hclk Clock Range between 16-17.2 MHz */ + UsbTrd = 0xDU; + } + else if ((hclk >= 17200000U) && (hclk < 18500000U)) + { + /* hclk Clock Range between 17.2-18.5 MHz */ + UsbTrd = 0xCU; + } + else if ((hclk >= 18500000U) && (hclk < 20000000U)) + { + /* hclk Clock Range between 18.5-20 MHz */ + UsbTrd = 0xBU; + } + else if ((hclk >= 20000000U) && (hclk < 21800000U)) + { + /* hclk Clock Range between 20-21.8 MHz */ + UsbTrd = 0xAU; + } + else if ((hclk >= 21800000U) && (hclk < 24000000U)) + { + /* hclk Clock Range between 21.8-24 MHz */ + UsbTrd = 0x9U; + } + else if ((hclk >= 24000000U) && (hclk < 27700000U)) + { + /* hclk Clock Range between 24-27.7 MHz */ + UsbTrd = 0x8U; + } + else if ((hclk >= 27700000U) && (hclk < 32000000U)) + { + /* hclk Clock Range between 27.7-32 MHz */ + UsbTrd = 0x7U; + } + else /* if(hclk >= 32000000) */ + { + /* hclk Clock Range between 32-200 MHz */ + UsbTrd = 0x6U; + } + } + else if (speed == USBD_HS_SPEED) + { + UsbTrd = USBD_HS_TRDT_VALUE; + } + else + { + UsbTrd = USBD_DEFAULT_TRDT_VALUE; + } + + USB_HS->GUSBCFG &= ~OTG_HS_GUSBCFG_TRDT; + USB_HS->GUSBCFG |= (uint32_t)((UsbTrd << 10) & OTG_HS_GUSBCFG_TRDT); + +} + + +/** + * @brief USB_HS_EnableGlobalInt + * Enables the controller's Global Int in the AHB Config reg + * @param USB_HS Selected device + */ +void USB_HS_EnableGlobalInt(void) +{ + USB_HS->GAHBCFG |= OTG_HS_GAHBCFG_GINT; +} + +/** + * @brief USB_HS_DisableGlobalInt + * Enables the controller's Global Int in the AHB Config reg + * @param USB_HS Selected device + */ +void USB_HS_DisableGlobalInt(void) +{ + USB_HS->GAHBCFG &= ~OTG_HS_GAHBCFG_GINT; +} + +/** + * @brief USB_HS_SetCurrentMode Set functional mode + * @param USB_HS Selected device + * @param mode current core mode + * This parameter can be one of these values: + * @arg USB_DEVICE_MODE Peripheral mode + * @arg USB_HOST_MODE Host mode + * @retval USB_HS status + */ +USB_HS_StatusTypeDef USB_HS_SetCurrentMode(USB_ModeTypeDef mode) +{ + uint32_t ms = 0U; + + USB_HS->GUSBCFG &= ~(OTG_HS_GUSBCFG_FHMOD | OTG_HS_GUSBCFG_FDMOD); + + if (mode == USB_HOST_MODE) + { + USB_HS->GUSBCFG |= OTG_HS_GUSBCFG_FHMOD; + do + { + USB_HS_Delayms(10U); + ms += 10U; + }while ((USB_HS_GetMode() != (uint32_t)USB_HOST_MODE) && (ms < USB_HS_CURRENT_MODE_MAX_DELAY_MS)); + } + else if (mode == USB_DEVICE_MODE) + { + USB_HS->GUSBCFG |= OTG_HS_GUSBCFG_FDMOD; + do + { + USB_HS_Delayms(10U); + ms += 10U; + }while ((USB_HS_GetMode() != (uint32_t)USB_DEVICE_MODE) && (ms < USB_HS_CURRENT_MODE_MAX_DELAY_MS)); + } + else + { + return USB_HS_ERROR; + } + if (ms == USB_HS_CURRENT_MODE_MAX_DELAY_MS) + { + return USB_HS_ERROR; + } + return USB_HS_OK ; +} + + +/** + * @brief USB_HS_DevInit Initializes the USB_OTG_HS controller registers + * for device mode + * @param USB_HS Selected device + * @param cfg pointer to a USB_OTG_HS_CfgTypeDef structure that contains + * the configuration information for the specified USB_HS peripheral. + * @retval USB_HS status + */ +USB_HS_StatusTypeDef USB_HS_DevInit(USB_OTG_HS_CfgTypeDef cfg) +{ + USB_HS_StatusTypeDef ret = USB_HS_OK ; + uint32_t i; + + /* Device InEndpoint FIFO size Iintialize */ + for (i = 0U; i < 15U; i++) + { + USB_HS->DIEPTXF[i] = 0U; + } + + /* VBUS sensing setup */ + if (cfg.bvalid_override_enable == 1U) + { + USB_HS_DEVICE->DCTL |= OTG_HS_DCTL_SDIS; + + /* B-peripheral session valid override enable */ + USB_HS->GOTGCTL |= OTG_HS_GOTGCTL_BOVALEN; + USB_HS->GOTGCTL |= OTG_HS_GOTGCTL_BOVAL; + } + else + { + /* ... */ + } + + /* Restart the Phy Clock */ + USB_HS_PCGCCTL = 0U; + + /* Device mode configuration */ + USB_HS_DEVICE->DCFG |= DCFG_FRAME_INTERVAL_80; + + if(cfg.speed == USBD_HS_SPEED) + { + /* Set Core speed to High speed mode */ + (void)USB_HS_SetDevSpeed(USB_OTG_SPEED_HIGH); + } + else + { + /* Set Core speed to Full speed mode */ + (void)USB_HS_SetDevSpeed(USB_OTG_SPEED_HIGH_IN_FULL); + } + + /* Flush the FIFOs */ + if (USB_HS_FlushTxFifo(0x10U) != USB_HS_OK) /* all Tx FIFOs */ + { + ret = USB_HS_ERROR; + } + + if (USB_HS_FlushRxFifo() != USB_HS_OK) + { + ret = USB_HS_ERROR; + } + + /* Clear all pending Device Interrupts */ + USB_HS_DEVICE->DIEPMSK = 0U; + USB_HS_DEVICE->DOEPMSK = 0U; + USB_HS_DEVICE->DAINTMSK = 0U; + + for (i = 0U; i < cfg.dev_endpoints; i++) + { + if ((USB_HS_INEP(i)->DIEPCTL & OTG_HS_DIEPCTL_EPENA) == OTG_HS_DIEPCTL_EPENA) + { + if (i == 0U) + { + USB_HS_INEP(i)->DIEPCTL = OTG_HS_DIEPCTL_SNAK; + } + else + { + USB_HS_INEP(i)->DIEPCTL = OTG_HS_DIEPCTL_EPDIS | OTG_HS_DIEPCTL_SNAK; + } + } + else + { + USB_HS_INEP(i)->DIEPCTL = 0U; + } + + USB_HS_INEP(i)->DIEPTSIZ = 0U; + USB_HS_INEP(i)->DIEPINT = 0xFB7FU; + } + + for (i = 0U; i < cfg.dev_endpoints; i++) + { + if ((USB_HS_OUTEP(i)->DOEPCTL & OTG_HS_DOEPCTL_EPENA) == OTG_HS_DOEPCTL_EPENA) + { + if (i == 0U) + { + USB_HS_OUTEP(i)->DOEPCTL = OTG_HS_DOEPCTL_SNAK; + } + else + { + USB_HS_OUTEP(i)->DOEPCTL = OTG_HS_DOEPCTL_EPDIS | OTG_HS_DOEPCTL_SNAK; + } + } + else + { + USB_HS_OUTEP(i)->DOEPCTL = 0U; + } + + USB_HS_OUTEP(i)->DOEPTSIZ = 0U; + USB_HS_OUTEP(i)->DOEPINT = 0xFB7FU; + } + + USB_HS_DEVICE->DIEPMSK &= ~(OTG_HS_DIEPMSK_TXFURM); + + /* Disable all interrupts. */ + USB_HS->GINTMSK = 0U; + + /* Clear any pending interrupts */ + USB_HS->GINTSTS = 0xBFFFFFFFU; + + /* Enable the common interrupts */ + if (cfg.dma_enable == 0U) + { + USB_HS->GINTMSK |= OTG_HS_GINTMSK_RXFLVLM; + } + /* Enable interrupts matching to the Device mode ONLY */ + USB_HS->GINTMSK |= OTG_HS_GINTMSK_USBSUSPM | OTG_HS_GINTMSK_USBRSTM | + OTG_HS_GINTMSK_ENDNEM | OTG_HS_GINTMSK_IEPINTM | + OTG_HS_GINTMSK_OEPINTM | OTG_HS_GINTMSK_IISOIXFRM | + OTG_HS_GINTMSK_PXFRM_IISOOXFRM | OTG_HS_GINTMSK_WUIM | + OTG_HS_GINTMSK_SOFM | OTG_HS_GINTMSK_OTGINTM | + OTG_HS_GINTMSK_SRQIM ; + + return ret; +} + +/** + * @brief USB_HS_FlushTxFifo : Flush a Tx FIFO + * @param USB_HS Selected device + * @param num FIFO number + * This parameter can be a value from 1 to 15 + 15 means Flush all Tx FIFOs + * @retval USB_HS status + */ +USB_HS_StatusTypeDef USB_HS_FlushTxFifo(uint32_t num) +{ + __IO uint32_t count = 0U; + + /* wait for AHB master IDLE state */ + do + { + count++; + if (count > USB_TIMEOUT) + { + return USB_HS_TIMEOUT; + } + } while ((USB_HS->GRSTCTL & OTG_HS_GRSTCTL_AHBIDL) == 0U); + + /* Flush TX fifo */ + count = 0U; + USB_HS->GRSTCTL = (OTG_HS_GRSTCTL_TXFFLSH | (num << 6)); + + do + { + count++; + if (count > USB_TIMEOUT) + { + return USB_HS_TIMEOUT; + } + } while ((USB_HS->GRSTCTL & OTG_HS_GRSTCTL_TXFFLSH) == OTG_HS_GRSTCTL_TXFFLSH); + + return USB_HS_OK; +} + +/** + * @brief USB_HS_FlushRxFifo : Flush Rx FIFO + * @param USB_HS Selected device + * @retval USB_HS status + */ +USB_HS_StatusTypeDef USB_HS_FlushRxFifo(void) +{ + __IO uint32_t count = 0U; + /* wait for AHB master IDLE state */ + do + { + count++; + if (count > USB_TIMEOUT) + { + return USB_HS_TIMEOUT; + } + } while ((USB_HS->GRSTCTL & OTG_HS_GRSTCTL_AHBIDL) == 0U); + + /* Flush RX fifo */ + count = 0U; + USB_HS->GRSTCTL = OTG_HS_GRSTCTL_RXFFLSH ; + + do + { + count++; + if (count > USB_TIMEOUT) + { + return USB_HS_TIMEOUT; + } + } while ((USB_HS->GRSTCTL & OTG_HS_GRSTCTL_RXFFLSH) == OTG_HS_GRSTCTL_RXFFLSH); + + return USB_HS_OK; +} + + +/** + * @brief USB_HS_SetDevSpeed Initializes the DevSpd field of DCFG register + * depending the PHY type and the enumeration speed of the device. + * @param USB_HS Selected device + * @param speed device speed + * This parameter can be one of these values: + * @arg USB_OTG_SPEED_HIGH: High speed mode + * @arg USB_OTG_SPEED_HIGH_IN_FULL: High speed core in Full speed mode + */ +void USB_HS_SetDevSpeed(uint8_t speed) +{ + USB_HS_DEVICE->DCFG |= speed; +} + +/** + * @brief USB_HS_GetDevSpeed Return the Dev Speed + * @param USB_HS Selected device + * @retval speed device speed + * This parameter can be one of these values: + * @arg PCD_SPEED_HIGH: High speed mode + * @arg PCD_SPEED_FULL: Full speed mode + */ +uint8_t USB_HS_GetDevSpeed(void) +{ + uint8_t speed; + uint32_t DevEnumSpeed = USB_HS_DEVICE->DSTS & OTG_HS_DSTS_ENUMSPD; + + if (DevEnumSpeed == DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ) + { + speed = USBD_HS_SPEED; + } + else if (DevEnumSpeed == DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ) + { + speed = USBD_FS_SPEED; + } + else + { + speed = 0xFU; + } + + return speed; +} + + +/** + * @brief Activate and configure an endpoint + * @param USB_HS Selected device + * @param ep pointer to endpoint structure + */ +void USB_HS_ActivateEndpoint(USB_OTG_HS_EPTypeDef *ep) +{ + uint32_t epnum = (uint32_t)ep->num; + /* read DI/OEPCTLn register */ + if (ep->is_in == 1U) + { + USB_HS_DEVICE->DAINTMSK |= OTG_HS_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK)); + + if ((USB_HS_INEP(epnum)->DIEPCTL & OTG_HS_DIEPCTL_USBAEP) == 0U) + { + USB_HS_INEP(epnum)->DIEPCTL |= (ep->maxpacket & OTG_HS_DIEPCTL_MPSIZ) | + ((uint32_t)ep->type << 18) | (epnum << 22) | + OTG_HS_DIEPCTL_SD0PID_SEVNFRM | + OTG_HS_DIEPCTL_USBAEP; + } + } + else + { + USB_HS_DEVICE->DAINTMSK |= OTG_HS_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16); + + if (((USB_HS_OUTEP(epnum)->DOEPCTL) & OTG_HS_DOEPCTL_USBAEP) == 0U) + { + USB_HS_OUTEP(epnum)->DOEPCTL |= (ep->maxpacket & OTG_HS_DOEPCTL_MPSIZ) | + ((uint32_t)ep->type << 18) | + OTG_HS_DOEPCTL_SD0PID_SEVNFRM | + OTG_HS_DOEPCTL_USBAEP; + } + } +} + + +/** + * @brief Activate and configure a dedicated endpoint + * @param USB_HS Selected device + * @param ep pointer to endpoint structure + */ +void USB_HS_ActivateDedicatedEndpoint(USB_OTG_HS_EPTypeDef *ep) +{ + uint32_t epnum = (uint32_t)ep->num; + /* read DI/OEPCTLn register */ + if (ep->is_in == 1U) + { + if ((USB_HS_INEP(epnum)->DIEPCTL & OTG_HS_DIEPCTL_USBAEP) == 0U) + { + USB_HS_INEP(epnum)->DIEPCTL |= (ep->maxpacket & OTG_HS_DIEPCTL_MPSIZ) | + ((uint32_t)ep->type << 18) | (epnum << 22) | + OTG_HS_DIEPCTL_SD0PID_SEVNFRM | + OTG_HS_DIEPCTL_USBAEP; + } + USB_HS_DEVICE->DEACHMSK |= OTG_HS_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK)); + } + else + { + if (((USB_HS_OUTEP(epnum)->DOEPCTL) & OTG_HS_DOEPCTL_USBAEP) == 0U) + { + USB_HS_OUTEP(epnum)->DOEPCTL |= (ep->maxpacket & OTG_HS_DOEPCTL_MPSIZ) | + ((uint32_t)ep->type << 18) | + OTG_HS_DOEPCTL_SD0PID_SEVNFRM | + OTG_HS_DOEPCTL_USBAEP; + } + USB_HS_DEVICE->DEACHMSK |= OTG_HS_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16 ); + } +} + +/** + * @brief De-activate and de-initialize an endpoint + * @param USB_HS Selected device + * @param ep pointer to endpoint structure + */ +void USB_HS_DeactivateEndpoint(USB_OTG_HS_EPTypeDef *ep) +{ + uint32_t epnum = (uint32_t)ep->num; + + /* Read DI/OEPCTLn register */ + if (ep->is_in == 1U) + { + if ((USB_HS_INEP(epnum)->DIEPCTL & OTG_HS_DIEPCTL_EPENA) == OTG_HS_DIEPCTL_EPENA) + { + USB_HS_INEP(epnum)->DIEPCTL |= OTG_HS_DIEPCTL_SNAK; + USB_HS_INEP(epnum)->DIEPCTL |= OTG_HS_DIEPCTL_EPDIS; + } + + USB_HS_DEVICE->DEACHMSK &= ~(OTG_HS_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK))); + USB_HS_DEVICE->DAINTMSK &= ~(OTG_HS_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK))); + USB_HS_INEP(epnum)->DIEPCTL &= ~(OTG_HS_DIEPCTL_USBAEP | + OTG_HS_DIEPCTL_MPSIZ | + OTG_HS_DIEPCTL_TXFNUM | + OTG_HS_DIEPCTL_SD0PID_SEVNFRM | + OTG_HS_DIEPCTL_EPTYP); + } + else + { + if ((USB_HS_OUTEP(epnum)->DOEPCTL & OTG_HS_DOEPCTL_EPENA) == OTG_HS_DOEPCTL_EPENA) + { + USB_HS_OUTEP(epnum)->DOEPCTL |= OTG_HS_DOEPCTL_SNAK; + USB_HS_OUTEP(epnum)->DOEPCTL |= OTG_HS_DOEPCTL_EPDIS; + } + + USB_HS_DEVICE->DEACHMSK &= ~(OTG_HS_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16)); + USB_HS_DEVICE->DAINTMSK &= ~(OTG_HS_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16)); + USB_HS_OUTEP(epnum)->DOEPCTL &= ~(OTG_HS_DOEPCTL_USBAEP | + OTG_HS_DOEPCTL_MPSIZ | + OTG_HS_DOEPCTL_SD0PID_SEVNFRM | + OTG_HS_DOEPCTL_EPTYP); + } +} + +/** + * @brief De-activate and de-initialize a dedicated endpoint + * @param USB_HS Selected device + * @param ep pointer to endpoint structure + */ +void USB_HS_DeactivateDedicatedEndpoint(USB_OTG_HS_EPTypeDef *ep) +{ + uint32_t epnum = (uint32_t)ep->num; + + /* Read DI/OEPCTLn register */ + if (ep->is_in == 1U) + { + if ((USB_HS_INEP(epnum)->DIEPCTL & OTG_HS_DIEPCTL_EPENA) == OTG_HS_DIEPCTL_EPENA) + { + USB_HS_INEP(epnum)->DIEPCTL |= OTG_HS_DIEPCTL_SNAK; + USB_HS_INEP(epnum)->DIEPCTL |= OTG_HS_DIEPCTL_EPDIS; + } + + USB_HS_INEP(epnum)->DIEPCTL &= ~OTG_HS_DIEPCTL_USBAEP ; + USB_HS_DEVICE->DAINTMSK &= ~(OTG_HS_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK))); + } + else + { + if ((USB_HS_OUTEP(epnum)->DOEPCTL & OTG_HS_DOEPCTL_EPENA) == OTG_HS_DOEPCTL_EPENA) + { + USB_HS_OUTEP(epnum)->DOEPCTL |= OTG_HS_DOEPCTL_SNAK; + USB_HS_OUTEP(epnum)->DOEPCTL |= OTG_HS_DOEPCTL_EPDIS; + } + + USB_HS_OUTEP(epnum)->DOEPCTL &= ~OTG_HS_DOEPCTL_USBAEP ; + USB_HS_DEVICE->DAINTMSK &= ~(OTG_HS_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16)); + } +} + + +/** + * @brief USB_HS_EPStartXfer : setup and starts a transfer over an EP + * @param USB_HS Selected device + * @param ep pointer ro endpoint structure + * @param dma USB_HS enable or disable + * This parameter can be one of these values: + * 0 : DMA feature not used + * 1 : DMA feature used + */ +void USB_HS_EPStartXfer(USB_OTG_HS_EPTypeDef *ep, uint8_t dma) +{ + uint32_t epnum = (uint32_t)ep->num; + uint16_t pktcnt; + + /* IN endpoint */ + if (ep->is_in == 1U) + { + /* Zero Length Packet? */ + if (ep->xfer_len == 0U) + { + USB_HS_INEP(epnum)->DIEPTSIZ &= ~(OTG_HS_DIEPTSIZ_PKTCNT); + USB_HS_INEP(epnum)->DIEPTSIZ |= (OTG_HS_DIEPTSIZ_PKTCNT & (1U << 19)); + USB_HS_INEP(epnum)->DIEPTSIZ &= ~(OTG_HS_DIEPTSIZ_XFRSIZ); + } + else + { + /* Program the transfer size and packet count + * as follows: xfersize = N * maxpacket + + * short_packet pktcnt = N + (short_packet + * exist ? 1 : 0) + */ + USB_HS_INEP(epnum)->DIEPTSIZ &= ~(OTG_HS_DIEPTSIZ_XFRSIZ); + USB_HS_INEP(epnum)->DIEPTSIZ &= ~(OTG_HS_DIEPTSIZ_PKTCNT); + + if (epnum == 0U) + { + if (ep->xfer_len > ep->maxpacket) + { + ep->xfer_len = ep->maxpacket; + } + + USB_HS_INEP(epnum)->DIEPTSIZ |= (OTG_HS_DIEPTSIZ_PKTCNT & (1U << 19)); + } + else + { + USB_HS_INEP(epnum)->DIEPTSIZ |= (OTG_HS_DIEPTSIZ_PKTCNT & + (((ep->xfer_len + ep->maxpacket - 1U) / ep->maxpacket) << 19)); + } + + USB_HS_INEP(epnum)->DIEPTSIZ |= (OTG_HS_DIEPTSIZ_XFRSIZ & ep->xfer_len); + + if (ep->type == EP_TYPE_ISOC) + { + USB_HS_INEP(epnum)->DIEPTSIZ &= ~(OTG_HS_DIEPTSIZ_MULCNT); + USB_HS_INEP(epnum)->DIEPTSIZ |= (OTG_HS_DIEPTSIZ_MULCNT & (1U << 29)); + } + } + if (dma == 1U) + { + if ((uint32_t)ep->dma_addr != 0U) + { + USB_HS_INEP(epnum)->DIEPDMA = (uint32_t)(ep->dma_addr); + } + if (ep->type == EP_TYPE_ISOC) + { + /* SOF frame is odd or even */ + if ((USB_HS_DEVICE->DSTS & (1U << 8)) == 0U) + { + USB_HS_INEP(epnum)->DIEPCTL |= OTG_HS_DIEPCTL_SODDFRM; + } + else + { + USB_HS_INEP(epnum)->DIEPCTL |= OTG_HS_DIEPCTL_SD0PID_SEVNFRM; + } + } + /* EP enable, IN data in FIFO */ + USB_HS_INEP(epnum)->DIEPCTL |= (OTG_HS_DIEPCTL_CNAK | OTG_HS_DIEPCTL_EPENA); + } + else + { + /* EP enable, IN data in FIFO */ + USB_HS_INEP(epnum)->DIEPCTL |= (OTG_HS_DIEPCTL_CNAK | OTG_HS_DIEPCTL_EPENA); + + if (ep->type != EP_TYPE_ISOC) + { + /* Enable the Tx FIFO Empty Interrupt for this EP */ + if (ep->xfer_len > 0U) + { + USB_HS_DEVICE->DIEPEMPMSK |= 1UL << (ep->num & EP_ADDR_MSK); + } + } + else + { + if ((USB_HS_DEVICE->DSTS & (1U << 8)) == 0U) + { + USB_HS_INEP(epnum)->DIEPCTL |= OTG_HS_DIEPCTL_SODDFRM; + } + else + { + USB_HS_INEP(epnum)->DIEPCTL |= OTG_HS_DIEPCTL_SD0PID_SEVNFRM; + } + USB_HS_WritePacket(ep->xfer_buff, ep->num, (uint16_t)ep->xfer_len, dma); + } + } + } + else /* OUT endpoint */ + { + /* Program the transfer size and packet count as follows: + * pktcnt = N + * xfersize = N * maxpacket + */ + USB_HS_OUTEP(epnum)->DOEPTSIZ &= ~(OTG_HS_DOEPTSIZ_XFRSIZ); + USB_HS_OUTEP(epnum)->DOEPTSIZ &= ~(OTG_HS_DOEPTSIZ_PKTCNT); + + if (epnum == 0U) + { + if (ep->xfer_len > 0U) + { + ep->xfer_len = ep->maxpacket; + } + + /* store transfer size, for EP0 this is equal to endpoint max packet size */ + ep->xfer_size = ep->maxpacket; + + USB_HS_OUTEP(epnum)->DOEPTSIZ |= (OTG_HS_DOEPTSIZ_XFRSIZ & ep->xfer_size); + USB_HS_OUTEP(epnum)->DOEPTSIZ |= (OTG_HS_DOEPTSIZ_PKTCNT & (1U << 19)); + } + else + { + if (ep->xfer_len == 0U) + { + USB_HS_OUTEP(epnum)->DOEPTSIZ |= (OTG_HS_DOEPTSIZ_XFRSIZ & ep->maxpacket); + USB_HS_OUTEP(epnum)->DOEPTSIZ |= (OTG_HS_DOEPTSIZ_PKTCNT & (1U << 19)); + } + else + { + pktcnt = (uint16_t)((ep->xfer_len + ep->maxpacket - 1U) / ep->maxpacket); + ep->xfer_size = ep->maxpacket * pktcnt; + + USB_HS_OUTEP(epnum)->DOEPTSIZ |= OTG_HS_DOEPTSIZ_PKTCNT & ((uint32_t)pktcnt << 19); + USB_HS_OUTEP(epnum)->DOEPTSIZ |= OTG_HS_DOEPTSIZ_XFRSIZ & (ep->xfer_size); + } + } + + if (dma == 1U) + { + if ((uint32_t)ep->xfer_buff != 0U) + { + USB_HS_OUTEP(epnum)->DOEPDMA = (uint32_t)(ep->xfer_buff); + } + } + if (ep->type == EP_TYPE_ISOC) + { + /* SOF frame is odd or even */ + if ((USB_HS_DEVICE->DSTS & (1U << 8)) == 0U) + { + USB_HS_OUTEP(epnum)->DOEPCTL |= OTG_HS_DOEPCTL_SODDFRM; + } + else + { + USB_HS_OUTEP(epnum)->DOEPCTL |= OTG_HS_DOEPCTL_SD0PID_SEVNFRM; + } + } + /* EP enable */ + USB_HS_OUTEP(epnum)->DOEPCTL |= (OTG_HS_DOEPCTL_CNAK | OTG_HS_DOEPCTL_EPENA); + } +} + +/** + * @brief USB_HS_EPStopXfer : Stop transfer on an EP + * @param USB_HS Selected device + * @param ep pointer to endpoint structure + * @retval USB_HS status + */ +USB_HS_StatusTypeDef USB_HS_EPStopXfer(USB_OTG_HS_EPTypeDef *ep) +{ + __IO uint32_t count = 0U; + USB_HS_StatusTypeDef ret = USB_HS_OK; + + /* IN endpoint */ + if (ep->is_in == 1U) + { + /* EP enable, IN data in FIFO */ + if (((USB_HS_INEP(ep->num)->DIEPCTL) & OTG_HS_DIEPCTL_EPENA) == OTG_HS_DIEPCTL_EPENA) + { + USB_HS_INEP(ep->num)->DIEPCTL |= (OTG_HS_DIEPCTL_SNAK); + USB_HS_INEP(ep->num)->DIEPCTL |= (OTG_HS_DIEPCTL_EPDIS); + + do + { + count++; + if (count > 10000U) + { + ret = USB_HS_ERROR; + break; + } + }while (((USB_HS_INEP(ep->num)->DIEPCTL) & OTG_HS_DIEPCTL_EPENA) == OTG_HS_DIEPCTL_EPENA); + } + } + else /* OUT endpoint */ + { + if (((USB_HS_OUTEP(ep->num)->DOEPCTL) & OTG_HS_DOEPCTL_EPENA) == OTG_HS_DOEPCTL_EPENA) + { + USB_HS_OUTEP(ep->num)->DOEPCTL |= (OTG_HS_DOEPCTL_SNAK); + USB_HS_OUTEP(ep->num)->DOEPCTL |= (OTG_HS_DOEPCTL_EPDIS); + + do + { + count++; + if (count > 10000U) + { + ret = USB_HS_ERROR; + break; + } + }while (((USB_HS_OUTEP(ep->num)->DOEPCTL) & OTG_HS_DOEPCTL_EPENA) == OTG_HS_DOEPCTL_EPENA); + } + } + return ret; +} + +/** + * @brief USB_HS_WritePacket : Writes a packet into the Tx FIFO associated + * with the EP/channel + * @param USB_HS Selected device + * @param src pointer to source buffer + * @param ch_ep_num endpoint or host channel number + * @param len Number of bytes to write + * @param dma USB dma enabled or disabled + * This parameter can be one of thes values: + * 0 : DMA feature not used + * 1 : DMA feature used + */ +void USB_HS_WritePacket(uint8_t *src, uint8_t ch_ep_num, uint16_t len, uint8_t dma) +{ + uint8_t *pSrc = src; + uint32_t count32b; + uint32_t i; + + if (dma == 0U) + { + count32b = ((uint32_t)len + 3U) / 4U; + for (i = 0U; i < count32b; i++) + { + USB_HS_DFIFO((uint32_t)ch_ep_num) = __UNALIGNED_UINT32_READ(pSrc); + pSrc++; + pSrc++; + pSrc++; + pSrc++; + } + } +} + + +/** + * @brief USB_HS_ReadPacket : read a packet from the RX FIFO + * @param USB_HS Selected device + * @param dest source pointer + * @param len Number of bytes to read + * @retval pointer to destination buffer + */ +void *USB_HS_ReadPacket(uint8_t *dest, uint16_t len) +{ + uint8_t *pDest = dest; + uint32_t pData; + uint32_t i; + uint32_t count32b = (uint32_t)len >> 2U; + uint16_t remaining_bytes = len % 4U; + + for (i = 0U; i < count32b; i++) + { + __UNALIGNED_UINT32_WRITE(pDest, USB_HS_DFIFO(0U)); + pDest++; + pDest++; + pDest++; + pDest++; + } + /* when number of data is not word aligned, read the remaining byte */ + if (remaining_bytes != 0U) + { + i = 0U; + __UNALIGNED_UINT32_WRITE(&pData, USB_HS_DFIFO(0U)); + + do + { + *(uint8_t *)pDest = (uint8_t)(pData >> (8U * (uint8_t)(i))); + i++; + pDest++; + remaining_bytes--; + }while (remaining_bytes != 0U); + } + return ((void *)pDest); +} + + +/** + * @brief USB_HS_EPSetStall : set a stall condition over an EP + * @param USB_HS Selected device + * @param ep pointer to endpoint structure + */ +void USB_HS_EPSetStall(USB_OTG_HS_EPTypeDef *ep) +{ + uint32_t epnum = (uint32_t)ep->num; + + if (ep->is_in == 1U) + { + if (((USB_HS_INEP(epnum)->DIEPCTL & OTG_HS_DIEPCTL_EPENA) == 0U) && (epnum != 0U)) + { + USB_HS_INEP(epnum)->DIEPCTL &= ~(OTG_HS_DIEPCTL_EPDIS); + } + USB_HS_INEP(epnum)->DIEPCTL |= OTG_HS_DIEPCTL_STALL; + } + else + { + if (((USB_HS_OUTEP(epnum)->DOEPCTL & OTG_HS_DOEPCTL_EPENA) == 0U) && (epnum != 0U)) + { + USB_HS_OUTEP(epnum)->DOEPCTL &= ~(OTG_HS_DOEPCTL_EPDIS); + } + USB_HS_OUTEP(epnum)->DOEPCTL |= OTG_HS_DOEPCTL_STALL; + } +} + +/** + * @brief USB_HS_EPClearStall : Clear a stall condition over an EP + * @param USB_HS Selected device + * @param ep pointer to endpoint structure + */ +void USB_HS_EPClearStall(USB_OTG_HS_EPTypeDef *ep) +{ + uint32_t epnum = (uint32_t)ep->num; + + if (ep->is_in == 1U) + { + USB_HS_INEP(epnum)->DIEPCTL &= ~OTG_HS_DIEPCTL_STALL; + if ((ep->type == EP_TYPE_INTR) || (ep->type == EP_TYPE_BULK)) + { + USB_HS_INEP(epnum)->DIEPCTL |= OTG_HS_DIEPCTL_SD0PID_SEVNFRM; /* DATA0 */ + } + } + else + { + USB_HS_OUTEP(epnum)->DOEPCTL &= ~OTG_HS_DOEPCTL_STALL; + if ((ep->type == EP_TYPE_INTR) || (ep->type == EP_TYPE_BULK)) + { + USB_HS_OUTEP(epnum)->DOEPCTL |= OTG_HS_DOEPCTL_SD0PID_SEVNFRM; /* DATA0 */ + } + } +} + + +/** + * @brief USB_HS_StopDevice : Stop the usb device mode + * @param USB_HS Selected device + * @retval USB_HS status + */ +USB_HS_StatusTypeDef USB_HS_StopDevice(void) +{ + USB_HS_StatusTypeDef ret; + uint32_t i; + + /* Clear Pending interrupt */ + for (i = 0U; i < 15U; i++) + { + USB_HS_INEP(i)->DIEPINT = 0xFB7FU; + USB_HS_OUTEP(i)->DOEPINT = 0xFB7FU; + } + + /* Clear interrupt masks */ + USB_HS_DEVICE->DIEPMSK = 0U; + USB_HS_DEVICE->DOEPMSK = 0U; + USB_HS_DEVICE->DAINTMSK = 0U; + + /* Flush the FIFO */ + ret = USB_HS_FlushRxFifo(); + if (ret != USB_HS_OK) + { + return ret; + } + + ret = USB_HS_FlushTxFifo(0x10U); + if (ret != USB_HS_OK) + { + return ret; + } + + return ret; +} + +/** + * @brief USB_HS_SetDevAddress : set device address + * @param USB_HS Selected device + * @param address new device address to be assigned + * This parameter can be a value from 0 to 255 + */ +void USB_HS_SetDevAddress(uint8_t address) +{ + USB_HS_DEVICE->DCFG &= ~(OTG_HS_DCFG_DAD); + USB_HS_DEVICE->DCFG |= ((uint32_t)address << 4) & OTG_HS_DCFG_DAD; +} + +/** + * @brief USB_HS_DevConnect : Connect the USB device by enabling Rpu + * @param USB_HS Selected device + */ +void USB_HS_DevConnect(void) +{ + /* In case phy is stopped, ensure to ungate and restore the phy CLK */ + USB_HS_PCGCCTL &= ~(OTG_HS_PCGCCTL_STOPCLK | OTG_HS_PCGCCTL_GATECLK); + + /* disable software disconnect */ + USB_HS_DEVICE->DCTL &= ~OTG_HS_DCTL_SDIS; + +} + + +/** + * @brief USB_HS_DevDisconnect : Disconnect the USB device by disabling Rpu + * @param USB_HS Selected device + * @retval none + */ +void USB_HS_DevDisconnect(void) +{ + /* In case phy is stopped, ensure to ungate and restore the phy CLK */ + USB_HS_PCGCCTL &= ~(OTG_HS_PCGCCTL_STOPCLK | OTG_HS_PCGCCTL_GATECLK); + /* enable software disconnect */ + USB_HS_DEVICE->DCTL |= OTG_HS_DCTL_SDIS; + +} + +/** + * @brief USB_HS_ReadInterrupts: return the global USB interrupt status + * @param USB_HS Selected device + * @retval global interrupt register + */ +uint32_t USB_HS_ReadInterrupts(void) +{ + uint32_t tmpreg; + + tmpreg = USB_HS->GINTSTS; + tmpreg &= USB_HS->GINTMSK; + + return tmpreg; +} + +/** + * @brief USB_HS_ReadChInterrupts: return the USB channel interrupt status + * @param USB_HS Selected device + * @param chnum channel number + * @retval USB HS Channel interrupt register + */ +uint32_t USB_HS_ReadChInterrupts(uint8_t chnum) +{ + uint32_t tmpreg; + + tmpreg = USB_HS_HC(chnum)->HCINT; + tmpreg &= USB_HS_HC(chnum)->HCINTMSK; + + return tmpreg; +} + + +/** + * @brief USB_HS_ReadDevAllOutEpInterrupt: return the USB device OUT endpoints interrupt status + * @param USB_HS Selected device + * @retval USB Device OUT EP interrupt status + */ +uint32_t USB_HS_ReadDevAllOutEpInterrupt(void) +{ + uint32_t tmpreg; + + tmpreg = USB_HS_DEVICE->DAINT; + tmpreg &= USB_HS_DEVICE->DAINTMSK; + + return ((tmpreg & 0xffff0000U) >> 16); +} + +/** + * @brief USB_HS_ReadDevAllInEpInterrupt: return the USB device IN endpoints interrupt status + * @param USB_HS Selected device + * @retval USB Device IN EP interrupt status + */ +uint32_t USB_HS_ReadDevAllInEpInterrupt(void) +{ + uint32_t tmpreg; + + tmpreg = USB_HS_DEVICE->DAINT; + tmpreg &= USB_HS_DEVICE->DAINTMSK; + + return ((tmpreg & 0xFFFFU)); +} + +/** + * @brief Returns Device OUT EP Interrupt register + * @param USB_HS Selected device + * @param epnum endpoint number + * This parameter can be a value from 0 to 15 + * @retval Device OUT EP Interrupt register + */ +uint32_t USB_HS_ReadDevOutEPInterrupt(uint8_t epnum) +{ + uint32_t tmpreg; + + tmpreg = USB_HS_OUTEP((uint32_t)epnum)->DOEPINT; + tmpreg &= USB_HS_DEVICE->DOEPMSK; + + return tmpreg; +} + +/** + * @brief Returns Device IN EP Interrupt register + * @param USB_HS Selected device + * @param epnum endpoint number + * This parameter can be a value from 0 to 15 + * @retval Device IN EP Interrupt register + */ +uint32_t USB_HS_ReadDevInEPInterrupt(uint8_t epnum) +{ + uint32_t tmpreg; + uint32_t msk; + uint32_t emp; + + msk = USB_HS_DEVICE->DIEPMSK; + emp = USB_HS_DEVICE->DIEPEMPMSK; + msk |= ((emp >> (epnum & EP_ADDR_MSK)) & 0x1U) << 7; + tmpreg = USB_HS_INEP((uint32_t)epnum)->DIEPINT & msk; + + return tmpreg; +} + +/** + * @brief USB_HS_ClearInterrupts: clear a USB interrupt + * @param USB_HS Selected device + * @param interrupt flag + * @retval None + */ +void USB_HS_ClearInterrupts(uint32_t interrupt) +{ + USB_HS->GINTSTS &= interrupt; +} + +/** + * @brief Returns USB_HS core mode + * @param USB_HS Selected device + * @retval return core mode : Host or Device + * This parameter can be one of these values: + * 0 : Host + * 1 : Device + */ +uint32_t USB_HS_GetMode(void) +{ + return ((USB_HS->GINTSTS) & 0x1U); +} + +/** + * @brief Activate EP0 for Setup transactions + * @param USB_HS Selected device + */ +void USB_HS_ActivateSetup(void) +{ + + /* Set the MPS of the IN EP0 to 64 bytes */ + USB_HS_INEP(0U)->DIEPCTL &= ~OTG_HS_DIEPCTL_MPSIZ; + + USB_HS_DEVICE->DCTL |= OTG_HS_DCTL_CGINAK; + +} + +/** + * @brief Prepare the EP0 to start the first control setup + * @param USB_HS Selected device + * @param dma USB_HS enabled or disabled + * This parameter can be one of these values: + * 0 : DMA feature not used + * 1 : DMA deature used + * @param psetup pointer to setup packet + * @retval USB_HS status + */ +USB_HS_StatusTypeDef USB_HS_EP0_OutStart(uint8_t dma, uint8_t *psetup) +{ + if ((USB_HS_OUTEP(0U)->DOEPCTL & OTG_HS_DOEPCTL_EPENA) == OTG_HS_DOEPCTL_EPENA) + { + return USB_HS_OK; + } + + USB_HS_OUTEP(0U)->DOEPTSIZ = 0U; + USB_HS_OUTEP(0U)->DOEPTSIZ |= (OTG_HS_DOEPTSIZ_PKTCNT & (1U << 19)); + USB_HS_OUTEP(0U)->DOEPTSIZ |= (3U * 8U); + USB_HS_OUTEP(0U)->DOEPTSIZ |= OTG_HS_DOEPTSIZ_STUPCNT; + + if (dma == 1U) + { + USB_HS_OUTEP(0U)->DOEPDMA = (uint32_t)psetup; + /* EP enable */ + USB_HS_OUTEP(0U)->DOEPCTL |= (OTG_HS_DOEPCTL_EPENA | OTG_HS_DOEPCTL_USBAEP); + } + + return USB_HS_OK; +} + +/** + * @brief Reset the USB_HS Core (needed after USB clock settings change) + * @param USB_HS Selected device + * @retval USB_HS status + */ +static USB_HS_StatusTypeDef USB_HS_CoreReset(void) +{ + __IO uint32_t count = 0U; + + /* Wait for AHB master IDLE state. */ + do + { + count++; + + if (count > USB_TIMEOUT) + { + return USB_HS_TIMEOUT; + } + } while ((USB_HS->GRSTCTL & OTG_HS_GRSTCTL_AHBIDL) == 0U); + + /* Core Soft Reset */ + count = 0U; + USB_HS->GRSTCTL |= OTG_HS_GRSTCTL_CSRST; + + do + { + count++; + + if (count > USB_TIMEOUT) + { + return USB_HS_TIMEOUT; + } + } while ((USB_HS->GRSTCTL & OTG_HS_GRSTCTL_CSRST) == OTG_HS_GRSTCTL_CSRST); + + return USB_HS_OK; +} + +/** + * @brief USB_HS_HostInit : Initializes the USB OTG controller registers + * for Host mode + * @param USB_HS Selected device + * @param cfg pointer to a USB_OTG_HS_CfgTypeDef structure that contains + * the configuration information for the specified USB_HS peripheral. + * @retval USB_HS status + */ +USB_HS_StatusTypeDef USB_HS_HostInit(USB_OTG_HS_CfgTypeDef cfg) +{ + USB_HS_StatusTypeDef ret = USB_HS_OK; + uint32_t i; + + /* Restart the Phy Clock */ + USB_HS_PCGCCTL = 0U; + + if ((USB_HS->GUSBCFG & OTG_HS_GUSBCFG_PHSEL) == 0U) + { + if (cfg.speed == USBH_FSLS_SPEED) + { + /* Force device enumeration to FS/LS mode only */ + USB_HS_HOST->HCFG |= OTG_HS_HCFG_FSLSS; + } + else + { + /* Set default Max speed support */ + USB_HS_HOST->HCFG &= ~(OTG_HS_HCFG_FSLSS); + } + } + else + { + ret = USB_HS_ERROR; + } + + /* Make sure the FIFOs are flushed. */ + if (USB_HS_FlushTxFifo(0x10U) != USB_HS_OK) /* all Tx FIFOs */ + { + ret = USB_HS_ERROR ; + } + if (USB_HS_FlushRxFifo() != USB_HS_OK) /* Rx FIFO */ + { + ret = USB_HS_ERROR ; + } + + /* Clear all pending HC Interrupts */ + for (i = 0U; i < cfg.Host_channels; i++) + { + USB_HS_HC(i)->HCINT = CLEAR_INTERRUPT_MASK; + USB_HS_HC(i)->HCINTMSK = 0U; + } + + /* Enable VBUS driving */ +// (void)USB_HS_DriveVbus(1U); +// USB_HS_Delayms(200U); + + /* Disable all interrupts. */ + USB_HS->GINTMSK = 0U; + + /* Clear any pending interrupts */ + USB_HS->GINTSTS = CLEAR_INTERRUPT_MASK; + + /* set Rx FIFO size */ + USB_HS->GRXFSIZ = 0x200U; + USB_HS->DIEPTXF0_HNPTXFSIZ = (uint32_t)(((0x100U << 16) & OTG_HS_HNPTXFSIZ_NPTXFD) | 0x200U); + USB_HS->HPTXFSIZ = (uint32_t)(((0xE0U << 16)& OTG_HS_HPTXFSIZ_PTXFD) | 0x300U); + + /* Enable the common interrupts */ + if (cfg.dma_enable == 0U) + { + USB_HS->GINTMSK |= OTG_HS_GINTMSK_RXFLVLM; + } + /* Enable interrupts matching to the Host mode ONLY */ + USB_HS->GINTMSK |= (OTG_HS_GINTMSK_PRTIM | OTG_HS_GINTMSK_HCIM | \ + OTG_HS_GINTMSK_SOFM | OTG_HS_GINTMSK_DISCINTM | \ + OTG_HS_GINTMSK_PXFRM_IISOOXFRM | OTG_HS_GINTMSK_WUIM ); + + return ret; +} + +/** + * @brief USB_HS_InitFSLSPClkSel : Initializes the FSLSPClkSel field of the + * HCFG register on the PHY type and set the right frame interval + * @param USB_HS Selected device + * @param freq clock frequency + * This parameter can be one of these values: + * HCFG_48_MHZ : Full Speed 48 MHz Clock + * HCFG_6_MHZ : Low Speed 6 MHz Clock + * @retval USB_HS status + */ +USB_HS_StatusTypeDef USB_HS_InitFSLSPClkSel(uint8_t freq) +{ + + USB_HS_HOST->HCFG &= ~(OTG_HS_HCFG_FSLSPCS); + USB_HS_HOST->HCFG |= (uint32_t)freq & OTG_HS_HCFG_FSLSPCS; + + if (freq == HCFG_48_MHZ) + { + USB_HS_HOST->HFIR = 48000U; + } + else if (freq == HCFG_6_MHZ) + { + USB_HS_HOST->HFIR = 6000U; + } + else + { + return USB_HS_ERROR; + } + + return USB_HS_OK; + +} + +/** + * @brief USB_OTG_ResetPort : Reset Host Port + * @param USB_HS Selected device + * @note (1)The application must wait at least 10 ms + * before clearing the reset bit. + */ +void USB_HS_ResetPort(void) +{ + + __IO uint32_t hprt0 = 0U; + __IO uint32_t num = 100; + + hprt0 = USB_HS_HPRT0; + + hprt0 &= ~(OTG_HS_HPRT_PENA | OTG_HS_HPRT_PCDET | + OTG_HS_HPRT_PENCHNG | OTG_HS_HPRT_POCCHNG); + + USB_HS_HPRT0 = (OTG_HS_HPRT_PRST | hprt0); + while(num--) /* update delay 20ms */ + { + SysTick->LOAD = SystemCoreClock / 1000; + SysTick->VAL = 0x00; + SysTick->CTRL = 0x00000005; + + while(!(SysTick->CTRL & 0x00010000)); + + SysTick->CTRL = 0x00000004; + } /* See Note #1 */ + + USB_HS_HPRT0 = ((~OTG_HS_HPRT_PRST) & hprt0); + USB_HS_Delayms(10U); + +} + +/** + * @brief USB_HS_DriveVbus : activate or de-activate vbus + * @param state VBUS state + * This parameter can be one of these values: + * 0 : Deactivate VBUS + * 1 : Activate VBUS + */ +void USB_HS_DriveVbus(uint8_t state) +{ + __IO uint32_t hprt0 = 0U; + + hprt0 = USB_HS_HPRT0; + + hprt0 &= ~(OTG_HS_HPRT_PENA | OTG_HS_HPRT_PCDET | + OTG_HS_HPRT_PENCHNG | OTG_HS_HPRT_POCCHNG); + + if (((hprt0 & OTG_HS_HPRT_PPWR) == 0U) && (state == 1U)) + { + USB_HS_HPRT0 = (OTG_HS_HPRT_PPWR | hprt0); + } + if (((hprt0 & OTG_HS_HPRT_PPWR) == OTG_HS_HPRT_PPWR) && (state == 0U)) + { + USB_HS_HPRT0 = ((~OTG_HS_HPRT_PPWR) & hprt0); + } +} + +/** + * @brief USB_HS_DriveID : activate or de-activate id + * @param state VBUS state + * This parameter can be one of these values: + * 0 : Deactivate ID + * 1 : Activate ID + * @note To use ID line detection, this function must be enabled; it is enabled by default. + * This function is connected to pin PB12. If PB12 is to use normal GPIO functions, + * this function must be disabled. + */ +void USB_HS_DriveID(uint8_t state) +{ + USB_HS_PKEY = 0x5057 ; + USB_HS_PKEY = 0x5948 ; + + *(uint32_t*)(0x40040E1C) |= (state << 25); + + USB_HS_PKEY = 0x0; +} + +/** + * @brief Return Host Core speed + * @param USB_HS Selected device + * @retval speed : Host speed + * This parameter can be one of these values: + * @arg HCD_SPEED_HIGH: Full speed mode + * @arg HCD_SPEED_FULL: Full speed mode + * @arg HCD_SPEED_LOW: Low speed mode + */ +uint32_t USB_HS_GetHostSpeed(void) +{ + __IO uint32_t hprt0 = 0U; + + hprt0 = USB_HS_HPRT0; + return ((hprt0 & OTG_HS_HPRT_PSPD) >> 17); +} + +/** + * @brief Return Host Current Frame number + * @param USB_HS Selected device + * @retval current frame number + */ +uint32_t USB_HS_GetCurrentFrame(void) +{ + return (USB_HS_HOST->HFNUM & OTG_HS_HFNUM_FRNUM); +} + +/** + * @brief Initialize a host channel + * @param USB_HS Selected device + * @param ch_num Channel number + * This parameter can be a value from 1 to 15 + * @param epnum Endpoint number + * This parameter can be a value from 1 to 15 + * @param dev_address Current device address + * This parameter can be a value from 0 to 255 + * @param speed Current device speed + * This parameter can be one of these values: + * @arg USB_OTG_SPEED_FULL: HIGH speed mode + * @arg USB_OTG_SPEED_FULL: Full speed mode + * @arg USB_OTG_SPEED_LOW: Low speed mode + * @param ep_type Endpoint Type + * This parameter can be one of these values: + * @arg EP_TYPE_CTRL: Control type + * @arg EP_TYPE_ISOC: Isochronous type + * @arg EP_TYPE_BULK: Bulk type + * @arg EP_TYPE_INTR: Interrupt type + * @param mps Max Packet Size + * This parameter can be a value from 0 to 32K + * @retval USB_HS state + */ +USB_HS_StatusTypeDef USB_HS_HC_Init(uint8_t ch_num, uint8_t epnum, uint8_t dev_address, + uint8_t speed, uint8_t ep_type, uint16_t mps) +{ + USB_HS_StatusTypeDef ret = USB_HS_OK; + uint32_t HCcharEpDir; + uint32_t HCcharLowSpeed; + uint32_t HostCoreSpeed; + + /* Clear old interrupt conditions for this host channel. */ + USB_HS_HC((uint32_t)ch_num)->HCINT = CLEAR_INTERRUPT_MASK; + + /* Enable channel interrupts required for this transfer. */ + switch (ep_type) + { + case EP_TYPE_CTRL: + case EP_TYPE_BULK: + USB_HS_HC((uint32_t)ch_num)->HCINTMSK = OTG_HS_HCINTMSK_XFRCM | + OTG_HS_HCINTMSK_STALLM | + OTG_HS_HCINTMSK_TXERRM | + OTG_HS_HCINTMSK_DTERRM | + OTG_HS_HCINTMSK_AHBERRM | + OTG_HS_HCINTMSK_NAKM; + + if ((epnum & 0x80U) == 0x80U) + { + USB_HS_HC((uint32_t)ch_num)->HCINTMSK |= OTG_HS_HCINTMSK_BBERRM; + } + else + { + USB_HS_HC((uint32_t)ch_num)->HCINTMSK |= (OTG_HS_HCINTMSK_NYETM | OTG_HS_HCINTMSK_ACKM); + } + break; + + case EP_TYPE_INTR: + USB_HS_HC((uint32_t)ch_num)->HCINTMSK = OTG_HS_HCINTMSK_XFRCM | + OTG_HS_HCINTMSK_STALLM | + OTG_HS_HCINTMSK_TXERRM | + OTG_HS_HCINTMSK_DTERRM | + OTG_HS_HCINTMSK_NAKM | + OTG_HS_HCINTMSK_AHBERRM | + OTG_HS_HCINTMSK_FRMORM ; + + if ((epnum & 0x80U) == 0x80U) + { + USB_HS_HC((uint32_t)ch_num)->HCINTMSK |= OTG_HS_HCINTMSK_BBERRM; + } + + break; + + case EP_TYPE_ISOC: + USB_HS_HC((uint32_t)ch_num)->HCINTMSK = OTG_HS_HCINTMSK_XFRCM | + OTG_HS_HCINTMSK_ACKM | + OTG_HS_HCINTMSK_AHBERRM | + OTG_HS_HCINTMSK_FRMORM ; + + if ((epnum & 0x80U) == 0x80U) + { + USB_HS_HC((uint32_t)ch_num)->HCINTMSK |= (OTG_HS_HCINTMSK_TXERRM | OTG_HS_HCINTMSK_BBERRM); + } + break; + + default: + ret = USB_HS_ERROR; + break; + } + + /* Clear Hub Start Split transaction */ + USB_HS_HC((uint32_t)ch_num)->HCSPLT = 0U; + + /* Enable host channel Halt interrupt */ + USB_HS_HC((uint32_t)ch_num)->HCINTMSK |= OTG_HS_HCINTMSK_CHHM; + + /* Enable the top level host channel interrupt. */ + USB_HS_HOST->HAINTMSK |= 1UL << (ch_num & 0xFU); + + /* Make sure host channel interrupts are enabled. */ + USB_HS->GINTMSK |= OTG_HS_GINTMSK_HCIM; + + /* Program the HCCHAR register */ + if ((epnum & 0x80U) == 0x80U) + { + HCcharEpDir = (0x1U << 15) & OTG_HS_HCCHAR_EPDIR; + } + else + { + HCcharEpDir = 0U; + } + + HostCoreSpeed = USB_HS_GetHostSpeed(); + + /* LS device plugged to HUB */ + if ((speed == HPRT0_PRTSPD_LOW_SPEED) && (HostCoreSpeed != HPRT0_PRTSPD_LOW_SPEED)) + { + HCcharLowSpeed = (0x1U << 17) & OTG_HS_HCCHAR_LSDEV; + } + else + { + HCcharLowSpeed = 0U; + } + + USB_HS_HC((uint32_t)ch_num)->HCCHAR = (((uint32_t)dev_address << 22) & OTG_HS_HCCHAR_DAD) | + ((((uint32_t)epnum & 0x7FU) << 11) & OTG_HS_HCCHAR_EPNUM) | + (((uint32_t)ep_type << 18) & OTG_HS_HCCHAR_EPTYP) | + ((uint32_t)mps & OTG_HS_HCCHAR_MPSIZ) | OTG_HS_HCCHAR_MEC_0 | + HCcharEpDir | HCcharLowSpeed; + + if ((ep_type == EP_TYPE_INTR) || (ep_type == EP_TYPE_ISOC)) + { + USB_HS_HC((uint32_t)ch_num)->HCCHAR |= OTG_HS_HCCHAR_ODDFRM ; + } + + return ret; +} + +/** + * @brief Start a transfer over a host channel + * @param USB_HS Selected device + * @param hc pointer to host channel structure + * @param dma USB_HS enable or disabled + * This parameter can be one of these values: + * 0 : DMA feature not used + * 1 : DMA feature used + */ +void USB_HS_HC_StartXfer(USB_OTG_HS_HCTypeDef *hc, uint8_t dma) +{ + uint32_t ch_num = (uint32_t)hc->ch_num; + __IO uint32_t tmpreg; + uint8_t is_oddframe; + uint16_t len_words; + uint16_t num_packets; + uint16_t max_hc_pkt_count = HC_MAX_PKT_CNT; + + if (dma == 1U) + { + if (((hc->ep_type == EP_TYPE_CTRL) || (hc->ep_type == EP_TYPE_BULK)) && (hc->do_ssplit == 0U)) + { + USB_HS_HC((uint32_t)ch_num)->HCINTMSK &= ~( OTG_HS_HCINTMSK_NYETM | + OTG_HS_HCINTMSK_ACKM | + OTG_HS_HCINTMSK_NAKM ); + } + } + else + { + if ((hc->speed == USBH_HS_SPEED) && (hc->do_ping == 1U)) + { + (void)USB_HS_DoPing(hc->ch_num); + + } + } + + if (hc->do_ssplit == 1U) + { + /* Set number of packet to 1 for Split transaction */ + num_packets = 1U; + if (hc->ep_is_in != 0U) + { + hc->XferSize = (uint32_t)num_packets * hc->max_packet; + } + else + { + if (hc->ep_type == EP_TYPE_ISOC) + { + if (hc->xfer_len > ISO_SPLT_MPS) + { + /* Isochrone Max Packet Size for Split mode */ + hc->XferSize = hc->max_packet; + hc->xfer_len = hc->XferSize; + + if ((hc->iso_splt_xactPos == HCSPLT_BEGIN) || (hc->iso_splt_xactPos == HCSPLT_MIDDLE)) + { + hc->iso_splt_xactPos = HCSPLT_MIDDLE; + } + else + { + hc->iso_splt_xactPos = HCSPLT_BEGIN; + } + } + else + { + hc->XferSize = hc->xfer_len; + + if ((hc->iso_splt_xactPos != HCSPLT_BEGIN) && (hc->iso_splt_xactPos != HCSPLT_MIDDLE)) + { + hc->iso_splt_xactPos = HCSPLT_FULL; + } + else + { + hc->iso_splt_xactPos = HCSPLT_END; + } + } + } + else + { + if ((dma == 1U) && (hc->xfer_len > hc->max_packet)) + { + hc->XferSize = (uint32_t)num_packets * hc->max_packet; + } + else + { + hc->XferSize = hc->xfer_len; + } + } + } + } + else + { + /* Compute the expected number of packets associated to the transfer */ + if (hc->xfer_len > 0U) + { + num_packets = (uint16_t)((hc->xfer_len + hc->max_packet - 1U) / hc->max_packet); + + if (num_packets > max_hc_pkt_count) + { + num_packets = max_hc_pkt_count; + hc->XferSize = (uint32_t)num_packets * hc->max_packet; + } + } + else + { + num_packets = 1U; + } + + /* + * For IN channel HCTSIZ.XferSize is expected to be an integer multiple of + * max_packet size. + */ + if (hc->ep_is_in != 0U) + { + hc->XferSize = (uint32_t)num_packets * hc->max_packet; + } + else + { + hc->XferSize = hc->xfer_len; + } + } + + /* Initialize the HCTSIZn register */ + USB_HS_HC(ch_num)->HCTSIZ = (hc->XferSize & OTG_HS_HCTSIZ_XFRSIZ) | + (((uint32_t)num_packets << 19) & OTG_HS_HCTSIZ_PKTCNT) | + (((uint32_t)hc->data_pid << 29) & OTG_HS_HCTSIZ_DPID); + + if (dma != 0U) + { + /* xfer_buff MUST be 32-bits aligned */ + USB_HS_HC(ch_num)->HCDMA = (uint32_t)hc->xfer_buff; + } + + is_oddframe = (((uint32_t)USB_HS_HOST->HFNUM & 0x01U) != 0U) ? 0U : 1U; + USB_HS_HC(ch_num)->HCCHAR &= ~OTG_HS_HCCHAR_ODDFRM; + USB_HS_HC(ch_num)->HCCHAR |= (uint32_t)is_oddframe << 29; + + if (hc->do_ssplit == 1U) + { + /* Set Hub start Split transaction */ + USB_HS_HC((uint32_t)ch_num)->HCSPLT = ((uint32_t)hc->hub_addr << OTG_HS_HCSPLT_HUBADDR_Pos) | + (uint32_t)hc->hub_port_nbr | OTG_HS_HCSPLT_SPLITEN; + /* unmask ack & nyet for IN/OUT transactions */ + USB_HS_HC((uint32_t)ch_num)->HCINTMSK |= (OTG_HS_HCINTMSK_ACKM | OTG_HS_HCINTMSK_NYETM); + + if ((hc->do_csplit == 1U) && (hc->ep_is_in == 0U)) + { + USB_HS_HC((uint32_t)ch_num)->HCSPLT |= OTG_HS_HCSPLT_COMPLSPLT; + USB_HS_HC((uint32_t)ch_num)->HCINTMSK |= OTG_HS_HCINTMSK_NYETM; + } + + if (((hc->ep_type == EP_TYPE_ISOC) || (hc->ep_type == EP_TYPE_INTR)) && + (hc->do_csplit == 1U) && (hc->ep_is_in == 1U)) + { + USB_HS_HC((uint32_t)ch_num)->HCSPLT |= OTG_HS_HCSPLT_COMPLSPLT; + } + + /* Position management for iso out transaction on split mode */ + if ((hc->ep_type == EP_TYPE_ISOC) && (hc->ep_is_in == 0U)) + { + /* Set data payload position */ + switch(hc->iso_splt_xactPos) + { + case HCSPLT_BEGIN: + /* First data payload for OUT Transaction */ + USB_HS_HC((uint32_t)ch_num)->HCSPLT |= OTG_HS_HCSPLT_XACTPOS_1; + break; + + case HCSPLT_MIDDLE: + /* Middle data payload for OUT Transaction */ + USB_HS_HC((uint32_t)ch_num)->HCSPLT |= OTG_HS_HCSPLT_XACTPOS_Pos; + break; + + case HCSPLT_END: + /* End data payload for OUT Transaction */ + USB_HS_HC((uint32_t)ch_num)->HCSPLT |= OTG_HS_HCSPLT_XACTPOS_0; + break; + + case HCSPLT_FULL: + /* Entire data payload for OUT Transaction */ + USB_HS_HC((uint32_t)ch_num)->HCSPLT |= OTG_HS_HCSPLT_XACTPOS; + break; + + default: + break; + } + } + } + else + { + /* Clear Hub Start Split transaction */ + USB_HS_HC((uint32_t)ch_num)->HCSPLT = 0U; + } + + /* Set host channel enable */ + tmpreg = USB_HS_HC(ch_num)->HCCHAR; + tmpreg &= ~OTG_HS_HCCHAR_CHDIS; + + /* make sure to set the correct ep direction */ + if (hc->ep_is_in != 0U) + { + tmpreg |= OTG_HS_HCCHAR_EPDIR; + } + else + { + tmpreg &= ~OTG_HS_HCCHAR_EPDIR; + } + + tmpreg |= OTG_HS_HCCHAR_CHENA; + USB_HS_HC(ch_num)->HCCHAR = tmpreg; + + if (dma != 0U) /*dma mode*/ + { + return ; + } + + if ((hc->ep_is_in == 0U) && (hc->xfer_len > 0U) && (hc->do_csplit == 0U)) + { + switch (hc->ep_type) + { + /* Non periodic transfer */ + case EP_TYPE_CTRL: + case EP_TYPE_BULK: + + len_words = (uint16_t)((hc->xfer_len + 3U) / 4U); + + /* check if there is enough space in FIFO space */ + if (len_words > (USB_HS->HNPTXSTS & 0xFFFFU)) + { + /* need to process data in nptxfempty interrupt */ + USB_HS->GINTMSK |= OTG_HS_GINTMSK_NPTXFEM; + } + break; + + /* Periodic transfer */ + case EP_TYPE_INTR: + case EP_TYPE_ISOC: + len_words = (uint16_t)((hc->xfer_len + 3U) / 4U); + /* check if there is enough space in FIFO space */ + if (len_words > (USB_HS_HOST->HPTXSTS & 0xFFFFU)) /* split the transfer */ + { + /* need to process data in ptxfempty interrupt */ + USB_HS->GINTMSK |= OTG_HS_GINTMSK_PTXFEM; + } + break; + + default: + break; + } + /* Write packet into the Tx FIFO. */ + (void)USB_HS_WritePacket(hc->xfer_buff, hc->ch_num, (uint16_t)hc->xfer_len, 0); + } +} + + +/** + * @brief Read all host channel interrupts status + * @param USB_HS Selected device + * @retval host channel interrupt state + */ +uint32_t USB_HS_HC_ReadInterrupt(void) +{ + return ((USB_HS_HOST->HAINT) & 0xFFFFU); +} + +/** + * @brief Halt a host channel + * @param USB_HS Selected device + * @param hc_num Host Channel number + * This parameter can be a value from 1 to 15 + */ +void USB_HS_HC_Halt(uint8_t hc_num) +{ + uint32_t hcnum = (uint32_t)hc_num; + uint32_t count = 0U; + uint32_t HcEpType = (USB_HS_HC(hcnum)->HCCHAR & OTG_HS_HCCHAR_EPTYP) >> 18; + uint32_t ChannelEna = (USB_HS_HC(hcnum)->HCCHAR & OTG_HS_HCCHAR_CHENA) >> 31; + uint32_t SplitEna = (USB_HS_HC(hcnum)->HCSPLT & OTG_HS_HCSPLT_SPLITEN) >> 31; + + if ((((USB_HS->GAHBCFG & OTG_HS_GAHBCFG_DMAEN) == OTG_HS_GAHBCFG_DMAEN) && (SplitEna == 0U)) && + ((ChannelEna == 0U) || (((HcEpType == HCCHAR_ISOC) || (HcEpType == HCCHAR_INTR))))) + { + return ; + } + + /* Check for space in the request queue to issue the halt. */ + if ((HcEpType == HCCHAR_CTRL) || (HcEpType == HCCHAR_BULK)) + { + USB_HS_HC(hcnum)->HCCHAR |= OTG_HS_HCCHAR_CHDIS; + + if ((USB_HS->GAHBCFG & OTG_HS_GAHBCFG_DMAEN) == 0U) + { + if ((USB_HS->HNPTXSTS & (0xFFU << 16)) == 0U) + { + USB_HS_HC(hcnum)->HCCHAR &= ~OTG_HS_HCCHAR_CHENA; + USB_HS_HC(hcnum)->HCCHAR |= OTG_HS_HCCHAR_CHENA; + do + { + count++; + if (count > 1000U) + { + break; + } + } while ((USB_HS_HC(hcnum)->HCCHAR & OTG_HS_HCCHAR_CHENA) == OTG_HS_HCCHAR_CHENA); + } + else + { + USB_HS_HC(hcnum)->HCCHAR |= OTG_HS_HCCHAR_CHENA; + } + } + else + { + USB_HS_HC(hcnum)->HCCHAR |= OTG_HS_HCCHAR_CHENA; + } + } + else + { + USB_HS_HC(hcnum)->HCCHAR |= OTG_HS_HCCHAR_CHDIS; + + if ((USB_HS_HOST->HPTXSTS & (0xFFU << 16)) == 0U) + { + USB_HS_HC(hcnum)->HCCHAR &= ~OTG_HS_HCCHAR_CHENA; + USB_HS_HC(hcnum)->HCCHAR |= OTG_HS_HCCHAR_CHENA; + do + { + count++; + if (count > 1000U) + { + break; + } + } while ((USB_HS_HC(hcnum)->HCCHAR & OTG_HS_HCCHAR_CHENA) == OTG_HS_HCCHAR_CHENA); + } + else + { + USB_HS_HC(hcnum)->HCCHAR |= OTG_HS_HCCHAR_CHENA; + } + } +} + +/** + * @brief Initiate Do Ping protocol + * @param USB_HS Selected device + * @param hc_num Host Channel number + * This parameter can be a value from 1 to 15 + */ +void USB_HS_DoPing(uint8_t ch_num) +{ + uint32_t chnum = (uint32_t)ch_num; + uint32_t num_packets = 1U; + uint32_t tmpreg; + + USB_HS_HC(chnum)->HCTSIZ = ((num_packets << 19) & OTG_HS_HCTSIZ_PKTCNT) | OTG_HS_HCTSIZ_DOPING; + + /* Set host channel enable */ + tmpreg = USB_HS_HC(chnum)->HCCHAR; + tmpreg &= ~OTG_HS_HCCHAR_CHDIS; + tmpreg |= OTG_HS_HCCHAR_CHENA; + USB_HS_HC(chnum)->HCCHAR = tmpreg; + +} + +/** + * @brief Stop Host Core + * @param USB_HS Selected device + * @retval USB_HS state + */ +USB_HS_StatusTypeDef USB_HS_StopHost(void) +{ + USB_HS_StatusTypeDef ret = USB_HS_OK; + __IO uint32_t count = 0U; + uint32_t value; + uint32_t i; + + USB_HS_DisableGlobalInt(); + + /* Flush FIFO */ + if (USB_HS_FlushTxFifo(0x10U) != USB_HS_OK) /* all Tx FIFOs */ + { + ret = USB_HS_ERROR; + } + if (USB_HS_FlushRxFifo() != USB_HS_OK) /* Rx FIFOs */ + { + ret = USB_HS_ERROR; + } + + /* Flush out any leftover queued requests. */ + for (i = 0U; i <= 15U; i++) + { + value = USB_HS_HC(i)->HCCHAR; + value |= OTG_HS_HCCHAR_CHDIS; + value &= ~OTG_HS_HCCHAR_CHENA; + value &= ~OTG_HS_HCCHAR_EPDIR; + USB_HS_HC(i)->HCCHAR = value; + } + + /* Halt all channels to put them into a known state. */ + for (i = 0U; i <= 15U; i++) + { + value = USB_HS_HC(i)->HCCHAR; + value |= OTG_HS_HCCHAR_CHDIS; + value |= OTG_HS_HCCHAR_CHENA; + value &= ~OTG_HS_HCCHAR_EPDIR; + USB_HS_HC(i)->HCCHAR = value; + + do + { + count++; + if (count > 1000U) + { + break; + } + } while ((USB_HS_HC(i)->HCCHAR & OTG_HS_HCCHAR_CHENA) == OTG_HS_HCCHAR_CHENA); + } + + /* Clear any pending Host interrupts */ + USB_HS_HOST->HAINT = CLEAR_INTERRUPT_MASK; + USB_HS->GINTSTS = CLEAR_INTERRUPT_MASK; + + (void)USB_HS_EnableGlobalInt(); + + return ret; +} + +/** + * @brief USB_HS_ActivateRemoteWakeup active remote wakeup signalling + * @param USB_HS Selected device + */ +void USB_HS_ActivateRemoteWakeup(void) +{ + + if ((USB_HS_DEVICE->DSTS & OTG_HS_DSTS_SUSPSTS) == OTG_HS_DSTS_SUSPSTS) + { + /* active Remote wakeup signalling */ + USB_HS_DEVICE->DCTL |= OTG_HS_DCTL_RWUSIG; + } + +} + +/** + * @brief USB_HS_DeActivateRemoteWakeup de-active remote wakeup signalling + * @param USB_HS Selected device + */ +void USB_HS_DeActivateRemoteWakeup(void) +{ + /* active Remote wakeup signalling */ + USB_HS_DEVICE->DCTL &= ~(OTG_HS_DCTL_RWUSIG); + +} +#endif /* defined (USB_OTG_HS) */ + +#endif /* defined (USB_OTG_HS) */ + + +#endif /* defined (PCD_MODULE_ENABLED) || defined (HCD_MODULE_ENABLED) */ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_wwdg.c b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_wwdg.c new file mode 100644 index 00000000000..6372f6e8c5d --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/src/ft32f4xx_wwdg.c @@ -0,0 +1,176 @@ +/** + ****************************************************************************** + * @file ft32f4xx_wwdg.c + * @author FMD AE + * @brief This file provides firmware functions to manage the following + * functionalities of the Window watchdog (WWDG) peripheral: + * + Prescaler, Refresh window and Counter configuration + * + WWDG activation + * + Interrupts and flags management + * @version V1.0.0 + * @data 2025-03-05 + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx_wwdg.h" +#include "ft32f4xx_rcc.h" +/* --------------------- WWDG registers bit mask ---------------------------- */ +/* CFR register bit mask */ +#define CFR_WDGTB_MASK ((uint32_t)0xFFFFFE7F) +#define CFR_W_MASK ((uint32_t)0xFFFFFF80) +#define BIT_MASK ((uint8_t)0x7F) + + +/** + * @brief Deinitializes the WWDG peripheral registers to their default reset values. + * @param None + * @retval None + */ +void WWDG_DeInit(void) +{ + RCC_APB1PeriphResetCmd(RCC_APB1Periph_WWDG, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_WWDG, DISABLE); +} + +/** + * @brief Sets the WWDG Prescaler. + * @param WWDG_Prescaler: specifies the WWDG Prescaler. + * This parameter can be one of the following values: + * @arg WWDG_Prescaler_1: WWDG counter clock = (PCLK1/4096)/1 + * @arg WWDG_Prescaler_2: WWDG counter clock = (PCLK1/4096)/2 + * @arg WWDG_Prescaler_4: WWDG counter clock = (PCLK1/4096)/4 + * @arg WWDG_Prescaler_8: WWDG counter clock = (PCLK1/4096)/8 + * @retval None + */ +void WWDG_SetPrescaler(uint32_t WWDG_Prescaler) +{ + uint32_t tmpreg = 0; + /* Check the parameters */ + assert_param(IS_WWDG_PRESCALER(WWDG_Prescaler)); + /* Clear WDGTB[1:0] bits */ + tmpreg = WWDG->CFR & CFR_WDGTB_MASK; + /* Set WDGTB[1:0] bits according to WWDG_Prescaler value */ + tmpreg |= WWDG_Prescaler; + /* Store the new value */ + WWDG->CFR = tmpreg; +} + +/** + * @brief Sets the WWDG window value. + * @param WindowValue: specifies the window value to be compared to the downcounter. + * This parameter value must be lower than 0x80. + * @retval None + */ +void WWDG_SetWindowValue(uint8_t WindowValue) +{ + __IO uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_WWDG_WINDOW_VALUE(WindowValue)); + /* Clear W[6:0] bits */ + + tmpreg = WWDG->CFR & CFR_W_MASK; + + /* Set W[6:0] bits according to WindowValue value */ + tmpreg |= WindowValue & (uint32_t) BIT_MASK; + + /* Store the new value */ + WWDG->CFR = tmpreg; +} + +/** + * @brief Enables the WWDG Early Wakeup interrupt(EWI). + * @note Once enabled this interrupt cannot be disabled except by a system reset. + * @param None + * @retval None + */ +void WWDG_EnableIT(void) +{ + WWDG->CFR |= WWDG_CFR_EWI; +} + +/** + * @brief Sets the WWDG counter value. + * @param Counter: specifies the watchdog counter value. + * This parameter must be a number between 0x40 and 0x7F (to prevent + * generating an immediate reset). + * @retval None + */ +void WWDG_SetCounter(uint8_t Counter) +{ + /* Check the parameters */ + assert_param(IS_WWDG_COUNTER(Counter)); + /* Write to T[6:0] bits to configure the counter value, no need to do + a read-modify-write; writing a 0 to WDGA bit does nothing */ + WWDG->CR = Counter & BIT_MASK; +} + +/** + * @} + */ + +/** + * @brief Enables WWDG and load the counter value. + * @param Counter: specifies the watchdog counter value. + * This parameter must be a number between 0x40 and 0x7F (to prevent + * generating an immediate reset). + * @retval None + */ +void WWDG_Enable(uint8_t Counter) +{ + /* Check the parameters */ + assert_param(IS_WWDG_COUNTER(Counter)); + WWDG->CR = WWDG_CR_WDGA | Counter; +} +/** + * @} + */ + +/** + * @brief Checks whether the Early Wakeup interrupt flag is set or not. + * @param None + * @retval The new state of the Early Wakeup interrupt flag (SET or RESET). + */ +FlagStatus WWDG_GetFlagStatus(void) +{ + FlagStatus bitstatus = RESET; + + if ((WWDG->SR) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + return bitstatus; +} + +/** + * @brief Clears Early Wakeup interrupt flag. + * @param None + * @retval None + */ +void WWDG_ClearFlag(void) +{ + WWDG->SR = (uint32_t)RESET; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT FMD *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/templates/inc/FT32F4xx_it.h b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/templates/inc/FT32F4xx_it.h new file mode 100644 index 00000000000..6ad4c5ee4e0 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/templates/inc/FT32F4xx_it.h @@ -0,0 +1,54 @@ +/** + ****************************************************************************** + * @file ../ + * @author FMD AE + * @brief Main program body + * @version V1.0.0 + * @date 3-July-2025 + ****************************************************************************** + * @attention + * COPYRIGHT (C) 2025 Fremont Micro Devices (SZ) Corporation All rights reserved. + * This software is provided by the copyright holders and contributors,and the + * software is believed to be accurate and reliable. However, Fremont Micro + * Devices (SZ) Corporation assumes no responsibility for the consequences of + * use of such software or for any infringement of patents of other rights + * of third parties, which may result from its use. No license is granted by + * implication or otherwise under any patent rights of Fremont Micro Devices (SZ) + * Corporation. + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __FT32F4xx_IT_H +#define __FT32F4xx_IT_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx.h" + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +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); + +#ifdef __cplusplus +} +#endif + +#endif /* __FT32F4xx_IT_H */ + + +/************************ (C) COPYRIGHT Fremont Micro Devices *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/templates/inc/main.h b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/templates/inc/main.h new file mode 100644 index 00000000000..bc283cc4375 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/templates/inc/main.h @@ -0,0 +1,36 @@ +/** + ****************************************************************************** + * @file ../ + * @author FMD AE + * @brief Main program body + * @version V1.0.0 + * @date 3-July-2025 + ****************************************************************************** + * @attention + * COPYRIGHT (C) 2025 Fremont Micro Devices (SZ) Corporation All rights reserved. + * This software is provided by the copyright holders and contributors,and the + * software is believed to be accurate and reliable. However, Fremont Micro + * Devices (SZ) Corporation assumes no responsibility for the consequences of + * use of such software or for any infringement of patents of other rights + * of third parties, which may result from its use. No license is granted by + * implication or otherwise under any patent rights of Fremont Micro Devices (SZ) + * Corporation. + ****************************************************************************** + */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __MAIN_H +#define __MAIN_H + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx.h" + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +void ADC_IRQHandler(void); + +#endif /* __MAIN_H */ + +/************************ (C) COPYRIGHT Fremont Micro Devices *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/templates/src/FT32F4xx_it.c b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/templates/src/FT32F4xx_it.c new file mode 100644 index 00000000000..860bc4ae893 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/templates/src/FT32F4xx_it.c @@ -0,0 +1,162 @@ +/** + ****************************************************************************** + * @file ../ + * @author FMD AE + * @brief Main program body + * @version V1.0.0 + * @date 3-July-2025 + ****************************************************************************** + * @attention + * COPYRIGHT (C) 2025 Fremont Micro Devices (SZ) Corporation All rights reserved. + * This software is provided by the copyright holders and contributors,and the + * software is believed to be accurate and reliable. However, Fremont Micro + * Devices (SZ) Corporation assumes no responsibility for the consequences of + * use of such software or for any infringement of patents of other rights + * of third parties, which may result from its use. No license is granted by + * implication or otherwise under any patent rights of Fremont Micro Devices (SZ) + * Corporation. + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "ft32f4xx_it.h" + +/** @addtogroup FT32F4xx_StdPeriph_Template + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/******************************************************************************/ +/* Cortex-M4 Processor Exceptions Handlers */ +/******************************************************************************/ + +/** + * @brief This function handles NMI exception. + * @param None + * @retval None + */ +void NMI_Handler(void) +{ +} + +/** + * @brief This function handles Hard Fault exception. + * @param None + * @retval None + */ +void HardFault_Handler(void) +{ + /* Go to infinite loop when Hard Fault exception occurs */ + while (1) + { + } +} + +/** + * @brief This function handles Memory Manage exception. + * @param None + * @retval None + */ +void MemManage_Handler(void) +{ + /* Go to infinite loop when Memory Manage exception occurs */ + while (1) + { + } +} + +/** + * @brief This function handles Bus Fault exception. + * @param None + * @retval None + */ +void BusFault_Handler(void) +{ + /* Go to infinite loop when Bus Fault exception occurs */ + while (1) + { + } +} + +/** + * @brief This function handles Usage Fault exception. + * @param None + * @retval None + */ +void UsageFault_Handler(void) +{ + /* Go to infinite loop when Usage Fault exception occurs */ + while (1) + { + } +} + +/** + * @brief This function handles SVCall exception. + * @param None + * @retval None + */ +#ifndef RTE_CMSIS_RTOS_RTX +void SVC_Handler(void) +{ +} +#endif + +/** + * @brief This function handles Debug Monitor exception. + * @param None + * @retval None + */ +void DebugMon_Handler(void) +{ +} + +/** + * @brief This function handles PendSVC exception. + * @param None + * @retval None + */ +#ifndef RTE_CMSIS_RTOS_RTX +void PendSV_Handler(void) +{ +} +#endif + +/** + * @brief This function handles SysTick Handler. + * @param None + * @retval None + */ +#ifndef RTE_CMSIS_RTOS_RTX +void SysTick_Handler(void) +{ +} +#endif + +/******************************************************************************/ +/* FT32F4xx Peripherals Interrupt Handlers */ +/* Add here the Interrupt Handler for the used peripheral(s) (PPP), for the */ +/* available peripheral interrupt handler's name please refer to the startup */ +/* file (startup_FT32F4xx_xx.s). */ +/******************************************************************************/ + +/** + * @brief This function handles PPP interrupt request. + * @param None + * @retval None + */ +/*void PPP_IRQHandler(void) +{ +}*/ + +/** + * @} + */ + +/************************ (C) COPYRIGHT Fremont Micro Devices *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/templates/src/main.c b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/templates/src/main.c new file mode 100644 index 00000000000..de104913c70 --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/FT32F4xx_Driver/templates/src/main.c @@ -0,0 +1,73 @@ +/** + ****************************************************************************** + * @file ../ + * @author FMD AE + * @brief Main program body + * @version V1.0.0 + * @date 3-July-2025 + ****************************************************************************** + * @attention + * COPYRIGHT (C) 2025 Fremont Micro Devices (SZ) Corporation All rights reserved. + * This software is provided by the copyright holders and contributors,and the + * software is believed to be accurate and reliable. However, Fremont Micro + * Devices (SZ) Corporation assumes no responsibility for the consequences of + * use of such software or for any infringement of patents of other rights + * of third parties, which may result from its use. No license is granted by + * implication or otherwise under any patent rights of Fremont Micro Devices (SZ) + * Corporation. + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ + +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** + * @brief Main program + * @param None + * @retval None + */ +int main(void) +{ + /* Main program loop */ + while(1) + { + } +} + +#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 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) */ + + while (1) + {} +} + +#endif + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT Fremont Micro Devices *****END OF FILE****/ diff --git a/bsp/ft32/libraries/FT32F4xx/SConscript b/bsp/ft32/libraries/FT32F4xx/SConscript new file mode 100644 index 00000000000..2e883833abd --- /dev/null +++ b/bsp/ft32/libraries/FT32F4xx/SConscript @@ -0,0 +1,97 @@ +import rtconfig +Import('RTT_ROOT') +from building import * + +# get current directory +cwd = GetCurrentDir() + +# The set of source files associated with this SConscript file. +src = Split(""" +CMSIS/FT32F4xx/source/system_ft32f4xx.c +FT32F4xx_Driver/src/ft32f4xx_comp.c +FT32F4xx_Driver/src/ft32f4xx_crc.c +FT32F4xx_Driver/src/ft32f4xx_crs.c +FT32F4xx_Driver/src/ft32f4xx_debug.c +FT32F4xx_Driver/src/ft32f4xx_dma.c +FT32F4xx_Driver/src/ft32f4xx_exti.c +FT32F4xx_Driver/src/ft32f4xx_gpio.c +FT32F4xx_Driver/src/ft32f4xx_iwdg.c +FT32F4xx_Driver/src/ft32f4xx_misc.c +FT32F4xx_Driver/src/ft32f4xx_opamp.c +FT32F4xx_Driver/src/ft32f4xx_pwr.c +FT32F4xx_Driver/src/ft32f4xx_rcc.c +FT32F4xx_Driver/src/ft32f4xx_syscfg.c +FT32F4xx_Driver/src/ft32f4xx_tim.c +""") + +if GetDepend(['RT_USING_ADC']): + src += ['FT32F4xx_Driver/src/ft32f4xx_adc.c'] + +if GetDepend(['RT_USING_DAC']): + src += ['FT32F4xx_Driver/src/ft32f4xx_dac.c'] + +if GetDepend(['RT_USING_ECAP']): + src += ['FT32F4xx_Driver/src/ft32f4xx_ecap.c'] + +if GetDepend(['RT_USING_EPWM']): + src += ['FT32F4xx_Driver/src/ft32f4xx_epwm.c'] + +if GetDepend(['RT_USING_EQEP']): + src += ['FT32F4xx_Driver/src/ft32f4xx_eqep.c'] + +if GetDepend(['RT_USING_FDCAN']): + src += ['FT32F4xx_Driver/src/ft32f4xx_fdcan.c'] + +if GetDepend(['RT_USING_FMC']): + src += ['FT32F4xx_Driver/src/ft32f4xx_fmc.c'] + +if GetDepend(['RT_USING_SERIAL']): + src += ['FT32F4xx_Driver/src/ft32f4xx_usart.c'] + src += ['FT32F4xx_Driver/src/ft32f4xx_uart.c'] + +if GetDepend(['RT_USING_I2C']): + src += ['FT32F4xx_Driver/src/ft32f4xx_i2c.c'] + +if GetDepend(['RT_USING_I2S']): + src += ['FT32F4xx_Driver/src/ft32f4xx_i2s.c'] + +if GetDepend(['RT_USING_LPTIM']): + src += ['FT32F4xx_Driver/src/ft32f4xx_lptim.c'] + +if GetDepend(['RT_USING_QSPI']): + src += ['FT32F4xx_Driver/src/ft32f4xx_qspi.c'] + +if GetDepend(['RT_USING_RNG']): + src += ['FT32F4xx_Driver/src/ft32f4xx_rng.c'] + +if GetDepend(['RT_USING_SPI']): + src += ['FT32F4xx_Driver/src/ft32f4xx_spi.c'] + +if GetDepend(['RT_USING_RTC']): + src += ['FT32F4xx_Driver/src/ft32f4xx_rtc.c'] + +if GetDepend(['RT_USING_SDIO']): + src += ['FT32F4xx_Driver/src/ft32f4xx_sdio.c'] + +if GetDepend(['RT_USING_SPDIF']): + src += ['FT32F4xx_Driver/src/ft32f4xx_spdif.c'] + +if GetDepend(['RT_USING_WDT']): + src += ['FT32F4xx_Driver/src/ft32f4xx_wwdg.c'] + +if GetDepend(['RT_USING_SSI']): + src += ['FT32F4xx_Driver/src/ft32f4xx_ssi.c'] + +if GetDepend(['BSP_USING_ON_CHIP_FLASH']): + src += ['FT32F4xx_Driver/src/ft32f4xx_flash.c'] + +if GetDepend(['BSP_USING_ETH']): + src += ['FT32F4xx_Driver/src/ft32f4xx_eth.c'] + +path = [cwd + '/CMSIS/FT32F4xx/include', + cwd + '/FT32F4xx_Driver/inc', + cwd + '/FT32F4xx_Driver/templates/inc'] + +group = DefineGroup('Libraries', src, depend = [''], CPPPATH = path) + +Return('group') diff --git a/bsp/ft32/libraries/Kconfig b/bsp/ft32/libraries/Kconfig index afdd0fb83f0..6c690ec86f3 100644 --- a/bsp/ft32/libraries/Kconfig +++ b/bsp/ft32/libraries/Kconfig @@ -6,5 +6,8 @@ config SOC_SERIES_FT32F0 select ARCH_ARM_CORTEX_M0 select SOC_FAMILY_FT32 - +config SOC_SERIES_FT32F4 + bool + select ARCH_ARM_CORTEX_M4 + select SOC_FAMILY_FT32