From 7cd6267c1a5ff6fc60171178fd966e3b7ff50595 Mon Sep 17 00:00:00 2001 From: cfif Date: Mon, 24 Aug 2026 15:50:35 +0300 Subject: [PATCH] Init Mono --- APP/Clock.c | 217 + APP/Clock.h | 20 + APP/FC7240_flash.ld | 244 + APP/FreeRTOSConfig.h | 177 + APP/main.c | 114 + APP/modular.json | 15 + APP/startup_FC7240.s | 480 ++ APP/syscalls.c | 75 + APP/system_init.c | 212 + APP/system_init.h | 32 + APP/text | 28 + CMakeLists.txt | 140 + .../BootJump_Flagchip_FC7240/Inc/BootJump.h | 14 + .../BootJump_Flagchip_FC7240/Src/BootJump.c | 193 + MODULES/BootJump_Flagchip_FC7240/modular.json | 10 + .../CmakeConfig_GCC_CortexM7/gcc_cm7.cmake | 50 + .../CmakeConfig_GCC_CortexM7/gcc_cm7f.cmake | 50 + MODULES/CmakeConfig_GCC_CortexM7/modular.json | 8 + .../VersionRandID.h | 1 + .../VersionRandID.h.in | 1 + .../modular.json | 10 + .../version.cmake | 6 + .../cm7/arm_cortex_m7_asm.h | 23 + .../Device_Flagchip_FC7240/cm7/cmsis_armcc.h | 865 ++++ .../cm7/cmsis_armcc_V6.h | 1800 ++++++++ .../cm7/cmsis_armclang.h | 1869 ++++++++ .../cm7/cmsis_compiler.h | 271 ++ .../Device_Flagchip_FC7240/cm7/cmsis_gcc.h | 2085 +++++++++ .../Device_Flagchip_FC7240/cm7/cmsis_ghs.h | 104 + .../Device_Flagchip_FC7240/cm7/cmsis_iccarm.h | 935 ++++ .../cm7/cmsis_version.h | 39 + .../cm7/core_cm7_regs.h | 2417 ++++++++++ .../Device_Flagchip_FC7240/cm7/mpu_armv7.h | 275 ++ MODULES/Device_Flagchip_FC7240/compiler.h | 54 + .../Device_Flagchip_FC7240/device_header.h | 121 + .../Device_Flagchip_FC7240/fc/Z_AddInclude.py | 44 + .../fc/fc7240_acc_regs.h | 719 +++ .../fc/fc7240_adc_regs.h | 831 ++++ .../fc/fc7240_ahb_overlay_regs.h | 805 ++++ .../fc/fc7240_aontimer_regs.h | 277 ++ .../fc/fc7240_cmp_regs.h | 773 ++++ .../fc/fc7240_cmu_regs.h | 351 ++ .../fc/fc7240_cordic_regs.h | 305 ++ .../fc/fc7240_cpm_regs.h | 354 ++ .../fc/fc7240_crc_regs.h | 139 + .../fc/fc7240_csc0_regs.h | 2329 ++++++++++ .../fc/fc7240_dma_regs.h | 2419 ++++++++++ .../fc/fc7240_dmamux_regs.h | 174 + .../fc/fc7240_eim_regs.h | 379 ++ .../fc/fc7240_erm_regs.h | 1357 ++++++ .../fc/fc7240_fciic_regs.h | 1277 ++++++ .../fc/fc7240_fcpit_regs.h | 456 ++ .../fc/fc7240_fcsmu_regs.h | 929 ++++ .../fc/fc7240_fcspi_regs.h | 821 ++++ .../fc/fc7240_fcuart_regs.h | 1059 +++++ .../fc/fc7240_flexcan_regs.h | 2643 +++++++++++ .../fc/fc7240_fmc_regs.h | 525 +++ .../fc/fc7240_freqm_regs.h | 293 ++ .../fc/fc7240_ftu_regs.h | 1515 +++++++ .../fc/fc7240_gpio_regs.h | 283 ++ .../fc/fc7240_intm_regs.h | 273 ++ .../fc/fc7240_ism_regs.h | 827 ++++ .../fc/fc7240_lu_regs.h | 499 +++ .../fc/fc7240_mam_regs.h | 701 +++ .../fc/fc7240_mb_regs.h | 479 ++ .../fc/fc7240_msc_regs.h | 1641 +++++++ .../fc/fc7240_pcc_regs.h | 2295 ++++++++++ .../fc/fc7240_pmc_regs.h | 353 ++ .../fc/fc7240_port_regs.h | 498 +++ .../fc/fc7240_ptimer_regs.h | 413 ++ .../fc/fc7240_rgm_regs.h | 827 ++++ .../fc/fc7240_rtc_regs.h | 381 ++ .../fc/fc7240_scg_regs.h | 1675 +++++++ .../fc/fc7240_scm_regs.h | 3059 +++++++++++++ .../fc/fc7240_sec_regs.h | 895 ++++ .../fc/fc7240_sent_regs.h | 1306 ++++++ .../fc/fc7240_smc_regs.h | 163 + .../fc/fc7240_stcu_regs.h | 1017 +++++ .../fc/fc7240_tmu_regs.h | 339 ++ .../fc/fc7240_tpu_e_regs.h | 1389 ++++++ .../fc/fc7240_tpu_h_regs.h | 882 ++++ .../fc/fc7240_trgsel_regs.h | 217 + .../fc/fc7240_tstmp_regs.h | 422 ++ .../fc/fc7240_wdog_regs.h | 333 ++ .../fc/fc7240_wku_regs.h | 375 ++ .../fc/fc7xxx_scm_regs.h | 3981 +++++++++++++++++ .../Device_Flagchip_FC7240/fc/z_runPython.bat | 11 + MODULES/Device_Flagchip_FC7240/fclib/fcfunc.c | 89 + MODULES/Device_Flagchip_FC7240/fclib/fcfunc.h | 32 + MODULES/Device_Flagchip_FC7240/fclib/fcmath.c | 45 + MODULES/Device_Flagchip_FC7240/fclib/fcmath.h | 32 + .../interrupt_manager.c | 159 + .../interrupt_manager.h | 207 + MODULES/Device_Flagchip_FC7240/modular.json | 16 + MODULES/Device_Flagchip_FC7240/typedef.h | 37 + MODULES/Device_Flagchip_FC7240/v_def.h | 60 + .../FirmwareMetadataSection.c | 54 + .../FirmwareMetadataSection.h | 24 + MODULES/FirmwareMetadataSection/modular.json | 10 + MODULES/HwA_Flagchip_FC7240/Inc/HwA_adc.h | 1537 +++++++ .../HwA_Flagchip_FC7240/Inc/HwA_aontimer.h | 299 ++ MODULES/HwA_Flagchip_FC7240/Inc/HwA_cm7.h | 39 + MODULES/HwA_Flagchip_FC7240/Inc/HwA_cmp.h | 947 ++++ MODULES/HwA_Flagchip_FC7240/Inc/HwA_cmu.h | 271 ++ MODULES/HwA_Flagchip_FC7240/Inc/HwA_cordic.h | 134 + MODULES/HwA_Flagchip_FC7240/Inc/HwA_cpm.h | 350 ++ MODULES/HwA_Flagchip_FC7240/Inc/HwA_crc.h | 313 ++ MODULES/HwA_Flagchip_FC7240/Inc/HwA_csc.h | 1705 +++++++ MODULES/HwA_Flagchip_FC7240/Inc/HwA_dma.h | 1514 +++++++ MODULES/HwA_Flagchip_FC7240/Inc/HwA_dmamux.h | 210 + MODULES/HwA_Flagchip_FC7240/Inc/HwA_eim.h | 276 ++ MODULES/HwA_Flagchip_FC7240/Inc/HwA_erm.h | 119 + MODULES/HwA_Flagchip_FC7240/Inc/HwA_fciic.h | 542 +++ MODULES/HwA_Flagchip_FC7240/Inc/HwA_fcpit.h | 412 ++ MODULES/HwA_Flagchip_FC7240/Inc/HwA_fcsmu.h | 671 +++ MODULES/HwA_Flagchip_FC7240/Inc/HwA_fcspi.h | 478 ++ MODULES/HwA_Flagchip_FC7240/Inc/HwA_fcuart.h | 830 ++++ MODULES/HwA_Flagchip_FC7240/Inc/HwA_flexcan.h | 1001 +++++ MODULES/HwA_Flagchip_FC7240/Inc/HwA_fmc.h | 402 ++ MODULES/HwA_Flagchip_FC7240/Inc/HwA_fpu.h | 52 + MODULES/HwA_Flagchip_FC7240/Inc/HwA_freqm.h | 229 + MODULES/HwA_Flagchip_FC7240/Inc/HwA_ftu.h | 1924 ++++++++ MODULES/HwA_Flagchip_FC7240/Inc/HwA_gpio.h | 245 + MODULES/HwA_Flagchip_FC7240/Inc/HwA_intm.h | 179 + MODULES/HwA_Flagchip_FC7240/Inc/HwA_ism.h | 645 +++ MODULES/HwA_Flagchip_FC7240/Inc/HwA_lu.h | 248 + MODULES/HwA_Flagchip_FC7240/Inc/HwA_mam.h | 126 + MODULES/HwA_Flagchip_FC7240/Inc/HwA_mb.h | 408 ++ MODULES/HwA_Flagchip_FC7240/Inc/HwA_mpu.h | 320 ++ MODULES/HwA_Flagchip_FC7240/Inc/HwA_msc.h | 841 ++++ MODULES/HwA_Flagchip_FC7240/Inc/HwA_overlay.h | 315 ++ MODULES/HwA_Flagchip_FC7240/Inc/HwA_pcc.h | 191 + MODULES/HwA_Flagchip_FC7240/Inc/HwA_pmc.h | 92 + MODULES/HwA_Flagchip_FC7240/Inc/HwA_port.h | 2348 ++++++++++ MODULES/HwA_Flagchip_FC7240/Inc/HwA_ptimer.h | 701 +++ MODULES/HwA_Flagchip_FC7240/Inc/HwA_rgm.h | 427 ++ MODULES/HwA_Flagchip_FC7240/Inc/HwA_rtc.h | 276 ++ MODULES/HwA_Flagchip_FC7240/Inc/HwA_scg.h | 917 ++++ MODULES/HwA_Flagchip_FC7240/Inc/HwA_scm.h | 2388 ++++++++++ MODULES/HwA_Flagchip_FC7240/Inc/HwA_sec.h | 859 ++++ MODULES/HwA_Flagchip_FC7240/Inc/HwA_sent.h | 1454 ++++++ MODULES/HwA_Flagchip_FC7240/Inc/HwA_smc.h | 74 + MODULES/HwA_Flagchip_FC7240/Inc/HwA_stcu.h | 265 ++ MODULES/HwA_Flagchip_FC7240/Inc/HwA_tmu.h | 548 +++ MODULES/HwA_Flagchip_FC7240/Inc/HwA_tpue.h | 2062 +++++++++ MODULES/HwA_Flagchip_FC7240/Inc/HwA_tpuh.h | 902 ++++ MODULES/HwA_Flagchip_FC7240/Inc/HwA_trgsel.h | 150 + MODULES/HwA_Flagchip_FC7240/Inc/HwA_tstmp.h | 222 + MODULES/HwA_Flagchip_FC7240/Inc/HwA_wdog.h | 115 + MODULES/HwA_Flagchip_FC7240/Inc/HwA_wku.h | 168 + MODULES/HwA_Flagchip_FC7240/modular.json | 7 + .../Inc/InternalFlashPage.h | 113 + .../Src/InternalFlashPage_DFlash.c | 310 ++ .../Src/InternalFlashPage_PFlash.c | 331 ++ .../modular.json | 10 + .../Inc/fc7xxx_board_conf.h | 58 + .../Inc/fc7xxx_driver_adc.h | 422 ++ .../Inc/fc7xxx_driver_aontimer.h | 140 + .../Inc/fc7xxx_driver_cmp.h | 295 ++ .../Inc/fc7xxx_driver_cmu.h | 197 + .../Inc/fc7xxx_driver_cordic.h | 150 + .../Inc/fc7xxx_driver_cpm.h | 106 + .../Inc/fc7xxx_driver_crc.h | 130 + .../Inc/fc7xxx_driver_csc.h | 594 +++ .../Inc/fc7xxx_driver_dma.h | 370 ++ .../Inc/fc7xxx_driver_dsp.h | 45 + .../Inc/fc7xxx_driver_eim.h | 87 + .../Inc/fc7xxx_driver_erm.h | 107 + .../Inc/fc7xxx_driver_fciic.h | 209 + .../Inc/fc7xxx_driver_fcpit.h | 179 + .../Inc/fc7xxx_driver_fcsmu.h | 251 ++ .../Inc/fc7xxx_driver_fcspi.h | 620 +++ .../Inc/fc7xxx_driver_fcuart.h | 437 ++ .../Inc/fc7xxx_driver_flash.h | 183 + .../Inc/fc7xxx_driver_flexcan.h | 463 ++ .../Inc/fc7xxx_driver_fmc.h | 188 + .../Inc/fc7xxx_driver_fpu.h | 64 + .../Inc/fc7xxx_driver_freqm.h | 143 + .../Inc/fc7xxx_driver_ftu.h | 855 ++++ .../Inc/fc7xxx_driver_gpio.h | 145 + .../Inc/fc7xxx_driver_hsm.h | 3277 ++++++++++++++ .../Inc/fc7xxx_driver_intm.h | 137 + .../Inc/fc7xxx_driver_ism.h | 249 ++ .../Inc/fc7xxx_driver_lin.h | 427 ++ .../Inc/fc7xxx_driver_lu.h | 138 + .../Inc/fc7xxx_driver_mam.h | 109 + .../Inc/fc7xxx_driver_mb.h | 201 + .../Inc/fc7xxx_driver_mpu.h | 242 + .../Inc/fc7xxx_driver_msc.h | 402 ++ .../Inc/fc7xxx_driver_overlay.h | 172 + .../Inc/fc7xxx_driver_pcc.h | 157 + .../Inc/fc7xxx_driver_pmc.h | 181 + .../Inc/fc7xxx_driver_port.h | 239 + .../Inc/fc7xxx_driver_ptimer.h | 226 + .../Inc/fc7xxx_driver_rgm.h | 182 + .../Inc/fc7xxx_driver_rtc.h | 152 + .../Inc/fc7xxx_driver_scg.h | 459 ++ .../Inc/fc7xxx_driver_scm.h | 232 + .../Inc/fc7xxx_driver_scst.h | 137 + .../Inc/fc7xxx_driver_sec.h | 371 ++ .../Inc/fc7xxx_driver_sent.h | 498 +++ .../Inc/fc7xxx_driver_smc.h | 55 + .../Inc/fc7xxx_driver_stcu.h | 266 ++ .../Inc/fc7xxx_driver_systick.h | 28 + .../Inc/fc7xxx_driver_tmu.h | 156 + .../Inc/fc7xxx_driver_tpu.h | 176 + .../Inc/fc7xxx_driver_trgsel.h | 850 ++++ .../Inc/fc7xxx_driver_tstmp.h | 165 + .../Inc/fc7xxx_driver_wdog.h | 114 + .../Inc/fc7xxx_driver_wku.h | 60 + .../Src/fc7xxx_driver_adc.c | 791 ++++ .../Src/fc7xxx_driver_aontimer.c | 187 + .../Src/fc7xxx_driver_cmp.c | 324 ++ .../Src/fc7xxx_driver_cmu.c | 386 ++ .../Src/fc7xxx_driver_cordic.c | 280 ++ .../Src/fc7xxx_driver_cpm.c | 210 + .../Src/fc7xxx_driver_crc.c | 167 + .../Src/fc7xxx_driver_csc.c | 1698 +++++++ .../Src/fc7xxx_driver_dma.c | 818 ++++ .../Src/fc7xxx_driver_dsp.c | 38 + .../Src/fc7xxx_driver_eim.c | 217 + .../Src/fc7xxx_driver_erm.c | 175 + .../Src/fc7xxx_driver_fciic.c | 817 ++++ .../Src/fc7xxx_driver_fcpit.c | 524 +++ .../Src/fc7xxx_driver_fcsmu.c | 408 ++ .../Src/fc7xxx_driver_fcspi.c | 3229 +++++++++++++ .../Src/fc7xxx_driver_fcuart.c | 1768 ++++++++ .../Src/fc7xxx_driver_flash.c | 998 +++++ .../Src/fc7xxx_driver_flexcan.c | 2994 +++++++++++++ .../Src/fc7xxx_driver_fmc.c | 231 + .../Src/fc7xxx_driver_fpu.c | 51 + .../Src/fc7xxx_driver_freqm.c | 186 + .../Src/fc7xxx_driver_ftu.c | 1810 ++++++++ .../Src/fc7xxx_driver_gpio.c | 175 + .../Src/fc7xxx_driver_hsm.c | 648 +++ .../Src/fc7xxx_driver_intm.c | 190 + .../Src/fc7xxx_driver_ism.c | 347 ++ .../Src/fc7xxx_driver_lin.c | 1505 +++++++ .../Src/fc7xxx_driver_lu.c | 184 + .../Src/fc7xxx_driver_mam.c | 259 ++ .../Src/fc7xxx_driver_mb.c | 456 ++ .../Src/fc7xxx_driver_mpu.c | 128 + .../Src/fc7xxx_driver_msc.c | 569 +++ .../Src/fc7xxx_driver_overlay.c | 498 +++ .../Src/fc7xxx_driver_pcc.c | 421 ++ .../Src/fc7xxx_driver_pmc.c | 175 + .../Src/fc7xxx_driver_port.c | 486 ++ .../Src/fc7xxx_driver_ptimer.c | 326 ++ .../Src/fc7xxx_driver_rgm.c | 312 ++ .../Src/fc7xxx_driver_rtc.c | 365 ++ .../Src/fc7xxx_driver_scg.c | 1941 ++++++++ .../Src/fc7xxx_driver_scm.c | 482 ++ .../Src/fc7xxx_driver_scst.c | 230 + .../Src/fc7xxx_driver_sec.c | 424 ++ .../Src/fc7xxx_driver_sent.c | 896 ++++ .../Src/fc7xxx_driver_smc.c | 122 + .../Src/fc7xxx_driver_stcu.c | 202 + .../Src/fc7xxx_driver_systick.c | 60 + .../Src/fc7xxx_driver_tmu.c | 312 ++ .../Src/fc7xxx_driver_tpu.c | 596 +++ .../Src/fc7xxx_driver_trgsel.c | 314 ++ .../Src/fc7xxx_driver_tstmp.c | 420 ++ .../Src/fc7xxx_driver_wdog.c | 131 + .../Src/fc7xxx_driver_wku.c | 97 + .../modular.json | 11 + modular.json | 59 + 266 files changed, 140684 insertions(+) create mode 100644 APP/Clock.c create mode 100644 APP/Clock.h create mode 100644 APP/FC7240_flash.ld create mode 100644 APP/FreeRTOSConfig.h create mode 100644 APP/main.c create mode 100644 APP/modular.json create mode 100644 APP/startup_FC7240.s create mode 100644 APP/syscalls.c create mode 100644 APP/system_init.c create mode 100644 APP/system_init.h create mode 100644 APP/text create mode 100644 CMakeLists.txt create mode 100644 MODULES/BootJump_Flagchip_FC7240/Inc/BootJump.h create mode 100644 MODULES/BootJump_Flagchip_FC7240/Src/BootJump.c create mode 100644 MODULES/BootJump_Flagchip_FC7240/modular.json create mode 100644 MODULES/CmakeConfig_GCC_CortexM7/gcc_cm7.cmake create mode 100644 MODULES/CmakeConfig_GCC_CortexM7/gcc_cm7f.cmake create mode 100644 MODULES/CmakeConfig_GCC_CortexM7/modular.json create mode 100644 MODULES/CmakeConfig_RandomBuildIdGenerator/VersionRandID.h create mode 100644 MODULES/CmakeConfig_RandomBuildIdGenerator/VersionRandID.h.in create mode 100644 MODULES/CmakeConfig_RandomBuildIdGenerator/modular.json create mode 100755 MODULES/CmakeConfig_RandomBuildIdGenerator/version.cmake create mode 100644 MODULES/Device_Flagchip_FC7240/cm7/arm_cortex_m7_asm.h create mode 100644 MODULES/Device_Flagchip_FC7240/cm7/cmsis_armcc.h create mode 100644 MODULES/Device_Flagchip_FC7240/cm7/cmsis_armcc_V6.h create mode 100644 MODULES/Device_Flagchip_FC7240/cm7/cmsis_armclang.h create mode 100644 MODULES/Device_Flagchip_FC7240/cm7/cmsis_compiler.h create mode 100644 MODULES/Device_Flagchip_FC7240/cm7/cmsis_gcc.h create mode 100644 MODULES/Device_Flagchip_FC7240/cm7/cmsis_ghs.h create mode 100644 MODULES/Device_Flagchip_FC7240/cm7/cmsis_iccarm.h create mode 100644 MODULES/Device_Flagchip_FC7240/cm7/cmsis_version.h create mode 100644 MODULES/Device_Flagchip_FC7240/cm7/core_cm7_regs.h create mode 100644 MODULES/Device_Flagchip_FC7240/cm7/mpu_armv7.h create mode 100644 MODULES/Device_Flagchip_FC7240/compiler.h create mode 100644 MODULES/Device_Flagchip_FC7240/device_header.h create mode 100644 MODULES/Device_Flagchip_FC7240/fc/Z_AddInclude.py create mode 100644 MODULES/Device_Flagchip_FC7240/fc/fc7240_acc_regs.h create mode 100644 MODULES/Device_Flagchip_FC7240/fc/fc7240_adc_regs.h create mode 100644 MODULES/Device_Flagchip_FC7240/fc/fc7240_ahb_overlay_regs.h create mode 100644 MODULES/Device_Flagchip_FC7240/fc/fc7240_aontimer_regs.h create mode 100644 MODULES/Device_Flagchip_FC7240/fc/fc7240_cmp_regs.h create mode 100644 MODULES/Device_Flagchip_FC7240/fc/fc7240_cmu_regs.h create mode 100644 MODULES/Device_Flagchip_FC7240/fc/fc7240_cordic_regs.h create mode 100644 MODULES/Device_Flagchip_FC7240/fc/fc7240_cpm_regs.h create mode 100644 MODULES/Device_Flagchip_FC7240/fc/fc7240_crc_regs.h create mode 100644 MODULES/Device_Flagchip_FC7240/fc/fc7240_csc0_regs.h create mode 100644 MODULES/Device_Flagchip_FC7240/fc/fc7240_dma_regs.h create mode 100644 MODULES/Device_Flagchip_FC7240/fc/fc7240_dmamux_regs.h create mode 100644 MODULES/Device_Flagchip_FC7240/fc/fc7240_eim_regs.h create mode 100644 MODULES/Device_Flagchip_FC7240/fc/fc7240_erm_regs.h create mode 100644 MODULES/Device_Flagchip_FC7240/fc/fc7240_fciic_regs.h create mode 100644 MODULES/Device_Flagchip_FC7240/fc/fc7240_fcpit_regs.h create mode 100644 MODULES/Device_Flagchip_FC7240/fc/fc7240_fcsmu_regs.h create mode 100644 MODULES/Device_Flagchip_FC7240/fc/fc7240_fcspi_regs.h create mode 100644 MODULES/Device_Flagchip_FC7240/fc/fc7240_fcuart_regs.h create mode 100644 MODULES/Device_Flagchip_FC7240/fc/fc7240_flexcan_regs.h create mode 100644 MODULES/Device_Flagchip_FC7240/fc/fc7240_fmc_regs.h create mode 100644 MODULES/Device_Flagchip_FC7240/fc/fc7240_freqm_regs.h create mode 100644 MODULES/Device_Flagchip_FC7240/fc/fc7240_ftu_regs.h create mode 100644 MODULES/Device_Flagchip_FC7240/fc/fc7240_gpio_regs.h create mode 100644 MODULES/Device_Flagchip_FC7240/fc/fc7240_intm_regs.h create mode 100644 MODULES/Device_Flagchip_FC7240/fc/fc7240_ism_regs.h create mode 100644 MODULES/Device_Flagchip_FC7240/fc/fc7240_lu_regs.h create mode 100644 MODULES/Device_Flagchip_FC7240/fc/fc7240_mam_regs.h create mode 100644 MODULES/Device_Flagchip_FC7240/fc/fc7240_mb_regs.h create mode 100644 MODULES/Device_Flagchip_FC7240/fc/fc7240_msc_regs.h create mode 100644 MODULES/Device_Flagchip_FC7240/fc/fc7240_pcc_regs.h create mode 100644 MODULES/Device_Flagchip_FC7240/fc/fc7240_pmc_regs.h create mode 100644 MODULES/Device_Flagchip_FC7240/fc/fc7240_port_regs.h create mode 100644 MODULES/Device_Flagchip_FC7240/fc/fc7240_ptimer_regs.h create mode 100644 MODULES/Device_Flagchip_FC7240/fc/fc7240_rgm_regs.h create mode 100644 MODULES/Device_Flagchip_FC7240/fc/fc7240_rtc_regs.h create mode 100644 MODULES/Device_Flagchip_FC7240/fc/fc7240_scg_regs.h create mode 100644 MODULES/Device_Flagchip_FC7240/fc/fc7240_scm_regs.h create mode 100644 MODULES/Device_Flagchip_FC7240/fc/fc7240_sec_regs.h create mode 100644 MODULES/Device_Flagchip_FC7240/fc/fc7240_sent_regs.h create mode 100644 MODULES/Device_Flagchip_FC7240/fc/fc7240_smc_regs.h create mode 100644 MODULES/Device_Flagchip_FC7240/fc/fc7240_stcu_regs.h create mode 100644 MODULES/Device_Flagchip_FC7240/fc/fc7240_tmu_regs.h create mode 100644 MODULES/Device_Flagchip_FC7240/fc/fc7240_tpu_e_regs.h create mode 100644 MODULES/Device_Flagchip_FC7240/fc/fc7240_tpu_h_regs.h create mode 100644 MODULES/Device_Flagchip_FC7240/fc/fc7240_trgsel_regs.h create mode 100644 MODULES/Device_Flagchip_FC7240/fc/fc7240_tstmp_regs.h create mode 100644 MODULES/Device_Flagchip_FC7240/fc/fc7240_wdog_regs.h create mode 100644 MODULES/Device_Flagchip_FC7240/fc/fc7240_wku_regs.h create mode 100644 MODULES/Device_Flagchip_FC7240/fc/fc7xxx_scm_regs.h create mode 100644 MODULES/Device_Flagchip_FC7240/fc/z_runPython.bat create mode 100644 MODULES/Device_Flagchip_FC7240/fclib/fcfunc.c create mode 100644 MODULES/Device_Flagchip_FC7240/fclib/fcfunc.h create mode 100644 MODULES/Device_Flagchip_FC7240/fclib/fcmath.c create mode 100644 MODULES/Device_Flagchip_FC7240/fclib/fcmath.h create mode 100644 MODULES/Device_Flagchip_FC7240/interrupt_manager.c create mode 100644 MODULES/Device_Flagchip_FC7240/interrupt_manager.h create mode 100644 MODULES/Device_Flagchip_FC7240/modular.json create mode 100644 MODULES/Device_Flagchip_FC7240/typedef.h create mode 100644 MODULES/Device_Flagchip_FC7240/v_def.h create mode 100644 MODULES/FirmwareMetadataSection/FirmwareMetadataSection.c create mode 100644 MODULES/FirmwareMetadataSection/FirmwareMetadataSection.h create mode 100644 MODULES/FirmwareMetadataSection/modular.json create mode 100644 MODULES/HwA_Flagchip_FC7240/Inc/HwA_adc.h create mode 100644 MODULES/HwA_Flagchip_FC7240/Inc/HwA_aontimer.h create mode 100644 MODULES/HwA_Flagchip_FC7240/Inc/HwA_cm7.h create mode 100644 MODULES/HwA_Flagchip_FC7240/Inc/HwA_cmp.h create mode 100644 MODULES/HwA_Flagchip_FC7240/Inc/HwA_cmu.h create mode 100644 MODULES/HwA_Flagchip_FC7240/Inc/HwA_cordic.h create mode 100644 MODULES/HwA_Flagchip_FC7240/Inc/HwA_cpm.h create mode 100644 MODULES/HwA_Flagchip_FC7240/Inc/HwA_crc.h create mode 100644 MODULES/HwA_Flagchip_FC7240/Inc/HwA_csc.h create mode 100644 MODULES/HwA_Flagchip_FC7240/Inc/HwA_dma.h create mode 100644 MODULES/HwA_Flagchip_FC7240/Inc/HwA_dmamux.h create mode 100644 MODULES/HwA_Flagchip_FC7240/Inc/HwA_eim.h create mode 100644 MODULES/HwA_Flagchip_FC7240/Inc/HwA_erm.h create mode 100644 MODULES/HwA_Flagchip_FC7240/Inc/HwA_fciic.h create mode 100644 MODULES/HwA_Flagchip_FC7240/Inc/HwA_fcpit.h create mode 100644 MODULES/HwA_Flagchip_FC7240/Inc/HwA_fcsmu.h create mode 100644 MODULES/HwA_Flagchip_FC7240/Inc/HwA_fcspi.h create mode 100644 MODULES/HwA_Flagchip_FC7240/Inc/HwA_fcuart.h create mode 100644 MODULES/HwA_Flagchip_FC7240/Inc/HwA_flexcan.h create mode 100644 MODULES/HwA_Flagchip_FC7240/Inc/HwA_fmc.h create mode 100644 MODULES/HwA_Flagchip_FC7240/Inc/HwA_fpu.h create mode 100644 MODULES/HwA_Flagchip_FC7240/Inc/HwA_freqm.h create mode 100644 MODULES/HwA_Flagchip_FC7240/Inc/HwA_ftu.h create mode 100644 MODULES/HwA_Flagchip_FC7240/Inc/HwA_gpio.h create mode 100644 MODULES/HwA_Flagchip_FC7240/Inc/HwA_intm.h create mode 100644 MODULES/HwA_Flagchip_FC7240/Inc/HwA_ism.h create mode 100644 MODULES/HwA_Flagchip_FC7240/Inc/HwA_lu.h create mode 100644 MODULES/HwA_Flagchip_FC7240/Inc/HwA_mam.h create mode 100644 MODULES/HwA_Flagchip_FC7240/Inc/HwA_mb.h create mode 100644 MODULES/HwA_Flagchip_FC7240/Inc/HwA_mpu.h create mode 100644 MODULES/HwA_Flagchip_FC7240/Inc/HwA_msc.h create mode 100644 MODULES/HwA_Flagchip_FC7240/Inc/HwA_overlay.h create mode 100644 MODULES/HwA_Flagchip_FC7240/Inc/HwA_pcc.h create mode 100644 MODULES/HwA_Flagchip_FC7240/Inc/HwA_pmc.h create mode 100644 MODULES/HwA_Flagchip_FC7240/Inc/HwA_port.h create mode 100644 MODULES/HwA_Flagchip_FC7240/Inc/HwA_ptimer.h create mode 100644 MODULES/HwA_Flagchip_FC7240/Inc/HwA_rgm.h create mode 100644 MODULES/HwA_Flagchip_FC7240/Inc/HwA_rtc.h create mode 100644 MODULES/HwA_Flagchip_FC7240/Inc/HwA_scg.h create mode 100644 MODULES/HwA_Flagchip_FC7240/Inc/HwA_scm.h create mode 100644 MODULES/HwA_Flagchip_FC7240/Inc/HwA_sec.h create mode 100644 MODULES/HwA_Flagchip_FC7240/Inc/HwA_sent.h create mode 100644 MODULES/HwA_Flagchip_FC7240/Inc/HwA_smc.h create mode 100644 MODULES/HwA_Flagchip_FC7240/Inc/HwA_stcu.h create mode 100644 MODULES/HwA_Flagchip_FC7240/Inc/HwA_tmu.h create mode 100644 MODULES/HwA_Flagchip_FC7240/Inc/HwA_tpue.h create mode 100644 MODULES/HwA_Flagchip_FC7240/Inc/HwA_tpuh.h create mode 100644 MODULES/HwA_Flagchip_FC7240/Inc/HwA_trgsel.h create mode 100644 MODULES/HwA_Flagchip_FC7240/Inc/HwA_tstmp.h create mode 100644 MODULES/HwA_Flagchip_FC7240/Inc/HwA_wdog.h create mode 100644 MODULES/HwA_Flagchip_FC7240/Inc/HwA_wku.h create mode 100644 MODULES/HwA_Flagchip_FC7240/modular.json create mode 100644 MODULES/InternalFlashPage_Flagchip_FC7240/Inc/InternalFlashPage.h create mode 100644 MODULES/InternalFlashPage_Flagchip_FC7240/Src/InternalFlashPage_DFlash.c create mode 100644 MODULES/InternalFlashPage_Flagchip_FC7240/Src/InternalFlashPage_PFlash.c create mode 100644 MODULES/InternalFlashPage_Flagchip_FC7240/modular.json create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_board_conf.h create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_adc.h create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_aontimer.h create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_cmp.h create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_cmu.h create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_cordic.h create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_cpm.h create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_crc.h create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_csc.h create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_dma.h create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_dsp.h create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_eim.h create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_erm.h create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_fciic.h create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_fcpit.h create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_fcsmu.h create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_fcspi.h create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_fcuart.h create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_flash.h create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_flexcan.h create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_fmc.h create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_fpu.h create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_freqm.h create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_ftu.h create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_gpio.h create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_hsm.h create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_intm.h create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_ism.h create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_lin.h create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_lu.h create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_mam.h create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_mb.h create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_mpu.h create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_msc.h create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_overlay.h create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_pcc.h create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_pmc.h create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_port.h create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_ptimer.h create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_rgm.h create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_rtc.h create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_scg.h create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_scm.h create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_scst.h create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_sec.h create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_sent.h create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_smc.h create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_stcu.h create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_systick.h create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_tmu.h create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_tpu.h create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_trgsel.h create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_tstmp.h create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_wdog.h create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_wku.h create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_adc.c create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_aontimer.c create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_cmp.c create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_cmu.c create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_cordic.c create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_cpm.c create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_crc.c create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_csc.c create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_dma.c create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_dsp.c create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_eim.c create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_erm.c create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_fciic.c create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_fcpit.c create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_fcsmu.c create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_fcspi.c create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_fcuart.c create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_flash.c create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_flexcan.c create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_fmc.c create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_fpu.c create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_freqm.c create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_ftu.c create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_gpio.c create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_hsm.c create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_intm.c create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_ism.c create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_lin.c create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_lu.c create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_mam.c create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_mb.c create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_mpu.c create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_msc.c create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_overlay.c create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_pcc.c create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_pmc.c create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_port.c create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_ptimer.c create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_rgm.c create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_rtc.c create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_scg.c create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_scm.c create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_scst.c create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_sec.c create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_sent.c create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_smc.c create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_stcu.c create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_systick.c create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_tmu.c create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_tpu.c create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_trgsel.c create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_tstmp.c create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_wdog.c create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_wku.c create mode 100644 MODULES/PeripheralDriver_Flagchip_FC7240/modular.json create mode 100644 modular.json diff --git a/APP/Clock.c b/APP/Clock.c new file mode 100644 index 0000000..d1e2a4d --- /dev/null +++ b/APP/Clock.c @@ -0,0 +1,217 @@ +#include "Clock.h" + + +/* ################################################################################## */ +/* ################################### Type define ################################## */ + +/* PCBA external oscillator value, these macro is user defined. */ +/* FOSC/SOSC clock need to manually configuration according to PCBA XTAL value + * in SOSC/FOSc configuration. + * Current default value is the XTAL value on EVB board. */ + + +/* ################################################################################## */ +/* ########################### Local Prototype Functions ############################ */ +static void Bsp_SCG_Init(void); + +static void Bsp_PCC_Init(void); + +/* ################################################################################## */ +/* ################################ Local Functions ################################# */ + + +/** + * @brief Local SCG initial + * + */ + +// Ядро процессора: 240 МГц +// Системная шина: 120 МГц +// Медленная периферия: 120 МГц +// PLL0/PLL1: 240 МГц +// FOSC: 24 МГц +// SIRC: 12 МГц + +static void Bsp_SCG_Init(void) { + + SCG_Deinit(); + + /* Enable FOSC, frequency is 24M, DIVH=DIV1(24M), DIVM=DIV1(24M), DIVL=DIV2(12M)*/ + // FOSC - Внешний кварцевый генератор (Базовый источник 24 МГц) + SCG_FoscType tFoscStruct = + { + .bLock = false, + .bCm = false, + .bCmre = false, + .bSten = false, + .bBypass = false, + .eDivH = SCG_ASYNCCLOCKDIV_BY1, + .eDivM = SCG_ASYNCCLOCKDIV_BY1, + .eDivL = SCG_ASYNCCLOCKDIV_BY2, + }; + SCG_EnableFOSC(&tFoscStruct); + + /* Enable PLL0, frequency is 240M, DIVH=DIV2(120M), DIVM=DIV2(120M), DIVL=DIV4(60M), src=FOSC*/ + /* The value of multiplier factor(FOSC/u8Prediv) between 2 ~ 4 is better*/ + + // FOSC = 24 МГц + // После предделителя: 24 МГц / (11 + 1) = 24 МГц / 12 = 2 МГц + // После умножения: 2 МГц × (239 + 1) = 2 МГц × 240 = 480 МГц + // После постделителя: 480 МГц / 2 = 240 МГц + + SCG_PllType tPll0Struct = + { + .bLock = false, + .bCm = false, + .bCmre = false, + .bSten = false, + .eDivH = SCG_ASYNCCLOCKDIV_BY2, + .eDivM = SCG_ASYNCCLOCKDIV_BY2, + .eDivL = SCG_ASYNCCLOCKDIV_BY4, + .u8Prediv = 11U, + .ePstDiv = SCG_PLLPSTDIV_BY2, + .u16Mult = 239U, + .eSrc = SCG_PLLSOURCE_FOSC + }; + SCG_EnablePLL(SCG_PLL0, &tPll0Struct); + + /* Enable PLL1, frequency is 240M, DIVH=DIV2(120M), DIVM=DIV2(120M), DIVL=DIV4(60M), src=FOSC*/ + /* The value of multiplier factor(FOSC/u8Prediv) between 2 ~ 4 is better*/ + + // Аналогична PLL0, также 240 МГц + // Обычно используется для периферии + + SCG_PllType tPll1Struct = + { + .bLock = false, + .bCm = false, + .bCmre = false, + .bSten = false, + .eDivH = SCG_ASYNCCLOCKDIV_BY2, + .eDivM = SCG_ASYNCCLOCKDIV_BY2, + .eDivL = SCG_ASYNCCLOCKDIV_BY4, + .u8Prediv = 11U, + .ePstDiv = SCG_PLLPSTDIV_BY2, + .u16Mult = 239U, + .eSrc = SCG_PLLSOURCE_FOSC + }; + SCG_EnablePLL(SCG_PLL1, &tPll1Struct); + + /* Enable SIRC DIV, DIVH=DIV1(12M), DIVM=DIV1(12M), DIVL=DIV2(6M) */ + // Резервный источник тактирования + // Меньшая точность, но быстрый запуск + + SCG_SircType tSircStruct = + { + .bLock = false, + .bCm = false, + .bTrEn = false, + .bLpen = false, + .bSten = false, + .eDivH = SCG_ASYNCCLOCKDIV_BY1, + .eDivM = SCG_ASYNCCLOCKDIV_BY1, + .eDivL = SCG_ASYNCCLOCKDIV_BY2, + .u8TrimSrc = 0U + }; + SCG_SetSIRC(&tSircStruct); + + /* Set core clock source from PLL0, DIV_CORE=DIV1(240M), DIV_BUS=DIV2(120M), DIV_SLOW=DIV4(60M)*/ + // Системное тактирование + + //.eSrc = PLL0, // Источник - PLL0 (240 МГц) + //.eDivCore = DIV1, // Ядро: 240 МГц + //.eDivBus = DIV2, // Шина: 120 МГц + //.eDivSlow = DIV2 // Медленная периферия: 120 МГц + + SCG_ClockCtrlType tClockStruct = + { + .bSysClkMonitor = false, + .eSrc = SCG_CLOCK_SRC_PLL0, + .eDivSlow = SCG_CLOCK_DIV_BY2, + .eDivBus = SCG_CLOCK_DIV_BY2, + .eDivCore = SCG_CLOCK_DIV_BY1 + }; + SCG_SetClkCtrl(&tClockStruct); + +} + +/** + * @brief Local PCC Initial + * + */ +static void Bsp_PCC_Init(void) { + PCC_CtrlType bSP_PCC_Config; + + // UART 1 (DBG) + bSP_PCC_Config.eClockName = PCC_CLK_FCUART1; + bSP_PCC_Config.bEn = true; + bSP_PCC_Config.eClkSrc = PCC_CLKGATE_SRC_FOSCDIV; + bSP_PCC_Config.eDivider = PCC_CLK_UNINVOLVED; + + PCC_SetPcc(&bSP_PCC_Config); + + // DMA 0 + bSP_PCC_Config.eClockName = PCC_CLK_DMA0; + bSP_PCC_Config.bEn = true; + bSP_PCC_Config.eClkSrc = PCC_CLKGATE_SRC_FOSCDIV; + bSP_PCC_Config.eDivider = PCC_CLK_UNINVOLVED; + + PCC_SetPcc(&bSP_PCC_Config); + + // DMAMUX 0 + bSP_PCC_Config.eClockName = PCC_CLK_DMAMUX0; + bSP_PCC_Config.bEn = true; + bSP_PCC_Config.eClkSrc = PCC_CLKGATE_SRC_FOSCDIV; + bSP_PCC_Config.eDivider = PCC_CLK_UNINVOLVED; + + PCC_SetPcc(&bSP_PCC_Config); + + // PCC_CLK_WKU0 + bSP_PCC_Config.eClockName = PCC_CLK_WKU0; + bSP_PCC_Config.bEn = true; + bSP_PCC_Config.eClkSrc = PCC_CLKGATE_UNINVOLVED; + bSP_PCC_Config.eDivider = PCC_CLK_UNINVOLVED; + + PCC_SetPcc(&bSP_PCC_Config); +} + +void Bsp_Systick_Init(void) +{ + uint32_t u32ReloadVal; + uint32_t SystemCoreClock; + + SystemCoreClock = SCG_GetScgClockFreq(SCG_CORE_CLK); + while(SystemCoreClock == 0){}; + u32ReloadVal = SystemCoreClock / 1000; + Core_SysTick_Config(u32ReloadVal); + NVIC_SetPriority(SysTick_IRQn, 0); + Core_SysTick_Enable(); +} + + +/* ################################################################################## */ +/* ################################# Global Functions ############################### */ + + +/** + * @brief General Clock Initial + * + */ +void Bsp_CLOCK_Init(void) { + CSC0_ClkoutType tCSCClkOutCfg = {0}; + + /* Configure CSC(clock out configuration) */ + tCSCClkOutCfg.bEnable = true; + tCSCClkOutCfg.eClkOutSrc = CSC0_CLKOUT_BUS_CLK; + tCSCClkOutCfg.eDivider = CSC0_CLKOUT_DIV_BY4; + + SCG_Deinit(); + Bsp_SCG_Init(); +// Bsp_PCC_Init(); + + /* Set clock out */ + SCG_SetClkOut(SCG_CLOCKOUT_SRC_FOSC); + CSC0_SetClockOut(&tCSCClkOutCfg, false); + + Bsp_Systick_Init(); +} diff --git a/APP/Clock.h b/APP/Clock.h new file mode 100644 index 0000000..fad051f --- /dev/null +++ b/APP/Clock.h @@ -0,0 +1,20 @@ +#ifndef INCLUDE_BSP_CLOCK_H_ +#define INCLUDE_BSP_CLOCK_H_ + +#include "fc7xxx_driver_fcuart.h" +#include "fc7xxx_driver_pcc.h" +#include "fc7xxx_driver_port.h" +#include "fc7xxx_driver_scg.h" +#include "fc7xxx_driver_gpio.h" +#include "fc7xxx_driver_dma.h" +#include "fc7xxx_driver_csc.h" +#include "interrupt_manager.h" +#include "fc7xxx_driver_systick.h" + +/** + * @brief General Clock Initial + * + */ +void Bsp_CLOCK_Init(void); + +#endif /* INCLUDE_BSP_CLOCK_H_ */ diff --git a/APP/FC7240_flash.ld b/APP/FC7240_flash.ld new file mode 100644 index 0000000..c05220a --- /dev/null +++ b/APP/FC7240_flash.ld @@ -0,0 +1,244 @@ +/* Entry Point */ +ENTRY(Reset_Handler) + + +M_VECTOR_RAM_SIZE = 0x0400; + +_BootloaderSize = 64K; +_BootloaderBegin = 0x01000000; /* BANK1 */ + +_FirmwareSize = 704K; +_MetadataSize = 256; +_FirmwareSize_CALIB = 256K; + +_FirmwareMainBegin = _BootloaderBegin + _BootloaderSize; +_FirmwareMetaBegin = _FirmwareMainBegin + _FirmwareSize - _MetadataSize; +_FirmwareCalibBegin = _FirmwareMainBegin + _FirmwareSize; +_FirmwareMetaCalibBegin = _FirmwareCalibBegin + _FirmwareSize_CALIB - _MetadataSize; + +_FirmwareRecoveryBegin = 0x01100000; /* BANK2 */ +_FirmwareRecoveryMetaBegin = _FirmwareRecoveryBegin + _FirmwareSize - _MetadataSize; +_FirmwareRecoveryCalibBegin = _FirmwareRecoveryBegin + _FirmwareSize; +_FirmwareRecoveryMetaCalibBegin = _FirmwareRecoveryCalibBegin + _FirmwareSize_CALIB - _MetadataSize; + +/* Specify the memory areas */ +MEMORY +{ + + ITCM (RW) : ORIGIN = 0x00000000, LENGTH = 0x00008000 /* 32KB */ + + SRAM0 (RW) : ORIGIN = 0x21000000, LENGTH = 0x00010000 /* 64KB */ + SRAM1 (RW) : ORIGIN = 0x21010000, LENGTH = 0x00008000 /* 32KB */ + + PFLASH_BOOT (RW) : ORIGIN = _BootloaderBegin, LENGTH = _BootloaderSize /* 64K */ + PFLASH_BOOT_META (RW) : ORIGIN = _BootloaderBegin + _BootloaderSize - _MetadataSize, LENGTH = _MetadataSize + + PFLASH_MAIN (RW) : ORIGIN = _FirmwareMainBegin, LENGTH = _FirmwareSize /* 704K */ + PFLASH_MAIN_META (RW) : ORIGIN = _FirmwareMetaBegin, LENGTH = _MetadataSize /* 256 */ + PFLASH_CALIB (RW) : ORIGIN = _FirmwareCalibBegin, LENGTH = _FirmwareSize_CALIB /* 256K */ + PFLASH_CALIB_META (RW) : ORIGIN = _FirmwareMetaCalibBegin, LENGTH = _MetadataSize /* 256 */ + + PFLASH_R_MAIN (RW) : ORIGIN = _FirmwareRecoveryBegin, LENGTH = _FirmwareSize /* 704K */ + PFLASH_R_MAIN_META (RW) : ORIGIN = _FirmwareRecoveryMetaBegin, LENGTH = _MetadataSize /* 256 */ + PFLASH_R_CALIB (RW) : ORIGIN = _FirmwareRecoveryCalibBegin, LENGTH = _FirmwareSize_CALIB /* 192K */ + PFLASH_R_CALIB_META (RW) : ORIGIN = _FirmwareRecoveryMetaCalibBegin, LENGTH = _FirmwareSize_CALIB /* 256 */ + + + DFLASH (RW) : ORIGIN = 0x04000000, LENGTH = 0x00020000 /* 128KB */ + + NVR0 (RW) : ORIGIN = 0x04400000, LENGTH = 0x00004000 /* 16KB */ + NVR1 (RW) : ORIGIN = 0x04408000, LENGTH = 0x00004000 /* 16KB */ + NVR2 (RW) : ORIGIN = 0x04410000, LENGTH = 0x00002000 /* 8KB */ + + /* DTCM */ + DTCM (RW) : ORIGIN = 0x20000000, LENGTH = 0x0001FA00 /* 128K - 0x600 */ + DTCM_STACK (RW) : ORIGIN = 0x2001FA00, LENGTH = 0x00000600 /* 0x600 */ + +} + +/* Define output sections */ +SECTIONS +{ + + /* The program code and other data goes into internal flash */ + .text : + { + . = ALIGN(1024); /* VTOR must be align to 1K */ + __vector_table = .; + __interrupts_start__ = .; + . = ALIGN(4); + KEEP(*(.isr_vector)) + __interrupts_end__ = .; + . = ALIGN(4); + + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + *(.init) /* section used in crti.o files */ + *(.fini) /* section used in crti.o files */ + *(.eh_frame) /* section used in crtbegin.o files */ + . = ALIGN(4); + } > PFLASH_BOOT + + .meta_boot : SUBALIGN(1) + { + __ram_boot_meta_start = .; + + KEEP(*(.meta_fw_name_size)) + KEEP(*(.meta_fw_name)) + + KEEP(*(.meta_internal_hw_year)) + KEEP(*(.meta_internal_hw_month)) + KEEP(*(.meta_internal_hw_day)) + KEEP(*(.meta_internal_hw_rev)) + + KEEP(*(.meta_internal_sw_year)) + KEEP(*(.meta_internal_sw_month)) + KEEP(*(.meta_internal_sw_day)) + KEEP(*(.meta_internal_sw_rev)) + + KEEP(*(.meta_internal_mdb_year)) + KEEP(*(.meta_internal_mdb_month)) + KEEP(*(.meta_internal_mdb_day)) + KEEP(*(.meta_internal_mdb_rev)) + + KEEP(*(.meta_finger_module)) + KEEP(*(.meta_finger_tester_serial)) + KEEP(*(.meta_finger_year)) + KEEP(*(.meta_finger_month)) + KEEP(*(.meta_finger_day)) + + . = ALIGN(256); + + } > PFLASH_BOOT_META + + .data : + { + __ram_data_start = .; + . = ALIGN(4); + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + . = ALIGN(4); + /* All data end */ + __ram_data_end = .; + + } > DTCM AT > PFLASH_BOOT + + /* Non-cache RAM section with data initialization */ + .ncache_data : + { + . = ALIGN(4); + __ram_ncache_data_start = .; + *(.nocacheable_data*) + __ram_ncache_data_end = .; + . = ALIGN(4); + } > SRAM1 AT > PFLASH_BOOT + + + + + + +.cals_data(NOLOAD) : +{ + __itcm_start = .; + + /* Начало .caldata */ + __caldata_start = .; + KEEP(*(.caldata)) + . = ALIGN(4); + + /* Проверяем и резервируем 20K */ + __caldata_actual_size = . - __caldata_start; + ASSERT(__caldata_actual_size <= 20K, "Ошибка: .caldata превышает 20K!"); + + /* Если данные меньше 20K, резервируем оставшееся пространство */ + . = __caldata_start + 20K; + + KEEP(*(.nvmdata)) + + __itcm_end = .; + . = ALIGN(4); +} > ITCM + + + + + + + + + + + + .xcp_data(NOLOAD) : + { + __xcp_start = .; + KEEP(*(.xcpdata)) + __xcp_end = .; + . = ALIGN(4); + } > SRAM0 + + .cals_text : + { + KEEP(*(.caltext)) + . = ALIGN(4); + } > DFLASH + + .bss(NOLOAD) : + { + . = ALIGN(4); + __bss_start = .; + + *Model_actuator.c.obj(.bss .bss*) + . = ALIGN(4); + + *(.bss*) + *(COMMON) + __bss_end = .; + . = ALIGN(4); + } > DTCM + + /* Non-cache RAM section with no initialization */ + .ncache_bss(NOLOAD) : + { + . = ALIGN(4); + __ncache_bss_start = .; + *(.nocacheable_bss*) + __ncache_bss_end = .; + . = ALIGN(4); + } > SRAM1 + + __HeapBegin = ORIGIN(DTCM_STACK); + __HeapLimit = ORIGIN(DTCM_STACK) + 0x200 - 8; + + __StackLimit = ORIGIN(DTCM_STACK)+0x200; + __StackTop = ORIGIN(DTCM_STACK) + LENGTH(DTCM_STACK) - 8; + + __rom_data_start = LOADADDR(.data); + __rom_ncache_data_start = LOADADDR(.ncache_data); + +} + diff --git a/APP/FreeRTOSConfig.h b/APP/FreeRTOSConfig.h new file mode 100644 index 0000000..8f15b24 --- /dev/null +++ b/APP/FreeRTOSConfig.h @@ -0,0 +1,177 @@ +/* USER CODE BEGIN Header */ +/* + * FreeRTOS Kernel V10.3.1 + * Portion Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Portion Copyright (C) 2019 StMicroelectronics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ +/* USER CODE END Header */ + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * These parameters and more are described within the 'configuration' section of the + * FreeRTOS API documentation available on the FreeRTOS.org web site. + * + * See http://www.freertos.org/a00110.html + *----------------------------------------------------------*/ + +/* USER CODE BEGIN Includes */ +/* Section where include file can be added */ +/* USER CODE END Includes */ + +/* Ensure definitions are only used by the compiler, and not by the assembler. */ +#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) + +#include + +extern uint32_t SystemCoreClock; +#endif + +//#ifndef CMSIS_device_header +//#define CMSIS_device_header "niietcm4.h" +//#define CMSIS_device_header "at32f435_437.h" +//#endif /* CMSIS_device_header */ +//#include "niietcm4.h" +//#include "at32f435_437.h" + +#define configCHECK_FOR_STACK_OVERFLOW 1 + +#define configENABLE_FPU 1 +#define configENABLE_MPU 0 + +#define configUSE_PREEMPTION 1 +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 1 +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configCPU_CLOCK_HZ ( 240000000 ) +#define configTICK_RATE_HZ ((TickType_t)1000) +#define configMAX_PRIORITIES ( 56 ) +#define configMINIMAL_STACK_SIZE ((uint16_t)64) +#define configTOTAL_HEAP_SIZE ((size_t)16 * 1024) +#define configMAX_TASK_NAME_LEN ( 16 ) +#define configUSE_TRACE_FACILITY 1 +#define configUSE_16_BIT_TICKS 0 +#define configUSE_MUTEXES 1 +#define configQUEUE_REGISTRY_SIZE 8 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +/* USER CODE BEGIN MESSAGE_BUFFER_LENGTH_TYPE */ +/* Defaults to size_t for backward compatibility, but can be changed + if lengths will always be less than the number of bytes in a size_t. */ +#define configMESSAGE_BUFFER_LENGTH_TYPE size_t +/* USER CODE END MESSAGE_BUFFER_LENGTH_TYPE */ + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) + +/* Software timer definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY ( 2 ) +#define configTIMER_QUEUE_LENGTH 10 +#define configTIMER_TASK_STACK_DEPTH 128 + +/* CMSIS-RTOS V2 flags */ +#define configUSE_OS2_THREAD_SUSPEND_RESUME 1 +#define configUSE_OS2_THREAD_ENUMERATE 1 +#define configUSE_OS2_EVENTFLAGS_FROM_ISR 1 +#define configUSE_OS2_THREAD_FLAGS 1 +#define configUSE_OS2_TIMER 1 +#define configUSE_OS2_MUTEX 1 + +/* Set the following definitions to 1 to include the API function, or zero +to exclude the API function. */ +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskCleanUpResources 0 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_xTaskGetSchedulerState 1 +#define INCLUDE_xTimerPendFunctionCall 1 +#define INCLUDE_xQueueGetMutexHolder 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 1 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_eTaskGetState 1 + +/* + * The CMSIS-RTOS V2 FreeRTOS wrapper is dependent on the heap implementation used + * by the application thus the correct define need to be enabled below + */ +#define USE_FreeRTOS_HEAP_4 + +/* Cortex-M specific definitions. */ +#ifdef __NVIC_PRIO_BITS +/* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */ +#define configPRIO_BITS __NVIC_PRIO_BITS +#else +#define configPRIO_BITS 3U +#endif + +/* The lowest interrupt priority that can be used in a call to a "set priority" +function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 7 // 15 + +/* The highest interrupt priority that can be used by any interrupt service +routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL +INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER +PRIORITY THAN THIS! (higher priorities are lower numeric values. */ +#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 1 // 5 + +/* Interrupt priorities used by the kernel port layer itself. These are generic +to all Cortex-M ports, and do not rely on any particular library functions. */ +#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) +/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! +See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ +#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) + +/* Normal assert() semantics without relying on the provision of an assert.h +header file. */ +/* USER CODE BEGIN 1 */ + +//#define configASSERT(x) if ((x) == 0) {nvic_system_reset();} +#define configASSERT(x) if ((x) == 0) {taskDISABLE_INTERRUPTS(); for( ;; );} +/* USER CODE END 1 */ + +/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS +standard names. */ +#define vPortSVCHandler SVC_Handler +#define xPortPendSVHandler PendSV_Handler + +/* IMPORTANT: After 10.3.1 update, Systick_Handler comes from NVIC (if SYS timebase = systick), otherwise from cmsis_os2.c */ + +#define USE_CUSTOM_SYSTICK_HANDLER_IMPLEMENTATION 0 + + +#endif /* FREERTOS_CONFIG_H */ diff --git a/APP/main.c b/APP/main.c new file mode 100644 index 0000000..8a12d33 --- /dev/null +++ b/APP/main.c @@ -0,0 +1,114 @@ +// +// Created by cfif on 22.09.2025. +// +#include "Clock.h" +#include "fc7xxx_driver_fmc.h" +#include "InternalFlashPage.h" +#include "fc7xxx_driver_rgm.h" +#include "memory.h" +#include "BootJump.h" + +#define _BootloaderSize (64 * 1024) +#define _BootloaderBegin 0x01000000 +#define _FirmwareMainBegin (_BootloaderBegin + _BootloaderSize) + +#define FMC_FB_FPELCK_COUNT_V2 3 +#define FMC_FB_CPELCK_COUNT_V2 2 +#define FMC_OTA_VER_LOC_COUNT_V2 2 +#define FMC_OTA_ACT_VER_COUNT_V2 2 + +typedef struct { + + __IO uint32_t FAPC0; /* Flash Access Port Control Register0, offset: 0x0 */ + __IO uint32_t FAPC1; /* Flash Access Port Control Register1, offset: 0x4 */ + uint8_t RESERVED_0[8]; + __IO uint32_t FEEC; /* Flash ECC Error Control Register, offset: 0x10 */ + uint8_t RESERVED_1[748]; + __IO uint32_t FPESA_L; /* Flash Program Erase Start Address Logical Register, offset: 0x300 */ + __I uint32_t FPESA_P; /* Flash Program Erase Start Address Physical Register, offset: 0x304 */ + uint8_t RESERVED_2[56]; + __IO uint32_t FB_FPELCK[FMC_FB_FPELCK_COUNT_V2]; /* Flash Block n Fine Program Erase Lock Register, offset: 0x340 */ + uint8_t RESERVED_3[12]; + __IO uint32_t FN_FPELCK; /* Flash NVR Fine Program Erase Lock Register, offset: 0x358 */ + __IO uint32_t FB_CPELCK[FMC_FB_CPELCK_COUNT_V2]; /* Flash Block n Coarse Program Erase Lock Register, offset: 0x35c */ + uint8_t RESERVED_4[412]; + __IO uint32_t OTA_CTRL; /* OTA Control Register, offset: 0x500 */ + uint8_t RESERVED_5[4]; + __I uint32_t OTA_VER_LOC[FMC_OTA_VER_LOC_COUNT_V2]; /* OTA Version Location Register, offset: 0x508 */ + __I uint32_t OTA_ACT_VER[FMC_OTA_ACT_VER_COUNT_V2]; /* OTA Active Version Register, offset: 0x510 */ + +} FMC_Type_V2; + +#define FMC0_BASE_V2 (0x4001e000u) +#define FMC0_V2 ((FMC_Type_V2 *)FMC0_BASE_V2) + +static void swap_bank(uint8_t eBank) { + if (0U == (FMC0_V2->OTA_CTRL)) { + if (0 == eBank) { + FMC0_V2->OTA_CTRL &= (~(1u << 5u)); + } else { + FMC0_V2->OTA_CTRL |= (1u << 5u); + } + FMC0_V2->OTA_CTRL |= 0xA; + } +} + +void DefaultISR(void) { + +} + + +static void Boot2App(void) { + uint32_t u32StackAddr = *((uint32_t *) ((uint32_t) _FirmwareMainBegin)); + uint32_t u32ResetAddr = *((uint32_t *) (((uint32_t) _FirmwareMainBegin) + 4U)); + SCB->VTOR = (uint32_t) _FirmwareMainBegin; + __asm volatile("MOV R0, %0\n" + "MOV SP, R0\n" + "MOV R0, %1\n" + "MOV PC, R0" + : + : "r"(u32StackAddr), "r"(u32ResetAddr) + : "memory", "r0" + ); +} + + +#define CHECK_JTAG_DEBUG_ACTIVE ((CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk) != 0) +#define CHECK_PARALLEL_ENABLE (((*(volatile uint32_t*)0x044000E8) & 0x0000000F) != 0x00000005) + +uint64_t NumberBank = 0; + +int main(void) { + Bsp_CLOCK_Init(); + + if (CHECK_JTAG_DEBUG_ACTIVE) { + + NumberBank = (*(__IO uint64_t *) (0x04000000)); + + if (NumberBank == 0x1122334455667788) { + D_bInternalFlashPage_Clear(0x04000000, NULL, NULL); + } + + swap_bank(0); + } else { + + if (CHECK_PARALLEL_ENABLE) { + swap_bank(0); + } else { + + NumberBank = (*(__IO uint64_t *) (0x04000000)); + + if (NumberBank == 0x1122334455667788) { + swap_bank(1); + } else { + swap_bank(0); + } + + } + } + +// BootJumpToAddress(_FirmwareMainBegin); +// BootFastJumpToAddress(_FirmwareMainBegin); + Boot2App(); + +} diff --git a/APP/modular.json b/APP/modular.json new file mode 100644 index 0000000..7eef019 --- /dev/null +++ b/APP/modular.json @@ -0,0 +1,15 @@ +{ + "cmake": { + "inc_dirs": [ + "./", + "./clock", + "./int" + ], + "srcs": [ + "./**.c", + "./clock/**.c", + "./int/**.c", + "./**.s" + ] + } +} \ No newline at end of file diff --git a/APP/startup_FC7240.s b/APP/startup_FC7240.s new file mode 100644 index 0000000..8de644a --- /dev/null +++ b/APP/startup_FC7240.s @@ -0,0 +1,480 @@ +/* ================================================================================================== */ +/* BRIEF : Startup - Startup file for FC7240 */ +/* PERIPHERAL : N/A */ +/* PLATFORM : Flagchip FC7240 */ +/* SOFTWARE VERSION : 0.1.0 */ +/* VENDOR : Flagchip */ +/* Copyright 2024 Flagchip Semiconductors Co., Ltd. */ +/* All Rights Reserved. */ +/* ================================================================================================== */ +/* ================================================================================================== */ +/* Revision History */ +/* Version Date Initials CR# Descriptions */ +/* --------- ---------- ------------- ---------- --------------- */ +/* 0.1.0 2024-01-12 qxw0030 N/A Initial version */ +/* ================================================================================================== */ + + .syntax unified + .arch armv7-m + + .extern __StackTop + .extern __StackLimit + +/* ================================================================================================== */ +/* Set vector table */ +/* ================================================================================================== */ + .section .isr_vector + .align 2 + .globl __isr_vector + + /* vector table */ +__isr_vector: + .long __StackTop /* Top of Stack */ + .long Reset_Handler /* Reset Handler */ + .long NMI_Handler /* NMI Handler */ + .long HardFault_Handler /* Hard Fault Handler */ + .long MemManage_Handler /* MPU Fault Handler */ + .long BusFault_Handler /* Bus Fault Handler */ + .long UsageFault_Handler /* Usage Fault Handler */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long SVC_Handler /* SVCall Handler */ + .long DebugMon_Handler /* Debug Monitor Handler */ + .long 0 /* Reserved */ + .long PendSV_Handler /* PendSV Handler */ + .long SysTick_Handler /* SysTick Handler */ + + /* External Interrupts*/ + .long DMA0_IRQHandler /* DMA channel 0 transfer complete */ + .long DMA1_IRQHandler /* DMA channel 1 transfer complete */ + .long DMA2_IRQHandler /* DMA channel 2 transfer complete */ + .long DMA3_IRQHandler /* DMA channel 3 transfer complete */ + .long DMA4_IRQHandler /* DMA channel 4 transfer complete */ + .long DMA5_IRQHandler /* DMA channel 5 transfer complete */ + .long DMA6_IRQHandler /* DMA channel 6 transfer complete */ + .long DMA7_IRQHandler /* DMA channel 7 transfer complete */ + .long DMA8_IRQHandler /* DMA channel 8 transfer complete */ + .long DMA9_IRQHandler /* DMA channel 9 transfer complete */ + .long DMA10_IRQHandler /* DMA channel 10 transfer complete */ + .long DMA11_IRQHandler /* DMA channel 11 transfer complete */ + .long DMA12_IRQHandler /* DMA channel 12 transfer complete */ + .long DMA13_IRQHandler /* DMA channel 13 transfer complete */ + .long DMA14_IRQHandler /* DMA channel 14 transfer complete */ + .long DMA15_IRQHandler /* DMA channel 15 transfer complete */ + .long DMA_Error_IRQHandler /* DMA error interrupt channels 0-31 */ + .long CPM_IRQHandler /* FPU etc. interrupt */ + .long FC_IRQHandler /* FC Command complete */ + .long PMC_IRQHandler /* HVD/LVD etc. interrupt */ + .long TMU_IRQHandler /* Temperature Monitor Unit interrupt */ + .long WDOG0_IRQHandler /* interrupt request out before wdg reset out */ + .long WDOG1_IRQHandler /* interrupt request out before wdg reset out */ + .long FCSMU0_IRQHandler /* Fault Control and Safety Manage Unit */ + .long STCU0_IRQHandler /* Safety Control Unit interrupt */ + .long ERM_fault_IRQHandler /* ERM single/double bit error correction */ + .long MAM0_IRQHandler /* Matrix Access Monitor interrupt */ + .long RGM_Pre_IRQHandler /* RGM pre-reset Interrupt */ + .long INTM0_IRQHandler /* INTM alarm interrupt */ + .long ISM0_IRQHandler /* ISM0 interrupt */ + .long MB_IRQHandler /* Mail Box interrupt */ + .long SCG_IRQHandler /* SCG bus interrupt request */ + .long CMU0_IRQHandler /* CMU0 interrupt */ + .long CMU1_IRQHandler /* CMU1 interrupt */ + .long CMU2_IRQHandler /* CMU2 interrupt */ + .long CMU3_IRQHandler /* CMU3 interrupt */ + .long CMU4_IRQHandler /* CMU4 interrupt */ + .long TSTMP0_IRQHandler /* TimerStamp0 interrupt */ + .long TSTMP1_IRQHandler /* TimerStamp1 interrupt */ + .long CORDIC_IRQHandler /* CORDIC Accelerator interrupt */ + .long HSM0_IRQHandler /* HSM error interrupt */ + .long FCPIT0_IRQHandler /* FCPIT0 interrupt */ + .long RTC_IRQHandler /* RTC alarm or seconds interrupt */ + .long AONTIMER_IRQHandler /* AONTIMER interrupt request */ + .long SWI_IRQHandler /* Software interrupt */ + .long FREQM_IRQHandler /* FREQM interrupt */ + .long ADC0_IRQHandler /* ADC0 interrupt request. */ + .long ADC1_IRQHandler /* ADC1 interrupt request. */ + .long PTIMER0_IRQHandler /* PTIMER0 interrupt */ + .long PTIMER1_IRQHandler /* PTIMER1 interrupt */ + .long CAN0_IRQHandler /* CAN0 Interrupt */ + .long CAN1_IRQHandler /* CAN1 Interrupt */ + .long CAN2_IRQHandler /* CAN2 Interrupt */ + .long CAN3_IRQHandler /* CAN3 Interrupt */ + .long FCIIC0_IRQHandler /* FCIIC0 Interrupt */ + .long FCIIC1_IRQHandler /* FCIIC1 Interrupt */ + .long FCSPI0_IRQHandler /* FCSPI0 Interrupt */ + .long FCSPI1_IRQHandler /* FCSPI1 Interrupt */ + .long FCSPI2_IRQHandler /* FCSPI2 Interrupt */ + .long FCSPI3_IRQHandler /* FCSPI3 Interrupt */ + .long FCSPI4_IRQHandler /* FCSPI4 Interrupt */ + .long FCSPI5_IRQHandler /* FCSPI5 Interrupt */ + .long FCUART0_RxTx_IRQHandler /* FCUART0 Transmit / Receive Interrupt */ + .long FCUART1_RxTx_IRQHandler /* FCUART1 Transmit / Receive Interrupt */ + .long FCUART2_RxTx_IRQHandler /* FCUART2 Transmit / Receive Interrupt */ + .long FCUART3_RxTx_IRQHandler /* FCUART3 Transmit / Receive Interrupt */ + .long FCUART4_RxTx_IRQHandler /* FCUART4 Transmit / Receive Interrupt */ + .long FCUART5_RxTx_IRQHandler /* FCUART5 Transmit / Receive Interrupt */ + .long FCUART6_RxTx_IRQHandler /* FCUART6 Transmit / Receive Interrupt */ + .long FCUART7_RxTx_IRQHandler /* FCUART7 Transmit / Receive Interrupt */ + .long FTU0_IRQHandler /* FTU0 all source interrupt */ + .long FTU1_IRQHandler /* FTU1 all source interrupt */ + .long FTU2_IRQHandler /* FTU2 all source interrupt */ + .long FTU3_IRQHandler /* FTU3 all source interrupt */ + .long FTU4_IRQHandler /* FTU4 all source interrupt */ + .long FTU5_IRQHandler /* FTU5 all source interrupt */ + .long FTU6_IRQHandler /* FTU6 all source interrupt */ + .long FTU7_IRQHandler /* FTU7 all source interrupt */ + .long CMP0_IRQHandler /* CMP0 interrupt request */ + .long CMP1_IRQHandler /* CMP1 interrupt request */ + .long PORTA_IRQHandler /* Port A pin detect interrupt */ + .long PORTB_IRQHandler /* Port B pin detect interrupt */ + .long PORTC_IRQHandler /* Port C pin detect interrupt */ + .long PORTD_IRQHandler /* Port D pin detect interrupt */ + .long PORTE_IRQHandler /* Port E pin detect interrupt */ + .long MSC0_IRQHandler /* MSC interrupt */ + .long SENT0_IRQHandler /* SENT all interrupt (fast or slow) */ + .long TPU0_CH0_7_IRQHandler /* TPU0 CH0-7 interrupt */ + .long TPU0_CH8_15_IRQHandler /* TPU0 CH8-15 interrupt */ + .long TPU0_CH16_23_IRQHandler /* TPU0 CH16-23 interrupt */ + .long TPU0_CH24_31_IRQHandler /* TPU0 CH24-31 interrupt */ + .long HSM0_CRYPTO_IRQHandler /* HSM crypto interrupt */ + .long DefaultISR /* 108 */ + .long DefaultISR /* 109 */ + .long DefaultISR /* 110 */ + .long DefaultISR /* 111 */ + .long DefaultISR /* 112 */ + .long DefaultISR /* 113 */ + .long DefaultISR /* 114 */ + .long DefaultISR /* 115 */ + .long DefaultISR /* 116 */ + .long DefaultISR /* 117 */ + .long DefaultISR /* 118 */ + .long DefaultISR /* 119 */ + .long DefaultISR /* 120 */ + .long DefaultISR /* 121 */ + .long DefaultISR /* 122 */ + .long DefaultISR /* 123 */ + .long DefaultISR /* 124 */ + .long DefaultISR /* 125 */ + .long DefaultISR /* 126 */ + .long DefaultISR /* 127 */ + .long DefaultISR /* 128 */ + .long DefaultISR /* 129 */ + .long DefaultISR /* 130 */ + .long DefaultISR /* 131 */ + .long DefaultISR /* 132 */ + .long DefaultISR /* 133 */ + .long DefaultISR /* 134 */ + .long DefaultISR /* 135 */ + .long DefaultISR /* 136 */ + .long DefaultISR /* 137 */ + .long DefaultISR /* 138 */ + .long DefaultISR /* 139 */ + .long DefaultISR /* 140 */ + .long DefaultISR /* 141 */ + .long DefaultISR /* 142 */ + .long DefaultISR /* 143 */ + .long DefaultISR /* 144 */ + .long DefaultISR /* 145 */ + .long DefaultISR /* 146 */ + .long DefaultISR /* 147 */ + .long DefaultISR /* 148 */ + .long DefaultISR /* 149 */ + .long DefaultISR /* 150 */ + .long DefaultISR /* 151 */ + .long DefaultISR /* 152 */ + .long DefaultISR /* 153 */ + .long DefaultISR /* 154 */ + .long DefaultISR /* 155 */ + .long DefaultISR /* 156 */ + .long DefaultISR /* 157 */ + .long DefaultISR /* 158 */ + .long DefaultISR /* 159 */ + .long DefaultISR /* 160 */ + .long DefaultISR /* 161 */ + .long DefaultISR /* 162 */ + .long DefaultISR /* 163 */ + .long DefaultISR /* 164 */ + .long DefaultISR /* 165 */ + .long DefaultISR /* 166 */ + .long DefaultISR /* 167 */ + .long DefaultISR /* 168 */ + .long DefaultISR /* 169 */ + .long DefaultISR /* 170 */ + .long DefaultISR /* 171 */ + .long DefaultISR /* 172 */ + .long DefaultISR /* 173 */ + .long DefaultISR /* 174 */ + .long DefaultISR /* 175 */ + .long DefaultISR /* 176 */ + .long DefaultISR /* 177 */ + .long DefaultISR /* 178 */ + .long DefaultISR /* 179 */ + .long DefaultISR /* 180 */ + .long DefaultISR /* 181 */ + .long DefaultISR /* 182 */ + .long DefaultISR /* 183 */ + .long DefaultISR /* 184 */ + .long DefaultISR /* 185 */ + .long DefaultISR /* 186 */ + .long DefaultISR /* 187 */ + .long DefaultISR /* 188 */ + .long DefaultISR /* 189 */ + .long DefaultISR /* 190 */ + .long DefaultISR /* 191 */ + .long DefaultISR /* 192 */ + .long DefaultISR /* 193 */ + .long DefaultISR /* 194 */ + .long DefaultISR /* 195 */ + .long DefaultISR /* 196 */ + .long DefaultISR /* 197 */ + .long DefaultISR /* 198 */ + .long DefaultISR /* 199 */ + .long DefaultISR /* 200 */ + .long DefaultISR /* 201 */ + .long DefaultISR /* 202 */ + .long DefaultISR /* 203 */ + .long DefaultISR /* 204 */ + .long DefaultISR /* 205 */ + .long DefaultISR /* 206 */ + .long DefaultISR /* 207 */ + .long DefaultISR /* 208 */ + .long DefaultISR /* 209 */ + .long DefaultISR /* 210 */ + .long DefaultISR /* 211 */ + .long DefaultISR /* 212 */ + .long DefaultISR /* 213 */ + .long DefaultISR /* 214 */ + .long DefaultISR /* 215 */ + .long DefaultISR /* 216 */ + .long DefaultISR /* 217 */ + .long DefaultISR /* 218 */ + .long DefaultISR /* 219 */ + .long DefaultISR /* 220 */ + .long DefaultISR /* 221 */ + .long DefaultISR /* 222 */ + .long DefaultISR /* 223 */ + .long DefaultISR /* 224 */ + .long DefaultISR /* 225 */ + .long DefaultISR /* 226 */ + .long DefaultISR /* 227 */ + .long DefaultISR /* 228 */ + .long DefaultISR /* 229 */ + .long DefaultISR /* 230 */ + .long DefaultISR /* 231 */ + .long DefaultISR /* 232 */ + .long DefaultISR /* 233 */ + .long DefaultISR /* 234 */ + .long DefaultISR /* 235 */ + .long DefaultISR /* 236 */ + .long DefaultISR /* 237 */ + .long DefaultISR /* 238 */ + .long DefaultISR /* 239 */ + .long DefaultISR /* 240 */ + .long DefaultISR /* 241 */ + .long DefaultISR /* 242 */ + .long DefaultISR /* 243 */ + .long DefaultISR /* 244 */ + .long DefaultISR /* 245 */ + .long DefaultISR /* 246 */ + .long DefaultISR /* 247 */ + .long DefaultISR /* 248 */ + .long DefaultISR /* 249 */ + .long DefaultISR /* 250 */ + .long DefaultISR /* 251 */ + .long DefaultISR /* 252 */ + .long DefaultISR /* 253 */ + .long DefaultISR /* 254 */ + .long 0xFFFFFFFF /* Reserved for user TRIM value */ + + .size __isr_vector, . - __isr_vector + + +/**************************************************************/ +/************************ set other ***************************/ + .text + .thumb + +/* Reset Handler */ + + .thumb_func + .align 2 + .globl Reset_Handler + .weak Reset_Handler + .type Reset_Handler, %function + +Reset_Handler: + cpsid i /* Mask interrupts */ + + /* Init the rest of the registers */ + ldr r1,=0 + ldr r2,=0 + ldr r3,=0 + ldr r4,=0 + ldr r5,=0 + ldr r6,=0 + ldr r7,=0 + mov r8,r7 + mov r9,r7 + mov r10,r7 + mov r11,r7 + mov r12,r7 + + ldr r0, =0xE000ED08 + ldr r1, =__vector_table + str r1, [r0] + + /* Initialize the stack pointer */ + ldr r0,=__StackTop + mov sp,r0 ; sp=r13 + + /* Clear Stack */ + ldr r2, =__StackLimit + ldr r4, =__StackTop + movs r3, #0 + b LoopFillZero_STACK + +FillZero_STACK: + str r3, [r2] + adds r2, r2, #4 + +LoopFillZero_STACK: + cmp r2, r4 + bcc FillZero_STACK + + /* System Initialization */ + ldr r0,=System_Init + blx r0 + + /* Initialize .data and .bss sections */ + ldr r0,=Data_Init + blx r0 + + cpsie i /* Unmask interrupts */ + bl main +JumpToSelf: + b JumpToSelf + + .pool + .size Reset_Handler, . - Reset_Handler + + .align 1 + .thumb_func + .weak DefaultISR + .type DefaultISR, %function +DefaultISR: + b DefaultISR + .size DefaultISR, . - DefaultISR + +/* Macro to define default handlers. Default handler + * will be weak symbol and just dead loops. They can be + * overwritten by other handlers */ + .macro def_irq_handler handler_name + .weak \handler_name + .set \handler_name, DefaultISR + .endm + +/* Exception Handlers */ + def_irq_handler NMI_Handler + def_irq_handler HardFault_Handler + def_irq_handler MemManage_Handler + def_irq_handler BusFault_Handler + def_irq_handler UsageFault_Handler + def_irq_handler SVC_Handler + def_irq_handler DebugMon_Handler + def_irq_handler PendSV_Handler + def_irq_handler SysTick_Handler + def_irq_handler DMA0_IRQHandler + def_irq_handler DMA1_IRQHandler + def_irq_handler DMA2_IRQHandler + def_irq_handler DMA3_IRQHandler + def_irq_handler DMA4_IRQHandler + def_irq_handler DMA5_IRQHandler + def_irq_handler DMA6_IRQHandler + def_irq_handler DMA7_IRQHandler + def_irq_handler DMA8_IRQHandler + def_irq_handler DMA9_IRQHandler + def_irq_handler DMA10_IRQHandler + def_irq_handler DMA11_IRQHandler + def_irq_handler DMA12_IRQHandler + def_irq_handler DMA13_IRQHandler + def_irq_handler DMA14_IRQHandler + def_irq_handler DMA15_IRQHandler + def_irq_handler DMA_Error_IRQHandler + def_irq_handler CPM_IRQHandler + def_irq_handler FC_IRQHandler + def_irq_handler PMC_IRQHandler + def_irq_handler TMU_IRQHandler + def_irq_handler WDOG0_IRQHandler + def_irq_handler WDOG1_IRQHandler + def_irq_handler FCSMU0_IRQHandler + def_irq_handler STCU0_IRQHandler + def_irq_handler ERM_fault_IRQHandler + def_irq_handler MAM0_IRQHandler + def_irq_handler RGM_Pre_IRQHandler + def_irq_handler INTM0_IRQHandler + def_irq_handler ISM0_IRQHandler + def_irq_handler MB_IRQHandler + def_irq_handler SCG_IRQHandler + def_irq_handler CMU0_IRQHandler + def_irq_handler CMU1_IRQHandler + def_irq_handler CMU2_IRQHandler + def_irq_handler CMU3_IRQHandler + def_irq_handler CMU4_IRQHandler + def_irq_handler TSTMP0_IRQHandler + def_irq_handler TSTMP1_IRQHandler + def_irq_handler CORDIC_IRQHandler + def_irq_handler HSM0_IRQHandler + def_irq_handler FCPIT0_IRQHandler + def_irq_handler RTC_IRQHandler + def_irq_handler AONTIMER_IRQHandler + def_irq_handler SWI_IRQHandler + def_irq_handler FREQM_IRQHandler + def_irq_handler ADC0_IRQHandler + def_irq_handler ADC1_IRQHandler + def_irq_handler PTIMER0_IRQHandler + def_irq_handler PTIMER1_IRQHandler + def_irq_handler CAN0_IRQHandler + def_irq_handler CAN1_IRQHandler + def_irq_handler CAN2_IRQHandler + def_irq_handler CAN3_IRQHandler + def_irq_handler FCIIC0_IRQHandler + def_irq_handler FCIIC1_IRQHandler + def_irq_handler FCSPI0_IRQHandler + def_irq_handler FCSPI1_IRQHandler + def_irq_handler FCSPI2_IRQHandler + def_irq_handler FCSPI3_IRQHandler + def_irq_handler FCSPI4_IRQHandler + def_irq_handler FCSPI5_IRQHandler + def_irq_handler FCUART0_RxTx_IRQHandler + def_irq_handler FCUART1_RxTx_IRQHandler + def_irq_handler FCUART2_RxTx_IRQHandler + def_irq_handler FCUART3_RxTx_IRQHandler + def_irq_handler FCUART4_RxTx_IRQHandler + def_irq_handler FCUART5_RxTx_IRQHandler + def_irq_handler FCUART6_RxTx_IRQHandler + def_irq_handler FCUART7_RxTx_IRQHandler + def_irq_handler FTU0_IRQHandler + def_irq_handler FTU1_IRQHandler + def_irq_handler FTU2_IRQHandler + def_irq_handler FTU3_IRQHandler + def_irq_handler FTU4_IRQHandler + def_irq_handler FTU5_IRQHandler + def_irq_handler FTU6_IRQHandler + def_irq_handler FTU7_IRQHandler + def_irq_handler CMP0_IRQHandler + def_irq_handler CMP1_IRQHandler + def_irq_handler PORTA_IRQHandler + def_irq_handler PORTB_IRQHandler + def_irq_handler PORTC_IRQHandler + def_irq_handler PORTD_IRQHandler + def_irq_handler PORTE_IRQHandler + def_irq_handler MSC0_IRQHandler + def_irq_handler SENT0_IRQHandler + def_irq_handler TPU0_CH0_7_IRQHandler + def_irq_handler TPU0_CH8_15_IRQHandler + def_irq_handler TPU0_CH16_23_IRQHandler + def_irq_handler TPU0_CH24_31_IRQHandler + def_irq_handler HSM0_CRYPTO_IRQHandler + .end diff --git a/APP/syscalls.c b/APP/syscalls.c new file mode 100644 index 0000000..931a5b1 --- /dev/null +++ b/APP/syscalls.c @@ -0,0 +1,75 @@ +#if (defined(__ICCARM__)) + +#elif defined(__ARMCC_VERSION) + +#elif defined __GNUC__ + #include "sys/types.h" + #include "sys/stat.h" +#endif + +static uint32_t s_u32Current_heap_end; + +#if (defined(__ICCARM__)) +extern uint32_t __HeapBegin[1]; // Defined by the linker. +extern uint32_t __HeapLimit[1]; // Defined by the linker. +#elif defined __GNUC__ +extern uint32_t __HeapBegin[1]; // Defined by the linker. +extern uint32_t __HeapLimit[1]; // Defined by the linker. +#endif + + +#if (defined(__ICCARM__)) +/** + * TODO: something can be done to make sure the start address used in heap is defined heap start +*/ +#elif defined(__ARMCC_VERSION) + +#elif defined __GNUC__ +extern caddr_t _sbrk(int incr); + +/** + * \brief Replacement of C library of _sbrk + */ +caddr_t _sbrk(int incr) +{ + if (s_u32Current_heap_end == 0U) + { + #if (defined(__ICCARM__)) + s_u32Current_heap_end = (uint32_t)__HeapBegin; + #elif defined __GNUC__ + s_u32Current_heap_end = (uint32_t)__HeapBegin; + #endif + } + + // Need to align heap to word boundary, else will get + // hard faults on Cortex-M0. So we assume that heap starts on + // word boundary, hence make sure we always add a multiple of + // 4 to it. + incr = (incr + 3) & (~3); // align value to 4 + #if (defined(__ICCARM__)) + if ( (s_u32Current_heap_end + incr) > (uint32_t)__HeapLimit ) + #elif defined __GNUC__ + if ( (s_u32Current_heap_end + incr) > (uint32_t)__HeapLimit ) + #endif + { + // Some of the libstdc++-v3 tests rely upon detecting + // out of memory errors, so do not abort here. + #if 0 + extern void abort(void); + + _write(1, "_sbrk: Heap and stack collision\n", 32); + + abort(); + #else + return (caddr_t) - 1; + #endif + } + else + { + s_u32Current_heap_end+= incr; + } + + return (caddr_t) s_u32Current_heap_end; +} + +#endif diff --git a/APP/system_init.c b/APP/system_init.c new file mode 100644 index 0000000..589aefa --- /dev/null +++ b/APP/system_init.c @@ -0,0 +1,212 @@ +/** + * @file system_init.c + * @author Flagchip + * @brief interrupt configuration + * @version 0.1.0 + * @date 2024-01-12 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + */ + +/* ******************************************************************************** + * Revision History: + * + * Version Date Author Descriptions + * --------- ---------- ------------ --------------- + * 0.1.0 2024-01-12 Flagchip038 First version for gcc, iar, keil, ghs data init + ******************************************************************************** */ + + +#include "system_init.h" +#include "fc7xxx_driver_fpu.h" + +static void data_clear(uint32_t u32StartAddr, uint32_t u32EndAddr); +static void data_copy(uint32_t u32SourceAddr, uint32_t u32DestAddr, uint32_t u32DestEndAddr); + + +#define REG_VAL(addr) (*(volatile uint32 *)(addr)) +#define REG_VAL_OFF(addr,offset) (*(volatile uint32 *)((addr)+(offset))) +#define WDOG0_BASE_ADDR 0x40022000U +#define WDOG1_BASE_ADDR 0x40433000U +#define SMC_STANDBY_CFG_ADDR 0x40045010U +#define SCM_BASE_ADDR 0x40072000U +#define RGM_BASE_ADDR 0x40046000U +#define PCC_STCU_ADDR 0x400241FCU +#define STCU_BASE_ADDR 0x4007F000U + +#define DWT_CYCCNT_ADDR 0xE0001004U +#define DEMCR_ADDR 0xE000EDFCU + +#define CPACR_ADDR 0xE000ED88U + +static void wdog_disable(uint32 wdog_base) +{ + uint32 u32ttt = 128; + uint32 u32First = 1; + /* if it is not first time configure wdog, unlock status only pending for 128 bus clock */ + do { + /* check unlock active */ + if (0U == (0x800u & REG_VAL(wdog_base))) + { + /* if unlock statue turn to 0, means not first time configuring wdog */ + u32First = 0; + break; + } + } while (u32ttt--); + + if (u32First == 0U) + { + /* only unlock=0, reconfig=1, can unlock wdog*/ + + /* waiting reconfiguration successful */ + while (0U == (0x400u & REG_VAL(wdog_base))); + + /* unlock wdog */ + REG_VAL_OFF(wdog_base, 4) = 0x08181982; + /* waiting unlock active */ + while (0U == (0x800u & REG_VAL(wdog_base))); + + } + REG_VAL(wdog_base) = 0x2920; + REG_VAL_OFF(wdog_base, 8) = 0xF000; + /* waiting reconfiguration successful */ + while (0U == (0x400u & REG_VAL(wdog_base))); +} + +/** + * \brief System Initialization + * + */ +void System_Init(void) +{ + // disable wdog 0 + *(volatile uint32 *)0x40022004 = 0x08181982; + while (0U == (0x800u & *(volatile uint32 *)0x40022000)); + *(volatile uint32 *)0x40022000 = 0x2920; + *(volatile uint32 *)0x40022008 = 0xF000; + while (0U == (0x400u & *(volatile uint32 *)0x40022000)); + + // disable wdog 1 + *(volatile uint32 *)0x40433004 = 0x08181982; + while (0U == (0x800u & *(volatile uint32 *)0x40433000)); + *(volatile uint32 *)0x40433000 = 0x2920; + *(volatile uint32 *)0x40433008 = 0xF000; + while (0U == (0x400u & *(volatile uint32 *)0x40433000)); + +#if ((__FPU_PRESENT == 1) && (__FPU_USED == 1)) + FPU_Enable(); // Enable FPU +#endif +} + +void Data_Init(void) +{ +#if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + extern uint32_t Load$$RW_m_dtcm$$Base; + extern uint32_t Image$$RW_m_dtcm$$Base; + extern uint32_t Image$$RW_m_dtcm$$Limit; + + extern uint32_t Image$$RW_m_dtcm$$ZI$$Limit; + extern uint32_t Image$$RW_m_dtcm$$ZI$$Base; + + extern uint32_t Image$$ARM_LIB_HEAP$$ZI$$Base; + extern uint32_t Image$$ARM_LIB_HEAP$$ZI$$Limit; + + /* data/bss/heap clear */ + data_clear((uint32_t)&Image$$RW_m_dtcm$$Base, (uint32_t)&Image$$RW_m_dtcm$$Limit); + data_clear((uint32_t)&Image$$RW_m_dtcm$$ZI$$Base, (uint32_t)&Image$$RW_m_dtcm$$ZI$$Limit); + data_clear((uint32_t)&Image$$ARM_LIB_HEAP$$ZI$$Base, (uint32_t)&Image$$ARM_LIB_HEAP$$ZI$$Limit); + + /* data */ + data_copy((uint32_t)&Load$$RW_m_dtcm$$Base, (uint32_t)&Image$$RW_m_dtcm$$Base, (uint32_t)&Image$$RW_m_dtcm$$Limit); + +#elif defined(__GNUC__) || defined(__ghs__) + extern uint32 __rom_data_start[]; + extern uint32 __ram_data_start[]; + extern uint32 __ram_data_end[]; + extern uint32 __bss_start[]; + extern uint32 __bss_end[]; + extern uint32 __rom_ncache_data_start[]; + extern uint32 __ram_ncache_data_start[]; + extern uint32 __ram_ncache_data_end[]; + extern uint32 __ncache_bss_start[]; + extern uint32 __ncache_bss_end[]; + + extern uint32_t __itcm_start[]; + extern uint32_t __itcm_end[]; + + + extern uint32_t __xcp_start[]; + extern uint32_t __xcp_end[]; + + + /* data clear */ + data_clear((uint32_t)__ram_data_start, (uint32_t)__ram_data_end); + data_clear((uint32_t)__bss_start, (uint32_t)__bss_end); +// data_clear((uint32_t)__ram_ncache_data_start, (uint32_t)__ram_ncache_data_end); +// data_clear((uint32_t)__ncache_bss_start, (uint32_t)__ncache_bss_end); + +// data_clear((uint32_t)__itcm_start, (uint32_t)__itcm_end); +// data_clear((uint32_t)__xcp_start, (uint32_t)__xcp_end); + + /* data copy */ + data_copy((uint32_t)__rom_data_start, (uint32_t)__ram_data_start, (uint32_t)__ram_data_end); +// data_copy((uint32_t)__rom_ncache_data_start, (uint32_t)__ram_ncache_data_start, (uint32_t)__ram_ncache_data_end); + +#elif defined(__ICCARM__) + #pragma section=".data" + #pragma section=".data_init" + #pragma section=".ncsram" + #pragma section=".ncsram_init" + #pragma section=".bss" + #pragma section="RAM_VECTOR" + #pragma section=".intvec" + + data_clear((uint32_t)__section_begin(".bss"), (uint32_t)__section_end(".bss")); + + data_copy((uint32_t)__section_begin(".data_init"), (uint32_t)__section_begin(".data"), (uint32_t)__section_end(".data")); + + data_copy((uint32_t)__section_begin(".ncsram_init"), (uint32_t)__section_begin(".ncsram"), (uint32_t)__section_end(".ncsram")); + +#endif +} + +/* to avoid ecc issue, FC7240 clear ram with 64bits once after power on reset */ +static void data_clear(uint32_t u32StartAddr, uint32_t u32EndAddr) +{ + /* 64 bits align */ + uint32_t u32AlignStart = u32StartAddr & 0xFFFFFFF8; + uint32_t u32AlignEnd = (u32EndAddr - u32AlignStart); + volatile uint64_t *pData = (uint64_t *)u32AlignStart; + + /* 32 word Align */ + uint32_t u32LeftCount = u32AlignEnd & 0x1Fu; + u32AlignEnd = u32EndAddr - u32LeftCount; + + while ((uint32_t)pData < u32AlignEnd) + { + *pData++ = 0u; + *pData++ = 0u; + *pData++ = 0u; + *pData++ = 0u; + } + + while ((uint32_t)pData < u32EndAddr) + { + *pData++ = 0u; + } +} + +static void data_copy(uint32_t u32SourceAddr, uint32_t u32DestAddr, uint32_t u32DestEndAddr) +{ + uint32_t *pSource = (uint32_t *)u32SourceAddr; + uint32_t *pDest = (uint32_t *)u32DestAddr; + + while ((uint32_t)pDest < u32DestEndAddr) + { + *pDest = *pSource; + pDest++; + pSource++; + } +} + diff --git a/APP/system_init.h b/APP/system_init.h new file mode 100644 index 0000000..8057dbe --- /dev/null +++ b/APP/system_init.h @@ -0,0 +1,32 @@ +/** + * @file system_init.h + * @author Flagchip + * @brief interrupt configuration + * @version 0.1.0 + * @date 2024-01-12 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + */ +#if !defined(SYSTEM_INIT_H) +#define SYSTEM_INIT_H + + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + + +#include "device_header.h" + +void System_Init(void); + +void Data_Init(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + + + +#endif /* SYSTEM_INIT_H */ diff --git a/APP/text b/APP/text new file mode 100644 index 0000000..df5be91 --- /dev/null +++ b/APP/text @@ -0,0 +1,28 @@ +.cals_data(NOLOAD) : +{ + __itcm_start = .; + + /* Резервируем ровно 20K для .caldata */ + .caldata : { + KEEP(*(.caldata)) + . = ALIGN(4); + } > ITCM + + /* Проверяем размер и заполняем до 20K */ + __caldata_end = .; + __caldata_start = ADDR(.caldata); + __caldata_size = SIZEOF(.caldata); + + /* Если .caldata меньше 20K, добавляем пустое пространство */ + . = __caldata_start + 20K; + + /* Проверяем, что не превысили размер */ + ASSERT((. - __caldata_start) >= 20K, "Зарезервировано менее 20K для .caldata"); + ASSERT(__caldata_size <= 20K, "Раздел .caldata превышает 20K!"); + + KEEP(*(.nvmdata)) + . = ALIGN(4); + *Model_actuator.c.obj(.bss .bss*) + __itcm_end = .; + . = ALIGN(4); +} > ITCM \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..2b3e6b7 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,140 @@ +#-- Service -------------------------------------------------------------------- +SET(CMAKE_TOOLCHAIN_FILE ${CMAKE_SOURCE_DIR}/MODULES/CmakeConfig_GCC_CortexM7/gcc_cm7f.cmake) +ENABLE_LANGUAGE(ASM) +CMAKE_MINIMUM_REQUIRED(VERSION 3.8.0) + +set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0") +set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0") + +IF (${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR}) + MESSAGE( + FATAL_ERROR + "In-source builds not allowed. + Please make a new directory (called a build directory) and run CMake from there. + You may need to remove CMakeCache.txt." + ) +ENDIF () + +SET(CMAKE_EXPORT_COMPILE_COMMANDS ON) +#-- Project config ------------------------------------------------------------- +PROJECT(HVAC_BOOT_OTA_M7) # Project name + +SET(INTERNAL_HW_YEAR 26) +SET(INTERNAL_HW_MONTH 8) +SET(INTERNAL_HW_DAY 21) +SET(INTERNAL_HW_REV 1) + +SET(INTERNAL_SW_YEAR 26) +SET(INTERNAL_SW_MONTH 8) +SET(INTERNAL_SW_DAY 21) +SET(INTERNAL_SW_REV 1) + +SET(INTERNAL_MDB_YEAR 26) +SET(INTERNAL_MDB_MONTH 8) +SET(INTERNAL_MDB_DAY 21) +SET(INTERNAL_MDB_REV 1) + +SET(FINGER_MODULE 0x00) +SET(FINGER_TESTER_SERIAL \"B\") +SET(FINGER_YEAR 0x26) +SET(FINGER_MONTH 0x02) +SET(FINGER_DAY 0x24) + + + +SET(VECT_TAB_OFFSET "0x00000") + +#-- Defines -------------------------------------------------------------------- + + +ADD_DEFINITIONS(-DINTERNAL_HW_YEAR=${INTERNAL_HW_YEAR}) +ADD_DEFINITIONS(-DINTERNAL_HW_MONTH=${INTERNAL_HW_MONTH}) +ADD_DEFINITIONS(-DINTERNAL_HW_DAY=${INTERNAL_HW_DAY}) +ADD_DEFINITIONS(-DINTERNAL_HW_REV=${INTERNAL_HW_REV}) + +ADD_DEFINITIONS(-DINTERNAL_SW_YEAR=${INTERNAL_SW_YEAR}) +ADD_DEFINITIONS(-DINTERNAL_SW_MONTH=${INTERNAL_SW_MONTH}) +ADD_DEFINITIONS(-DINTERNAL_SW_DAY=${INTERNAL_SW_DAY}) +ADD_DEFINITIONS(-DINTERNAL_SW_REV=${INTERNAL_SW_REV}) + +ADD_DEFINITIONS(-DINTERNAL_MDB_YEAR=${INTERNAL_MDB_YEAR}) +ADD_DEFINITIONS(-DINTERNAL_MDB_MONTH=${INTERNAL_MDB_MONTH}) +ADD_DEFINITIONS(-DINTERNAL_MDB_DAY=${INTERNAL_MDB_DAY}) +ADD_DEFINITIONS(-DINTERNAL_MDB_REV=${INTERNAL_MDB_REV}) + +ADD_DEFINITIONS(-DFINGER_MODULE=${FINGER_MODULE}) +ADD_DEFINITIONS(-DFINGER_TESTER_SERIAL=${FINGER_TESTER_SERIAL}) +ADD_DEFINITIONS(-DFINGER_YEAR=${FINGER_YEAR}) +ADD_DEFINITIONS(-DFINGER_MONTH=${FINGER_MONTH}) +ADD_DEFINITIONS(-DFINGER_DAY=${FINGER_DAY}) + +ADD_DEFINITIONS(-DUSING_OS_FREERTOS) + +ADD_DEFINITIONS(-DVERSION_SEDANL_Y=25) +ADD_DEFINITIONS(-DVERSION_SEDANL_M=10) +ADD_DEFINITIONS(-DVERSION_SEDANL_D=29) + +ADD_DEFINITIONS(-DVERSION_SEDANH_Y=25) +ADD_DEFINITIONS(-DVERSION_SEDANH_M=10) +ADD_DEFINITIONS(-DVERSION_SEDANH_D=29) + +ADD_DEFINITIONS(-DVERSION_LIMO_Y=25) +ADD_DEFINITIONS(-DVERSION_LIMO_M=10) +ADD_DEFINITIONS(-DVERSION_LIMO_D=29) + +ADD_DEFINITIONS(-DVERSION_SUV_Y=25) +ADD_DEFINITIONS(-DVERSION_SUV_M=10) +ADD_DEFINITIONS(-DVERSION_SUV_D=29) + +ADD_DEFINITIONS(-DVERSION_MPV_Y=25) +ADD_DEFINITIONS(-DVERSION_MPV_M=10) +ADD_DEFINITIONS(-DVERSION_MPV_D=29) + +ADD_DEFINITIONS(-DVECT_TAB_OFFSET=${VECT_TAB_OFFSET}) +ADD_DEFINITIONS(-DCMSIS_device_header="interrupt_manager.h") + +ADD_DEFINITIONS(-DFLASH_PAGE_P_SIZE=4096) +ADD_DEFINITIONS(-DFLASH_PAGE_D_SIZE=2048) +ADD_DEFINITIONS(-DCOM_INT_BIG_BUFFERS) +ADD_DEFINITIONS(-DVARIABLE_TABLE_WITH_ID) +ADD_DEFINITIONS(-DLFS_THREADSAFE=1) +ADD_DEFINITIONS(-DHALF_DUPLEX_NO_DELAY=1) +ADD_DEFINITIONS(-DACCESS_ADC=1) +ADD_DEFINITIONS(-DACCESS_RTC=1) +ADD_DEFINITIONS(-DSTORAGE_ARTERY_CHECK_CLEAR=1) + +#ADD_DEFINITIONS(-DSTORAGE_ARTERY_CHECK_WRITE_SECTORS=1) # Включение записи по секторам (Тестово, закоментированно) + +#-- Project paths, Include dirs, Sources list --------------------------------- +#ADD_FILES(SOURCES "MODULES/DeviceStartup_ARTERY_AT32F437ZMT7/ld/startup_at32f435_437.s") +include(modular.cmake) + +#-- Options -------------------------------------------------------------------- +IF (PRINTF_FLOAT STREQUAL "1") + SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -u_printf_float") +ENDIF () +IF (SCANF_FLOAT STREQUAL "1") + SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -u_scanf_float") +ENDIF () + +#-- Linker script -------------------------------------------------------------- +SET(LDSCRIPT ${CMAKE_SOURCE_DIR}/APP/FC7240_flash.ld) +SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -T ${LDSCRIPT} -Wl,-Map=${CMAKE_BINARY_DIR}/${PROJECT_NAME}.map -Wl,--print-memory-usage") + +#-- Random BuildId Generation ------------------------------------------------------------ +SET(RANDOM_BUILD_ID_GEN_FILE ${CMAKE_SOURCE_DIR}/MODULES/CmakeConfig_RandomBuildIdGenerator/version.cmake) +add_custom_target(GEN_RANDOM_BUILD_ID) +ADD_CUSTOM_COMMAND(TARGET GEN_RANDOM_BUILD_ID POST_BUILD + COMMAND ${CMAKE_COMMAND} -P ${RANDOM_BUILD_ID_GEN_FILE}) + +#-- Project linking ------------------------------------------------------------ +ADD_EXECUTABLE(${PROJECT_NAME}.elf ${SOURCES}) +TARGET_LINK_LIBRARIES(${PROJECT_NAME}.elf m) +add_dependencies(${PROJECT_NAME}.elf GEN_RANDOM_BUILD_ID) + +#-- Custom commands ------------------------------------------------------------ +ADD_CUSTOM_COMMAND(TARGET ${PROJECT_NAME}.elf POST_BUILD + COMMAND ${CMAKE_OBJCOPY} "-Oihex" ${PROJECT_NAME}.elf ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.hex + COMMAND ${CMAKE_OBJCOPY} "-Obinary" ${PROJECT_NAME}.elf ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.bin + # COMMAND ${CMAKE_OBJDUMP} "-DS" ${PROJECT_NAME}.elf > ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.dasm + COMMAND ${CMAKE_SIZE} ${PROJECT_NAME}.elf) \ No newline at end of file diff --git a/MODULES/BootJump_Flagchip_FC7240/Inc/BootJump.h b/MODULES/BootJump_Flagchip_FC7240/Inc/BootJump.h new file mode 100644 index 0000000..059a109 --- /dev/null +++ b/MODULES/BootJump_Flagchip_FC7240/Inc/BootJump.h @@ -0,0 +1,14 @@ +// +// Created by cfif on 02.11.22. +// + +#ifndef HVAC_ON_CHIP_BOOTLOADER_JUMP_H +#define HVAC_ON_CHIP_BOOTLOADER_JUMP_H + +#include "stdint.h" + +void BootFastJumpToAddress(const uint32_t address); +void BootJumpToAddress(const uint32_t address); +void Reset(); + +#endif //HVAC_ON_CHIP_BOOTLOADER_JUMP_H diff --git a/MODULES/BootJump_Flagchip_FC7240/Src/BootJump.c b/MODULES/BootJump_Flagchip_FC7240/Src/BootJump.c new file mode 100644 index 0000000..9a301a0 --- /dev/null +++ b/MODULES/BootJump_Flagchip_FC7240/Src/BootJump.c @@ -0,0 +1,193 @@ +// +// Created by cfif on 02.11.22. +// +#include CMSIS_device_header +#include "fc7xxx_driver_dma.h" +#include "fc7xxx_driver_fcuart.h" +#include "fc7240_fcuart_regs.h" +#include "fc7xxx_driver_pcc.h" +#include "fc7xxx_driver_adc.h" +#include "fc7xxx_driver_flexcan.h" +#include "fc7xxx_driver_tpu.h" + + + +typedef void (*pFunction)(void); + +#define EnablePrivilegedMode() __asm("SVC #0") + + +void DeInitAll() { + // 1. ГЛОБАЛЬНО отключаем прерывания (первое, что делаем) + __disable_irq(); + + // 2. Отключаем ВСЕ прерывания в NVIC + for (int i = 0; i < 8; i++) { // Обычно достаточно 8 банков для всех прерываний + NVIC->ICER[i] = 0xFFFFFFFF; + NVIC->ICPR[i] = 0xFFFFFFFF; + } + + // 3. Останавливаем SysTick и сбрасываем + SysTick->CTRL = 0; + SysTick->LOAD = 0; + SysTick->VAL = 0; + + // 4. Сбрасываем все pending-флаги + SCB->ICSR |= SCB_ICSR_PENDSVCLR_Msk | SCB_ICSR_PENDSTCLR_Msk; + + // 5. Отключаем периферию, которая может генерировать прерывания + + // 5.1. DMA + DMA_DeInit(DMA_INSTANCE_0); + + // 5.2. UART + for (uint8_t i = 0; i < FCUART_INSTANCE_COUNT; ++i) { + FCUART_DeInit(i); + } + + // 5.3. CAN + for (uint8_t i = 0; i < FLEXCAN_INSTANCE_COUNT; ++i) { + FLEXCAN_DeInit(i); + } + + // 5.4. ADC + for (uint8_t i = 0; i < ADC_INSTANCE_COUNT; ++i) { + ADC_DeInit(i); + } + + // 5.5. TPU + TPU_DeInit(); + + + // 5.6 RESET CLK + PCC_GenPeripheralReset(PCC_CLK_DMA0); + PCC_GenPeripheralReset(PCC_CLK_DMAMUX0); + PCC_GenPeripheralReset(PCC_CLK_FLEXCAN0); + PCC_GenPeripheralReset(PCC_CLK_FLEXCAN1); + PCC_GenPeripheralReset(PCC_CLK_FLEXCAN2); + PCC_GenPeripheralReset(PCC_CLK_FLEXCAN3); + PCC_GenPeripheralReset(PCC_CLK_ADC0); + PCC_GenPeripheralReset(PCC_CLK_ADC1); + PCC_GenPeripheralReset(PCC_CLK_FCUART0); + PCC_GenPeripheralReset(PCC_CLK_FCUART1); + PCC_GenPeripheralReset(PCC_CLK_FCUART2); + PCC_GenPeripheralReset(PCC_CLK_FCUART3); + PCC_GenPeripheralReset(PCC_CLK_FCUART4); + PCC_GenPeripheralReset(PCC_CLK_FCUART5); + PCC_GenPeripheralReset(PCC_CLK_FCUART6); + PCC_GenPeripheralReset(PCC_CLK_FCUART7); + +} + +void BootJumpToAddress(const uint32_t address) { + + // 1. ГЛОБАЛЬНО отключаем прерывания (первое, что делаем) + __disable_irq(); + + // 2. Отключаем ВСЕ прерывания в NVIC + for (int i = 0; i < 8; i++) { // Обычно достаточно 8 банков для всех прерываний + NVIC->ICER[i] = 0xFFFFFFFF; + NVIC->ICPR[i] = 0xFFFFFFFF; + } + + // 3. Останавливаем SysTick и сбрасываем + SysTick->CTRL = 0; + SysTick->LOAD = 0; + SysTick->VAL = 0; + + // 4. Сбрасываем все pending-флаги + SCB->ICSR |= SCB_ICSR_PENDSVCLR_Msk | SCB_ICSR_PENDSTCLR_Msk; + + // 5. Отключаем периферию, которая может генерировать прерывания + + // 5.1. DMA + DMA_DeInit(DMA_INSTANCE_0); + + // 5.2. UART + for (uint8_t i = 0; i < FCUART_INSTANCE_COUNT; ++i) { + FCUART_DeInit(i); + } + + // 5.3 RESET CLK + PCC_GenPeripheralReset(PCC_CLK_DMA0); + PCC_GenPeripheralReset(PCC_CLK_DMAMUX0); + PCC_GenPeripheralReset(PCC_CLK_FCUART0); + PCC_GenPeripheralReset(PCC_CLK_FCUART1); + PCC_GenPeripheralReset(PCC_CLK_FCUART2); + PCC_GenPeripheralReset(PCC_CLK_FCUART3); + PCC_GenPeripheralReset(PCC_CLK_FCUART4); + PCC_GenPeripheralReset(PCC_CLK_FCUART5); + PCC_GenPeripheralReset(PCC_CLK_FCUART6); + PCC_GenPeripheralReset(PCC_CLK_FCUART7); + + + // 6. Подготовка процессора + if (CONTROL_nPRIV_Msk & __get_CONTROL()) { + EnablePrivilegedMode(); + } + + if (CONTROL_SPSEL_Msk & __get_CONTROL()) { + __set_MSP(__get_PSP()); + __set_CONTROL(__get_CONTROL() & ~CONTROL_SPSEL_Msk); + } + + // 7. Получаем стек и точку входа приложения + uint32_t appStack = *((__IO uint32_t *) address); + pFunction appEntry = (pFunction) *((__IO uint32_t *) (address + 4)); + + // 8. Устанавливаем VTOR и стек + SCB->VTOR = address; + __set_MSP(appStack); + + // 9. Очищаем регистры, которые могут содержать данные загрузчика + __ISB(); // Instruction Synchronization Barrier + __DSB(); // Data Synchronization Barrier + + // 10. Переход БЕЗ включения прерываний! + // Приложение само должно включить прерывания после инициализации + appEntry(); + + while (1); +} + + +void BootFastJumpToAddress(const uint32_t address) { + + + // 1. Подготовка процессора + if (CONTROL_nPRIV_Msk & __get_CONTROL()) { + EnablePrivilegedMode(); + } + + if (CONTROL_SPSEL_Msk & __get_CONTROL()) { + __set_MSP(__get_PSP()); + __set_CONTROL(__get_CONTROL() & ~CONTROL_SPSEL_Msk); + } + + // 2. Получаем стек и точку входа приложения + uint32_t appStack = *((__IO uint32_t *) address); + pFunction appEntry = (pFunction) *((__IO uint32_t *) (address + 4)); + + // 3. Устанавливаем VTOR и стек + SCB->VTOR = address; + __set_MSP(appStack); + + // 4. Очищаем регистры, которые могут содержать данные загрузчика + __ISB(); // Instruction Synchronization Barrier + __DSB(); // Data Synchronization Barrier + + // 5. Переход БЕЗ включения прерываний! + // Приложение само должно включить прерывания после инициализации + appEntry(); + + while (1); +} + + +void Reset() { + +// DeInitAll(); + + NVIC_SystemReset(); + +} \ No newline at end of file diff --git a/MODULES/BootJump_Flagchip_FC7240/modular.json b/MODULES/BootJump_Flagchip_FC7240/modular.json new file mode 100644 index 0000000..71971cd --- /dev/null +++ b/MODULES/BootJump_Flagchip_FC7240/modular.json @@ -0,0 +1,10 @@ +{ + "cmake": { + "inc_dirs": [ + "Inc" + ], + "srcs": [ + "Src/**.c" + ] + } +} \ No newline at end of file diff --git a/MODULES/CmakeConfig_GCC_CortexM7/gcc_cm7.cmake b/MODULES/CmakeConfig_GCC_CortexM7/gcc_cm7.cmake new file mode 100644 index 0000000..6817c6f --- /dev/null +++ b/MODULES/CmakeConfig_GCC_CortexM7/gcc_cm7.cmake @@ -0,0 +1,50 @@ +#-- System --------------------------------------------------------------------- +SET(CMAKE_SYSTEM_NAME Generic) +SET(CMAKE_SYSTEM_PROCESSOR arm) + +#-- Toolchain ------------------------------------------------------------------ +SET(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) +IF(WIN32) + SET(TOOL_EXECUTABLE_SUFFIX ".exe") +ELSE() + SET(TOOL_EXECUTABLE_SUFFIX "") +ENDIF() +SET(CMAKE_C_COMPILER "arm-none-eabi-gcc${TOOL_EXECUTABLE_SUFFIX}") +SET(CMAKE_CXX_COMPILER "arm-none-eabi-g++${TOOL_EXECUTABLE_SUFFIX}") +SET(CMAKE_ASM_COMPILER "arm-none-eabi-gcc${TOOL_EXECUTABLE_SUFFIX}") +SET(CMAKE_OBJCOPY "arm-none-eabi-objcopy${TOOL_EXECUTABLE_SUFFIX}" CACHE STRING "objcopy tool") +SET(CMAKE_OBJDUMP "arm-none-eabi-objdump${TOOL_EXECUTABLE_SUFFIX}" CACHE STRING "objdump tool") +SET(CMAKE_SIZE "arm-none-eabi-size${TOOL_EXECUTABLE_SUFFIX}" CACHE STRING "size tool") + +#-- Common flags --------------------------------------------------------------- +SET(COMPILER_COMMON_FLAGS "-mthumb -mcpu=cortex-m7 -mfloat-abi=soft -mfpu=fpv5-sp-d16 -Wall -Wextra -ffunction-sections -fdata-sections -mlong-calls") +SET(CMAKE_C_FLAGS "${COMPILER_COMMON_FLAGS} -std=gnu99" CACHE STRING "c compiler flags") +SET(CMAKE_CXX_FLAGS "${COMPILER_COMMON_FLAGS} -std=c++11" CACHE STRING "c++ compiler flags") +SET(CMAKE_ASM_FLAGS "-mthumb -mcpu=cortex-m7" CACHE STRING "assembler compiler flags") +SET(CMAKE_EXE_LINKER_FLAGS "-mthumb -mcpu=cortex-m7 -mfloat-abi=soft -mfpu=fpv5-sp-d16 -mlong-calls -Wl,--gc-sections -specs=nosys.specs -specs=nano.specs -lgcc -lc" CACHE STRING "executable linker flags") +SET(CMAKE_MODULE_LINKER_FLAGS "-mthumb -mcpu=cortex-m7 -mfloat-abi=soft -mfpu=fpv5-sp-d16" CACHE STRING "module linker flags") +SET(CMAKE_SHARED_LINKER_FLAGS "-mthumb -mcpu=cortex-m7 -mfloat-abi=soft -mfpu=fpv5-sp-d16" CACHE STRING "shared linker flags") + +#-- Debug flags ---------------------------------------------------------------- +SET(CMAKE_C_FLAGS_DEBUG "-g -Og -DDEBUG" CACHE STRING "c compiler flags debug") +SET(CMAKE_CXX_FLAGS_DEBUG "-g -Og -DDEBUG" CACHE STRING "c++ compiler flags debug") +SET(CMAKE_ASM_FLAGS_DEBUG "-g" CACHE STRING "assembler compiler flags debug") +SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "" CACHE STRING "linker flags debug") + +#-- Release flags ---------------------------------------------------------------- +SET(CMAKE_C_FLAGS_RELEASE "-O2 " CACHE STRING "c compiler flags release") +SET(CMAKE_CXX_FLAGS_RELEASE "-O2" CACHE STRING "c++ compiler flags release") +SET(CMAKE_ASM_FLAGS_RELEASE "" CACHE STRING "assembler compiler flags release") +SET(CMAKE_EXE_LINKER_FLAGS_RELEASE "" CACHE STRING "linker flags release") + +#-- Release with debug info flags ---------------------------------------------------------------- +SET(CMAKE_C_FLAGS_RELWITHDEBINFO "-g -O2" CACHE STRING "c compiler flags release with debug info") +SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-g -O2" CACHE STRING "c++ compiler flags release with debug info") +SET(CMAKE_ASM_FLAGS_RELWITHDEBINFO "" CACHE STRING "assembler compiler flags release with debug info") +SET(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "" CACHE STRING "linker flags release with debug info") + +#-- Minimum size release flags ---------------------------------------------------------------- +SET(CMAKE_C_FLAGS_MINSIZEREL "-Os -flto -ffat-lto-objects" CACHE STRING "c compiler flags minimum size release") +SET(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -flto -ffat-lto-objects" CACHE STRING "c++ compiler flags minimum size release") +SET(CMAKE_ASM_FLAGS_MINSIZEREL "" CACHE STRING "assembler compiler flags minimum size release") +SET(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "-flto" CACHE STRING "linker flags minimum size release") diff --git a/MODULES/CmakeConfig_GCC_CortexM7/gcc_cm7f.cmake b/MODULES/CmakeConfig_GCC_CortexM7/gcc_cm7f.cmake new file mode 100644 index 0000000..d4853b0 --- /dev/null +++ b/MODULES/CmakeConfig_GCC_CortexM7/gcc_cm7f.cmake @@ -0,0 +1,50 @@ +#-- System --------------------------------------------------------------------- +SET(CMAKE_SYSTEM_NAME Generic) +SET(CMAKE_SYSTEM_PROCESSOR arm) + +#-- Toolchain ------------------------------------------------------------------ +SET(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) +IF(WIN32) + SET(TOOL_EXECUTABLE_SUFFIX ".exe") +ELSE() + SET(TOOL_EXECUTABLE_SUFFIX "") +ENDIF() +SET(CMAKE_C_COMPILER "arm-none-eabi-gcc${TOOL_EXECUTABLE_SUFFIX}") +SET(CMAKE_CXX_COMPILER "arm-none-eabi-g++${TOOL_EXECUTABLE_SUFFIX}") +SET(CMAKE_ASM_COMPILER "arm-none-eabi-gcc${TOOL_EXECUTABLE_SUFFIX}") +SET(CMAKE_OBJCOPY "arm-none-eabi-objcopy${TOOL_EXECUTABLE_SUFFIX}" CACHE STRING "objcopy tool") +SET(CMAKE_OBJDUMP "arm-none-eabi-objdump${TOOL_EXECUTABLE_SUFFIX}" CACHE STRING "objdump tool") +SET(CMAKE_SIZE "arm-none-eabi-size${TOOL_EXECUTABLE_SUFFIX}" CACHE STRING "size tool") + +#-- Common flags --------------------------------------------------------------- +SET(COMPILER_COMMON_FLAGS "-mcpu=cortex-m7 -march=armv7e-m+fp -mthumb -mfloat-abi=hard -mfpu=fpv5-sp-d16 -Wall -Wextra -ffunction-sections -fdata-sections -mlong-calls -Wno-unused-function -Wno-unused-variable -Wno-unused-parameter -fno-builtin -fno-builtin-printf") +SET(CMAKE_C_FLAGS "${COMPILER_COMMON_FLAGS} -std=gnu99" CACHE STRING "c compiler flags") +SET(CMAKE_CXX_FLAGS "${COMPILER_COMMON_FLAGS} -std=c++11" CACHE STRING "c++ compiler flags") +SET(CMAKE_ASM_FLAGS "-mthumb -mcpu=cortex-m7" CACHE STRING "assembler compiler flags") +SET(CMAKE_EXE_LINKER_FLAGS "-mcpu=cortex-m7 -march=armv7e-m+fp -mthumb -mfloat-abi=hard -mfpu=fpv5-sp-d16 -mlong-calls -Wl,--gc-sections -specs=nosys.specs -specs=nano.specs -lgcc -lc" CACHE STRING "executable linker flags") +SET(CMAKE_MODULE_LINKER_FLAGS "-mcpu=cortex-m7 -march=armv7e-m+fp -mthumb -mfloat-abi=soft -mfpu=fpv5-sp-d16" CACHE STRING "module linker flags") +SET(CMAKE_SHARED_LINKER_FLAGS "-mcpu=cortex-m7 -march=armv7e-m+fp -mthumb -mfloat-abi=hard -mfpu=fpv5-sp-d16" CACHE STRING "shared linker flags") + +#-- Debug flags ---------------------------------------------------------------- +SET(CMAKE_C_FLAGS_DEBUG "-g -Og -DDEBUG" CACHE STRING "c compiler flags debug") +SET(CMAKE_CXX_FLAGS_DEBUG "-g -Og -DDEBUG" CACHE STRING "c++ compiler flags debug") +SET(CMAKE_ASM_FLAGS_DEBUG "-g" CACHE STRING "assembler compiler flags debug") +SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "" CACHE STRING "linker flags debug") + +#-- Release flags ---------------------------------------------------------------- +SET(CMAKE_C_FLAGS_RELEASE "-O2 " CACHE STRING "c compiler flags release") +SET(CMAKE_CXX_FLAGS_RELEASE "-O2" CACHE STRING "c++ compiler flags release") +SET(CMAKE_ASM_FLAGS_RELEASE "" CACHE STRING "assembler compiler flags release") +SET(CMAKE_EXE_LINKER_FLAGS_RELEASE "" CACHE STRING "linker flags release") + +#-- Release with debug info flags ---------------------------------------------------------------- +SET(CMAKE_C_FLAGS_RELWITHDEBINFO "-g -O2" CACHE STRING "c compiler flags release with debug info") +SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-g -O2" CACHE STRING "c++ compiler flags release with debug info") +SET(CMAKE_ASM_FLAGS_RELWITHDEBINFO "" CACHE STRING "assembler compiler flags release with debug info") +SET(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "" CACHE STRING "linker flags release with debug info") + +#-- Minimum size release flags ---------------------------------------------------------------- +SET(CMAKE_C_FLAGS_MINSIZEREL "-Os -flto -ffat-lto-objects" CACHE STRING "c compiler flags minimum size release") +SET(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -flto -ffat-lto-objects" CACHE STRING "c++ compiler flags minimum size release") +SET(CMAKE_ASM_FLAGS_MINSIZEREL "" CACHE STRING "assembler compiler flags minimum size release") +SET(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "-flto" CACHE STRING "linker flags minimum size release") diff --git a/MODULES/CmakeConfig_GCC_CortexM7/modular.json b/MODULES/CmakeConfig_GCC_CortexM7/modular.json new file mode 100644 index 0000000..28b6c64 --- /dev/null +++ b/MODULES/CmakeConfig_GCC_CortexM7/modular.json @@ -0,0 +1,8 @@ +{ + "cmake": { + "inc_dirs": [ + ], + "srcs": [ + ] + } +} \ No newline at end of file diff --git a/MODULES/CmakeConfig_RandomBuildIdGenerator/VersionRandID.h b/MODULES/CmakeConfig_RandomBuildIdGenerator/VersionRandID.h new file mode 100644 index 0000000..435941f --- /dev/null +++ b/MODULES/CmakeConfig_RandomBuildIdGenerator/VersionRandID.h @@ -0,0 +1 @@ +#define VERSION_RANDOM_BUILD_IDENTIFIER "mcpAH" diff --git a/MODULES/CmakeConfig_RandomBuildIdGenerator/VersionRandID.h.in b/MODULES/CmakeConfig_RandomBuildIdGenerator/VersionRandID.h.in new file mode 100644 index 0000000..cf7f03a --- /dev/null +++ b/MODULES/CmakeConfig_RandomBuildIdGenerator/VersionRandID.h.in @@ -0,0 +1 @@ +#define VERSION_RANDOM_BUILD_IDENTIFIER "${VRS_BUILD_RND}" diff --git a/MODULES/CmakeConfig_RandomBuildIdGenerator/modular.json b/MODULES/CmakeConfig_RandomBuildIdGenerator/modular.json new file mode 100644 index 0000000..8802620 --- /dev/null +++ b/MODULES/CmakeConfig_RandomBuildIdGenerator/modular.json @@ -0,0 +1,10 @@ +{ + "cmake": { + "inc_dirs": [ + "./" + ], + "srcs": [ + + ] + } +} \ No newline at end of file diff --git a/MODULES/CmakeConfig_RandomBuildIdGenerator/version.cmake b/MODULES/CmakeConfig_RandomBuildIdGenerator/version.cmake new file mode 100755 index 0000000..649bd15 --- /dev/null +++ b/MODULES/CmakeConfig_RandomBuildIdGenerator/version.cmake @@ -0,0 +1,6 @@ +set(WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}) + +string(RANDOM VRS_BUILD_RND) +configure_file(${WORKING_DIRECTORY}/VersionRandID.h.in ${WORKING_DIRECTORY}/VersionRandID.h) + +message(STATUS "New build identifier: " \"${VRS_BUILD_RND}\") \ No newline at end of file diff --git a/MODULES/Device_Flagchip_FC7240/cm7/arm_cortex_m7_asm.h b/MODULES/Device_Flagchip_FC7240/cm7/arm_cortex_m7_asm.h new file mode 100644 index 0000000..a18c907 --- /dev/null +++ b/MODULES/Device_Flagchip_FC7240/cm7/arm_cortex_m7_asm.h @@ -0,0 +1,23 @@ +#ifndef _DEVICE_CM7_ARM_CORTEXM7_ASM_H_ +#define _DEVICE_CM7_ARM_CORTEXM7_ASM_H_ + + +/** \brief Reverse byte order in a word. + */ +#if defined (__GNUC__) || defined (__ICCARM__) || defined (__ghs__) || defined (__ARMCC_VERSION) +#define REV_BYTES_32(a, b) __asm volatile ("rev %0, %1" : "=r" (b) : "r" (a)) +#else +#define REV_BYTES_32(a, b) (b = ((a & 0xFF000000U) >> 24U) | ((a & 0xFF0000U) >> 8U) \ + | ((a & 0xFF00U) << 8U) | ((a & 0xFFU) << 24U)) +#endif + +/** \brief Enter low-power standby state + * WFI (Wait For Interrupt) makes the processor suspend execution (Clock is stopped) until an IRQ interrupts. + */ +#if defined (__GNUC__) +#define STANDBY() __asm volatile ("wfi") +#else +#define STANDBY() __asm("wfi") +#endif + +#endif diff --git a/MODULES/Device_Flagchip_FC7240/cm7/cmsis_armcc.h b/MODULES/Device_Flagchip_FC7240/cm7/cmsis_armcc.h new file mode 100644 index 0000000..4d9d064 --- /dev/null +++ b/MODULES/Device_Flagchip_FC7240/cm7/cmsis_armcc.h @@ -0,0 +1,865 @@ +/**************************************************************************//** + * @file cmsis_armcc.h + * @brief CMSIS compiler ARMCC (Arm Compiler 5) header file + * @version V5.0.4 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CMSIS_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 */ + + +/* 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 + +/* ########################### 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 the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __enable_irq(); */ + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __disable_irq(); */ + +/** + \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; +} + + +/** + \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 the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __enable_fault_irq __enable_fiq + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __disable_fault_irq __disable_fiq + + +/** + \brief Get 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 */ + + +/* ########################## 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() do {\ + __schedule_barrier();\ + __isb(0xF);\ + __schedule_barrier();\ + } while (0U) + +/** + \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() do {\ + __schedule_barrier();\ + __dsb(0xF);\ + __schedule_barrier();\ + } while (0U) + +/** + \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() do {\ + __schedule_barrier();\ + __dmb(0xF);\ + __schedule_barrier();\ + } while (0U) + + +/** + \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 */ + + +/* ################### 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)) + +#endif /* ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#endif /* __CMSIS_ARMCC_H */ diff --git a/MODULES/Device_Flagchip_FC7240/cm7/cmsis_armcc_V6.h b/MODULES/Device_Flagchip_FC7240/cm7/cmsis_armcc_V6.h new file mode 100644 index 0000000..cd13240 --- /dev/null +++ b/MODULES/Device_Flagchip_FC7240/cm7/cmsis_armcc_V6.h @@ -0,0 +1,1800 @@ +/**************************************************************************//** + * @file cmsis_armcc_V6.h + * @brief CMSIS Cortex-M Core Function/Instruction Header File + * @version V4.30 + * @date 20. October 2015 + ******************************************************************************/ +/* Copyright (c) 2009 - 2015 ARM LIMITED + + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - 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. + - 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. + ---------------------------------------------------------------------------*/ + + +#ifndef __CMSIS_ARMCC_V6_H +#define __CMSIS_ARMCC_V6_H + + +/* ########################### 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 the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__((always_inline)) __STATIC_INLINE void __enable_irq(void) +{ + __ASM volatile ("cpsie i" : : : "memory"); +} + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__((always_inline)) __STATIC_INLINE 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 + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_CONTROL(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + + +#if (__ARM_FEATURE_CMSE == 3U) +/** + \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 + */ +__attribute__((always_inline)) __STATIC_INLINE 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 + */ +__attribute__((always_inline)) __STATIC_INLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); +} + + +#if (__ARM_FEATURE_CMSE == 3U) +/** + \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 + */ +__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_CONTROL_NS(uint32_t control) +{ + __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory"); +} +#endif + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +#if (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get IPSR Register (non-secure) + \details Returns the content of the non-secure IPSR Register when in secure state. + \return IPSR Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_IPSR_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_APSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr" : "=r" (result) ); + return(result); +} + + +#if (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get APSR Register (non-secure) + \details Returns the content of the non-secure APSR Register when in secure state. + \return APSR Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_APSR_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_xPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); + return(result); +} + + +#if (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get xPSR Register (non-secure) + \details Returns the content of the non-secure xPSR Register when in secure state. + \return xPSR Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_xPSR_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_PSP(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, psp" : "=r" (result) ); + return(result); +} + + +#if (__ARM_FEATURE_CMSE == 3U) +/** + \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 + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_PSP_NS(void) +{ + register 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 + */ +__attribute__((always_inline)) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : "sp"); +} + + +#if (__ARM_FEATURE_CMSE == 3U) +/** + \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 + */ +__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : "sp"); +} +#endif + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_MSP(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, msp" : "=r" (result) ); + return(result); +} + + +#if (__ARM_FEATURE_CMSE == 3U) +/** + \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 + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_MSP_NS(void) +{ + register 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 + */ +__attribute__((always_inline)) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : "sp"); +} + + +#if (__ARM_FEATURE_CMSE == 3U) +/** + \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 + */ +__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : "sp"); +} +#endif + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask" : "=r" (result) ); + return(result); +} + + +#if (__ARM_FEATURE_CMSE == 3U) +/** + \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 + */ +__attribute__((always_inline)) __STATIC_INLINE 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 + */ +__attribute__((always_inline)) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); +} + + +#if (__ARM_FEATURE_CMSE == 3U) +/** + \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 + */ +__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_PRIMASK_NS(uint32_t priMask) +{ + __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory"); +} +#endif + + +#if ((__ARM_ARCH_7M__ == 1U) || (__ARM_ARCH_7EM__ == 1U) || (__ARM_ARCH_8M__ == 1U)) /* ToDo: ARMCC_V6: check if this is ok for cortex >=3 */ + +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__((always_inline)) __STATIC_INLINE void __enable_fault_irq(void) +{ + __ASM volatile ("cpsie f" : : : "memory"); +} + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__((always_inline)) __STATIC_INLINE 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 + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_BASEPRI(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri" : "=r" (result) ); + return(result); +} + + +#if (__ARM_FEATURE_CMSE == 3U) +/** + \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 + */ +__attribute__((always_inline)) __STATIC_INLINE 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 + */ +__attribute__((always_inline)) __STATIC_INLINE void __set_BASEPRI(uint32_t value) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (value) : "memory"); +} + + +#if (__ARM_FEATURE_CMSE == 3U) +/** + \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 + */ +__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_BASEPRI_NS(uint32_t value) +{ + __ASM volatile ("MSR basepri_ns, %0" : : "r" (value) : "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 + */ +__attribute__((always_inline)) __STATIC_INLINE void __set_BASEPRI_MAX(uint32_t value) +{ + __ASM volatile ("MSR basepri_max, %0" : : "r" (value) : "memory"); +} + + +#if (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Base Priority with condition (non_secure) + \details Assigns the given value to the non-secure Base Priority register when in secure state only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_BASEPRI_MAX_NS(uint32_t value) +{ + __ASM volatile ("MSR basepri_max_ns, %0" : : "r" (value) : "memory"); +} +#endif + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_FAULTMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + + +#if (__ARM_FEATURE_CMSE == 3U) +/** + \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 + */ +__attribute__((always_inline)) __STATIC_INLINE 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 + */ +__attribute__((always_inline)) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); +} + + +#if (__ARM_FEATURE_CMSE == 3U) +/** + \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 + */ +__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory"); +} +#endif + + +#endif /* ((__ARM_ARCH_7M__ == 1U) || (__ARM_ARCH_8M__ == 1U)) */ + + +#if (__ARM_ARCH_8M__ == 1U) + +/** + \brief Get Process Stack Pointer Limit + \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). + \return PSPLIM Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_PSPLIM(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, psplim" : "=r" (result) ); + return(result); +} + + +#if (__ARM_FEATURE_CMSE == 3U) && (__ARM_ARCH_PROFILE == 'M') /* ToDo: ARMCC_V6: check predefined macro for mainline */ +/** + \brief Get Process Stack Pointer Limit (non-secure) + \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \return PSPLIM Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_PSPLIM_NS(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Process Stack Pointer Limit + \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit) +{ + __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit)); +} + + +#if (__ARM_FEATURE_CMSE == 3U) && (__ARM_ARCH_PROFILE == 'M') /* ToDo: ARMCC_V6: check predefined macro for mainline */ +/** + \brief Set Process Stack Pointer (non-secure) + \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 + */ +__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit) +{ + __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit)); +} +#endif + + +/** + \brief Get Main Stack Pointer Limit + \details Returns the current value of the Main Stack Pointer Limit (MSPLIM). + \return MSPLIM Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_MSPLIM(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, msplim" : "=r" (result) ); + + return(result); +} + + +#if (__ARM_FEATURE_CMSE == 3U) && (__ARM_ARCH_PROFILE == 'M') /* ToDo: ARMCC_V6: check predefined macro for mainline */ +/** + \brief Get Main Stack Pointer Limit (non-secure) + \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state. + \return MSPLIM Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_MSPLIM_NS(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Main Stack Pointer Limit + \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM). + \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __set_MSPLIM(uint32_t MainStackPtrLimit) +{ + __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit)); +} + + +#if (__ARM_FEATURE_CMSE == 3U) && (__ARM_ARCH_PROFILE == 'M') /* ToDo: ARMCC_V6: check predefined macro for mainline */ +/** + \brief Set Main Stack Pointer Limit (non-secure) + \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 + */ +__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit) +{ + __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit)); +} +#endif + +#endif /* (__ARM_ARCH_8M__ == 1U) */ + + +#if ((__ARM_ARCH_7EM__ == 1U) || (__ARM_ARCH_8M__ == 1U)) /* ToDo: ARMCC_V6: check if this is ok for cortex >=4 */ + +/** + \brief Get FPSCR + \details eturns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +#define __get_FPSCR __builtin_arm_get_fpscr +#if 0 +__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_FPSCR(void) +{ +#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U) + uint32_t result; + + __ASM volatile (""); /* Empty asm statement works as a scheduling barrier */ + __ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); + __ASM volatile (""); + return(result); +#else + return(0); +#endif +} +#endif + +#if (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get FPSCR (non-secure) + \details Returns the current value of the non-secure Floating Point Status/Control register when in secure state. + \return Floating Point Status/Control register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_FPSCR_NS(void) +{ +#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U) + uint32_t result; + + __ASM volatile (""); /* Empty asm statement works as a scheduling barrier */ + __ASM volatile ("VMRS %0, fpscr_ns" : "=r" (result) ); + __ASM volatile (""); + return(result); +#else + return(0); +#endif +} +#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 + */ +#define __set_FPSCR __builtin_arm_set_fpscr +#if 0 +__attribute__((always_inline)) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr) +{ +#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U) + __ASM volatile (""); /* Empty asm statement works as a scheduling barrier */ + __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc"); + __ASM volatile (""); +#endif +} +#endif + +#if (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set FPSCR (non-secure) + \details Assigns the given value to the non-secure Floating Point Status/Control register when in secure state. + \param [in] fpscr Floating Point Status/Control value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_FPSCR_NS(uint32_t fpscr) +{ +#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U) + __ASM volatile (""); /* Empty asm statement works as a scheduling barrier */ + __ASM volatile ("VMSR fpscr_ns, %0" : : "r" (fpscr) : "vfpcc"); + __ASM volatile (""); +#endif +} +#endif + +#endif /* ((__ARM_ARCH_7EM__ == 1U) || (__ARM_ARCH_8M__ == 1U)) */ + + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ########################## 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 integer value. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV __builtin_bswap32 + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in two unsigned short values. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV16 __builtin_bswap16 /* ToDo: ARMCC_V6: check if __builtin_bswap16 could be used */ +#if 0 +__attribute__((always_inline)) __STATIC_INLINE uint32_t __REV16(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} +#endif + + +/** + \brief Reverse byte order in signed short value + \details Reverses the byte order in a signed short value with sign extension to integer. + \param [in] value Value to reverse + \return Reversed value + */ + /* ToDo: ARMCC_V6: check if __builtin_bswap16 could be used */ +__attribute__((always_inline)) __STATIC_INLINE int32_t __REVSH(int32_t value) +{ + int32_t result; + + __ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** + \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 + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + 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 + */ + /* ToDo: ARMCC_V6: check if __builtin_arm_rbit is supported */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + +#if ((__ARM_ARCH_7M__ == 1U) || (__ARM_ARCH_7EM__ == 1U) || (__ARM_ARCH_8M__ == 1U)) /* ToDo: ARMCC_V6: check if this is ok for cortex >=3 */ + __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); +#else + int32_t s = 4 /*sizeof(v)*/ * 8 - 1; /* extra shift needed at end */ + + result = value; /* r will be reversed bits of v; first get LSB of v */ + for (value >>= 1U; value; 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 + */ +#define __CLZ __builtin_clz + + +#if ((__ARM_ARCH_7M__ == 1U) || (__ARM_ARCH_7EM__ == 1U) || (__ARM_ARCH_8M__ == 1U)) /* ToDo: ARMCC_V6: check if this is ok for cortex >=3 */ + +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDREXB (uint8_t)__builtin_arm_ldrex + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDREXH (uint16_t)__builtin_arm_ldrex + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDREXW (uint32_t)__builtin_arm_ldrex + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXB (uint32_t)__builtin_arm_strex + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXH (uint32_t)__builtin_arm_strex + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXW (uint32_t)__builtin_arm_strex + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +#define __CLREX __builtin_arm_clrex + + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +/*#define __SSAT __builtin_arm_ssat*/ +#define __SSAT(ARG1,ARG2) \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT __builtin_arm_usat +#if 0 +#define __USAT(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) +#endif + + +/** + \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 + */ +__attribute__((always_inline)) __STATIC_INLINE 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) + */ +__attribute__((always_inline)) __STATIC_INLINE 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) + */ +__attribute__((always_inline)) __STATIC_INLINE 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) + */ +__attribute__((always_inline)) __STATIC_INLINE 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 + */ +__attribute__((always_inline)) __STATIC_INLINE 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 + */ +__attribute__((always_inline)) __STATIC_INLINE 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 + */ +__attribute__((always_inline)) __STATIC_INLINE void __STRT(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) ); +} + +#endif /* ((__ARM_ARCH_7M__ == 1U) || (__ARM_ARCH_7EM__ == 1U) || (__ARM_ARCH_8M__ == 1U)) */ + + +#if (__ARM_ARCH_8M__ == 1U) + +/** + \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) + */ +__attribute__((always_inline)) __STATIC_INLINE uint8_t __LDAB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) ); + 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) + */ +__attribute__((always_inline)) __STATIC_INLINE uint16_t __LDAH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) ); + 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) + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __LDA(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) ); + 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 + */ +__attribute__((always_inline)) __STATIC_INLINE void __STLB(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \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 + */ +__attribute__((always_inline)) __STATIC_INLINE void __STLH(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \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 + */ +__attribute__((always_inline)) __STATIC_INLINE void __STL(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \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 /* (__ARM_ARCH_8M__ == 1U) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if (__ARM_FEATURE_DSP == 1U) /* ToDo: ARMCC_V6: This should be ARCH >= ARMv7-M + SIMD */ + +__attribute__((always_inline)) __STATIC_INLINE 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); +} + +__attribute__((always_inline)) __STATIC_INLINE 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); +} + +__attribute__((always_inline)) __STATIC_INLINE 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); +} + +__attribute__((always_inline)) __STATIC_INLINE 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); +} + +__attribute__((always_inline)) __STATIC_INLINE 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); +} + +__attribute__((always_inline)) __STATIC_INLINE 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); +} + + +__attribute__((always_inline)) __STATIC_INLINE 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); +} + +__attribute__((always_inline)) __STATIC_INLINE 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); +} + +__attribute__((always_inline)) __STATIC_INLINE 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); +} + +__attribute__((always_inline)) __STATIC_INLINE 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); +} + +__attribute__((always_inline)) __STATIC_INLINE 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); +} + +__attribute__((always_inline)) __STATIC_INLINE 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); +} + + +__attribute__((always_inline)) __STATIC_INLINE 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); +} + +__attribute__((always_inline)) __STATIC_INLINE 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); +} + +__attribute__((always_inline)) __STATIC_INLINE 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); +} + +__attribute__((always_inline)) __STATIC_INLINE 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); +} + +__attribute__((always_inline)) __STATIC_INLINE 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); +} + +__attribute__((always_inline)) __STATIC_INLINE 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); +} + +__attribute__((always_inline)) __STATIC_INLINE 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); +} + +__attribute__((always_inline)) __STATIC_INLINE 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); +} + +__attribute__((always_inline)) __STATIC_INLINE 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); +} + +__attribute__((always_inline)) __STATIC_INLINE 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); +} + +__attribute__((always_inline)) __STATIC_INLINE 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); +} + +__attribute__((always_inline)) __STATIC_INLINE 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); +} + +__attribute__((always_inline)) __STATIC_INLINE 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); +} + +__attribute__((always_inline)) __STATIC_INLINE 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); +} + +__attribute__((always_inline)) __STATIC_INLINE 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); +} + +__attribute__((always_inline)) __STATIC_INLINE 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); +} + +__attribute__((always_inline)) __STATIC_INLINE 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); +} + +__attribute__((always_inline)) __STATIC_INLINE 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); +} + +__attribute__((always_inline)) __STATIC_INLINE 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); +} + +__attribute__((always_inline)) __STATIC_INLINE 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); +} + +__attribute__((always_inline)) __STATIC_INLINE 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); +} + +__attribute__((always_inline)) __STATIC_INLINE 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); +} + +__attribute__((always_inline)) __STATIC_INLINE 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); +} + +__attribute__((always_inline)) __STATIC_INLINE 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); +} + +__attribute__((always_inline)) __STATIC_INLINE 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); +} + +__attribute__((always_inline)) __STATIC_INLINE 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) \ +({ \ + uint32_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; \ + }) + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __UXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE 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); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __SXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE 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); +} + +__attribute__((always_inline)) __STATIC_INLINE 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); +} + +__attribute__((always_inline)) __STATIC_INLINE 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); +} + +__attribute__((always_inline)) __STATIC_INLINE 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); +} + +__attribute__((always_inline)) __STATIC_INLINE 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); +} + +__attribute__((always_inline)) __STATIC_INLINE 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); +} + +__attribute__((always_inline)) __STATIC_INLINE 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); +} + +__attribute__((always_inline)) __STATIC_INLINE 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); +} + +__attribute__((always_inline)) __STATIC_INLINE 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); +} + +__attribute__((always_inline)) __STATIC_INLINE 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); +} + +__attribute__((always_inline)) __STATIC_INLINE 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); +} + +__attribute__((always_inline)) __STATIC_INLINE 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); +} + +__attribute__((always_inline)) __STATIC_INLINE 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); +} + +__attribute__((always_inline)) __STATIC_INLINE 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); +} + +__attribute__((always_inline)) __STATIC_INLINE 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); +} + +__attribute__((always_inline)) __STATIC_INLINE 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 __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) \ +({ \ + 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; \ + }) + +__attribute__((always_inline)) __STATIC_INLINE uint32_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 == 1U) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#endif /* __CMSIS_ARMCC_V6_H */ diff --git a/MODULES/Device_Flagchip_FC7240/cm7/cmsis_armclang.h b/MODULES/Device_Flagchip_FC7240/cm7/cmsis_armclang.h new file mode 100644 index 0000000..162a400 --- /dev/null +++ b/MODULES/Device_Flagchip_FC7240/cm7/cmsis_armclang.h @@ -0,0 +1,1869 @@ +/**************************************************************************//** + * @file cmsis_armclang.h + * @brief CMSIS compiler armclang (Arm Compiler 6) header file + * @version V5.0.4 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/*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 */ + +#ifndef __ARM_COMPAT_H +#include /* Compatibility header for Arm Compiler 5 intrinsics */ +#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 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 + + +/* ########################### 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 the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __enable_irq(); see arm_compat.h */ + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __disable_irq(); see arm_compat.h */ + + +/** + \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"); +} + + +#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"); +} +#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 the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __enable_fault_irq __enable_fiq /* see arm_compat.h */ + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __disable_fault_irq __disable_fiq /* see arm_compat.h */ + + +/** + \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 */ + + +/* ########################## 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 + */ +#define __CLZ (uint8_t)__builtin_clz + + +#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) ); + 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) ); + 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) ); + 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) ); +} + + +/** + \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) ); +} + + +/** + \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) ); +} + + +/** + \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 */ + + +/* ################### 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); +} + +#if 0 +#define __PKHBT(ARG1,ARG2,ARG3) \ +({ \ + 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) \ +({ \ + 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; \ + }) +#endif + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +__STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#endif /* (__ARM_FEATURE_DSP == 1) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#endif /* __CMSIS_ARMCLANG_H */ diff --git a/MODULES/Device_Flagchip_FC7240/cm7/cmsis_compiler.h b/MODULES/Device_Flagchip_FC7240/cm7/cmsis_compiler.h new file mode 100644 index 0000000..9664d6c --- /dev/null +++ b/MODULES/Device_Flagchip_FC7240/cm7/cmsis_compiler.h @@ -0,0 +1,271 @@ +/**************************************************************************//** + * @file cmsis_compiler.h + * @brief CMSIS compiler generic header file + * @version V5.0.4 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CMSIS_COMPILER_H +#define __CMSIS_COMPILER_H + +#include + +/* + * Arm Compiler 4/5 + */ +#if defined ( __CC_ARM ) + #include "cmsis_armcc.h" + + +/* + * Arm Compiler 6 (armclang) + */ +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #include "cmsis_armclang.h" + + +/* + * GNU Compiler + */ +#elif defined ( __GNUC__ ) + #include "cmsis_gcc.h" + + +/* + * IAR Compiler + */ +#elif defined ( __ICCARM__ ) + #include "cmsis_iccarm.h" + +/* + * GHS Compiler + */ +#elif defined ( __ghs__ ) + #include "cmsis_ghs.h" + +/* + * TI Arm Compiler + */ +#elif defined ( __TI_ARM__ ) + #include + + #ifndef __ASM + #define __ASM __asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_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 + #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. + #define __RESTRICT + #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 + + +/* + * 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 + + +#else + #error Unknown compiler. +#endif + + +#endif /* __CMSIS_COMPILER_H */ + diff --git a/MODULES/Device_Flagchip_FC7240/cm7/cmsis_gcc.h b/MODULES/Device_Flagchip_FC7240/cm7/cmsis_gcc.h new file mode 100644 index 0000000..2d9db15 --- /dev/null +++ b/MODULES/Device_Flagchip_FC7240/cm7/cmsis_gcc.h @@ -0,0 +1,2085 @@ +/**************************************************************************//** + * @file cmsis_gcc.h + * @brief CMSIS compiler GCC header file + * @version V5.0.4 + * @date 09. April 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_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 + + +/* ########################### 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 the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_irq(void) +{ + __ASM volatile ("cpsie i" : : : "memory"); +} + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_irq(void) +{ + __ASM volatile ("cpsid i" : : : "memory"); +} + + +/** + \brief 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"); +} + + +#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"); +} +#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) :: "memory"); + 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) :: "memory"); + 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 the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_fault_irq(void) +{ + __ASM volatile ("cpsie f" : : : "memory"); +} + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_fault_irq(void) +{ + __ASM volatile ("cpsid f" : : : "memory"); +} + + +/** + \brief Get 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 */ + + +/* ########################## 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") + + +/** + \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") + + +/** + \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 volatile ("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 volatile ("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 volatile ("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 volatile ("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 + */ +#define __CLZ (uint8_t)__builtin_clz + + +#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 ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __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 ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __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) ); + 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) ); + 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) ); + 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) ); +} + + +/** + \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) ); +} + + +/** + \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) ); +} + + +/** + \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) ); + 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) ); + 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) ); + 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) ); + 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) ); + 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) ); + 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 */ + + +/* ################### 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); +} + +#if 0 +#define __PKHBT(ARG1,ARG2,ARG3) \ +({ \ + 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) \ +({ \ + 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; \ + }) +#endif + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +__STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#endif /* (__ARM_FEATURE_DSP == 1) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#pragma GCC diagnostic pop + +#endif /* __CMSIS_GCC_H */ diff --git a/MODULES/Device_Flagchip_FC7240/cm7/cmsis_ghs.h b/MODULES/Device_Flagchip_FC7240/cm7/cmsis_ghs.h new file mode 100644 index 0000000..390d532 --- /dev/null +++ b/MODULES/Device_Flagchip_FC7240/cm7/cmsis_ghs.h @@ -0,0 +1,104 @@ +/**************************************************************************//** + * @file cmsis_ghs.h + * @brief CMSIS compiler GHS header file + * @version V5.0.4 + * @date 09. April 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_GHS_H +#define __CMSIS_GHS_H +/* GHS MULTI intrinsic functions (e.g. __enable_interrupt()) */ +#include + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __RESTRICT + #define __RESTRICT restrict +#endif +#ifndef __INLINE + #define __INLINE inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_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 __UNALIGNED_UINT32 + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif +#ifndef __DMB + #define __DMB() __ASM("dmb") +#endif +#ifndef __DSB + #define __DSB() __ASM("dsb") +#endif +#ifndef __ISB + #define __ISB() __ASM("isb") +#endif +#ifndef __WFI + #define __WFI() __ASM("wfi") +#endif +#ifndef __WFE + #define __WFE() __ASM("wfe") +#endif +#ifndef __enable_irq + #define __enable_irq() __ASM("cpsie i") +#endif +#ifndef __disable_irq + #define __disable_irq() __ASM("cpsid i") +#endif +#ifndef __get_FPSCR + /** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ + __attribute__((always_inline)) __STATIC_INLINE uint32_t __get_FPSCR(void) + { + #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + return __VMRS(__VFP_FPSCR);; + #else + return(0U); + #endif + } +#endif + + +#endif /* __CMSIS_GHS_H */ diff --git a/MODULES/Device_Flagchip_FC7240/cm7/cmsis_iccarm.h b/MODULES/Device_Flagchip_FC7240/cm7/cmsis_iccarm.h new file mode 100644 index 0000000..11c4af0 --- /dev/null +++ b/MODULES/Device_Flagchip_FC7240/cm7/cmsis_iccarm.h @@ -0,0 +1,935 @@ +/**************************************************************************//** + * @file cmsis_iccarm.h + * @brief CMSIS compiler ICCARM (IAR Compiler for Arm) header file + * @version V5.0.7 + * @date 19. June 2018 + ******************************************************************************/ + +//------------------------------------------------------------------------------ +// +// Copyright (c) 2017-2018 IAR Systems +// +// 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 __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 + #define __RESTRICT __restrict +#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 + +#ifndef __WEAK + #if __ICCARM_V8 + #define __WEAK __attribute__((weak)) + #else + #define __WEAK _Pragma("__weak") + #endif +#endif + + +#ifndef __ICCARM_INTRINSICS_VERSION__ + #define __ICCARM_INTRINSICS_VERSION__ 0 +#endif + +#if __ICCARM_INTRINSICS_VERSION__ == 2 + + #if defined(__CLZ) + #undef __CLZ + #endif + #if defined(__REVSH) + #undef __REVSH + #endif + #if defined(__RBIT) + #undef __RBIT + #endif + #if defined(__SSAT) + #undef __SSAT + #endif + #if defined(__USAT) + #undef __USAT + #endif + + #include "iccarm_builtin.h" + + #define __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))) + #define __set_CONTROL(VALUE) (__arm_wsr("CONTROL", (VALUE))) + #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")) + #define __TZ_set_CONTROL_NS(VALUE) (__arm_wsr("CONTROL_NS", (VALUE))) + #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("RRX %0, %1" : "=r"(result) : "r" (value) : "cc"); + 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_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("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("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("LDRT %0, [%1]" : "=r" (res) : "r" (addr) : "memory"); + return res; + } + + __IAR_FT void __STRBT(uint8_t value, volatile uint8_t *addr) + { + __ASM("STRBT %1, [%0]" : : "r" (addr), "r" ((uint32_t)value) : "memory"); + } + + __IAR_FT void __STRHT(uint16_t value, volatile uint16_t *addr) + { + __ASM("STRHT %1, [%0]" : : "r" (addr), "r" ((uint32_t)value) : "memory"); + } + + __IAR_FT void __STRT(uint32_t value, volatile uint32_t *addr) + { + __ASM("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 + +#endif /* __CMSIS_ICCARM_H__ */ diff --git a/MODULES/Device_Flagchip_FC7240/cm7/cmsis_version.h b/MODULES/Device_Flagchip_FC7240/cm7/cmsis_version.h new file mode 100644 index 0000000..660f612 --- /dev/null +++ b/MODULES/Device_Flagchip_FC7240/cm7/cmsis_version.h @@ -0,0 +1,39 @@ +/**************************************************************************//** + * @file cmsis_version.h + * @brief CMSIS Core(M) Version definitions + * @version V5.0.2 + * @date 19. April 2017 + ******************************************************************************/ +/* + * Copyright (c) 2009-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CMSIS_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 ( 1U) /*!< [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/MODULES/Device_Flagchip_FC7240/cm7/core_cm7_regs.h b/MODULES/Device_Flagchip_FC7240/cm7/core_cm7_regs.h new file mode 100644 index 0000000..7ee1cd6 --- /dev/null +++ b/MODULES/Device_Flagchip_FC7240/cm7/core_cm7_regs.h @@ -0,0 +1,2417 @@ +/**************************************************************************//** + * @file core_cm7.h + * @brief CMSIS Cortex-M7 Core Peripheral Access Layer Header File + * @version V5.0.8 + * @date 04. June 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM7_H_GENERIC +#define __CORE_CM7_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M7 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM7 definitions */ +#define __CM7_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM7_CMSIS_VERSION_SUB ( __CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM7_CMSIS_VERSION ((__CM7_CMSIS_VERSION_MAIN << 16U) | \ + __CM7_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (7U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. +*/ +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM7_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM7_H_DEPENDANT +#define __CORE_CM7_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM7_REV + #define __CM7_REV 0x0000U + #warning "__CM7_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __ICACHE_PRESENT + #define __ICACHE_PRESENT 0U + #warning "__ICACHE_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DCACHE_PRESENT + #define __DCACHE_PRESENT 0U + #warning "__DCACHE_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DTCM_PRESENT + #define __DTCM_PRESENT 0U + #warning "__DTCM_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M7 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core FPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + +#define APSR_GE_Pos 16U /*!< APSR: GE Position */ +#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:1; /*!< bit: 9 Reserved */ + uint32_t ICI_IT_1:6; /*!< bit: 10..15 ICI/IT part 1 */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit */ + uint32_t ICI_IT_2:2; /*!< bit: 25..26 ICI/IT part 2 */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_ICI_IT_2_Pos 25U /*!< xPSR: ICI/IT part 2 Position */ +#define xPSR_ICI_IT_2_Msk (3UL << xPSR_ICI_IT_2_Pos) /*!< xPSR: ICI/IT part 2 Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ +#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ + +#define xPSR_ICI_IT_1_Pos 10U /*!< xPSR: ICI/IT part 1 Position */ +#define xPSR_ICI_IT_1_Msk (0x3FUL << xPSR_ICI_IT_1_Pos) /*!< xPSR: ICI/IT part 1 Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */ + uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ +#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ + +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24U]; + __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[24U]; + __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24U]; + __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24U]; + __IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56U]; + __IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHPR[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t ID_PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t ID_DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ID_AFR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t ID_MFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ID_ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[1U]; + __IM uint32_t CLIDR; /*!< Offset: 0x078 (R/ ) Cache Level ID register */ + __IM uint32_t CTR; /*!< Offset: 0x07C (R/ ) Cache Type register */ + __IM uint32_t CCSIDR; /*!< Offset: 0x080 (R/ ) Cache Size ID Register */ + __IOM uint32_t CSSELR; /*!< Offset: 0x084 (R/W) Cache Size Selection Register */ + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ + uint32_t RESERVED3[93U]; + __OM uint32_t STIR; /*!< Offset: 0x200 ( /W) Software Triggered Interrupt Register */ + uint32_t RESERVED4[15U]; + __IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 2 */ + uint32_t RESERVED5[1U]; + __OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */ + uint32_t RESERVED6[1U]; + __OM uint32_t ICIMVAU; /*!< Offset: 0x258 ( /W) I-Cache Invalidate by MVA to PoU */ + __OM uint32_t DCIMVAC; /*!< Offset: 0x25C ( /W) D-Cache Invalidate by MVA to PoC */ + __OM uint32_t DCISW; /*!< Offset: 0x260 ( /W) D-Cache Invalidate by Set-way */ + __OM uint32_t DCCMVAU; /*!< Offset: 0x264 ( /W) D-Cache Clean by MVA to PoU */ + __OM uint32_t DCCMVAC; /*!< Offset: 0x268 ( /W) D-Cache Clean by MVA to PoC */ + __OM uint32_t DCCSW; /*!< Offset: 0x26C ( /W) D-Cache Clean by Set-way */ + __OM uint32_t DCCIMVAC; /*!< Offset: 0x270 ( /W) D-Cache Clean and Invalidate by MVA to PoC */ + __OM uint32_t DCCISW; /*!< Offset: 0x274 ( /W) D-Cache Clean and Invalidate by Set-way */ + uint32_t RESERVED7[6U]; + __IOM uint32_t ITCMCR; /*!< Offset: 0x290 (R/W) Instruction Tightly-Coupled Memory Control Register */ + __IOM uint32_t DTCMCR; /*!< Offset: 0x294 (R/W) Data Tightly-Coupled Memory Control Registers */ + __IOM uint32_t AHBPCR; /*!< Offset: 0x298 (R/W) AHBP Control Register */ + __IOM uint32_t CACR; /*!< Offset: 0x29C (R/W) L1 Cache Control Register */ + __IOM uint32_t AHBSCR; /*!< Offset: 0x2A0 (R/W) AHB Slave Control Register */ + uint32_t RESERVED8[1U]; + __IOM uint32_t ABFSR; /*!< Offset: 0x2A8 (R/W) Auxiliary Bus Fault Status Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0U /*!< SCB AIRCR: VECTRESET Position */ +#define SCB_AIRCR_VECTRESET_Msk (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/) /*!< SCB AIRCR: VECTRESET Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_BP_Pos 18U /*!< SCB CCR: Branch prediction enable bit Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: Branch prediction enable bit Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: Instruction cache enable bit Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: Instruction cache enable bit Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: Cache enable bit Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: Cache enable bit Mask */ + +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0U /*!< SCB CCR: NONBASETHRDENA Position */ +#define SCB_CCR_NONBASETHRDENA_Msk (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/) /*!< SCB CCR: NONBASETHRDENA Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_SHCSR_MEMFAULTACT_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_SHCSR_MEMFAULTACT_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_SHCSR_MEMFAULTACT_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_SHCSR_MEMFAULTACT_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_SHCSR_MEMFAULTACT_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_SHCSR_MEMFAULTACT_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_LSPERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 5U) /*!< SCB CFSR (BFSR): LSPERR Position */ +#define SCB_CFSR_LSPERR_Msk (1UL << SCB_CFSR_LSPERR_Pos) /*!< SCB CFSR (BFSR): LSPERR Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/* SCB Cache Level ID Register Definitions */ +#define SCB_CLIDR_LOUU_Pos 27U /*!< SCB CLIDR: LoUU Position */ +#define SCB_CLIDR_LOUU_Msk (7UL << SCB_CLIDR_LOUU_Pos) /*!< SCB CLIDR: LoUU Mask */ + +#define SCB_CLIDR_LOC_Pos 24U /*!< SCB CLIDR: LoC Position */ +#define SCB_CLIDR_LOC_Msk (7UL << SCB_CLIDR_LOC_Pos) /*!< SCB CLIDR: LoC Mask */ + +/* SCB Cache Type Register Definitions */ +#define SCB_CTR_FORMAT_Pos 29U /*!< SCB CTR: Format Position */ +#define SCB_CTR_FORMAT_Msk (7UL << SCB_CTR_FORMAT_Pos) /*!< SCB CTR: Format Mask */ + +#define SCB_CTR_CWG_Pos 24U /*!< SCB CTR: CWG Position */ +#define SCB_CTR_CWG_Msk (0xFUL << SCB_CTR_CWG_Pos) /*!< SCB CTR: CWG Mask */ + +#define SCB_CTR_ERG_Pos 20U /*!< SCB CTR: ERG Position */ +#define SCB_CTR_ERG_Msk (0xFUL << SCB_CTR_ERG_Pos) /*!< SCB CTR: ERG Mask */ + +#define SCB_CTR_DMINLINE_Pos 16U /*!< SCB CTR: DminLine Position */ +#define SCB_CTR_DMINLINE_Msk (0xFUL << SCB_CTR_DMINLINE_Pos) /*!< SCB CTR: DminLine Mask */ + +#define SCB_CTR_IMINLINE_Pos 0U /*!< SCB CTR: ImInLine Position */ +#define SCB_CTR_IMINLINE_Msk (0xFUL /*<< SCB_CTR_IMINLINE_Pos*/) /*!< SCB CTR: ImInLine Mask */ + +/* SCB Cache Size ID Register Definitions */ +#define SCB_CCSIDR_WT_Pos 31U /*!< SCB CCSIDR: WT Position */ +#define SCB_CCSIDR_WT_Msk (1UL << SCB_CCSIDR_WT_Pos) /*!< SCB CCSIDR: WT Mask */ + +#define SCB_CCSIDR_WB_Pos 30U /*!< SCB CCSIDR: WB Position */ +#define SCB_CCSIDR_WB_Msk (1UL << SCB_CCSIDR_WB_Pos) /*!< SCB CCSIDR: WB Mask */ + +#define SCB_CCSIDR_RA_Pos 29U /*!< SCB CCSIDR: RA Position */ +#define SCB_CCSIDR_RA_Msk (1UL << SCB_CCSIDR_RA_Pos) /*!< SCB CCSIDR: RA Mask */ + +#define SCB_CCSIDR_WA_Pos 28U /*!< SCB CCSIDR: WA Position */ +#define SCB_CCSIDR_WA_Msk (1UL << SCB_CCSIDR_WA_Pos) /*!< SCB CCSIDR: WA Mask */ + +#define SCB_CCSIDR_NUMSETS_Pos 13U /*!< SCB CCSIDR: NumSets Position */ +#define SCB_CCSIDR_NUMSETS_Msk (0x7FFFUL << SCB_CCSIDR_NUMSETS_Pos) /*!< SCB CCSIDR: NumSets Mask */ + +#define SCB_CCSIDR_ASSOCIATIVITY_Pos 3U /*!< SCB CCSIDR: Associativity Position */ +#define SCB_CCSIDR_ASSOCIATIVITY_Msk (0x3FFUL << SCB_CCSIDR_ASSOCIATIVITY_Pos) /*!< SCB CCSIDR: Associativity Mask */ + +#define SCB_CCSIDR_LINESIZE_Pos 0U /*!< SCB CCSIDR: LineSize Position */ +#define SCB_CCSIDR_LINESIZE_Msk (7UL /*<< SCB_CCSIDR_LINESIZE_Pos*/) /*!< SCB CCSIDR: LineSize Mask */ + +/* SCB Cache Size Selection Register Definitions */ +#define SCB_CSSELR_LEVEL_Pos 1U /*!< SCB CSSELR: Level Position */ +#define SCB_CSSELR_LEVEL_Msk (7UL << SCB_CSSELR_LEVEL_Pos) /*!< SCB CSSELR: Level Mask */ + +#define SCB_CSSELR_IND_Pos 0U /*!< SCB CSSELR: InD Position */ +#define SCB_CSSELR_IND_Msk (1UL /*<< SCB_CSSELR_IND_Pos*/) /*!< SCB CSSELR: InD Mask */ + +/* SCB Software Triggered Interrupt Register Definitions */ +#define SCB_STIR_INTID_Pos 0U /*!< SCB STIR: INTID Position */ +#define SCB_STIR_INTID_Msk (0x1FFUL /*<< SCB_STIR_INTID_Pos*/) /*!< SCB STIR: INTID Mask */ + +/* SCB D-Cache Invalidate by Set-way Register Definitions */ +#define SCB_DCISW_WAY_Pos 30U /*!< SCB DCISW: Way Position */ +#define SCB_DCISW_WAY_Msk (3UL << SCB_DCISW_WAY_Pos) /*!< SCB DCISW: Way Mask */ + +#define SCB_DCISW_SET_Pos 5U /*!< SCB DCISW: Set Position */ +#define SCB_DCISW_SET_Msk (0x1FFUL << SCB_DCISW_SET_Pos) /*!< SCB DCISW: Set Mask */ + +/* SCB D-Cache Clean by Set-way Register Definitions */ +#define SCB_DCCSW_WAY_Pos 30U /*!< SCB DCCSW: Way Position */ +#define SCB_DCCSW_WAY_Msk (3UL << SCB_DCCSW_WAY_Pos) /*!< SCB DCCSW: Way Mask */ + +#define SCB_DCCSW_SET_Pos 5U /*!< SCB DCCSW: Set Position */ +#define SCB_DCCSW_SET_Msk (0x1FFUL << SCB_DCCSW_SET_Pos) /*!< SCB DCCSW: Set Mask */ + +/* SCB D-Cache Clean and Invalidate by Set-way Register Definitions */ +#define SCB_DCCISW_WAY_Pos 30U /*!< SCB DCCISW: Way Position */ +#define SCB_DCCISW_WAY_Msk (3UL << SCB_DCCISW_WAY_Pos) /*!< SCB DCCISW: Way Mask */ + +#define SCB_DCCISW_SET_Pos 5U /*!< SCB DCCISW: Set Position */ +#define SCB_DCCISW_SET_Msk (0x1FFUL << SCB_DCCISW_SET_Pos) /*!< SCB DCCISW: Set Mask */ + +/* Instruction Tightly-Coupled Memory Control Register Definitions */ +#define SCB_ITCMCR_SZ_Pos 3U /*!< SCB ITCMCR: SZ Position */ +#define SCB_ITCMCR_SZ_Msk (0xFUL << SCB_ITCMCR_SZ_Pos) /*!< SCB ITCMCR: SZ Mask */ + +#define SCB_ITCMCR_RETEN_Pos 2U /*!< SCB ITCMCR: RETEN Position */ +#define SCB_ITCMCR_RETEN_Msk (1UL << SCB_ITCMCR_RETEN_Pos) /*!< SCB ITCMCR: RETEN Mask */ + +#define SCB_ITCMCR_RMW_Pos 1U /*!< SCB ITCMCR: RMW Position */ +#define SCB_ITCMCR_RMW_Msk (1UL << SCB_ITCMCR_RMW_Pos) /*!< SCB ITCMCR: RMW Mask */ + +#define SCB_ITCMCR_EN_Pos 0U /*!< SCB ITCMCR: EN Position */ +#define SCB_ITCMCR_EN_Msk (1UL /*<< SCB_ITCMCR_EN_Pos*/) /*!< SCB ITCMCR: EN Mask */ + +/* Data Tightly-Coupled Memory Control Register Definitions */ +#define SCB_DTCMCR_SZ_Pos 3U /*!< SCB DTCMCR: SZ Position */ +#define SCB_DTCMCR_SZ_Msk (0xFUL << SCB_DTCMCR_SZ_Pos) /*!< SCB DTCMCR: SZ Mask */ + +#define SCB_DTCMCR_RETEN_Pos 2U /*!< SCB DTCMCR: RETEN Position */ +#define SCB_DTCMCR_RETEN_Msk (1UL << SCB_DTCMCR_RETEN_Pos) /*!< SCB DTCMCR: RETEN Mask */ + +#define SCB_DTCMCR_RMW_Pos 1U /*!< SCB DTCMCR: RMW Position */ +#define SCB_DTCMCR_RMW_Msk (1UL << SCB_DTCMCR_RMW_Pos) /*!< SCB DTCMCR: RMW Mask */ + +#define SCB_DTCMCR_EN_Pos 0U /*!< SCB DTCMCR: EN Position */ +#define SCB_DTCMCR_EN_Msk (1UL /*<< SCB_DTCMCR_EN_Pos*/) /*!< SCB DTCMCR: EN Mask */ + +/* AHBP Control Register Definitions */ +#define SCB_AHBPCR_SZ_Pos 1U /*!< SCB AHBPCR: SZ Position */ +#define SCB_AHBPCR_SZ_Msk (7UL << SCB_AHBPCR_SZ_Pos) /*!< SCB AHBPCR: SZ Mask */ + +#define SCB_AHBPCR_EN_Pos 0U /*!< SCB AHBPCR: EN Position */ +#define SCB_AHBPCR_EN_Msk (1UL /*<< SCB_AHBPCR_EN_Pos*/) /*!< SCB AHBPCR: EN Mask */ + +/* L1 Cache Control Register Definitions */ +#define SCB_CACR_FORCEWT_Pos 2U /*!< SCB CACR: FORCEWT Position */ +#define SCB_CACR_FORCEWT_Msk (1UL << SCB_CACR_FORCEWT_Pos) /*!< SCB CACR: FORCEWT Mask */ + +#define SCB_CACR_ECCEN_Pos 1U /*!< SCB CACR: ECCEN Position */ +#define SCB_CACR_ECCEN_Msk (1UL << SCB_CACR_ECCEN_Pos) /*!< SCB CACR: ECCEN Mask */ + +#define SCB_CACR_SIWT_Pos 0U /*!< SCB CACR: SIWT Position */ +#define SCB_CACR_SIWT_Msk (1UL /*<< SCB_CACR_SIWT_Pos*/) /*!< SCB CACR: SIWT Mask */ + +/* AHBS Control Register Definitions */ +#define SCB_AHBSCR_INITCOUNT_Pos 11U /*!< SCB AHBSCR: INITCOUNT Position */ +#define SCB_AHBSCR_INITCOUNT_Msk (0x1FUL << SCB_AHBPCR_INITCOUNT_Pos) /*!< SCB AHBSCR: INITCOUNT Mask */ + +#define SCB_AHBSCR_TPRI_Pos 2U /*!< SCB AHBSCR: TPRI Position */ +#define SCB_AHBSCR_TPRI_Msk (0x1FFUL << SCB_AHBPCR_TPRI_Pos) /*!< SCB AHBSCR: TPRI Mask */ + +#define SCB_AHBSCR_CTL_Pos 0U /*!< SCB AHBSCR: CTL Position*/ +#define SCB_AHBSCR_CTL_Msk (3UL /*<< SCB_AHBPCR_CTL_Pos*/) /*!< SCB AHBSCR: CTL Mask */ + +/* Auxiliary Bus Fault Status Register Definitions */ +#define SCB_ABFSR_AXIMTYPE_Pos 8U /*!< SCB ABFSR: AXIMTYPE Position*/ +#define SCB_ABFSR_AXIMTYPE_Msk (3UL << SCB_ABFSR_AXIMTYPE_Pos) /*!< SCB ABFSR: AXIMTYPE Mask */ + +#define SCB_ABFSR_EPPB_Pos 4U /*!< SCB ABFSR: EPPB Position*/ +#define SCB_ABFSR_EPPB_Msk (1UL << SCB_ABFSR_EPPB_Pos) /*!< SCB ABFSR: EPPB Mask */ + +#define SCB_ABFSR_AXIM_Pos 3U /*!< SCB ABFSR: AXIM Position*/ +#define SCB_ABFSR_AXIM_Msk (1UL << SCB_ABFSR_AXIM_Pos) /*!< SCB ABFSR: AXIM Mask */ + +#define SCB_ABFSR_AHBP_Pos 2U /*!< SCB ABFSR: AHBP Position*/ +#define SCB_ABFSR_AHBP_Msk (1UL << SCB_ABFSR_AHBP_Pos) /*!< SCB ABFSR: AHBP Mask */ + +#define SCB_ABFSR_DTCM_Pos 1U /*!< SCB ABFSR: DTCM Position*/ +#define SCB_ABFSR_DTCM_Msk (1UL << SCB_ABFSR_DTCM_Pos) /*!< SCB ABFSR: DTCM Mask */ + +#define SCB_ABFSR_ITCM_Pos 0U /*!< SCB ABFSR: ITCM Position*/ +#define SCB_ABFSR_ITCM_Msk (1UL /*<< SCB_ABFSR_ITCM_Pos*/) /*!< SCB ABFSR: ITCM Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/* Auxiliary Control Register Definitions */ +#define SCnSCB_ACTLR_DISITMATBFLUSH_Pos 12U /*!< ACTLR: DISITMATBFLUSH Position */ +#define SCnSCB_ACTLR_DISITMATBFLUSH_Msk (1UL << SCnSCB_ACTLR_DISITMATBFLUSH_Pos) /*!< ACTLR: DISITMATBFLUSH Mask */ + +#define SCnSCB_ACTLR_DISRAMODE_Pos 11U /*!< ACTLR: DISRAMODE Position */ +#define SCnSCB_ACTLR_DISRAMODE_Msk (1UL << SCnSCB_ACTLR_DISRAMODE_Pos) /*!< ACTLR: DISRAMODE Mask */ + +#define SCnSCB_ACTLR_FPEXCODIS_Pos 10U /*!< ACTLR: FPEXCODIS Position */ +#define SCnSCB_ACTLR_FPEXCODIS_Msk (1UL << SCnSCB_ACTLR_FPEXCODIS_Pos) /*!< ACTLR: FPEXCODIS Mask */ + +#define SCnSCB_ACTLR_DISFOLD_Pos 2U /*!< ACTLR: DISFOLD Position */ +#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ + +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[29U]; + __OM uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ + __IM uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ + __IOM uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ + 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 Integration Write Register Definitions */ +#define ITM_IWR_ATVALIDM_Pos 0U /*!< ITM IWR: ATVALIDM Position */ +#define ITM_IWR_ATVALIDM_Msk (1UL /*<< ITM_IWR_ATVALIDM_Pos*/) /*!< ITM IWR: ATVALIDM Mask */ + +/* ITM Integration Read Register Definitions */ +#define ITM_IRR_ATREADYM_Pos 0U /*!< ITM IRR: ATREADYM Position */ +#define ITM_IRR_ATREADYM_Msk (1UL /*<< ITM_IRR_ATREADYM_Pos*/) /*!< ITM IRR: ATREADYM Mask */ + +/* ITM Integration Mode Control Register Definitions */ +#define ITM_IMCR_INTEGRATION_Pos 0U /*!< ITM IMCR: INTEGRATION Position */ +#define ITM_IMCR_INTEGRATION_Msk (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/) /*!< ITM IMCR: INTEGRATION Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IOM uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IOM uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IOM uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IOM uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + uint32_t RESERVED3[981U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( W) Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R ) Lock Status Register */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Mask Register Definitions */ +#define DWT_MASK_MASK_Pos 0U /*!< DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16U /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12U /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9U /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8U /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7U /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5U /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0U /*!< DWT FUNCTION: FUNCTION Position */ +#define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ + __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << 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 (0x3UL << 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 (0x3UL << 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 (0x3UL << 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 */ + +/*@} end of group CMSIS_FPU */ + +/** + \ingroup MCM_register + \brief Type definitions for the MCM_register Registers + @{ + */ +/** + \brief Structure type to access the MCM Register (CoreDebug). + */ +typedef struct +{ + __IM uint32_t RESERVE; /*!< Offset: 0x000 */ + __IM uint32_t MICR; /*!< Offset: 0x004 ( / ) Core ID Register */ +} MCM_Type; + +#define MCM_MICR_COREID_Pos 16U /*!< MCM MICR: COREID Position */ +#define MCM_MICR_COREID_Msk 0x000F0000UL /*!< MCM MICR: COREID Mask */ + +/*@} end of group MCM */ + + + + +/** + \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 MCM_BASE (0xE0080000UL) /*!< MICR 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 */ +#define MCM ((MCM_Type *) MCM_BASE) /*!< MCM 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 IntMgr_SetGroupPriority//__NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ IntMgr_EnableInterrupt//__NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ IntMgr_DisableInterrupt + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority IntMgr_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 System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv7.h" + +#endif + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + uint32_t mvfr0; + + mvfr0 = SCB->MVFR0; + if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x220U) + { + return 2U; /* Double + Single precision FPU */ + } + else if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x020U) + { + return 1U; /* Single precision FPU */ + } + else + { + return 0U; /* No FPU */ + } +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ########################## Cache functions #################################### */ +/** + \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 ) + + +/** + \brief Enable I-Cache + \details Turns on I-Cache + */ +__STATIC_INLINE void SCB_EnableICache (void) +{ + #if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) + __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_INLINE 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_INLINE void SCB_InvalidateICache (void) +{ + #if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) + __DSB(); + __ISB(); + SCB->ICIALLU = 0UL; + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Enable D-Cache + \details Turns on D-Cache + */ +__STATIC_INLINE void SCB_EnableDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = 0U; /*(0U << 1U) | 0U;*/ /* 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_INLINE void SCB_DisableDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = 0U; /*(0U << 1U) | 0U;*/ /* 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_INLINE void SCB_InvalidateDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = 0U; /*(0U << 1U) | 0U;*/ /* 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_INLINE void SCB_CleanDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = 0U; /*(0U << 1U) | 0U;*/ /* 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_INLINE void SCB_CleanInvalidateDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = 0U; /*(0U << 1U) | 0U;*/ /* 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 + \param[in] addr address (aligned to 32-byte boundary) + \param[in] dsize size of memory block (in number of bytes) +*/ +__STATIC_INLINE void SCB_InvalidateDCache_by_Addr (uint32_t *addr, int32_t dsize) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + int32_t op_size = dsize; + uint32_t op_addr = (uint32_t)addr; + int32_t linesize = 32; /* in Cortex-M7 size of cache line is fixed to 8 words (32 bytes) */ + + __DSB(); + + while (op_size > 0) { + SCB->DCIMVAC = op_addr; + op_addr += (uint32_t)linesize; + op_size -= linesize; + } + + __DSB(); + __ISB(); +#else + (void)addr; + (void)dsize; + #endif +} + + +/** + \brief D-Cache Clean by address + \details Cleans D-Cache for the given address + \param[in] addr address (aligned to 32-byte boundary) + \param[in] dsize size of memory block (in number of bytes) +*/ +__STATIC_INLINE void SCB_CleanDCache_by_Addr (uint32_t *addr, int32_t dsize) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + int32_t op_size = dsize; + uint32_t op_addr = (uint32_t) addr; + int32_t linesize = 32; /* in Cortex-M7 size of cache line is fixed to 8 words (32 bytes) */ + + __DSB(); + + while (op_size > 0) { + SCB->DCCMVAC = op_addr; + op_addr += (uint32_t)linesize; + op_size -= linesize; + } + + __DSB(); + __ISB(); +#else + (void)addr; + (void)dsize; + #endif +} + + +/** + \brief D-Cache Clean and Invalidate by address + \details Cleans and invalidates D_Cache for the given address + \param[in] addr address (aligned to 32-byte boundary) + \param[in] dsize size of memory block (in number of bytes) +*/ +__STATIC_INLINE void SCB_CleanInvalidateDCache_by_Addr (uint32_t *addr, int32_t dsize) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + int32_t op_size = dsize; + uint32_t op_addr = (uint32_t) addr; + int32_t linesize = 32; /* in Cortex-M7 size of cache line is fixed to 8 words (32 bytes) */ + + __DSB(); + + while (op_size > 0) { + SCB->DCCIMVAC = op_addr; + op_addr += (uint32_t)linesize; + op_size -= linesize; + } + + __DSB(); + __ISB(); +#else + (void)addr; + (void)dsize; + #endif +} + + +/*@} end of CMSIS_Core_CacheFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM7_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/MODULES/Device_Flagchip_FC7240/cm7/mpu_armv7.h b/MODULES/Device_Flagchip_FC7240/cm7/mpu_armv7.h new file mode 100644 index 0000000..d9eedf8 --- /dev/null +++ b/MODULES/Device_Flagchip_FC7240/cm7/mpu_armv7.h @@ -0,0 +1,275 @@ +/****************************************************************************** + * @file mpu_armv7.h + * @brief CMSIS MPU API for Armv7-M MPU + * @version V5.1.2 + * @date 25. May 2020 + ******************************************************************************/ +/* + * Copyright (c) 2017-2020 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef ARM_MPU_ARMV7_H +#define ARM_MPU_ARMV7_H + +#define ARM_MPU_REGION_SIZE_32B ((uint8_t)0x04U) ///!< MPU Region Size 32 Bytes +#define ARM_MPU_REGION_SIZE_64B ((uint8_t)0x05U) ///!< MPU Region Size 64 Bytes +#define ARM_MPU_REGION_SIZE_128B ((uint8_t)0x06U) ///!< MPU Region Size 128 Bytes +#define ARM_MPU_REGION_SIZE_256B ((uint8_t)0x07U) ///!< MPU Region Size 256 Bytes +#define ARM_MPU_REGION_SIZE_512B ((uint8_t)0x08U) ///!< MPU Region Size 512 Bytes +#define ARM_MPU_REGION_SIZE_1KB ((uint8_t)0x09U) ///!< MPU Region Size 1 KByte +#define ARM_MPU_REGION_SIZE_2KB ((uint8_t)0x0AU) ///!< MPU Region Size 2 KBytes +#define ARM_MPU_REGION_SIZE_4KB ((uint8_t)0x0BU) ///!< MPU Region Size 4 KBytes +#define ARM_MPU_REGION_SIZE_8KB ((uint8_t)0x0CU) ///!< MPU Region Size 8 KBytes +#define ARM_MPU_REGION_SIZE_16KB ((uint8_t)0x0DU) ///!< MPU Region Size 16 KBytes +#define ARM_MPU_REGION_SIZE_32KB ((uint8_t)0x0EU) ///!< MPU Region Size 32 KBytes +#define ARM_MPU_REGION_SIZE_64KB ((uint8_t)0x0FU) ///!< MPU Region Size 64 KBytes +#define ARM_MPU_REGION_SIZE_128KB ((uint8_t)0x10U) ///!< MPU Region Size 128 KBytes +#define ARM_MPU_REGION_SIZE_256KB ((uint8_t)0x11U) ///!< MPU Region Size 256 KBytes +#define ARM_MPU_REGION_SIZE_512KB ((uint8_t)0x12U) ///!< MPU Region Size 512 KBytes +#define ARM_MPU_REGION_SIZE_1MB ((uint8_t)0x13U) ///!< MPU Region Size 1 MByte +#define ARM_MPU_REGION_SIZE_2MB ((uint8_t)0x14U) ///!< MPU Region Size 2 MBytes +#define ARM_MPU_REGION_SIZE_4MB ((uint8_t)0x15U) ///!< MPU Region Size 4 MBytes +#define ARM_MPU_REGION_SIZE_8MB ((uint8_t)0x16U) ///!< MPU Region Size 8 MBytes +#define ARM_MPU_REGION_SIZE_16MB ((uint8_t)0x17U) ///!< MPU Region Size 16 MBytes +#define ARM_MPU_REGION_SIZE_32MB ((uint8_t)0x18U) ///!< MPU Region Size 32 MBytes +#define ARM_MPU_REGION_SIZE_64MB ((uint8_t)0x19U) ///!< MPU Region Size 64 MBytes +#define ARM_MPU_REGION_SIZE_128MB ((uint8_t)0x1AU) ///!< MPU Region Size 128 MBytes +#define ARM_MPU_REGION_SIZE_256MB ((uint8_t)0x1BU) ///!< MPU Region Size 256 MBytes +#define ARM_MPU_REGION_SIZE_512MB ((uint8_t)0x1CU) ///!< MPU Region Size 512 MBytes +#define ARM_MPU_REGION_SIZE_1GB ((uint8_t)0x1DU) ///!< MPU Region Size 1 GByte +#define ARM_MPU_REGION_SIZE_2GB ((uint8_t)0x1EU) ///!< MPU Region Size 2 GBytes +#define ARM_MPU_REGION_SIZE_4GB ((uint8_t)0x1FU) ///!< MPU Region Size 4 GBytes + +#define ARM_MPU_AP_NONE 0U ///!< MPU Access Permission no access +#define ARM_MPU_AP_PRIV 1U ///!< MPU Access Permission privileged access only +#define ARM_MPU_AP_URO 2U ///!< MPU Access Permission unprivileged access read-only +#define ARM_MPU_AP_FULL 3U ///!< MPU Access Permission full access +#define ARM_MPU_AP_PRO 5U ///!< MPU Access Permission privileged access read-only +#define ARM_MPU_AP_RO 6U ///!< MPU Access Permission read-only access + +/** MPU Region Base Address Register Value +* +* \param Region The region to be configured, number 0 to 15. +* \param BaseAddress The base address for the region. +*/ +#define ARM_MPU_RBAR(Region, BaseAddress) \ + (((BaseAddress) & MPU_RBAR_ADDR_Msk) | \ + ((Region) & MPU_RBAR_REGION_Msk) | \ + (MPU_RBAR_VALID_Msk)) + +/** +* MPU Memory Access Attributes +* +* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral. +* \param IsShareable Region is shareable between multiple bus masters. +* \param IsCacheable Region is cacheable, i.e. its value may be kept in cache. +* \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy. +*/ +#define ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable) \ + ((((TypeExtField) << MPU_RASR_TEX_Pos) & MPU_RASR_TEX_Msk) | \ + (((IsShareable) << MPU_RASR_S_Pos) & MPU_RASR_S_Msk) | \ + (((IsCacheable) << MPU_RASR_C_Pos) & MPU_RASR_C_Msk) | \ + (((IsBufferable) << MPU_RASR_B_Pos) & MPU_RASR_B_Msk)) + +/** +* MPU Region Attribute and Size Register Value +* +* \param DisableExec Instruction access disable bit, 1= disable instruction fetches. +* \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode. +* \param AccessAttributes Memory access attribution, see \ref ARM_MPU_ACCESS_. +* \param SubRegionDisable Sub-region disable field. +* \param Size Region size of the region to be configured, for example 4K, 8K. +*/ +#define ARM_MPU_RASR_EX(DisableExec, AccessPermission, AccessAttributes, SubRegionDisable, Size) \ + ((((DisableExec) << MPU_RASR_XN_Pos) & MPU_RASR_XN_Msk) | \ + (((AccessPermission) << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) | \ + (((AccessAttributes) & (MPU_RASR_TEX_Msk | MPU_RASR_S_Msk | MPU_RASR_C_Msk | MPU_RASR_B_Msk))) | \ + (((SubRegionDisable) << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk) | \ + (((Size) << MPU_RASR_SIZE_Pos) & MPU_RASR_SIZE_Msk) | \ + (((MPU_RASR_ENABLE_Msk)))) + +/** +* MPU Region Attribute and Size Register Value +* +* \param DisableExec Instruction access disable bit, 1= disable instruction fetches. +* \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode. +* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral. +* \param IsShareable Region is shareable between multiple bus masters. +* \param IsCacheable Region is cacheable, i.e. its value may be kept in cache. +* \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy. +* \param SubRegionDisable Sub-region disable field. +* \param Size Region size of the region to be configured, for example 4K, 8K. +*/ +#define ARM_MPU_RASR(DisableExec, AccessPermission, TypeExtField, IsShareable, IsCacheable, IsBufferable, SubRegionDisable, Size) \ + ARM_MPU_RASR_EX(DisableExec, AccessPermission, ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable), SubRegionDisable, Size) + +/** +* MPU Memory Access Attribute for strongly ordered memory. +* - TEX: 000b +* - Shareable +* - Non-cacheable +* - Non-bufferable +*/ +#define ARM_MPU_ACCESS_ORDERED ARM_MPU_ACCESS_(0U, 1U, 0U, 0U) + +/** +* MPU Memory Access Attribute for device memory. +* - TEX: 000b (if shareable) or 010b (if non-shareable) +* - Shareable or non-shareable +* - Non-cacheable +* - Bufferable (if shareable) or non-bufferable (if non-shareable) +* +* \param IsShareable Configures the device memory as shareable or non-shareable. +*/ +#define ARM_MPU_ACCESS_DEVICE(IsShareable) ((IsShareable) ? ARM_MPU_ACCESS_(0U, 1U, 0U, 1U) : ARM_MPU_ACCESS_(2U, 0U, 0U, 0U)) + +/** +* MPU Memory Access Attribute for normal memory. +* - TEX: 1BBb (reflecting outer cacheability rules) +* - Shareable or non-shareable +* - Cacheable or non-cacheable (reflecting inner cacheability rules) +* - Bufferable or non-bufferable (reflecting inner cacheability rules) +* +* \param OuterCp Configures the outer cache policy. +* \param InnerCp Configures the inner cache policy. +* \param IsShareable Configures the memory as shareable or non-shareable. +*/ +#define ARM_MPU_ACCESS_NORMAL(OuterCp, InnerCp, IsShareable) ARM_MPU_ACCESS_((4U | (OuterCp)), IsShareable, ((InnerCp) >> 1U), ((InnerCp) & 1U)) + +/** +* MPU Memory Access Attribute non-cacheable policy. +*/ +#define ARM_MPU_CACHEP_NOCACHE 0U + +/** +* MPU Memory Access Attribute write-back, write and read allocate policy. +*/ +#define ARM_MPU_CACHEP_WB_WRA 1U + +/** +* MPU Memory Access Attribute write-through, no write allocate policy. +*/ +#define ARM_MPU_CACHEP_WT_NWA 2U + +/** +* MPU Memory Access Attribute write-back, no write allocate policy. +*/ +#define ARM_MPU_CACHEP_WB_NWA 3U + + +/** +* Struct for a single MPU Region +*/ +typedef struct { + uint32_t RBAR; //!< The region base address register value (RBAR) + uint32_t RASR; //!< The region attribute and size register value (RASR) \ref MPU_RASR +} ARM_MPU_Region_t; + +/** Enable the MPU. +* \param MPU_Control Default access permissions for unconfigured regions. +*/ +__STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control) +{ + __DMB(); + MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; +#endif + __DSB(); + __ISB(); +} + +/** Disable the MPU. +*/ +__STATIC_INLINE void ARM_MPU_Disable(void) +{ + __DMB(); +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; +#endif + MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk; + __DSB(); + __ISB(); +} + +/** Clear and disable the given MPU region. +* \param rnr Region number to be cleared. +*/ +__STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr) +{ + MPU->RNR = rnr; + MPU->RASR = 0U; +} + +/** Configure an MPU region. +* \param rbar Value for RBAR register. +* \param rasr Value for RASR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rbar, uint32_t rasr) +{ + MPU->RBAR = rbar; + MPU->RASR = rasr; +} + +/** Configure the given MPU region. +* \param rnr Region number to be configured. +* \param rbar Value for RBAR register. +* \param rasr Value for RASR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegionEx(uint32_t rnr, uint32_t rbar, uint32_t rasr) +{ + MPU->RNR = rnr; + MPU->RBAR = rbar; + MPU->RASR = rasr; +} + +/** Memcpy with strictly ordered memory access, e.g. used by code in ARM_MPU_Load(). +* \param dst Destination data is copied to. +* \param src Source data is copied from. +* \param len Amount of data words to be copied. +*/ +__STATIC_INLINE void ARM_MPU_OrderedMemcpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len) +{ + uint32_t i; + for (i = 0U; i < len; ++i) + { + dst[i] = src[i]; + } +} + +/** Load the given number of MPU regions from a table. +* \param table Pointer to the MPU configuration table. +* \param cnt Amount of regions to be configured. +*/ +__STATIC_INLINE void ARM_MPU_Load(ARM_MPU_Region_t const* table, uint32_t cnt) +{ + const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t)/4U; + while (cnt > MPU_TYPE_RALIASES) { + ARM_MPU_OrderedMemcpy(&(MPU->RBAR), &(table->RBAR), MPU_TYPE_RALIASES*rowWordSize); + table += MPU_TYPE_RALIASES; + cnt -= MPU_TYPE_RALIASES; + } + ARM_MPU_OrderedMemcpy(&(MPU->RBAR), &(table->RBAR), cnt*rowWordSize); +} + +#endif diff --git a/MODULES/Device_Flagchip_FC7240/compiler.h b/MODULES/Device_Flagchip_FC7240/compiler.h new file mode 100644 index 0000000..353a060 --- /dev/null +++ b/MODULES/Device_Flagchip_FC7240/compiler.h @@ -0,0 +1,54 @@ +/** + * @file compiler.h + * @author Flagchip + * @brief compiler define + * @version 0.1.1 + * @date 2024-01-12 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + */ +#ifndef DEVICE_COMPILER_H_ +#define DEVICE_COMPILER_H_ + + +#ifndef __IO + #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 */ +#endif + + +#if defined (__GNUC__) + #define INLINE __attribute__((always_inline)) inline + #define LOCAL_INLINE __attribute__((always_inline)) static inline + +#else + #define INLINE inline + #define LOCAL_INLINE static inline + +#endif + +#if (defined(__ICCARM__)) +#define STRINGIZE(x) #x +#define ALIGN(n) _Pragma(STRINGIZE(data_alignment=(n))) +#define PACKED __packed +#endif + +#if (defined(__GNUC__)) +#define ALIGN(n) __attribute__ ((aligned (n))) +#define PACKED __packed +#endif + +#if (defined(__ghs__)) +#define INLINE inline +#define LOCAL_INLINE static inline +#define ALIGN(n) __attribute__((aligned(n))) +#define PCAKED __attribute__((packed)) +#endif + +#endif /* DEVICE_COMPILER_H_ */ diff --git a/MODULES/Device_Flagchip_FC7240/device_header.h b/MODULES/Device_Flagchip_FC7240/device_header.h new file mode 100644 index 0000000..7958f8a --- /dev/null +++ b/MODULES/Device_Flagchip_FC7240/device_header.h @@ -0,0 +1,121 @@ +/** + * @file device_header.h + * @author Flagchip + * @brief include all peripheral register files + * @version 0.1.0 + * @date 2024-01-12 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + */ +#ifndef DEVICE_HEADER_H +#define DEVICE_HEADER_H + +#define __FPU_PRESENT 1 +#define __MPU_PRESENT 1 /**< Defines if an MPU is present or not */ +#define __ICACHE_PRESENT 1U +#define __DCACHE_PRESENT 1U + +#include + +#include "typedef.h" +#include "v_def.h" + +#include "fcmath.h" +#include "fcfunc.h" +#include "cmsis_compiler.h" +#include "core_cm7_regs.h" +#include "arm_cortex_m7_asm.h" +#include "mpu_armv7.h" + +#include "fc7240_acc_regs.h" +#include "fc7240_adc_regs.h" +#include "fc7240_aontimer_regs.h" +#include "fc7240_cmp_regs.h" +#include "fc7240_cmu_regs.h" +#include "fc7240_cordic_regs.h" +#include "fc7240_cpm_regs.h" +#include "fc7240_crc_regs.h" +#include "fc7240_csc0_regs.h" +#include "fc7240_dmamux_regs.h" +#include "fc7240_dma_regs.h" +#include "fc7240_eim_regs.h" +#include "fc7240_erm_regs.h" +#include "fc7240_fciic_regs.h" +#include "fc7240_fcpit_regs.h" +#include "fc7240_fcsmu_regs.h" +#include "fc7240_fcspi_regs.h" +#include "fc7240_fcuart_regs.h" +#include "fc7240_flexcan_regs.h" +#include "fc7240_fmc_regs.h" +#include "fc7240_freqm_regs.h" +#include "fc7240_ftu_regs.h" +#include "fc7240_gpio_regs.h" +#include "fc7240_intm_regs.h" +#include "fc7240_ism_regs.h" +#include "fc7240_lu_regs.h" +#include "fc7240_mam_regs.h" +#include "fc7240_mb_regs.h" +#include "fc7240_msc_regs.h" +#include "fc7240_ahb_overlay_regs.h" +#include "fc7240_pcc_regs.h" +#include "fc7240_pmc_regs.h" +#include "fc7240_port_regs.h" +#include "fc7240_ptimer_regs.h" +#include "fc7240_rgm_regs.h" +#include "fc7240_rtc_regs.h" +#include "fc7240_scg_regs.h" +#include "fc7240_scm_regs.h" +#include "fc7240_stcu_regs.h" +#include "fc7240_sec_regs.h" +#include "fc7240_sent_regs.h" +#include "fc7240_smc_regs.h" +#include "fc7240_stcu_regs.h" +#include "fc7240_tmu_regs.h" +#include "fc7240_tpu_e_regs.h" +#include "fc7240_tpu_h_regs.h" +#include "fc7240_trgsel_regs.h" +#include "fc7240_tstmp_regs.h" +#include "fc7240_wdog_regs.h" +#include "fc7240_wku_regs.h" + + +#define PFLASH_START 0x01000000U +#define PFLASH_END 0x011FFFFFU + +#define SRAM_START 0x21000000U +#define SRAM_END 0x21017FFFU + + +#define INLINE_FLASHDRIVER_RAM STD_OFF + +#define WDOG0_RECONF_LOCK_DELAY_US 100U /* 100us */ + + + +#if (defined(__ICCARM__)) + +#define PROCESS_UNUSED_VAR(var) (var) = (var); + +#elif defined __GNUC__ +#define PROCESS_UNUSED_VAR(var) (void)(var); + +#elif defined __ghs__ + +#define PROCESS_UNUSED_VAR(var) (void)(var); +#endif + + +#define FC4150F512 0x01U +#define FC4150F2M 0x02U +#define FC7300HSM 0x03U +#define FC7300CM7 0x04U +#define FC7240HOST 0x05U +#define FC7240FLEXCORE 0x06U +#define DEVICE_TYPE FC7240HOST + +#endif /* DEVICE_HEADER_H */ + +/******************************************************************************* + * EOF + ******************************************************************************/ diff --git a/MODULES/Device_Flagchip_FC7240/fc/Z_AddInclude.py b/MODULES/Device_Flagchip_FC7240/fc/Z_AddInclude.py new file mode 100644 index 0000000..dd4f6cd --- /dev/null +++ b/MODULES/Device_Flagchip_FC7240/fc/Z_AddInclude.py @@ -0,0 +1,44 @@ +import os +import re +import time + +def Add_Include(filePath,name): + fp = open(filePath) + lines = [] + for line in fp: + lines.append(line) + fp.close() + fp.close() + + del lines[:2] #delete previous define DRIVER_xxx_H + lines.insert(0, r'#ifndef _'+name.upper()+'_H_') #add in LINE+1 + lines.insert(1, r'#define _'+name.upper()+'_H_') #add in LINE+1 + lines.insert(2, r'#ifdef __cplusplus') #add in LINE+1 + lines.insert(3, r' extern "C" {') #add in LINE+1 + lines.insert(4, r'#endif') #add in LINE+1 + + lines.insert(len(lines)-1, r'#ifdef __cplusplus') #add in LINE+1 + lines.insert(len(lines)-1, r'}') #add in LINE+1 + lines.insert(len(lines)-1, r'#endif') #add in LINE+1 + + s = '\n'.join(lines) + fp = open(filePath, 'w') + fp.write(s) + fp.close() + + +if __name__=='__main__': + path = os.getcwd() + for filename in os.listdir(path): + result1 = os.path.splitext(filename) + #print(filename+', '+result1[0]+'\n') + + if result1[1] == '.h' : + oldname=filename + print(filename[7:-9]) + #time.sleep() + newname='fc7240_'+filename[7:-9].lower()+'_regs.h' + os.rename(oldname,newname); + result1 = os.path.splitext(newname) + Add_Include(newname,result1[0]) + #print(newname+'\n') diff --git a/MODULES/Device_Flagchip_FC7240/fc/fc7240_acc_regs.h b/MODULES/Device_Flagchip_FC7240/fc/fc7240_acc_regs.h new file mode 100644 index 0000000..625f7b6 --- /dev/null +++ b/MODULES/Device_Flagchip_FC7240/fc/fc7240_acc_regs.h @@ -0,0 +1,719 @@ +#ifndef _FC7240_ACC_NU_Tztufn3_REGS_H_ +#define _FC7240_ACC_NU_Tztufn3_REGS_H_ +#ifdef __cplusplus + extern "C" { +#endif + + +/* ---------------------------------------------------------------------------- + + -- ACC Peripheral Access Layer + + ---------------------------------------------------------------------------- */ + + + +/*! + + * @addtogroup ACC_Peripheral_Access_Layer ACC Peripheral Access Layer + + * @{ + + */ + + + +/** ACC - Size of Registers Arrays */ + + + +/** ACC - Register Layout Typedef */ + +#define ACC_IEBR_COUNT 2 + +#define ACC_DEBR_COUNT 2 + + + +typedef struct { + + + + uint8_t RESERVED_0[20]; + + __IO uint32_t CCR ; /* Configuration and Control Register, offset: 0x14 */ + + uint8_t RESERVED_1[96]; + + __I uint32_t CLIDR ; /* Cache Level ID Register, offset: 0x78 */ + + __I uint32_t CTR ; /* Cache Type Register, offset: 0x7C */ + + __I uint32_t CCSIDR ; /* Cache Size ID Register, offset: 0x80 */ + + __IO uint32_t CSSELR ; /* Cache Size Selection Register, offset: 0x84 */ + + uint8_t RESERVED_2[456]; + + __O uint32_t ICIALLU ; /* I-cache Invalidate All to PoU Register, offset: 0x250 */ + + uint8_t RESERVED_3[4]; + + __O uint32_t ICIMVAU ; /* I-cache Invalidate by MVA to PoU Register, offset: 0x258 */ + + __O uint32_t DCIMVAC ; /* D-cache Invalidate by MVA to PoC Register, offset: 0x25C */ + + __O uint32_t DCISW ; /* D-cache Invalidate by Set-way Register, offset: 0x260 */ + + __O uint32_t DCCMVAU ; /* D-cache Clean by MVA to PoU Register, offset: 0x264 */ + + __O uint32_t DCCMVAC ; /* D-cache Clean by MVA to PoC Register, offset: 0x268 */ + + __O uint32_t DCCSW ; /* D-cache Clean by Set-way Register, offset: 0x26C */ + + __O uint32_t DCCIMVAC ; /* D-cache Clean and Invalidate by MVA to PoC Register, offset: 0x270 */ + + __O uint32_t DCCISW ; /* D-cache Clean and Invalidate by Set-way Register, offset: 0x274 */ + + uint8_t RESERVED_4[36]; + + __IO uint32_t CACR ; /* L1 Cache Control Register, offset: 0x29C */ + + uint8_t RESERVED_5[16]; + + __IO uint32_t IEBR[ACC_IEBR_COUNT] ; /* Instruction Error Bank Register, offset: 0x2b0 */ + + __IO uint32_t DEBR[ACC_DEBR_COUNT] ; /* Data Error Bank Register, offset: 0x2b8 */ + + + +} ACC_Type, *ACC_MemMapPtr; + + + +/** Number of instances of the ACC module. */ + +#define ACC_INSTANCE_COUNT (1u) + + + +/* ACC - Peripheral instance base addresses */ + +/** Peripheral ACC base address */ + +#define ACC_BASE (0xE000ED00u) + +/** Peripheral ACC base pointer */ + +#define ACC ((ACC_Type *)ACC_BASE) + +/** Array initializer of ACC peripheral base addresses */ + +#define ACC_BASE_ADDRS {ACC_BASE} + +/** Array initializer of ACC peripheral base pointers */ + +#define ACC_BASE_PTRS {ACC} + +// need fill by yourself + +///** Number of interrupt vector arrays for the ACC module. */ + +//#define ACC_IRQS_ARR_COUNT (1u) + +///** Number of interrupt channels for the ACC module. */ + +//#define ACC_IRQS_CH_COUNT (1u) + +///** Interrupt vectors for the ACC peripheral type */ + +//#define ACC_IRQS {ACC_IRQn} + + + + + +/* ---------------------------------------------------------------------------- + + -- ACC Register Masks + + ---------------------------------------------------------------------------- */ + + + +/*! + + * @addtogroup ACC_Register_Masks ACC Register Masks + + * @{ + + */ + + + +/* CCR Bit Fields */ + +#define ACC_CCR_BP_MASK 0x40000u + +#define ACC_CCR_BP_SHIFT 18u + +#define ACC_CCR_BP_WIDTH 1u + +#define ACC_CCR_BP(x) (((uint32_t)(((uint32_t)(x))<--memcpy() + * + * \param pDest pSource u32Count wdogTriggerFunc + */ +void* FCFUNC_FcOwnMemcpy(uint8_t *pDest, const uint8_t *pSource, uint32_t u32Count, void_functype wdogTriggerFunc ) +{ + uint8_t* plocalDest; + const uint8_t* plocalSource; + uint32_t u32Index; + + /* Initialize variables */ + plocalDest = (uint8_t*)pDest; + plocalSource = (uint8_t const *)pSource; + + for (u32Index = 0u; u32Index < u32Count; u32Index++) + { + if ((u32Index & 0x3Fu) == 0u) + { + if(wdogTriggerFunc!=NULL) + { + (void)wdogTriggerFunc(); + } + } + plocalDest[u32Index] = plocalSource[u32Index]; + } + + return pDest; +} + + +void* FC_OwnMemcpy(void *pDest, const void *pSource, uint32_t u32Count) +{ + uint8_t* plocalDest; + const uint8_t* plocalSource; + uint32_t u32Index; + + /* Initialize variables */ + plocalDest = (uint8_t*)pDest; + plocalSource = (const uint8_t*)pSource; + + for (u32Index = 0u; u32Index < u32Count; u32Index++) + { + plocalDest[u32Index] = plocalSource[u32Index]; + } + + return pDest; +} + + + +void* FC_OwnMemcpyWithWdg(void *pDest, const void *pSource, uint32_t u32Count, void_functype wdogTriggerFunc, uint32_t u32CallBackCnt) +{ + uint8_t* plocalDest; + const uint8_t* plocalSource; + uint32_t u32Index; + + /* Initialize variables */ + plocalDest = (uint8_t*)pDest; + plocalSource = (const uint8_t*)pSource; + + for (u32Index = 0u; u32Index < u32Count; u32Index++) + { + if ((u32Index % u32CallBackCnt) == 0u) + { + if(wdogTriggerFunc!=NULL) + { + (void)wdogTriggerFunc(); + } + } + plocalDest[u32Index] = plocalSource[u32Index]; + } + + return pDest; +} + diff --git a/MODULES/Device_Flagchip_FC7240/fclib/fcfunc.h b/MODULES/Device_Flagchip_FC7240/fclib/fcfunc.h new file mode 100644 index 0000000..27e3590 --- /dev/null +++ b/MODULES/Device_Flagchip_FC7240/fclib/fcfunc.h @@ -0,0 +1,32 @@ +/** + * @file fc7xxx_fclib.h + * @author Flagchip + * @brief include fclib file + * @version 0.2.1 + * @date 2022-02-20 + * + * @copyright Copyright (c) 2022 Flagchip Semiconductors Co., Ltd. + * + */ +#ifndef _DEVICE_FCLIB_FCFUNC_H_ +#define _DEVICE_FCLIB_FCFUNC_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#include "typedef.h" +#include "v_def.h" + + void* FCFUNC_FcOwnMemcpy(uint8_t *pDest, const uint8_t *pSource, uint32_t u32Count, void_functype wdogTriggerFunc ); + +void* FC_OwnMemcpy(void *pDest, const void *pSource, uint32_t u32Count); + +void* FC_OwnMemcpyWithWdg(void *pDest, const void *pSource, uint32_t u32Count, void_functype wdogTriggerFunc, uint32_t u32CallBackCnt ); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/MODULES/Device_Flagchip_FC7240/fclib/fcmath.c b/MODULES/Device_Flagchip_FC7240/fclib/fcmath.c new file mode 100644 index 0000000..9d9d725 --- /dev/null +++ b/MODULES/Device_Flagchip_FC7240/fclib/fcmath.c @@ -0,0 +1,45 @@ +/** + * @file fc7xxx_fcmath.h + * @author Flagchip + * @brief include fcmath file + * @version 0.2.1 + * @date 2022-02-20 + * + * @copyright Copyright (c) 2022 Flagchip Semiconductors Co., Ltd. + * + */ +#include "fcmath.h" + + +uint32_t Fc_Power(uint32_t num, uint32_t u8Power) +{ + uint8_t u8Index; + uint32_t u32RetVal; + + u32RetVal = 1; + for(u8Index=0;u8Indexu32Val2) + return u32Val1; + else + return u32Val2; +} + + +uint32_t Fc_Min(uint32_t u32Val1, uint32_t u32Val2) +{ + if(u32Val1>u32Val2) + return u32Val2; + else + return u32Val1; +} diff --git a/MODULES/Device_Flagchip_FC7240/fclib/fcmath.h b/MODULES/Device_Flagchip_FC7240/fclib/fcmath.h new file mode 100644 index 0000000..c51d32e --- /dev/null +++ b/MODULES/Device_Flagchip_FC7240/fclib/fcmath.h @@ -0,0 +1,32 @@ +/** + * @file fc7xxx_fclib.h + * @author Flagchip + * @brief include fclib file + * @version 0.2.1 + * @date 2022-02-20 + * + * @copyright Copyright (c) 2022 Flagchip Semiconductors Co., Ltd. + * + */ +#ifndef _DEVICE_FCLIB_FCMATH_H_ +#define _DEVICE_FCLIB_FCMATH_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#include "typedef.h" + +uint32_t Fc_Power(uint32_t num, uint32_t u8Power); + +uint32_t Fc_Max(uint32_t u32Val1, uint32_t u32Val2); + +uint32_t Fc_Min(uint32_t u32Val1, uint32_t u32Val2); + + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/MODULES/Device_Flagchip_FC7240/interrupt_manager.c b/MODULES/Device_Flagchip_FC7240/interrupt_manager.c new file mode 100644 index 0000000..a261dc8 --- /dev/null +++ b/MODULES/Device_Flagchip_FC7240/interrupt_manager.c @@ -0,0 +1,159 @@ +/** + * @file interrupt_manager.c + * @author Flagchip + * @brief interrupt configuration + * @version 0.1.0 + * @date 2024-01-12 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + */ +#include "interrupt_manager.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + + +#define FC7300_PERI_VECTOR_START 16U + +#define FC7300_NVIC_PRIO_BITS 3U + + +#define __NVIC_PRIO_BITS 2U + + + +/******************************************************************************* + * Code + ******************************************************************************/ + +#if 0 +/** + * \brief Initial the interrupt table and data and bss + * + */ +void IntMgr_Init(void) +{ +#if defined ( __GNUC__ ) + extern uint32 __isr0_vector[1]; + SCB->VTOR = (uint32_t)__isr0_vector; +#elif defined (__ICCARM__) + extern uint32 __vector_table[1]; + SCB->VTOR = (uint32_t)__vector_table; +#endif +} +#endif + + +/** + * \brief enable interrupt via interrupt number + * + * \param eIrqNumber is interrupt number + */ +void IntMgr_EnableInterrupt(IRQn_Type eIrqNumber) +{ + if ((int32_t)(eIrqNumber) >= 0) + { + NVIC->ISER[(((uint32_t)eIrqNumber) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)eIrqNumber) & 0x1FUL)); + } +} + + +/** + * \brief disable interrupt via interrupt number + * + * \param eIrqNumber is interrupt number + */ +void IntMgr_DisableInterrupt(IRQn_Type eIrqNumber) +{ + if ((int32_t)(eIrqNumber) >= 0) + { + NVIC->ICER[(((uint32_t)eIrqNumber) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)eIrqNumber) & 0x1FUL)); + __DSB(); + __ISB(); + } + +} + +/** + * \brief enable global interrupt + * + */ +void IntMgr_EnableGlobalInterrupt(void) +{ + /* Enable the global interrupt*/ + __enable_irq(); + +} + +/** + * \brief disable global interrupt + * + */ +void IntMgr_DisableGlobalInterrupt(void) +{ + /* Disable the global interrupt */ + __disable_irq(); + +} + +/** + * \brief Set Priority group + * + * \param u32PriorityGroup is the group bits + */ +void IntMgr_SetGroupPriority(uint32_t u32PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (u32PriorityGroup & (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 set the interrupt service Priority + * + * \param eIrqNumber is interrupt number + * \param u8Priority is u8Priority number + */ +void IntMgr_SetPriority(IRQn_Type eIrqNumber, uint8_t u8Priority) +{ + + if ((int32_t)(eIrqNumber) >= 0) + { + NVIC->IP[((uint32_t)eIrqNumber)] = (uint8_t)(((uint32_t)u8Priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFU); + } + else + { + SCB->SHPR[(((uint32_t)eIrqNumber) & 0xFUL) - 4UL] = (uint8_t)(((uint32_t)u8Priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFU); + } +} + + +/** + * \brief get the interrupt service Priority + * + * \param eIrqNumber is interrupt number + * \return the Priority + */ +uint8_t IntMgr_GetPriority(IRQn_Type eIrqNumber) +{ + if ((int32_t)(eIrqNumber) >= 0) + { + return (((uint32_t)NVIC->IP[((uint32_t)eIrqNumber)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return (((uint32_t)SCB->SHPR[(((uint32_t)eIrqNumber) & 0xFUL) - 4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + +/******************************************************************************* + * EOF + ******************************************************************************/ diff --git a/MODULES/Device_Flagchip_FC7240/interrupt_manager.h b/MODULES/Device_Flagchip_FC7240/interrupt_manager.h new file mode 100644 index 0000000..112f323 --- /dev/null +++ b/MODULES/Device_Flagchip_FC7240/interrupt_manager.h @@ -0,0 +1,207 @@ +/** + * @file interrupt_manager.h + * @author Flagchip + * @brief interrupt configuration + * @version 0.1.0 + * @date 2024-01-12 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + */ +#if !defined(INTERRUPT_MANAGER_H) +#define INTERRUPT_MANAGER_H + + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + + +#include "device_header.h" + +typedef enum +{ + NVIC_PRIORITY_GROUP_0 = ((uint32_t)0x7), /*!< 0 bits for preemption priority, 4 bits for subpriority */ + NVIC_PRIORITY_GROUP_1 = ((uint32_t)0x6), /*!< 1 bits for preemption priority, 3 bits for subpriority */ + NVIC_PRIORITY_GROUP_2 = ((uint32_t)0x5), /*!< 2 bits for preemption priority, 2 bits for subpriority */ + NVIC_PRIORITY_GROUP_3 = ((uint32_t)0x4), /*!< 3 bits for preemption priority, 1 bits for subpriority */ + NVIC_PRIORITY_GROUP_4 = ((uint32_t)0x3) /*!< 4 bits for preemption priority, 0 bits for subpriority */ +} nvic_priority_group_type; + +typedef enum +{ + /* Auxiliary constants */ + NotAvail_IRQn = -128, /**< Not available device specific interrupt */ + + /* Core interrupts */ + NonMaskableInt_IRQn = -14, /**< Non Maskable Interrupt */ + HardFault_IRQn = -13, /**< Cortex-M4 SV Hard Fault Interrupt */ + MemoryManagement_IRQn = -12, /**< Cortex-M4 Memory Management Interrupt */ + BusFault_IRQn = -11, /**< Cortex-M4 Bus Fault Interrupt */ + UsageFault_IRQn = -10, /**< Cortex-M4 Usage Fault Interrupt */ + SVCall_IRQn = -5, /**< Cortex-M4 SV Call Interrupt */ + DebugMonitor_IRQn = -4, /**< Cortex-M4 Debug Monitor Interrupt */ + PendSV_IRQn = -2, /**< Cortex-M4 Pend SV Interrupt */ + SysTick_IRQn = -1, /**< Cortex-M4 System Tick Interrupt */ + + /* FC100 Device specific interrupts */ + DMA0_IRQn = 0U, /**< DMA channel 0 transfer complete */ + DMA1_IRQn = 1U, /**< DMA channel 1 transfer complete */ + DMA2_IRQn = 2U, /**< DMA channel 2 transfer complete */ + DMA3_IRQn = 3U, /**< DMA channel 3 transfer complete */ + DMA4_IRQn = 4U, /**< DMA channel 4 transfer complete */ + DMA5_IRQn = 5U, /**< DMA channel 5 transfer complete */ + DMA6_IRQn = 6U, /**< DMA channel 6 transfer complete */ + DMA7_IRQn = 7U, /**< DMA channel 7 transfer complete */ + DMA8_IRQn = 8U, /**< DMA channel 8 transfer complete */ + DMA9_IRQn = 9U, /**< DMA channel 9 transfer complete */ + DMA10_IRQn = 10U, /**< DMA channel 10 transfer complete */ + DMA11_IRQn = 11U, /**< DMA channel 11 transfer complete */ + DMA12_IRQn = 12U, /**< DMA channel 12 transfer complete */ + DMA13_IRQn = 13U, /**< DMA channel 13 transfer complete */ + DMA14_IRQn = 14U, /**< DMA channel 14 transfer complete */ + DMA15_IRQn = 15U, /**< DMA channel 15 transfer complete */ + DMA_Error_IRQn = 16U, /**< DMA error interrupt channels 0-63 */ + CPM_IRQn = 17U, /**< FPU etc. interrupt */ + FC_IRQn = 18U, /**< Flash Controller Command complete, time out etc. interrupt */ + LVD_LVW_IRQn = 19U, /**< HVD/LVD etc. interrupt */ + TMU_IRQn = 20U, /**< Temperature Monitor Unit interrupt */ + WDOG0_IRQn = 21U, /**< Interrupt request out before wdg0 reset out */ + WDOG1_IRQn = 22U, /**< Interrupt request out before wdg1 reset out */ + FCSMU0_IRQn = 23U, /**< Fault Control and Safety Manage Unit */ + STCU0_IRQn = 24U, /**< Safety Control Unit interrupt */ + ERM_fault_IRQn = 25U, /**< ERM single- or double-bit error interrupt */ + MAM0_IRQn = 26U, /**< Matrix Access Monitor interrupt */ + RGM_Pre_IRQn = 27U, /**< RGM pre-reset Interrupt */ + INTM0_IRQn = 28U, /**< INTM0 timeout interrupt */ + ISM0_IRQn = 29U, /**< ISM0 interrupt */ + MB_IRQn = 30U, /**< Mail Box interrupt */ + SCG_IRQn = 31U, /**< SCG bus interrupt request */ + CMU0_IRQn = 32U, /**< CMU0 interrupt */ + CMU1_IRQn = 33U, /**< CMU1 interrupt */ + CMU2_IRQn = 34U, /**< CMU2 interrupt */ + CMU3_IRQn = 35U, /**< CMU3 interrupt */ + CMU4_IRQn = 36U, /**< CMU4 interrupt */ + TSTMP0_IRQn = 37U, /**< TimerStamp0 interrupt */ + TSTMP1_IRQn = 38U, /**< TimerStamp1 interrupt */ + CORDIC_IRQn = 39U, /**< CORDIC Accelerator interrupt */ + HSM0_ERR_IRQn = 40U, /**< HSM error interrupt */ + FCPIT0_IRQn = 41U, /**< FCPIT interrupt */ + RTC_IRQn = 42U, /**< RTC alarm or seconds interrupt */ + AONTIMER_IRQn = 43U, /**< AONTIMER interrupt request */ + SWI_IRQn = 44U, /**< Software interrupt */ + FREQM_IRQn = 45U, /**< FREQM interrupt */ + ADC0_IRQn = 46U, /**< ADC0 interrupt request */ + ADC1_IRQn = 47U, /**< ADC1 interrupt request */ + PTIMER0_IRQn = 48U, /**< PTIMER0 interrupt */ + PTIMER1_IRQn = 49U, /**< PTIMER1 interrupt */ + FlexCAN0_IRQn = 50U, /**< FLEXCAN0 interrupt */ + FlexCAN1_IRQn = 51U, /**< FLEXCAN1 interrupt */ + FlexCAN2_IRQn = 52U, /**< FLEXCAN2 interrupt */ + FlexCAN3_IRQn = 53U, /**< FLEXCAN3 interrupt */ + FCIIC0_IRQn = 54U, /**< FCIIC0 Interrupt */ + FCIIC1_IRQn = 55U, /**< FCIIC1 Interrupt */ + FCSPI0_IRQn = 56U, /**< FCSPI0 Interrupt */ + FCSPI1_IRQn = 57U, /**< FCSPI1 Interrupt */ + FCSPI2_IRQn = 58U, /**< FCSPI2 Interrupt */ + FCSPI3_IRQn = 59U, /**< FCSPI3 Interrupt */ + FCSPI4_IRQn = 60U, /**< FCSPI4 Interrupt */ + FCSPI5_IRQn = 61U, /**< FCSPI5 Interrupt */ + FCUART0_IRQn = 62U, /**< FCUART0 Interrupt */ + FCUART1_IRQn = 63U, /**< FCUART1 Interrupt */ + FCUART2_IRQn = 64U, /**< FCUART2 Interrupt */ + FCUART3_IRQn = 65U, /**< FCUART3 Interrupt */ + FCUART4_IRQn = 66U, /**< FCUART4 Interrupt */ + FCUART5_IRQn = 67U, /**< FCUART5 Interrupt */ + FCUART6_IRQn = 68U, /**< FCUART6 Interrupt */ + FCUART7_IRQn = 69U, /**< FCUART7 Interrupt */ + FTU0_IRQn = 70U, /**< FTU0 all source interrupt */ + FTU1_IRQn = 71U, /**< FTU1 all source interrupt */ + FTU2_IRQn = 72U, /**< FTU2 all source interrupt */ + FTU3_IRQn = 73U, /**< FTU3 all source interrupt */ + FTU4_IRQn = 74U, /**< FTU4 all source interrupt */ + FTU5_IRQn = 75U, /**< FTU5 all source interrupt */ + FTU6_IRQn = 76U, /**< FTU6 all source interrupt */ + FTU7_IRQn = 77U, /**< FTU7 all source interrupt */ + CMP0_IRQn = 78U, /**< CMP0 all source interrupt */ + CMP1_IRQn = 79U, /**< CMP1 all source interrupt */ + PORTA_IRQn = 80U, /**< Port A pin detect interrupt */ + PORTB_IRQn = 81U, /**< Port B pin detect interrupt */ + PORTC_IRQn = 82U, /**< Port C pin detect interrupt */ + PORTD_IRQn = 83U, /**< Port D pin detect interrupt */ + PORTE_IRQn = 84U, /**< Port E pin detect interrupt */ + MSC0_IRQn = 85U, /**< MSC Interrupt */ + SENT0_IRQn = 86U, /**< SENT all interrupt (fast or slow) */ + TPU0_CH0_7_IRQn = 87U, /**< TPU0 CH0-7 interrupt */ + TPU0_CH8_15_IRQn = 88U, /**< TPU0 CH8-15 interrupt */ + TPU0_CH16_23_IRQn = 89U, /**< TPU0 CH16-23 interrupt */ + TPU0_CH24_31_IRQn = 90U, /**< TPU0 CH24-31 interrupt */ + HSM0_IRQn = 91U, /**< HSM crypto interrupt */ + IRQn_MAX = 92U +} IRQn_Type; + + + + + +/** + * \brief enable interrupt via interrupt number + * + * \param eIrqNumber is interrupt number + */ +void IntMgr_EnableInterrupt(IRQn_Type eIrqNumber); + +/** + * \brief disable interrupt via interrupt number + * + * \param eIrqNumber is interrupt number + */ +void IntMgr_DisableInterrupt(IRQn_Type eIrqNumber); + +/** + * \brief enable global interrupt + * + */ +void IntMgr_EnableGlobalInterrupt(void); + +/** + * \brief disable global interrupt + * + */ +void IntMgr_DisableGlobalInterrupt(void); + +/** + * \brief Set Priority group + * + * \param u32PriorityGroup is the group bits + */ +void IntMgr_SetGroupPriority(uint32_t u32PriorityGroup); + +/** + * \brief set the interrupt service priority + * + * \param eIrqNumber is interrupt number + * \param u8Priority is priority number + */ +void IntMgr_SetPriority(IRQn_Type eIrqNumber, uint8_t u8Priority); + +/** + * \brief get the interrupt service priority + * + * \param eIrqNumber is interrupt number + * \return the priority + */ +uint8_t IntMgr_GetPriority(IRQn_Type eIrqNumber); + + + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + + + +#endif /* INTERRUPT_MANAGER_H */ +/******************************************************************************* + * EOF + ******************************************************************************/ diff --git a/MODULES/Device_Flagchip_FC7240/modular.json b/MODULES/Device_Flagchip_FC7240/modular.json new file mode 100644 index 0000000..d398fbb --- /dev/null +++ b/MODULES/Device_Flagchip_FC7240/modular.json @@ -0,0 +1,16 @@ +{ + "cmake": { + "inc_dirs": [ + "./", + "./cm7", + "./fc", + "./fclib" + ], + "srcs": [ + "./**.c", + "./cm7/**.c", + "./fc/**.c", + "./fclib/**.c" + ] + } +} \ No newline at end of file diff --git a/MODULES/Device_Flagchip_FC7240/typedef.h b/MODULES/Device_Flagchip_FC7240/typedef.h new file mode 100644 index 0000000..ead96ba --- /dev/null +++ b/MODULES/Device_Flagchip_FC7240/typedef.h @@ -0,0 +1,37 @@ +/** + * @file typedef.h + * @author Flagchip + * @brief type defines + * @version 0.1.0 + * @date 2024-01-12 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + */ +#ifndef DEVICE_TYPEDEF_H_ +#define DEVICE_TYPEDEF_H_ + + +#include +#include +#include +#include "compiler.h" + +#define STD_ON 1 +#define STD_OFF 0 + +#ifdef NDEBUG + #define DEV_ASSERT(x) ((void)0) +#else + #define DEV_ASSERT(x) do{}while((x) != 1) +#endif + +#ifndef __IO +#define __IO volatile +#endif + +#ifndef __I +#define __I const +#endif + +#endif /* DEVICE_TYPEDEF_H_ */ diff --git a/MODULES/Device_Flagchip_FC7240/v_def.h b/MODULES/Device_Flagchip_FC7240/v_def.h new file mode 100644 index 0000000..7053b98 --- /dev/null +++ b/MODULES/Device_Flagchip_FC7240/v_def.h @@ -0,0 +1,60 @@ +/** + * @file v_def.h + * @author Flagchip + * @brief variables type define + * @version 0.1.0 + * @date 2024-01-12 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + */ +#ifndef DEVICE_V_DEF_H_ +#define DEVICE_V_DEF_H_ + +#ifndef TRUE + #define TRUE 1U +#endif + +#ifndef FALSE + #define FALSE 0U +#endif + +#ifndef NULL_PTR + #define NULL_PTR ((void*)0) +#endif + +#ifndef int8 + typedef signed char int8; +#endif + +#ifndef int16 + typedef signed short int16; +#endif + +#ifndef int32 + typedef signed int int32; +#endif + +#ifndef uint8 + typedef unsigned char uint8; +#endif + +#ifndef uint16 + typedef unsigned short uint16; +#endif + +#ifndef uint32 + typedef unsigned int uint32; +#endif + +#ifndef boolean + typedef uint8_t boolean; +#endif + +typedef void (*void_functype)(void); + +#ifdef __GUNC__ + +#endif + +#endif /* DEVICE_V_DEF_H_ */ diff --git a/MODULES/FirmwareMetadataSection/FirmwareMetadataSection.c b/MODULES/FirmwareMetadataSection/FirmwareMetadataSection.c new file mode 100644 index 0000000..f78dce8 --- /dev/null +++ b/MODULES/FirmwareMetadataSection/FirmwareMetadataSection.c @@ -0,0 +1,54 @@ +// +// Created by CFIF on 10.10.25. +// + + +#include "FirmwareMetadataSection.h" +#include "VersionRandID.h" + +#define DEF_INTERNAL_HW_YEAR INTERNAL_HW_YEAR +#define DEF_INTERNAL_HW_MONTH INTERNAL_HW_MONTH +#define DEF_INTERNAL_HW_DAY INTERNAL_HW_DAY +#define DEF_INTERNAL_HW_REV INTERNAL_HW_REV + +#define DEF_INTERNAL_SW_YEAR INTERNAL_SW_YEAR +#define DEF_INTERNAL_SW_MONTH INTERNAL_SW_MONTH +#define DEF_INTERNAL_SW_DAY INTERNAL_SW_DAY +#define DEF_INTERNAL_SW_REV INTERNAL_SW_REV + +#define DEF_INTERNAL_MDB_YEAR INTERNAL_MDB_YEAR +#define DEF_INTERNAL_MDB_MONTH INTERNAL_MDB_MONTH +#define DEF_INTERNAL_MDB_DAY INTERNAL_MDB_DAY +#define DEF_INTERNAL_MDB_REV INTERNAL_MDB_REV + +#define DEF_FINGER_MODULE FINGER_MODULE +#define DEF_FINGER_YEAR FINGER_YEAR +#define DEF_FINGER_MONTH FINGER_MONTH +#define DEF_FINGER_DAY FINGER_DAY +#define DEF_FINGER_TESTER_SERIAL FINGER_TESTER_SERIAL "_(" VERSION_RANDOM_BUILD_IDENTIFIER ")" + +volatile const uint8_t META_FW_NAME_SIZE __attribute__((section (".meta_fw_name_size"))) = sizeof(DEF_FINGER_TESTER_SERIAL) - 1; +volatile const char META_FW_NAME[sizeof(DEF_FINGER_TESTER_SERIAL) - 1] __attribute__((section (".meta_fw_name"))) = DEF_FINGER_TESTER_SERIAL; + +volatile const char META_INTERNAL_HW_YEAR __attribute__((section (".meta_internal_hw_year"))) = DEF_INTERNAL_HW_YEAR; +volatile const char META_INTERNAL_HW_MONTH __attribute__((section (".meta_internal_hw_month"))) = DEF_INTERNAL_HW_MONTH; +volatile const char META_INTERNAL_HW_DAY __attribute__((section (".meta_internal_hw_day"))) = DEF_INTERNAL_HW_DAY; +volatile const char META_INTERNAL_HW_REV __attribute__((section (".meta_internal_hw_rev"))) = DEF_INTERNAL_HW_REV; + +volatile const char META_INTERNAL_SW_YEAR __attribute__((section (".meta_internal_sw_year"))) = DEF_INTERNAL_SW_YEAR; +volatile const char META_INTERNAL_SW_MONTH __attribute__((section (".meta_internal_sw_month"))) = DEF_INTERNAL_SW_MONTH; +volatile const char META_INTERNAL_SW_DAY __attribute__((section (".meta_internal_sw_day"))) = DEF_INTERNAL_SW_DAY; +volatile const char META_INTERNAL_SW_REV __attribute__((section (".meta_internal_sw_rev"))) = DEF_INTERNAL_SW_REV; + +volatile const char META_INTERNAL_MDB_YEAR __attribute__((section (".meta_internal_mdb_year"))) = DEF_INTERNAL_MDB_YEAR; +volatile const char META_INTERNAL_MDB_MONTH __attribute__((section (".meta_internal_mdb_month"))) = DEF_INTERNAL_MDB_MONTH; +volatile const char META_INTERNAL_MDB_DAY __attribute__((section (".meta_internal_mdb_day"))) = DEF_INTERNAL_MDB_DAY; +volatile const char META_INTERNAL_MDB_REV __attribute__((section (".meta_internal_mdb_rev"))) = DEF_INTERNAL_MDB_REV; + +volatile const char META_FINGER_MODULE __attribute__((section (".meta_finger_module"))) = DEF_FINGER_MODULE; +volatile const char META_FINGER[sizeof(DEF_FINGER_TESTER_SERIAL) - 1] __attribute__((section (".meta_finger_tester_serial"))) = DEF_FINGER_TESTER_SERIAL; +volatile const char META_FINGER_YEAR __attribute__((section (".meta_finger_year"))) = DEF_FINGER_YEAR; +volatile const char META_FINGER_MONTH __attribute__((section (".meta_finger_month"))) = DEF_FINGER_MONTH; +volatile const char META_FINGER_DAY __attribute__((section (".meta_finger_day"))) = DEF_FINGER_DAY; + + diff --git a/MODULES/FirmwareMetadataSection/FirmwareMetadataSection.h b/MODULES/FirmwareMetadataSection/FirmwareMetadataSection.h new file mode 100644 index 0000000..5dda523 --- /dev/null +++ b/MODULES/FirmwareMetadataSection/FirmwareMetadataSection.h @@ -0,0 +1,24 @@ +// +// Created by CFIF on 07.12.22. +// + +#ifndef UVEOS_ON_NATION_FIRMWAREMETADATASECTION_H +#define UVEOS_ON_NATION_FIRMWAREMETADATASECTION_H + +#include "stdint.h" + +#define ADR_META_BOOT (0x01000000 + (64 * 1024) - 256) +#define ADR_META_MAIN (0x01000000 + ((64 + 704) * 1024) - 256) + +#define ADR_META_MAPPED_BOOT (0x01100000 + (64 * 1024) - 256) +#define ADR_META_MAPPED_MAIN (0x01100000 + ((64 + 704) * 1024) - 256) + +extern volatile const uint32_t META_FW_CRC; + +extern volatile const uint8_t META_FW_NAME_SIZE; +extern volatile const char META_FW_NAME[]; + +extern volatile const uint8_t META_HW_NAME_SIZE; +extern volatile const char META_HW_NAME[]; + +#endif //UVEOS_ON_NATION_FIRMWAREMETADATASECTION_H diff --git a/MODULES/FirmwareMetadataSection/modular.json b/MODULES/FirmwareMetadataSection/modular.json new file mode 100644 index 0000000..5017ac6 --- /dev/null +++ b/MODULES/FirmwareMetadataSection/modular.json @@ -0,0 +1,10 @@ +{ + "cmake": { + "inc_dirs": [ + "./" + ], + "srcs": [ + "./*.c" + ] + } +} \ No newline at end of file diff --git a/MODULES/HwA_Flagchip_FC7240/Inc/HwA_adc.h b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_adc.h new file mode 100644 index 0000000..328e643 --- /dev/null +++ b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_adc.h @@ -0,0 +1,1537 @@ +/** + * @file HwA_adc.h + * @author Flagchip0126 + * @brief Hardware access layer for ADC + * @version 0.1.0 + * @date 2024-01-15 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-01-15 Flagchip0126 N/A First version for FC7240 + ******************************************************************************** */ + +#ifndef _HWA_ADC_H_ +#define _HWA_ADC_H_ + +#include "device_header.h" + +/** + * @defgroup HwA_adc + * @ingroup fc7xxx_driver_adc + * @{ + */ + +/** + * @brief Select the ADC Resolution + * + */ +typedef enum +{ + ADC_RESOLUTION_12_BIT = 0U, /*!< 12 bit resolution */ + ADC_RESOLUTION_10_BIT = 1U, /*!< 10 bit resolution */ + ADC_RESOLUTION_8_BIT = 2U /*!< 8 bit resolution */ +} ADC_ResolutionType; + +/** + * @brief Select the ADC result alignment + * + */ +typedef enum +{ + ADC_ALIGN_RIGHT = 0U, /*!< ADC result is aligned in right */ + ADC_ALIGN_LEFT = 1U /*!< ADC result is aligned in left */ +} ADC_AlignType; + +/** + * @brief Select the ADC trigger mode + * + * @note This option is only valid in ADC single sequence mode and ADC continuous mode. + * In ADC discontinuous mode, the ADC trigger mode is fixed as ADC_TRIGMODE_RISING_EDGE + * + */ +typedef enum +{ + ADC_TRIGMODE_SW = 0U, /*!< ADC is triggered by software */ + ADC_TRIGMODE_RISING_EDGE = 1U, /*!< ADC is triggered by hardware trigger on rising edge */ + ADC_TRIGMODE_FALLING_EDGE = 2U, /*!< ADC is triggered by hardware trigger on falling edge */ + ADC_TRIGMODE_BOTH_EDGE = 3U, /*!< ADC is triggered by hardware trigger on both edges */ + ADC_TRIGMODE_HIGH_VOLTAGE = 4U, /*!< ADC is triggered when hardware trigger is high voltage */ + ADC_TRIGMODE_LOW_VOLTAGE = 5U /*!< ADC is triggered when hardware trigger is low voltage */ +} ADC_TrigModeType; + +/** + * @brief Select the ADC sequence mode + * + */ +typedef enum +{ + ADC_SEQMODE_SINGLE = 0U, /*!< ADC single sequence mode */ + ADC_SEQMODE_CONTINUOUS = 1U, /*!< ADC continuous mode */ + ADC_SEQMODE_DISCONTINUOUS_0 = 2U, /*!< ADC discontinuous 0 mode */ + ADC_SEQMODE_DISCONTINUOUS_1 = 3U /*!< ADC discontinuous 1 mode */ +} ADC_SeqModeType; + +/** + * @brief Select the ADC overrun management mode + * + * To select whether the old data are preserved or overwritten by the new data when ADC + * is overrun (The FIFO is full when new convertion result comes) + * + */ +typedef enum +{ + ADC_OVERRUN_MODE_PRESERVE = 0U, /*!< old data are preserved when ADC is overrun */ + ADC_OVERRUN_MODE_OVERWRITE = 1U /*!< old data are overwritten when ADC is overrun */ +} ADC_OvrModeType; + +/** + * @brief Select the ADC voltage reference source + * + */ +typedef enum +{ + ADC_REF_INTERNAL = 0U, /*!< select the internal voltage reference */ + ADC_REF_EXTERNAL = 1U /*!< select the external voltage reference */ +} ADC_RefType; + +/** + * @brief Select the priority of Trigger Latch Unit + * + */ +typedef enum +{ + TRG_LATCH_UNIT_PRI_ROUND_ROBIN = 0U, /*!< select the round robin scheduling priority */ + TRG_LATCH_UNIT_PRI_FIX = 1U /*!< select the fixed priority(0>1>2>3) */ +} ADC_TrgLatchUnitPri; + +/** + * @brief Select the ADC hardware average samples + * + */ +typedef enum +{ + ADC_AVERAGE_4 = 0U, /*!< result average by 4 samples */ + ADC_AVERAGE_8 = 1U, /*!< result average by 8 samples */ + ADC_AVERAGE_16 = 2U, /*!< result average by 16 samples */ + ADC_AVERAGE_32 = 3U /*!< result average by 32 samples */ +} ADC_AverageType; + +/** + * @brief Set the ADC clock divider + * + * @note ADC clock divider is not available in FC4150F512K + * + */ +typedef enum +{ + ADC_CLOCK_DIV_1 = 0U, + ADC_CLOCK_DIV_2 = 1U, + ADC_CLOCK_DIV_4 = 2U, + ADC_CLOCK_DIV_8 = 3U +} ADC_ClockDivideType; + +/** + * @brief The trigger source of the ADC instance + * + * @note In ADC discontinuous 1 mode, the trigger source is from Ptimer + * In ADC single and continuous mode, if hardware trigger is enabled, the trigger + * source is from TRGSEL + * + */ +typedef enum +{ + ADC_TRIGSRC_PTIMER = 0U, /* Trigger source from PTIMER/TRGSEL with Ptimer */ + ADC_TRIGSRC_TRGSEL = 2U, /* Trigger source from TRGSEL */ + ADC_TRIGSRC_TRIG_LATCH_UNIT = 3U /* Trigger source from LATCH UNIT */ +} ADC_TrigSrcType; + +/** + * @brief Select the channel compare mode + * + * Select whether the channel compare is enabled on all channels or on the single + * selected channel + * + */ +typedef enum +{ + ADC_CMP_CHANNEL_ALL = 0U, /*!< Compare enabled in all channels */ + ADC_CMP_CHANNEL_SINGLE = 1U /*!< Compare enabled in the specified channel */ +} ADC_CmpChannelType; + +/** + * @brief Check whether the conversion result is in the comparing range + * + * @param pAdc the base address of the ADC instance + * @return true the conversion result is in the comparing range + * @return false the conversion result is not in the comparing range + */ +LOCAL_INLINE bool ADC_HWA_GetCompareFlag(const ADC_Type *const pAdc) +{ + uint32_t u32TmpVal = pAdc->INT_STATUS; + u32TmpVal = (u32TmpVal & ADC_INT_STATUS_ACMP_MASK) >> ADC_INT_STATUS_ACMP_SHIFT; + + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Clear the compare flag + * + * @param pAdc the base address of the ADC instance + */ +LOCAL_INLINE void ADC_HWA_ClearCompareFlag(ADC_Type *const pAdc) +{ + pAdc->INT_STATUS = ADC_INT_STATUS_ACMP(1U); +} + +/** + * @brief Get the overrrun status of the ADC instance + * + * @param pAdc the base address of the ADC instance + * @return true the ADC is in overrun status + * @return false the ADC is not overrun + */ +LOCAL_INLINE bool ADC_HWA_GetOverRun(const ADC_Type *const pAdc) +{ + uint32_t u32TmpVal = pAdc->INT_STATUS; + u32TmpVal = (u32TmpVal & ADC_INT_STATUS_OVR_MASK) >> ADC_INT_STATUS_OVR_SHIFT; + + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Clear the overrun flag of the ADC instance + * + * @param pAdc the base address of the ADC instance + */ +LOCAL_INLINE void ADC_HWA_ClearOverRun(ADC_Type *const pAdc) +{ + pAdc->INT_STATUS = ADC_INT_STATUS_OVR(1U); +} + +/** + * @brief Check whether the ADC conversion sequence is finished + * + * @param pAdc the base address of the ADC instance + * @return true the ADC conversion sequence is finished + * @return false the ADC conversion sequence is unfinished + */ +LOCAL_INLINE bool ADC_HWA_GetEndOfSequence(const ADC_Type *const pAdc) +{ + uint32_t u32TmpVal = pAdc->INT_STATUS; + u32TmpVal = (u32TmpVal & ADC_INT_STATUS_EOSEQ_MASK) >> ADC_INT_STATUS_EOSEQ_SHIFT; + + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Clear the ADC conversion sequence complete flag + * + * @param pAdc the base address of the ADC instance + */ +LOCAL_INLINE void ADC_HWA_ClearEndOfSequence(ADC_Type *const pAdc) +{ + pAdc->INT_STATUS = ADC_INT_STATUS_EOSEQ(1U); +} + +/** + * @brief Check whether the current ADC conversion is finished + * + * @param pAdc the base address of the ADC instance + * @return true the current ADC conversion is finished + * @return false the current ADC conversion is unfinished + */ +LOCAL_INLINE bool ADC_HWA_GetEndOfConversion(const ADC_Type *const pAdc) +{ + uint32_t u32TmpVal = pAdc->INT_STATUS; + u32TmpVal = (u32TmpVal & ADC_INT_STATUS_EOC_MASK) >> ADC_INT_STATUS_EOC_SHIFT; + + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Clear the ADC single conversion complete flag + * + * @param pAdc the base address of the ADC instance + */ +LOCAL_INLINE void ADC_HWA_ClearEndOfConversion(ADC_Type *const pAdc) +{ + pAdc->INT_STATUS = ADC_INT_STATUS_EOC(1U); +} + +/** + * @brief Check whether the sampling phase of the current ADC conversion is finished + * + * @param pAdc the base address of the ADC instance + * @return true the sampling phase of the ADC conversion is finished + * @return false the sampling phase of the ADC conversion is unfinished + */ +LOCAL_INLINE bool ADC_HWA_GetEndOfSample(const ADC_Type *const pAdc) +{ + uint32_t u32TmpVal = pAdc->INT_STATUS; + u32TmpVal = (u32TmpVal & ADC_INT_STATUS_EOSMP_MASK) >> ADC_INT_STATUS_EOSMP_SHIFT; + + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Clear the ADC sampling complete flag + * + * @param pAdc the base address of the ADC instance + */ +LOCAL_INLINE void ADC_HWA_ClearEndOfSample(ADC_Type *const pAdc) +{ + pAdc->INT_STATUS = ADC_INT_STATUS_EOSMP(1U); +} + +/** + * @brief Check whether the data quantity in the FIFO is greater than watermark + * + * @param pAdc the base address of the ADC instance + * @return true the ADC FIFO is ready + * @return false the ADC FIFO is unready + */ +LOCAL_INLINE bool ADC_HWA_GetFIFOReady(const ADC_Type *const pAdc) +{ + uint32_t u32TmpVal = pAdc->INT_STATUS; + u32TmpVal = (u32TmpVal & ADC_INT_STATUS_FIFO_RDY_MASK) >> ADC_INT_STATUS_FIFO_RDY_SHIFT; + + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Clear the FIFO ready flag + * + * @param pAdc the base address of the ADC instance + */ +LOCAL_INLINE void ADC_HWA_ClearFIFOReady(ADC_Type *const pAdc) +{ + pAdc->INT_STATUS = ADC_INT_STATUS_FIFO_RDY(1U); +} + +/** + * @brief Check whether the ADC FIFO is full + * + * @param pAdc the base address of the ADC instance + * @return true the ADC FIFO is full + * @return false the ADC FIFO is not full + */ +LOCAL_INLINE bool ADC_HWA_GetFull(const ADC_Type *const pAdc) +{ + uint32_t u32TmpVal = pAdc->INT_STATUS; + u32TmpVal = (u32TmpVal & ADC_INT_STATUS_FULL_MASK) >> ADC_INT_STATUS_FULL_SHIFT; + + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Check whether the ADC FIFO is empty + * + * @param pAdc the base address of the ADC instance + * @return true the ADC FIFO is empty + * @return false the ADC FIFO is not empty + */ +LOCAL_INLINE bool ADC_HWA_GetEmpty(const ADC_Type *const pAdc) +{ + uint32_t u32TmpVal = pAdc->INT_STATUS; + u32TmpVal = (u32TmpVal & ADC_INT_STATUS_EMPTY_MASK) >> ADC_INT_STATUS_EMPTY_SHIFT; + + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Check whether the ADC instance is ready to operate + * + * @param pAdc the base address of the ADC instance + * @return true the ADC instance is ready for a new conversion + * @return false the ADC instance is unready + */ +LOCAL_INLINE bool ADC_HWA_GetReady(const ADC_Type *const pAdc) +{ + uint32_t u32TmpVal = pAdc->INT_STATUS; + u32TmpVal = (u32TmpVal & ADC_INT_STATUS_ADRDY_MASK) >> ADC_INT_STATUS_ADRDY_SHIFT; + + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Clear the ready flag of the ADC instance + * + * @param pAdc the base address of the ADC instance + */ +LOCAL_INLINE void ADC_HWA_ClearReady(ADC_Type *const pAdc) +{ + pAdc->INT_STATUS = ADC_INT_STATUS_ADRDY(1U); +} + +/** + * @brief Get the FIFO Ready interrupt flag + * If enabled, ADC interrupt is generated when the FIFO water mark is greater than FWMARK + * @param pAdc the base address of the ADC instance + * @return true ADC FIFO Ready interrupt is enabled + * @return false ADC FIFO Ready interrupt is disabled + */ +LOCAL_INLINE bool ADC_HWA_GetFIFOReadyInterruptFlag(const ADC_Type *const pAdc) +{ + uint32_t u32TmpVal = (pAdc->INT_ENABLE & ADC_INT_ENABLE_FIFO_RDY_IE_MASK) >> ADC_INT_ENABLE_FIFO_RDY_IE_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Set the FIFO Ready interrupt flag + * If enabled, ADC interrupt is generated when the FIFO water mark is greater than FWMARK + * @param pAdc the base address of the ADC instance + * @param bEnable whether to enable the ADC FIFO Ready interrupt + */ +LOCAL_INLINE void ADC_HWA_SetFIFOReadyInterruptFlag(ADC_Type *const pAdc, bool bEnable) +{ + pAdc->INT_ENABLE = (pAdc->INT_ENABLE & ~ADC_INT_ENABLE_FIFO_RDY_IE_MASK) | ADC_INT_ENABLE_FIFO_RDY_IE(bEnable); +} + +/** + * @brief Get the Compare interrupt flag + * If enabled, ADC interrupt is generated when the ADC conversion result is not within the compare threshold + * @param pAdc the base address of the ADC instance + * @return true ADC Compare interrupt is enabled + * @return false ADC Compare interrupt is disabled + */ +LOCAL_INLINE bool ADC_HWA_GetCompareInterruptFlag(const ADC_Type *const pAdc) +{ + uint32_t u32TmpVal = (pAdc->INT_ENABLE & ADC_INT_ENABLE_ACMP_IE_MASK) >> ADC_INT_ENABLE_ACMP_IE_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Set the Compare interrupt flag + * If enabled, ADC interrupt is generated when the ADC conversion result is not within the compare threshold + * @param pAdc the base address of the ADC instance + * @param bEnable whether to enable the ADC Compare interrupt + */ +LOCAL_INLINE void ADC_HWA_SetCompareInterruptFlag(ADC_Type *const pAdc, bool bEnable) +{ + pAdc->INT_ENABLE = (pAdc->INT_ENABLE & ~ADC_INT_ENABLE_ACMP_IE_MASK) | ADC_INT_ENABLE_ACMP_IE(bEnable); +} + +/** + * @brief Get the Overrun interrupt flag + * If enabled, ADC interrupt is generated when the ADC instance is overrun + * @param pAdc the base address of the ADC instance + * @return true ADC Overrun interrupt is enabled + * @return false ADC Overrun interrupt is disabled + */ +LOCAL_INLINE bool ADC_HWA_GetOverrunInterruptFlag(const ADC_Type *const pAdc) +{ + uint32_t u32TmpVal = (pAdc->INT_ENABLE & ADC_INT_ENABLE_OVRIE_MASK) >> ADC_INT_ENABLE_OVRIE_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Set the Overrun interrupt flag + * If enabled, ADC interrupt is generated when the ADC instance is overrun + * @param pAdc the base address of the ADC instance + * @param bEnable whether to enable the ADC Overrun interrupt + */ +LOCAL_INLINE void ADC_HWA_SetOverrunInterruptFlag(ADC_Type *const pAdc, bool bEnable) +{ + pAdc->INT_ENABLE = (pAdc->INT_ENABLE & ~ADC_INT_ENABLE_OVRIE_MASK) | ADC_INT_ENABLE_OVRIE(bEnable); +} + +/** + * @brief Get the End of Sequence interrupt enable flag + * If enabled, ADC interrupt is generated when the ADC sequence conversion is completed + * @param pAdc the base address of the ADC instance + * @return true ADC End of Sequence interrupt is enabled + * @return false ADC End of Sequence interrupt is disabled + */ +LOCAL_INLINE bool ADC_HWA_GetEndOfSequenceInterruptFlag(const ADC_Type *const pAdc) +{ + uint32_t u32TmpVal = (pAdc->INT_ENABLE & ADC_INT_ENABLE_EOSEQIE_MASK) >> ADC_INT_ENABLE_EOSEQIE_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Set the End of Sequence interrupt enable flag + * If enabled, ADC interrupt is generated when the ADC sequence conversion is completed + * @param pAdc the base address of the ADC instance + * @param bEnable whether to enable the ADC End of Sequence interrupt + */ +LOCAL_INLINE void ADC_HWA_SetEndOfSequenceInterruptFlag(ADC_Type *const pAdc, bool bEnable) +{ + pAdc->INT_ENABLE = (pAdc->INT_ENABLE & ~ADC_INT_ENABLE_EOSEQIE_MASK) | ADC_INT_ENABLE_EOSEQIE(bEnable); +} + +/** + * @brief Get the conversion complete interrupt enable flag + * If enabled, ADC interrupt is generated when each ADC conversion is completed + * @param pAdc the base address of the ADC instance + * @return true the ADC End of Conversion interrupt is enabled + * @return false the ADC End of Conversion interrupt is disabled + */ +LOCAL_INLINE bool ADC_HWAGetEndOfConversionInterruptFlag(const ADC_Type *const pAdc) +{ + uint32_t u32TmpVal = (pAdc->INT_ENABLE & ADC_INT_ENABLE_EOCIE_MASK) >> ADC_INT_ENABLE_EOCIE_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Set the conversion complete interrupt enable flag + * If enabled, ADC interrupt is generated when each ADC conversion is completed + * @param pAdc the base address of the ADC instance + * @param bEnable whether to enable the conversion complete interrupt + */ +LOCAL_INLINE void ADC_HWA_SetEndOfConversionInterruptFlag(ADC_Type *const pAdc, bool bEnable) +{ + pAdc->INT_ENABLE = (pAdc->INT_ENABLE & ~ADC_INT_ENABLE_EOCIE_MASK) | ADC_INT_ENABLE_EOCIE(bEnable); +} + +/** + * @brief Get the sample complete interrupt enable flag + * If enabled, ADC interrupt is generated when each ADC conversion finished the sampling phase + * @param pAdc the base address of the ADC instance + * @return true the sample complete interrupt is enabled + * @return false the sample complete interrupt is disabled + */ +LOCAL_INLINE bool ADC_HWA_GetEndOfSampleInterruptFlag(const ADC_Type *const pAdc) +{ + uint32_t u32TmpVal = (pAdc->INT_ENABLE & ADC_INT_ENABLE_EOSMPIE_MASK) >> ADC_INT_ENABLE_EOSMPIE_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Set the sample complete interrupt enable flag + * If enabled, ADC interrupt is generated when each ADC conversion finished the sampling phase + * @param pAdc the base address of the ADC instance + * @param bEnable whether to enable the sample complete interrupt + */ +LOCAL_INLINE void ADC_HWA_SetEndOfSampleInterruptFlag(ADC_Type *const pAdc, bool bEnable) +{ + pAdc->INT_ENABLE = (pAdc->INT_ENABLE & ~ADC_INT_ENABLE_EOSMPIE_MASK) | ADC_INT_ENABLE_EOSMPIE(bEnable); +} + +/** + * @brief Get the ADC ready interrupt enable flag + * If enabled, ADC interrupt is generated when the ADC module is ready for conversion + * @param pAdc the base address of the ADC instance + * @return true the ADC ready interrupt is enabled + * @return false the ADC ready interrupt is disabled + */ +LOCAL_INLINE bool ADC_HWA_GetADCReadyInterruptFlag(const ADC_Type *const pAdc) +{ + uint32_t u32TmpVal = (pAdc->INT_ENABLE & ADC_INT_ENABLE_ADRDYIE_MASK) >> ADC_INT_ENABLE_ADRDYIE_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Set the ADC ready interrupt enable flag + * If enabled, ADC interrupt is generated when the ADC module is ready for conversion + * @param pAdc the base address of the ADC instance + * @param bEnable Whether to enable the ADC ready interrupt + */ +LOCAL_INLINE void ADC_HWA_SetADCReadyInterruptFlag(ADC_Type *const pAdc, bool bEnable) +{ + pAdc->INT_ENABLE = (pAdc->INT_ENABLE & ~ADC_INT_ENABLE_ADRDYIE_MASK) | ADC_INT_ENABLE_ADRDYIE(bEnable); +} + +/** + * @brief Get the interrupt enable config + * + * @param pAdc the base address of the ADC instance + * @return uint32_t the interrupt enable config + */ +LOCAL_INLINE uint32_t ADC_HWA_GetInterruptEnable(const ADC_Type *const pAdc) +{ + return pAdc->INT_ENABLE; +} + +/** + * @brief Set the interrupt enable + * + * @param u32InterruptCfg the interrupt enable config + */ +LOCAL_INLINE void ADC_HWA_SetInterruptEnable(ADC_Type *const pAdc, uint32_t u32InterruptCfg) +{ + pAdc->INT_ENABLE = u32InterruptCfg; +} + +/** + * @brief Reset the ADC hardware + * + * @param pAdc the base address of the ADC instance + */ +LOCAL_INLINE void ADC_HWA_Reset(ADC_Type *const pAdc) +{ + pAdc->CONTROL = ADC_CONTROL_ADRST(1U); + pAdc->CONTROL = 0U; +} + +/** + * @brief Get the enable status of the ADC instance + * + * @param pAdc the base address of the ADC instance + * @return true the ADC instance is enabled + * @return false the ADC instance has not been enabled + */ +LOCAL_INLINE bool ADC_HWA_GetEnable(const ADC_Type *const pAdc) +{ + uint32_t u32TmpVal = pAdc->CONTROL; + u32TmpVal = (u32TmpVal & ADC_CONTROL_ADEN_MASK) >> ADC_CONTROL_ADEN_SHIFT; + + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Enable the ADC instance + * + * @param pAdc the base address of the ADC instance + */ +LOCAL_INLINE void ADC_HWA_Enable(ADC_Type *const pAdc) +{ + pAdc->CONTROL = ADC_CONTROL_ADEN(1U); +} + +/** + * @brief Get whether the ADC instance is in disable status + * + * @param pAdc the base address of the ADC instance + * @return true the ADC instance is in disable status + * @return false the ADC instance is not in disable status + */ +LOCAL_INLINE bool ADC_HWA_GetDisable(const ADC_Type *const pAdc) +{ + uint32_t u32TmpVal = pAdc->CONTROL; + u32TmpVal = (u32TmpVal & ADC_CONTROL_ADDIS_MASK) >> ADC_CONTROL_ADDIS_SHIFT; + + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Disable the ADC instance + * + * @param pAdc the base address of the ADC instance + */ +LOCAL_INLINE void ADC_HWA_Disable(ADC_Type *const pAdc) +{ + pAdc->CONTROL = ADC_CONTROL_ADDIS(1U); +} + +/** + * @brief Get the conversion start status of the ADC instance + * + * @param pAdc the base address of the ADC instance + * @return true the conversion of the ADC instance is started + * @return false the conversion of the ADC instance has not been started + */ +LOCAL_INLINE bool ADC_HWA_GetStart(const ADC_Type *const pAdc) +{ + uint32_t u32TmpVal = pAdc->CONTROL; + u32TmpVal = (u32TmpVal & ADC_CONTROL_ADSTART_MASK) >> ADC_CONTROL_ADSTART_SHIFT; + + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Start the ADC conversion + * + * @param pAdc the base address of the ADC instance + */ +LOCAL_INLINE void ADC_HWA_Start(ADC_Type *const pAdc) +{ + pAdc->CONTROL = ADC_CONTROL_ADSTART(1U); +} + +/** + * @brief Get whether ADC is in stopping status + * + * @param pAdc the base address of the ADC instance + * @return true the ADC instance is stopping + * @return false the ADC instance is not in stopping status + */ +LOCAL_INLINE bool ADC_HWA_GetStop(const ADC_Type *const pAdc) +{ + uint32_t u32TmpVal = pAdc->CONTROL; + u32TmpVal = (u32TmpVal & ADC_CONTROL_ADSTP_MASK) >> ADC_CONTROL_ADSTP_SHIFT; + + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Stop the ADC conversion + * + * @param pAdc the base address of the ADC instance + */ +LOCAL_INLINE void ADC_HWA_Stop(ADC_Type *const pAdc) +{ + pAdc->CONTROL = ADC_CONTROL_ADSTP(1U); +} + +/** + * @brief Get the overrun management mode + * + * @param pAdc the base address of the ADC instance + * @return ADC_OVERRUN_MODE_PRESERVE the conversion data is preserved when ADC is overrun + * @return ADC_OVERRUN_MODE_OVERWRITE the conversion data is overwritten when ADC is overrun + */ +LOCAL_INLINE ADC_OvrModeType ADC_HWA_GetOverrunManagementMode(const ADC_Type *const pAdc) +{ + uint32_t u32TmpVal = (pAdc->CFG1 & ADC_CFG1_OVRMOD_MASK) >> ADC_CFG1_OVRMOD_SHIFT; + return (ADC_OvrModeType)u32TmpVal; +} + +/** + * @brief Set the overrun management mode + * + * @param pAdc the base address of the ADC instance + * @param eOvrMode the overrun management for the ADC instance + */ +LOCAL_INLINE void ADC_HWA_SetOverrunManagementMode(ADC_Type *const pAdc, ADC_OvrModeType eOvrMode) +{ + pAdc->CFG1 = (pAdc->CFG1 & ~ADC_CFG1_OVRMOD_MASK) | ADC_CFG1_OVRMOD(eOvrMode); +} + +/** + * @brief Get the sequence group mode state + * + * @param pAdc the base address of the ADC instance + * @return the sequence group mode state + */ +LOCAL_INLINE bool ADC_HWA_GetSeqGpEn(const ADC_Type *const pAdc) +{ + uint32_t u32TmpVal = (pAdc->CFG1 & ADC_CFG1_SEQGP_EN_MASK) >> ADC_CFG1_SEQ_LEN_SHIFT; + return u32TmpVal ? true : false; +} + +/** + * @brief Set the sequence group mode state + * + * @param pAdc the base address of the ADC instance + * @param the sequence group mode state + */ +LOCAL_INLINE void ADC_HWA_SetSeqGpEn(ADC_Type *const pAdc, bool bEnable) +{ + pAdc->CFG1 = (pAdc->CFG1 & ~ADC_CFG1_SEQGP_EN_MASK) | ADC_CFG1_SEQGP_EN(bEnable); +} + +/** + * @brief Get the sequence length of the ADC conversion sequence + * + * @param pAdc the base address of the ADC instance + * @return uint8_t the sequence length of the ADC conversion sequence + */ +LOCAL_INLINE uint8_t ADC_HWA_GetSequenceLength(const ADC_Type *const pAdc) +{ + uint32_t u32TmpVal = pAdc->CFG1; + u32TmpVal = (u32TmpVal & ADC_CFG1_SEQ_LEN_MASK) >> ADC_CFG1_SEQ_LEN_SHIFT; + + return (uint8_t)u32TmpVal; +} + +/** + * @brief Set the sequence length of the ADC conversion sequence + * + * @param pAdc the base address of the ADC instance + * @param u8SequenceLength the sequence length of the ADC conversion sequence + */ +LOCAL_INLINE void ADC_HWA_SetSequenceLength(ADC_Type *const pAdc, uint8_t u8SequenceLength) +{ + pAdc->CFG1 = (pAdc->CFG1 & ~ADC_CFG1_SEQ_LEN_MASK) | ADC_CFG1_SEQ_LEN(u8SequenceLength); +} + +/** + * @brief Get the ADC sequence mode + * + * @param pAdc the base address of the ADC instance + * @return ADC_SeqModeType the sequence mode the the ADC instance + */ +LOCAL_INLINE ADC_SeqModeType ADC_HWA_GetSequenceMode(const ADC_Type *const pAdc) +{ + uint32_t u32TmpVal = pAdc->CFG1; + u32TmpVal = (u32TmpVal & ADC_CFG1_SEQ_MOD_MASK) >> ADC_CFG1_SEQ_MOD_SHIFT; + + return (ADC_SeqModeType)u32TmpVal; +} + +/** + * @brief Set the ADC sequence mode + * + * @param pAdc the base address of the ADC instance + * @param eSequenceMode the sequence mode the the ADC instance + */ +LOCAL_INLINE void ADC_HWA_SetSequenceMode(ADC_Type *const pAdc, ADC_SeqModeType eSequenceMode) +{ + pAdc->CFG1 = (pAdc->CFG1 & ~ADC_CFG1_SEQ_MOD_MASK) | ADC_CFG1_SEQ_MOD(eSequenceMode); +} + +/** + * @brief Get whether auto disable is enabled + * + * @note Auto disable mode is only available in FC4150F2M + * + * @param pAdc the base address of the ADC instance + * @return true auto disable mode is enabled + * @return false auto disable mode is disabled + */ +LOCAL_INLINE bool ADC_HWA_GetAutoDisableModeEnableFlag(const ADC_Type *const pAdc) +{ + uint32_t u32TmpVal = pAdc->CFG1; + u32TmpVal = (u32TmpVal & ADC_CFG1_AUTO_DIS_MASK) >> ADC_CFG1_AUTO_DIS_SHIFT; + + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Set whether to enable auto disable mode + * + * @note Auto disable mode is only available in FC4150F2M + * + * @param pAdc the base address of the ADC instance + * @param bEnable whether to enable auto disable mode + */ +LOCAL_INLINE void ADC_HWA_SetAutoDisableModeEnableFlag(ADC_Type *const pAdc, bool bEnable) +{ + pAdc->CFG1 = (pAdc->CFG1 & ~ADC_CFG1_AUTO_DIS_MASK) | ADC_CFG1_AUTO_DIS(bEnable); +} + +/** + * @brief Get whether the wait conversion mode is enabled + * + * @param pAdc the base address of the ADC instance + * @return true the wait conversion mode is enabled + * @return false the wait conversion mode is disabled + */ +LOCAL_INLINE bool ADC_HWA_GetWaitConversionModeFlag(const ADC_Type *const pAdc) +{ + uint32_t u32TmpVal = (pAdc->CFG1 & ADC_CFG1_WAIT_MASK) >> ADC_CFG1_WAIT_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Set the wait conversion mode + * + * @param pAdc the base address of the ADC instance + * @param bEnable whether to enable the wait conversion mode + */ +LOCAL_INLINE void ADC_HWA_SetWaitConversionModeFlag(ADC_Type *const pAdc, bool bEnable) +{ + pAdc->CFG1 = (pAdc->CFG1 & ~ADC_CFG1_WAIT_MASK) | ADC_CFG1_WAIT(bEnable); +} + +/** + * @brief Get the trigger source the the ADC instance + * + * @param pAdc the base address of the ADC instance + * @return ADC_TrigSrcType the trigger source of the ADC instance + */ +LOCAL_INLINE ADC_TrigSrcType ADC_HWA_GetTriggerSource(const ADC_Type *const pAdc) +{ + uint32_t u32TmpVal = pAdc->CFG1; + u32TmpVal = (u32TmpVal & ADC_CFG1_TRIGSRC_MASK) >> ADC_CFG1_TRIGSRC_SHIFT; + + return (ADC_TrigSrcType)u32TmpVal; +} + +/** + * @brief Set the trigger source the the ADC instance + * + * @param pAdc the base address of the ADC instance + * @param eTriggerSource the trigger source of the ADC instance + */ +LOCAL_INLINE void ADC_HWA_SetTriggerSource(ADC_Type *const pAdc, ADC_TrigSrcType eTriggerSource) +{ + pAdc->CFG1 = (pAdc->CFG1 & ~ADC_CFG1_TRIGSRC_MASK) | ADC_CFG1_TRIGSRC(eTriggerSource); +} + +/** + * @brief Get the trigger mode of the ADC instance + * + * @param pAdc the base address of the ADC instance + * @return ADC_TrigModeType the trigger mode if the ADC instance + */ +LOCAL_INLINE ADC_TrigModeType ADC_HWA_GetTriggerMode(const ADC_Type *const pAdc) +{ + uint32_t u32TmpVal = pAdc->CFG1; + u32TmpVal = (u32TmpVal & ADC_CFG1_TRIGMODE_MASK) >> ADC_CFG1_TRIGMODE_SHIFT; + + return (ADC_TrigModeType)u32TmpVal; +} + +/** + * @brief Set the trigger mode of the ADC instance + * + * @param pAdc the base address of the ADC instance + * @param eTriggerMode the trigger mode if the ADC instance + */ +LOCAL_INLINE void ADC_HWA_SetTriggerMode(ADC_Type *const pAdc, ADC_TrigModeType eTriggerMode) +{ + pAdc->CFG1 = (pAdc->CFG1 & ~ADC_CFG1_TRIGMODE_MASK) | ADC_CFG1_TRIGMODE(eTriggerMode); +} + +/** + * @brief Get the data align mode + * + * @param pAdc the base address of the ADC instance + * @return ADC_ALIGN_RIGHT the conversion data is aligned right + * @return ADC_ALIGN_LEFT the conversion is aligned left + */ +LOCAL_INLINE ADC_AlignType ADC_HWA_GetDataAlignment(const ADC_Type *const pAdc) +{ + uint32_t u32TmpVal = (pAdc->CFG1 & ADC_CFG1_ALIGN_MASK) >> ADC_CFG1_ALIGN_SHIFT; + return (ADC_AlignType)u32TmpVal; +} + +/** + * @brief Set the data align mode + * + * @param pAdc the base address of the ADC instance + * @param eAlign the data align mode + */ +LOCAL_INLINE void ADC_HWA_SetDataAlignment(ADC_Type *const pAdc, ADC_AlignType eAlign) +{ + pAdc->CFG1 = (pAdc->CFG1 & ~ADC_CFG1_ALIGN_MASK) | ADC_CFG1_ALIGN(eAlign); +} + +/** + * @brief Get the ADC resolution of the ADC instance + * + * @param pAdc the base address of the ADC instance + * @return ADC_ResolutionType the resolution of the ADC instance + */ +LOCAL_INLINE ADC_ResolutionType ADC_HWA_GetDataResolution(const ADC_Type *const pAdc) +{ + uint32_t u32TmpVal = (pAdc->CFG1 & ADC_CFG1_RES_MASK) >> ADC_CFG1_RES_SHIFT; + return (ADC_ResolutionType)u32TmpVal; +} + +/** + * @brief Set the resolution of the ADC instance + * + * @param pAdc the base address of the ADC instance + * @param eResolution the resolution of the ADC instance + */ +LOCAL_INLINE void ADC_HWA_SetDataResolution(ADC_Type *const pAdc, ADC_ResolutionType eResolution) +{ + pAdc->CFG1 = (pAdc->CFG1 & ~ADC_CFG1_RES_MASK) | ADC_CFG1_RES(eResolution); +} + +/** + * @brief Get whether DMA for the ADC instance is enabled + * + * @param pAdc the base address of the ADC instance + * @return true DMA is enabled for the ADC instance + * @return false DMA is disabled for the ADC instance + */ +LOCAL_INLINE bool ADC_HWA_GetDMAEnableFlag(const ADC_Type *const pAdc) +{ + uint32_t u32TmpVal = (pAdc->CFG1 & ADC_CFG1_DMAEN_MASK) >> ADC_CFG1_DMAEN_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Enable or disable the DMA for the ADC instance + * + * @param pAdc the base address of the ADC instance + * @param bEnable whether to enable the DMA for the ADC instance + */ +LOCAL_INLINE void ADC_HWA_SetDMAEnableFlag(ADC_Type *const pAdc, bool bEnable) +{ + pAdc->CFG1 = (pAdc->CFG1 & ~ADC_CFG1_DMAEN_MASK) | ADC_CFG1_DMAEN(bEnable); +} + +/** + * @brief Get the ADC_CFG1 config + * + * @param pAdc the base address of the ADC instance + * @return uint32_t the ADC_CFG1 config + */ +LOCAL_INLINE uint32_t ADC_HWA_GetConfig1(const ADC_Type *const pAdc) +{ + return pAdc->CFG1; +} + +/** + * @brief Set the ADC_CFG1 config + * + * @param pAdc the base address of the ADC instance + * @param u32Config the ADC_CFG1 config + */ +LOCAL_INLINE void ADC_HWA_SetConfig1(ADC_Type *const pAdc, uint32_t u32Config) +{ + pAdc->CFG1 = u32Config; +} + +/** + * @brief Get the FIFO water mark settings for the ADC instance + * + * @param pAdc the base address of the ADC instance + * @return uint8_t the ADC FIFO water mark setting + */ +LOCAL_INLINE uint8_t ADC_HWA_GetFIFOWaterMark(const ADC_Type *const pAdc) +{ + uint32_t u32TmpVal = (pAdc->CFG2 & ADC_CFG2_FWMARK_MASK) >> ADC_CFG2_FWMARK_SHIFT; + return (uint8_t)u32TmpVal; +} + +/** + * @brief Set the FIFO water mark for the ADC instance + * + * @param pAdc the base address of the ADC instance + * @param u8WaterMark the ADC FIFO water mark setting + */ +LOCAL_INLINE void ADC_HWA_SetFIFOWaterMark(ADC_Type *const pAdc, uint8_t u8WaterMark) +{ + pAdc->CFG2 = (pAdc->CFG2 & ~ADC_CFG2_FWMARK_MASK) | ADC_CFG2_FWMARK(u8WaterMark); +} + +/** + * @brief Get the priority of Trigger Latch + * + * @param pAdc the base address of the ADC instance + */ +LOCAL_INLINE uint8_t ADC_HWA_GetTriggerLatchUnitPriority(const ADC_Type *const pAdc) +{ + uint32_t u32TmpVal = (pAdc->CFG2 & ADC_CFG2_TRG_PRI_MASK) >> ADC_CFG2_TRG_PRI_SHIFT; + return (uint8_t)u32TmpVal; +} + +/** + * @brief Set the priority of Trigger Latch + * + * @param pAdc the base address of the ADC instance + * @param eTrgLatchUnitPri the priority of Trigger Latch Unit setting + */ +LOCAL_INLINE void ADC_HWA_SetTriggerLatchUnitPriority(ADC_Type *const pAdc, ADC_TrgLatchUnitPri eTrgLatchUnitPri) +{ + pAdc->CFG2 = (pAdc->CFG2 & ~ADC_CFG2_TRG_CLR_MASK) | ADC_CFG2_TRG_CLR(eTrgLatchUnitPri); +} + +/** + * @brief Clear Latch Trigger in Trigger Latch Unit + * + * @param pAdc the base address of the ADC instance + */ +LOCAL_INLINE void ADC_HWA_ClearLatchTrigger(ADC_Type *const pAdc) +{ + uint32_t u32TmpVal = pAdc->CFG2; + pAdc->CFG2 = u32TmpVal | ADC_CFG2_TRG_CLR(1); +} + +/** + * @brief Get whether hardware average is enabled + * + * @param pAdc the base address of the ADC instance + * @return true hardware average is enabled + * @return false hardware average is disabled + */ +LOCAL_INLINE bool ADC_HWA_GetAverageEnableFlag(const ADC_Type *const pAdc) +{ + uint32_t u32TmpVal = (pAdc->CFG2 & ADC_CFG2_AVG_EN_MASK) >> ADC_CFG2_AVG_EN_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Enable or disable hardware average for the ADC instance + * + * @param pAdc the base address of the ADC instance + * @param bEnable whether to enable the ADC hardware average + */ +LOCAL_INLINE void ADC_HWA_SetAverageEnableFlag(ADC_Type *const pAdc, bool bEnable) +{ + pAdc->CFG2 = (pAdc->CFG2 & ~ADC_CFG2_AVG_EN_MASK) | ADC_CFG2_AVG_EN(bEnable); +} + +/** + * @brief Get the hardware average number + * + * @param pAdc the base address of the ADC instance + * @return ADC_AverageType the hardware average number + */ +LOCAL_INLINE ADC_AverageType ADC_HWA_GetAverageNumber(const ADC_Type *const pAdc) +{ + uint32_t u32TmpVal = (pAdc->CFG2 & ADC_CFG2_AVG_LEN_MASK) >> ADC_CFG2_AVG_LEN_SHIFT; + return (ADC_AverageType)u32TmpVal; +} + +/** + * @brief Set the hardware average number + * + * @param pAdc the base address of the ADC instance + * @param eAverageNumber the hardware average number to set + */ +LOCAL_INLINE void ADC_HWA_SetAverageNumber(ADC_Type *const pAdc, ADC_AverageType eAverageNumber) +{ + pAdc->CFG2 = (pAdc->CFG2 & ~ADC_CFG2_AVG_LEN_MASK) | ADC_CFG2_AVG_LEN(eAverageNumber); +} +/** + * @brief Whether clock gating is acknowledged + * + * @note This feature is only available in FC4150F2M + * + * @param pAdc the base address of the ADC instance + * @return true ADC clock source is off after setting Clock Gating Enable Flag + * @return false ADC clock source is on after clearing Clock Gating Enable Flag + */ +LOCAL_INLINE bool ADC_HWA_GetClockGatingAck(const ADC_Type *const pAdc) +{ + uint32_t u32TmpVal = (pAdc->CFG2 & ADC_CFG2_CG_ACK_MASK) >> ADC_CFG2_CG_ACK_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get whether clock gating is enabled + * + * @note This feature is only available in FC4150F2M + * + * @param pAdc the base address of the ADC instance + * @return true Clock gating is enabled, ADC clock is off + * @return false Clock gating is disabled, ADC clock is on + */ +LOCAL_INLINE bool ADC_HWA_GetClockGatingEnableFlag(const ADC_Type *const pAdc) +{ + uint32_t u32TmpVal = (pAdc->CFG2 & ADC_CFG2_CG_MASK) >> ADC_CFG2_CG_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Set whether to enable ADC clock gating + * + * @note This feature is only available in FC4150F2M + * + * @param pAdc the base address of the ADC instance + * @param bEnable whether to enable ADC clock gating + */ +LOCAL_INLINE void ADC_HWA_SetClockGatingEnableFlag(ADC_Type *const pAdc, bool bEnable) +{ + pAdc->CFG2 = (pAdc->CFG2 & ~ADC_CFG2_CG_MASK) | ADC_CFG2_CG(bEnable); +} + +/** + * @brief Get the voltage reference of the ADC instance + * + * @param pAdc the base address of the ADC instance + * @return ADC_REF_INTERNAL the ADC instance uses internal voltage reference + * @return ADC_REF_EXTERNAL the ADC instance uses external voltage reference + */ +LOCAL_INLINE ADC_RefType ADC_HWA_GetVoltageReference(const ADC_Type *const pAdc) +{ + uint32_t u32TmpVal = (pAdc->CFG2 & ADC_CFG2_REF_EXT_MASK) >> ADC_CFG2_REF_EXT_SHIFT; + return (ADC_RefType)u32TmpVal; +} + +/** + * @brief Set the voltage reference of the ADC instance + * + * @param pAdc the base address of the ADC instance + * @param eRefSel the voltage reference of the ADC instance + */ +LOCAL_INLINE void ADC_HWA_SetVoltageReference(ADC_Type *const pAdc, ADC_RefType eRefSel) +{ + pAdc->CFG2 = (pAdc->CFG2 & ~ADC_CFG2_REF_EXT_MASK) | ADC_CFG2_REF_EXT(eRefSel); +} + +/** + * @brief Get the ADC clock divider + * + * @note This feature is only available in FC4150F2M + * + * @param pAdc the base address of the ADC instance + * @return ADC_ClockDivideType the ADC clock divider + */ +LOCAL_INLINE ADC_ClockDivideType ADC_HWA_GetClockDivider(const ADC_Type *const pAdc) +{ + uint32_t u32TmpVal = (pAdc->CFG2 & ADC_CFG2_DIV_MASK) >> ADC_CFG2_DIV_SHIFT; + return (ADC_ClockDivideType)u32TmpVal; +} + +/** + * @brief Set the ADC clock divider + * + * @note Before configuring DIV, must set CG and wait for CG_ACK=1. + * After configuring DIV, must clear CG and wait for CG_ACK=0. + * @note This feature is only available in FC4150F2M + * + * @param pAdc the base address of the ADC instance + * @param eDivider the ADC clock divider to set + */ +LOCAL_INLINE void ADC_HWA_SetClockDivider(ADC_Type *const pAdc, ADC_ClockDivideType eDivider) +{ + pAdc->CFG2 = (pAdc->CFG2 & ~ADC_CFG2_DIV_MASK) | ADC_CFG2_DIV(eDivider); +} + +/** + * @brief Get the ADC start up count + * + * @param pAdc the base address of the ADC instance + * @return uint8_t the start count of the ADC instance + */ +LOCAL_INLINE uint8_t ADC_HWA_GetStartupCnt(const ADC_Type *const pAdc) +{ + uint32_t u32TmpVal = (pAdc->CFG2 & ADC_CFG2_STCNT_MASK) >> ADC_CFG2_STCNT_SHIFT; + return (uint8_t)u32TmpVal; +} + +/** + * @brief Set the ADC start up count + * + * @param pAdc the base address of the ADC instance + * @param u8StartupCnt the start count of the ADC instance + */ +LOCAL_INLINE void ADC_HWA_SetStartupCnt(ADC_Type *const pAdc, uint8_t u8StartupCnt) +{ + pAdc->CFG2 = (pAdc->CFG2 & ~ADC_CFG2_STCNT_MASK) | ADC_CFG2_STCNT(u8StartupCnt); +} + +/** + * @brief Get the ADC_CFG2 config + * + * @param pAdc the base address of the ADC instance + * @return uint32_t the ADC_CFG2 config + */ +LOCAL_INLINE uint32_t ADC_HWA_GetConfig2(const ADC_Type *const pAdc) +{ + return pAdc->CFG2; +} + +/** + * @brief Set the ADC_CFG2 config + * + * @param pAdc the base address of the ADC instance + * @param u32Config the ADC_CFG2 config + */ +LOCAL_INLINE void ADC_HWA_SetConfig2(ADC_Type *const pAdc, uint32_t u32Config) +{ + pAdc->CFG2 = u32Config; +} + +/** + * @brief Set the ADC_CAL config + * + * @param pAdc the base address of the ADC instance + * @param u32Cal the ADC_CAL config + */ +LOCAL_INLINE void ADC_HWA_SetCal(ADC_Type *const pAdc, uint32_t u32Cal) +{ + pAdc->CAL = u32Cal; +} + +/** + * @brief Get the sample time of the ADC instance + * + * @param pAdc the base address of the ADC instance + * @param u8Selection the sample time index, range 0~3 + * @return uint8_t the sample time of the selected index + */ +LOCAL_INLINE uint8_t ADC_HWA_GetSampleTime(ADC_Type *const pAdc, uint8_t u8Selection) +{ + uint32_t ret; + ret = (pAdc->SMPR & (ADC_SMPR_SMP_OPT0_MASK << (8U * u8Selection))) >> (8U * u8Selection); + return (uint8_t)ret; +} + +/** + * @brief Set the sample time of the ADC instance + * + * @param pAdc the base address of the ADC instance + * @param u8Selection the sample time index, range 0~3 + * @param u8SampleTime the sample time of the selected index + */ +LOCAL_INLINE void ADC_HWA_SetSampleTime(ADC_Type *const pAdc, uint8_t u8Selection, uint8_t u8SampleTime) +{ + DEV_ASSERT(u8Selection < ADC_SAMPLE_TIME_OPTION_CNT); + pAdc->SMPR = (pAdc->SMPR & ~(ADC_SMPR_SMP_OPT0_MASK << (8U * u8Selection))) | + (ADC_SMPR_SMP_OPT0(u8SampleTime) << (8U * u8Selection)); +} + +/** + * @brief Set the ADC hardware compare channel + * + * @param pAdc the base address of the ADC instance + * @param eChannelType whether the hardware compare enabled on single channel or all channels + * @param u8ChannalNum if hardware compare is enabled on single channel, this specifies the channel number + */ +LOCAL_INLINE void ADC_HWA_SetHwCompareChannel(ADC_Type *const pAdc, ADC_CmpChannelType eChannelType, + uint8_t u8ChannalNum) +{ + pAdc->CMP_CTRL = (pAdc->CMP_CTRL & (~ADC_CMP_CTRL_ACMPSGL_MASK) & (~ADC_CMP_CTRL_ACMPCH_MASK)) | + ADC_CMP_CTRL_ACMPSGL(eChannelType) | ADC_CMP_CTRL_ACMPCH(u8ChannalNum); +} + +/** + * @brief Get whether hardware compare is enabled + * + * @param pAdc the base address of the ADC instance + * @return true hardware compare is enabled + * @return false hardware compare is disabled + */ +LOCAL_INLINE bool ADC_HWA_GetHwCompareEnableFlag(const ADC_Type *const pAdc) +{ + uint32_t u32TmpVal = (pAdc->CMP_CTRL & ADC_CMP_CTRL_ACMPEN_MASK) >> ADC_CMP_CTRL_ACMPEN_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Set to enable or disable the hardware compare + * + * @param pAdc the base address of the ADC instance + * @param bEnable whether the ADC hardware compare is enabled + */ +LOCAL_INLINE void ADC_HWA_SetHwCompareEnableFlag(ADC_Type *const pAdc, bool bEnable) +{ + pAdc->CMP_CTRL = (pAdc->CMP_CTRL & ~ADC_CMP_CTRL_ACMPEN_MASK) | ADC_CMP_CTRL_ACMPEN(bEnable); +} + +/** + * @brief Set the ADC hardware compare threshold + * + * @param pAdc the base address of the ADC instance + * @param u16LowThres the lower threshold + * @param u16HighThres the higher threshold + */ +LOCAL_INLINE void ADC_HWA_SetHwCompareThreshold(ADC_Type *const pAdc, uint16_t u16LowThres, uint16_t u16HighThres) +{ + pAdc->CMP_TR = ADC_CMP_TR_LT(u16LowThres) | ADC_CMP_TR_HT(u16HighThres); +} + +/** + * @brief Get the end of sequence group flag + * + * @param pAdc the base address of the ADC instance + * @param u8SeqGroupIndex the index of the sequence group + * @param bool the sequence group interrupt flag + */ +LOCAL_INLINE bool ADC_HWA_GetEndOfSequenceGroupInterruptFlag(ADC_Type *const pAdc, const uint8_t u8SeqGroupIndex) +{ + uint32_t u32TmpVal = (pAdc->SGCSR[u8SeqGroupIndex] & ADC_SGCSR_EOSG_MASK) >> ADC_SGCSR_EOSG_SHIFT; + return u32TmpVal ? true : false; +} + +/** + * @brief Clear the end of sequence group flag + * + * @param pAdc the base address of the ADC instance + * @param u8SeqGroupIndex the index of the sequence group + */ +LOCAL_INLINE void ADC_HWA_ClearEndOfSequenceGroupInterruptFlag(ADC_Type *const pAdc, const uint8_t u8SeqGroupIndex) +{ + uint32_t u32TmpVal = pAdc->SGCSR[u8SeqGroupIndex]; + pAdc->SGCSR[u8SeqGroupIndex] = (u32TmpVal & ~ADC_SGCSR_EOSG_MASK) | ADC_SGCSR_EOSG(1U); +} + +/** + * @brief Set the sequence group end of sequence interrupt enable + * + * @param pAdc the base address of the ADC instance + * @param u8SeqGroupIndex the index of the sequence group + * @param bEnable the sequence group interrupt enable or disable + */ +LOCAL_INLINE void ADC_HWA_SetEndOfSequenceGroupInterruptEnable(ADC_Type *const pAdc, const uint8_t u8SeqGroupIndex, const bool bEnable) +{ + uint32_t u32TmpVal = pAdc->SGCSR[u8SeqGroupIndex]; + pAdc->SGCSR[u8SeqGroupIndex] = (u32TmpVal & ~ADC_SGCSR_EOSGIE_MASK) | ADC_SGCSR_EOSGIE(bEnable); +} + +/** + * @brief Get the sequence group start point + * + * @param pAdc the base address of the ADC instance + * @param u8SeqGroupIndex the index of the sequence group + */ +LOCAL_INLINE uint32_t ADC_HWA_GetSeqGroupStartPoint(ADC_Type *const pAdc, const uint8_t u8SeqGroupIndex) +{ + return (pAdc->SGCSR[u8SeqGroupIndex] & ~ADC_SGCSR_SG_START_MASK) >> ADC_SGCSR_SG_START_SHIFT; +} + +/** + * @brief Get the sequence group end point + * + * @param pAdc the base address of the ADC instance + * @param u8SeqGroupIndex the index of the sequence group + */ +LOCAL_INLINE uint32_t ADC_HWA_GetSeqGroupEndPoint(ADC_Type *const pAdc, const uint8_t u8SeqGroupIndex) +{ + return (pAdc->SGCSR[u8SeqGroupIndex] & ~ADC_SGCSR_SG_END_MASK) >> ADC_SGCSR_SG_END_SHIFT; +} + +/** + * @brief Set the sequence group start point & end point + * + * @param pAdc the base address of the ADC instance + * @param u8SeqGroupIndex the index of the sequence group + * @param u8Start the sequence group start point + * @param u8End the sequence group end point + */ +LOCAL_INLINE void ADC_HWA_SetSeqGroupStartEndPoint(ADC_Type *const pAdc, const uint8_t u8SeqGroupIndex, const uint8_t u8Start, const uint8_t u8End) +{ + uint32_t u32TmpVal = pAdc->SGCSR[u8SeqGroupIndex]; + u32TmpVal = (u32TmpVal & ~ADC_SGCSR_SG_END_MASK) | ADC_SGCSR_SG_END(u8End); + u32TmpVal = (u32TmpVal & ~ADC_SGCSR_SG_START_MASK) | ADC_SGCSR_SG_START(u8Start); + pAdc->SGCSR[u8SeqGroupIndex] = u32TmpVal; +} + +/** + * @brief Get the conversion result FIFO data of the ADC instance + * + * @note only reslut data of ADC single mode and continuous mode will be stored + * in FIFO register. + * + * @param pAdc the base address of the ADC instance + * @return uint32_t the ADC conversion result + */ +LOCAL_INLINE uint32_t ADC_HWA_GetFIFOData(const ADC_Type *const pAdc) +{ + uint32_t u32TmpVal = pAdc->FIFO_DATA; + u32TmpVal = (u32TmpVal & ADC_FIFO_DATA_FIFO_DATA_MASK) >> ADC_FIFO_DATA_FIFO_DATA_SHIFT; + return (uint32_t)u32TmpVal; +} + +/** + * @brief Get the differential mode state of the ADC channel + * + * @param pAdc the base address of the ADC instance + * @param u8ChnIdx the index of the channel + * @return bool the state of diff mode for ADC channel + */ +LOCAL_INLINE bool ADC_HWA_GetChannelDiff(const ADC_Type *const pAdc, const uint8_t u8ChnIdx) +{ + uint32_t u32TmpVal = (pAdc->SC[u8ChnIdx] & ADC_SC_DIFF_MASK) >> ADC_SC_DIFF_SHIFT; + return u32TmpVal ? true : false; +} + +/** + * @brief Set the differential mode state of the ADC channel + * + * @param pAdc the base address of the ADC instance + * @param u8ChnIdx the index of the channel + * @param bEnable the state of diff mode for ADC channel + */ +LOCAL_INLINE void ADC_HWA_SetChannelDiff(ADC_Type *const pAdc, const uint8_t u8ChnIdx, const bool bEnable) +{ + pAdc->SC[u8ChnIdx] = (pAdc->SC[u8ChnIdx] & ~ADC_SC_DIFF_MASK) | ADC_SC_DIFF(bEnable); +} + +/** + * @brief Get the sample time index of the ADC channel + * + * @param pAdc the base address of the ADC instance + * @param u8ChnIdx the index of the channel + * @return uint8_t the sample time index of the ADC channel + */ +LOCAL_INLINE uint8_t ADC_HWA_GetChannelSampleTimeIndex(const ADC_Type *const pAdc, const uint8_t u8ChnIdx) +{ + uint32_t u32TmpVal = (pAdc->SC[u8ChnIdx] & ADC_SC_SMPSEL_MASK) >> ADC_SC_SMPSEL_SHIFT; + return (uint8_t)u32TmpVal; +} + +/** + * @brief Set the sample time index of the ADC channel + * + * @param pAdc the base address of the ADC instance + * @param u8ChnIdx the index of the channel + * @param u8SmpSel the sample time index of the ADC channel + */ +LOCAL_INLINE void ADC_HWA_SetChannelSampleTimeIndex(ADC_Type *const pAdc, const uint8_t u8ChnIdx, uint8_t u8SmpSel) +{ + pAdc->SC[u8ChnIdx] = (pAdc->SC[u8ChnIdx] & ~ADC_SC_SMPSEL_MASK) | ADC_SC_SMPSEL(u8SmpSel); +} + +/** + * @brief Get the channel conversion complete status of the ADC instance + * + * @note this function is used only in ADC discontinuous mode to get the channel complete + * status + * + * @param pAdc the base address of the ADC instance + * @param u8ChnIdx the index of the channel + * @return true the ADC conversion on the selected channel is completed + * @return false the ADC conversion on the selected channel is not completed + */ +LOCAL_INLINE bool ADC_HWA_GetChannelConvertComplete(const ADC_Type *const pAdc, const uint8_t u8ChnIdx) +{ + uint32_t u32TmpVal = pAdc->SC[u8ChnIdx]; + u32TmpVal = (u32TmpVal & ADC_SC_COCO_MASK) >> ADC_SC_COCO_SHIFT; + + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Check whether interrupt is enabled on the selected ADC channel + * + * @note this function is used only in ADC discontinuous mode to get the channel interrupt + * settings + * + * @param pAdc the base address of the ADC instance + * @param u8ChnIdx the index of the channel + * @return true interrupt is enabled on the selected channel + * @return false interrupt is disabled on the selected channel + */ +LOCAL_INLINE bool ADC_HWA_GetChannelInterruptEnable(const ADC_Type *const pAdc, const uint8_t u8ChnIdx) +{ + uint32_t u32TmpVal = pAdc->SC[u8ChnIdx]; + u32TmpVal = (u32TmpVal & ADC_SC_AIEN_MASK) >> ADC_SC_AIEN_SHIFT; + + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Set to enable or disable interrupt on the selected ADC channel + * + * @note this function is used only in ADC discontinuous mode to get the channel interrupt + * settings + * + * @param pAdc the base address of the ADC instance + * @param u8ChnIdx the index of the channel + * @param bEnable whether to enable interrupt on the selected ADC channel + */ +LOCAL_INLINE void ADC_HWA_SetChannelInterruptEnable(ADC_Type *const pAdc, const uint8_t u8ChnIdx, bool bEnable) +{ + pAdc->SC[u8ChnIdx] = (pAdc->SC[u8ChnIdx] & ~ADC_SC_AIEN_MASK) | ADC_SC_AIEN(bEnable); +} + +/** + * @brief Get the input channel of the selected ADC channel + * + * @param pAdc the base address of the ADC instance + * @param u8ChnIdx the index of the channel + * @return uint8_t the hardware input channel + */ +LOCAL_INLINE uint8_t ADC_HWA_GetChannelInput(const ADC_Type *const pAdc, const uint8_t u8ChnIdx) +{ + uint32_t u32TmpVal = (pAdc->SC[u8ChnIdx] & ADC_SC_CHS_MASK) >> ADC_SC_CHS_SHIFT; + return (uint8_t)u32TmpVal; +} + +/** + * @brief Set the input channel to the selected ADC channel + * + * @param pAdc the base address of the ADC instance + * @param u8ChnIdx the index of the channel + * @param u8InputChann the hardware input channel + */ +LOCAL_INLINE void ADC_HWA_SetChannelInput(ADC_Type *const pAdc, const uint8_t u8ChnIdx, uint8_t u8InputChann) +{ + pAdc->SC[u8ChnIdx] = (pAdc->SC[u8ChnIdx] & ~ADC_SC_CHS_MASK) | ADC_SC_CHS(u8InputChann); +} + +/** + * @brief Get the conversion result data of the ADC instance + * + * @note only result data of ADC discontinuous mode will be stored in RESULTn register. + * + * @param pAdc the base address of the ADC instance + * @param u8ChnIdx the index of the ADC channel + * @return uint32_t the ADC conversion result + */ +LOCAL_INLINE uint32_t ADC_HWA_GetChannelData(const ADC_Type *const pAdc, const uint8_t u8ChnIdx) +{ + uint32_t u32TmpVal = pAdc->RESULT[u8ChnIdx]; + u32TmpVal = (u32TmpVal & ADC_RESULT_RESULT_MASK) >> ADC_RESULT_RESULT_SHIFT; + + return (uint32_t)u32TmpVal; +} + +/** @}*/ + +#endif /* _HWA_ADC_H_ */ diff --git a/MODULES/HwA_Flagchip_FC7240/Inc/HwA_aontimer.h b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_aontimer.h new file mode 100644 index 0000000..c9fd40d --- /dev/null +++ b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_aontimer.h @@ -0,0 +1,299 @@ +/** + * @file HwA_aontimer.h + * @author Flagchip + * @brief FC7xxx aontimer hardware access layer + * @version 0.1.0 + * @date 2024-01-10 + * + * @copyright Copyright (c) 2023 Flagchip Semiconductors Co., Ltd. + * + * @details + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-01-10 Flagchip076 N/A First version for FC7240 + ******************************************************************************** */ + +#ifndef HWA_INCLUDE_HWA_AONTIMER_H_ +#define HWA_INCLUDE_HWA_AONTIMER_H_ + +#include "device_header.h" + +/** + * @addtogroup HwA_AONTIMER + * @{ + * + */ + +/********* Local typedef ************/ +/** + * @brief The clock source of the pulse mode + * + */ +typedef enum +{ + + AONTIMER_CLK0_PIN = 0, /*!< select the Aontimer_clk0 pin as pulse sourse*/ + AONTIMER_CLK1_PIN, /*!< select the Aontimer_clk1 pin as pulse sourse*/ + AONTIMER_CLK2_PIN, /*!< select the Aontimer_clk2 pin as pulse sourse*/ + AONTIMER_TRGSEL_OUTPUT, /*!< select the tresel as pulse sourse*/ + +} AONTIMER_PulseClkSrcType; + +/** + * @brief Aontimer clock source, please refer to Reference Manual chapter8.Aontimer for details. + * + * */ +typedef enum +{ + AONTIMER_SIRC_1MHZ = 0U, /*!< AONTIMER SIRC 1mhz clock */ + AONTIMER_RTC_CLK = 2U, /*!< AONTIMER RTC clock */ + AONTIMER_IRC_CLK = 3U /*!< AONTIMER internal clock, which comes from PCC */ +} AONTIMER_ClkSrcType; + +/** + * @brief The polarity of pulse mode + * + * */ +typedef enum +{ + AONTIMER_PulsePolarityType_HIGH = 0, /*!< select the high polarity */ + AONTIMER_PulsePolarityType_LOW /*!< select the low polarity */ +} AONTIMER_PulsePolarityType; + +/********* Local inline function ************/ +/** + * @brief Configure AONTIMER module + * + * @param u32RegValue CSR register value + */ +LOCAL_INLINE void AONTIMER_HWA_ConfigModule(uint32_t u32RegValue) +{ + AONTIMER->CSR = u32RegValue; +} + +/** + * @brief Configure AONTIMER module prescale + * + * @param u32RegValue PSR register value + */ +LOCAL_INLINE void AONTIMER_HWA_ConfigModulePrescale(uint32_t u32RegValue) +{ + AONTIMER->PSR = u32RegValue; +} + +/** + * @brief Set AONTIMER compare value + * + * @param u32RegValue CMR register value + */ +LOCAL_INLINE void AONTIMER_HWA_SetModuleCompareValue(uint32_t u32RegValue) +{ + AONTIMER->CMR = u32RegValue; +} + +/** + * @brief Set AONTIMER current counter value + * + * @param u32RegValue CNR register value + */ +LOCAL_INLINE void AONTIMER_HWA_SetModuleCounterValue(uint32_t u32RegValue) +{ + AONTIMER->CNR = u32RegValue; +} + +/** + * @brief Set AONTIMER module running on debug mode + * + */ +LOCAL_INLINE void AONTIMER_HWA_SetModuleRunOnDebug(void) +{ + AONTIMER->CSR |= (uint32_t)AONTIMER_CSR_DBGEN_MASK; +} + +/** + * @brief Enable AONTIMER module interrupt + * + */ +LOCAL_INLINE void AONTIMER_HWA_EnableModuleInterrupt(void) +{ + AONTIMER->CSR |= (uint32_t)AONTIMER_CSR_TIE_MASK; +} + +/** + * @brief Select AONTIMER module external clock source when timer configured to pulse mode + * + * @param eClk Input counter clock source + */ +LOCAL_INLINE void AONTIMER_HWA_SelectClkSrcOnPulseMode(AONTIMER_PulseClkSrcType eClk) +{ + uint32_t u32RegValue = AONTIMER->CSR; + AONTIMER->CSR |= (u32RegValue & ~(uint32_t)AONTIMER_CSR_TPS_MASK) | AONTIMER_CSR_TPS(eClk); +} + +/** + * @brief Clear AONTIMER interrupt flags + * + */ +LOCAL_INLINE void AONTIMER_HWA_ClearInterruptFlag(void) +{ + AONTIMER->CSR |= (uint32_t)AONTIMER_CSR_TCF_MASK; +} + +/** + * @brief Set AONTIMER module polarity. Pulse counter input source is active-low, and the CNR increments on falling-edge. + * + */ +LOCAL_INLINE void AONTIMER_HWA_SetModulePolarity(void) +{ + AONTIMER->CSR |= (uint32_t)AONTIMER_CSR_TPP_MASK; +} + +/** + * @brief Configure AONTIMER module polarity. If ePol is 0:Pulse counter input source is active-high, and the CNR increments on rising-edge. + * If ePol is 1:Pulse counter input source is active-low, and the CNR increments on falling-edge. + * + * @param ePol Polarity enumeration + */ +LOCAL_INLINE void AONTIMER_HWA_ConfigModulePolarity(AONTIMER_PulsePolarityType ePol) +{ + AONTIMER->CSR |= AONTIMER_CSR_TPP(ePol); +} + +/** + * @brief Enable AONTIMER module pulse mode + * + */ +LOCAL_INLINE void AONTIMER_HWA_EnablePulseMode(void) +{ + AONTIMER->CSR |= (uint32_t)AONTIMER_CSR_TMS_MASK; +} + +/** + * @brief Enable AONTIMER timer + * + */ +LOCAL_INLINE void AONTIMER_HWA_EnableTimer(void) +{ + AONTIMER->CSR |= (uint32_t)AONTIMER_CSR_TEN_MASK; +} + +/** + * @brief Set AONTIMER prescale + * + * @param u8PrescalerValue Prescaler value,the range of the input value is :0~15, and the range of prescaler is :2^1 ~ 2^16. + */ +LOCAL_INLINE void AONTIMER_HWA_SetPrescale(uint8_t u8PrescalerValue) +{ + uint32_t u32RegValue = AONTIMER->PSR; + AONTIMER->PSR = ((u32RegValue & ~(uint32_t)AONTIMER_PSR_PRESCALE_MASK) | AONTIMER_PSR_PRESCALE(u8PrescalerValue)); +} + +/** + * @brief If enable bypass mode, the timer will bypass the prescaler in timer counter mode or glitch filter in pulse mode + * + */ +LOCAL_INLINE void AONTIMER_HWA_EnableBypassMode(void) +{ + AONTIMER->PSR |= (uint32_t)AONTIMER_PSR_PBYP_MASK; +} + +/** + * @brief Select AONTIMER mdoule clock source + * + * @param eClk Aontimer clock source + */ +LOCAL_INLINE void AONTIMER_HWA_SelectModuleClkSrc(AONTIMER_ClkSrcType eClk) +{ + uint32_t u32RegValue = AONTIMER->PSR; + AONTIMER->PSR = ((u32RegValue & ~(uint32_t)AONTIMER_PSR_PCS_MASK) | AONTIMER_PSR_PCS(eClk)); +} + +/** + * @brief Set AONTIMER module stop on debug mode + * + */ +LOCAL_INLINE void AONTIMER_HWA_SetModuleStopOnDebug(void) +{ + AONTIMER->CSR &= ~(uint32_t)AONTIMER_CSR_DBGEN_MASK; +} + + +/** + * @brief Disable AONTIMER module interrupt + * + */ +LOCAL_INLINE void AONTIMER_HWA_DisableModuleInterrupt(void) +{ + AONTIMER->CSR &= ~(uint32_t)AONTIMER_CSR_TIE_MASK; +} + +/** + * @brief Clear AONTIMER module mode + * + */ +LOCAL_INLINE void AONTIMER_HWA_ClearModuleMode(void) +{ + AONTIMER->CSR &= ~(uint32_t)AONTIMER_CSR_TPS_MASK; +} + +/** + * @brief Clear AONTIMER module polarity. Pulse counter input source is active-high, and the CNR increments on rising-edge. + * + */ +LOCAL_INLINE void AONTIMER_HWA_ClearModulePolarity(void) +{ + AONTIMER->CSR &= ~(uint32_t)AONTIMER_CSR_TPP_MASK; +} + +/** + * @brief Disable AONTIEMR module pulse mode + * + */ +LOCAL_INLINE void AONTIMER_HWA_DisablePulseMode(void) +{ + AONTIMER->CSR &= ~(uint32_t)AONTIMER_CSR_TMS_MASK; +} + +/** + * @brief Disable AONTIMER module timer + * + */ +LOCAL_INLINE void AONTIMER_HWA_DisableTimer(void) +{ + AONTIMER->CSR &= ~(uint32_t)AONTIMER_CSR_TEN_MASK; +} + +/** + * @brief Clear AONTIMER module prescaler + * + */ +LOCAL_INLINE void AONTIMER_HWA_ClearPrescale(void) +{ + AONTIMER->PSR &= ~(uint32_t)AONTIMER_PSR_PRESCALE_MASK; +} + +/** + * @brief If disable bypass mode, the timer will enable the prescaler in timer counter mode or glitch filter in pulse mode + * + */ +LOCAL_INLINE void AONTIMER_HWA_DisableBypassMode(void) +{ + AONTIMER->PSR &= ~(uint32_t)AONTIMER_PSR_PBYP_MASK; +} + +/** + * @brief Clear AONTIMER module clock source + * + */ +LOCAL_INLINE void AONTIMER_HWA_ClearModuleClkSrc(void) +{ + AONTIMER->PSR &= ~(uint32_t)AONTIMER_PSR_PCS_MASK; +} + +/** @}*/ /* HwA_AONTIMER */ + +#endif /* HWA_INCLUDE_HWA_AONTIMER_H_ */ diff --git a/MODULES/HwA_Flagchip_FC7240/Inc/HwA_cm7.h b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_cm7.h new file mode 100644 index 0000000..694fbcc --- /dev/null +++ b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_cm7.h @@ -0,0 +1,39 @@ +/** + * @file HwA_cm7.h + * @author Flagchip + * @brief FC7xxx cortex m4 hardware access layer + * @version 0.1.0 + * @date 2022-11-21 + * + * @copyright Copyright (c) 2022 Flagchip Semiconductors Co., Ltd. + * + * @details + */ + +#ifndef _HWA_CM7_H_ +#define _HWA_CM7_H_ + +#include "device_header.h" + +/** + * @brief Enable deepsleep mode + * + */ +LOCAL_INLINE void CM7_HWA_EnableDeepSleep(void) +{ + SCB->SCR |= (uint32_t)SCB_SCR_SLEEPDEEP_Msk; +} + +/** + * @brief Disable deepsleep mode + * + */ +LOCAL_INLINE void CM7_HWA_DisableDeepSleep(void) +{ + SCB->SCR &= ~(uint32_t)SCB_SCR_SLEEPDEEP_Msk; +} + + + + +#endif /* #ifndef _HWA_CM7_H_ */ diff --git a/MODULES/HwA_Flagchip_FC7240/Inc/HwA_cmp.h b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_cmp.h new file mode 100644 index 0000000..ebdd75b --- /dev/null +++ b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_cmp.h @@ -0,0 +1,947 @@ +/** + * @file HwA_cmp.h + * @author Flagchip0126 + * @brief FC7xxx CMP driver type definition and API + * @version 0.1.0 + * @date 2024-01-15 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + * @details + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-01-15 Flagchip0126 N/A First version for FC7240 + ******************************************************************************** */ + + +#ifndef _HWA_CMP_H_ +#define _HWA_CMP_H_ + +#include "device_header.h" + +/********* Local typedef ************/ + +/** + * @brief The CMP complete DMA callback function prototype + * + */ + +/** + * @brief The instance index of the CMP mode + */ +typedef enum +{ + CMP_MOD_DISABLE = 0U, /*!< CMP function mode is disable */ + CMP_MOD_CONTINUOUS = 1U, /*!< CMP function mode is continuous */ + CMP_MOD_SAMPLE_NONFILTER_EXTCLK = 2U, /*!< CMP function mode is sampled,non-filtered mode 1*/ + CMP_MOD_SAMPLE_NONFILTER_INTCLK = 3U, /*!< CMP function mode is sampled,non-filtered mode 2*/ + CMP_MOD_SAMPLE_FILTER_EXTCLK = 4U, /*!< CMP function mode is sampled,filtered mode 1*/ + CMP_MOD_SAMPLE_FILTER_INTCLK = 5U, /*!< CMP function mode is sampled,filtered mode 2*/ + CMP_MOD_WINDOW = 6U, /*!< CMP function mode is windowed mode */ + CMP_MOD_WINDOW_RESAMPLE = 7U, /*!< CMP function mode is windowed,re-sampled mode */ + CMP_MOD_WINDOW_FILTER = 8U, /*!< CMP function mode is windowed,filtered mode */ + CMP_MOD_CHANNEL_SCAN = 9U /*!< CMP channel scan mode */ +} CMP_ModSelType; + +/** + * @brief The instance index of the CMP peripheral + */ +typedef enum +{ + CMP_INSTANCE_0 = 0U, /*!< CMP instance 0 is selected */ + CMP_INSTANCE_1 = 1U /*!< CMP instance 1 is selected */ +} CMP_InstanceType; + +/** + * @brief The instance index of the CMP DAC enable select + */ +typedef enum +{ + CMP_DACENABLE_DCR = 0U, /*!< CMP Dac is enabled by DCR[DAC_EN] */ + CMP_DACENABLE_CCR0 = 1U /*!< CMP Dac is enabled by CCR0[EN] */ +} CMP_DacEnableSrcType; + +/** + * @brief The instance index of the CMP output invert + */ +typedef enum +{ + CMP_NON_INVERT = 0U, /*!< CMP output do not Invert*/ + CMP_INVERT = 1U /*!< CMP output Invert */ +} CMP_InvertType; + +/** + * @brief The instance index of the CMP output select + */ +typedef enum +{ + CMP_FILTEROUT = 0U, /*!< CMP filter output */ + CMP_UNFILTEROUT = 1U /*!< CMP Unfilter output */ +} CMP_OutSelectType; + +/** + * @brief The instance index of the CMP window level + */ +typedef enum +{ + CMP_HOLD = 0U, /*!< CMP output hold when window close */ + CMP_USERDEF = 1U /*!< CMP output userdefine when window close */ +} CMP_OutWinLevelType; + +/** + * @brief The instance index of the window output under userdefine CMP window level + */ +typedef enum +{ + CMP_OUTWIN_0 = 0U, /*!< CMP window output is 0 */ + CMP_OUTWIN_1 = 1U /*!< CMP window output is 1 */ +} CMP_OutWinLevel_UserDefType; + + +/** + * @brief The instance index of the CMP Event caused window close + */ +typedef enum +{ + CMP_RISINGEDGE = 0U, /*!< CMP output event RisingEdge causes window close */ + CMP_FALLINGEDGE = 1U, /*!< CMP output event FallingEdge causes window close */ + CMP_BOTHEDGES = 2U, /*!< CMP output event bothEdges causes window close */ +} CMP_EventType; + +/** + * @brief The instance index of the CMP filter count numbers + */ +typedef enum +{ + CMP_FILTERCNT_0 = 0U, /*!< CMP filter is bypassed */ + CMP_FILTERCNT_1 = 1U, /*!< CMP filter is 1 consecutive sample */ + CMP_FILTERCNT_2 = 2U, /*!< CMP filter is 2 consecutive sample */ + CMP_FILTERCNT_3 = 3U, /*!< CMP filter is 3 consecutive sample */ + CMP_FILTERCNT_4 = 4U /*!< CMP filter is 4 consecutive sample */ +} CMP_FilterCntType; + +/** + * @brief The instance index of the CMP hysteresis control + */ +typedef enum +{ + CMP_HYSTCTRL_0 = 0U, /*!< CMP 0 hysteresis internal */ + CMP_HYSTCTRL_1 = 1U, /*!< CMP 1 hysteresis internal */ + CMP_HYSTCTRL_2 = 2U, /*!< CMP 2 hysteresis internal */ + CMP_HYSTCTRL_3 = 3U /*!< CMP 3 hysteresis internal */ +} CMP_HystCtrlType; + +/** + * @brief The fixed CMP port for reference in channel scan mode + */ +typedef enum +{ + CMP_PORTSEL_MUX_POSITIVE = 0U, + CMP_PORTSEL_MUX_NEGATIVE = 1U +} CMP_PortSelType; + +/** + * @brief The source of the CMP input + */ +typedef enum +{ + CMP_INSRCSEL_DAC = 0U, /*!< CMP input source is DAC */ + CMP_INSRCSEL_MUX = 1U /*!< CMP input source is analog 1-8 mux */ +} CMP_INSrcSelType; + +/** + * @brief The instance index of the CMP input mux + */ +typedef enum +{ + CMP_INSEL_MUX_IN0 = 0U, /*!< CMP input mux from IN0(CMP0,CMP1) */ + CMP_INSEL_MUX_IN1 = 1U, /*!< CMP input mux from IN1(CMP0,CMP1) */ + CMP_INSEL_MUX_IN2 = 2U, /*!< CMP input mux from IN2(CMP0,CMP1) */ + CMP_INSEL_MUX_IN3 = 3U, /*!< CMP input mux from IN3(CMP0,CMP1) */ + CMP_INSEL_MUX_IN4 = 4U, /*!< CMP input mux from IN4(CMP0,CMP1) */ + CMP_INSEL_MUX_IN5 = 5U, /*!< CMP input mux from IN5(CMP0,CMP1) */ + CMP_INSEL_MUX_IN6 = 6U, /*!< CMP input mux from IN6(CMP0,CMP1) */ + CMP_INSEL_MUX_IN7 = 7U /*!< CMP input mux from IN7(CMP0,CMP1) */ +} CMP_MuxSelType; + +/** + * @brief The instance index of DAC high voltage reference select + */ +typedef enum +{ + CMP_DACVINREF_H0 = 0U, /*!< CMP DAC high voltage input reference vrefh0 */ + CMP_DACVINREF_H1 = 1U /*!< CMP DAC high voltage input reference vrefh1 */ +} CMP_DacVinRefSelType; + +/** + * @brief The instance index of high power mode select + */ +typedef enum +{ + CMP_LOWSPEEDMOD = 0U, /*!< CMP low speed mode */ + CMP_HIGHSPEEDMOD = 1U /*!< CMP high speed mode */ +} CMP_SpeedModSelType; + +/** + * @brief Defines CMP out status + */ +typedef enum +{ + CMP_OUT_FALLING_EDGE = 0U, /*!< CMP out detect falling edge */ + CMP_OUT_RISING_EDGE = 1U, /*!< CMP out detect rising edge */ + CMP_OUT_NONE = 2U /*!< CMP out detect none */ +} CMP_OutStatus; + +/********* Local inline function ************/ + +/** + * @brief set CMP enable + * + * @param pCmp the CMP instance to use + */ +LOCAL_INLINE void CMP_HWA_Enable(CMP_Type *const pCmp) +{ + uint32_t u32RegVal = pCmp->CCR0; + pCmp->CCR0 = ((u32RegVal & (~(uint32_t)CMP_CCR0_EN_MASK)) | CMP_CCR0_EN(true)); +} + +/** + * @brief set CMP disable + * + * @param pCmp the CMP instance to use + */ +LOCAL_INLINE void CMP_HWA_Disable(CMP_Type *const pCmp) +{ + uint32_t u32RegVal = pCmp->CCR0; + pCmp->CCR0 = ((u32RegVal & (~(uint32_t)CMP_CCR0_EN_MASK)) | CMP_CCR0_EN(false)); +} + +/** + * @brief set CMP DMA enable + * + * @param pCmp the CMP instance to use + */ +LOCAL_INLINE void CMP_HWA_DmaEnable(CMP_Type *const pCmp) +{ + uint32_t u32RegVal = pCmp->CCR1; + pCmp->CCR1 = ((u32RegVal & (~(uint32_t)CMP_CCR1_DMA_EN_MASK)) | CMP_CCR1_DMA_EN(true)); +} + +/** + * @brief set CMP DMA disable + * + * @param pCmp the CMP instance to use + */ +LOCAL_INLINE void CMP_HWA_DmaDisable(CMP_Type *const pCmp) +{ + uint32_t u32RegVal = pCmp->CCR1; + pCmp->CCR1 = ((u32RegVal & (~(uint32_t)CMP_CCR1_DMA_EN_MASK)) | CMP_CCR1_DMA_EN(false)); +} + +/** + * @brief set CMP mode + * + * @param pCmp the CMP instance to use + * @param eMod the CMP mode to use + * @param u8FilterPrd the CMP filter period + * @param eFilterCnt the CMP filter sample count + */ +LOCAL_INLINE void CMP_HWA_SetComparatorMod(CMP_Type *const pCmp, CMP_ModSelType eMod, uint8_t u8FilterPrd, CMP_FilterCntType eFilterCnt) +{ + switch (eMod) + { + case CMP_MOD_DISABLE: + { + /* Nothing deal with */ + } + break; + + case CMP_MOD_CONTINUOUS: + { + pCmp->CCR1 |= CMP_CCR1_WIN_EN(false) | + CMP_CCR1_SAMPLE_EN(false); + } + break; + + case CMP_MOD_SAMPLE_NONFILTER_EXTCLK: + { + pCmp->CCR1 |= CMP_CCR1_WIN_EN(false) | + CMP_CCR1_SAMPLE_EN(true) | + CMP_CCR1_FILT_CNT(0x01); + } + break; + + case CMP_MOD_SAMPLE_NONFILTER_INTCLK: + { + pCmp->CCR1 |= CMP_CCR1_WIN_EN(false) | + CMP_CCR1_SAMPLE_EN(false) | + CMP_CCR1_FILT_CNT(0x01) | + CMP_CCR1_FILT_PER(u8FilterPrd); + } + break; + + case CMP_MOD_SAMPLE_FILTER_EXTCLK: + { + pCmp->CCR1 |= CMP_CCR1_WIN_EN(false) | + CMP_CCR1_SAMPLE_EN(true) | + CMP_CCR1_FILT_CNT(u8FilterPrd); + } + break; + + case CMP_MOD_SAMPLE_FILTER_INTCLK: + { + pCmp->CCR1 |= CMP_CCR1_WIN_EN(false) | + CMP_CCR1_SAMPLE_EN(false) | + CMP_CCR1_FILT_CNT(eFilterCnt) | + CMP_CCR1_FILT_PER(u8FilterPrd); + } + break; + + case CMP_MOD_WINDOW: + { + pCmp->CCR1 |= CMP_CCR1_WIN_EN(true) | + CMP_CCR1_SAMPLE_EN(false) | + CMP_CCR1_FILT_CNT(0x00) | + CMP_CCR1_FILT_PER(0x00); + } + break; + + case CMP_MOD_WINDOW_RESAMPLE: + { + pCmp->CCR1 |= CMP_CCR1_WIN_EN(true) | + CMP_CCR1_SAMPLE_EN(false) | + CMP_CCR1_FILT_CNT(0x01) | + CMP_CCR1_FILT_PER(u8FilterPrd); + } + break; + + case CMP_MOD_WINDOW_FILTER: + { + pCmp->CCR1 |= CMP_CCR1_WIN_EN(true) | + CMP_CCR1_SAMPLE_EN(false) | + CMP_CCR1_FILT_CNT(eFilterCnt) | + CMP_CCR1_FILT_PER(u8FilterPrd); + } + break; + + case CMP_MOD_CHANNEL_SCAN: + { + pCmp->CSCR0 |= CMP_CSCR0_CS_EN(true) ; + } + + break; + default: + break; + } +} + +/** + * @brief STOP mode enable + * + * @param pCmp the CMP instance to use + * @param bEnable enable/disable flag + */ +LOCAL_INLINE void CMP_HWA_SetEnStopMod(CMP_Type *const pCmp, bool bEnable) +{ + uint32_t u32RegVal = pCmp->CCR0; + pCmp->CCR0 = ((u32RegVal & (~(uint32_t)CMP_CCR0_STOP_EN_MASK)) | CMP_CCR0_STOP_EN(bEnable)); +} + +/** + * @brief set DAC enable selection + * + * @param pCmp the CMP instance to use + * @param eType Dac enable source + */ +LOCAL_INLINE void CMP_HWA_SetDacEnableSrc(CMP_Type *const pCmp, CMP_DacEnableSrcType eType) +{ + uint32_t u32RegVal = pCmp->CCR0; + pCmp->CCR0 = ((u32RegVal & (~(uint32_t)CMP_CCR0_DACEN_SEL_MASK)) | CMP_CCR0_DACEN_SEL(eType)); +} + +/** + * @brief set CPM output invert + * + * @param pCmp the CMP instance to use + * @param eType CPM output invert type + */ +LOCAL_INLINE void CMP_HWA_SetCmpOutInvert(CMP_Type *const pCmp, CMP_InvertType eType) +{ + uint32_t u32RegVal = pCmp->CCR1; + pCmp->CCR1 = ((u32RegVal & (~(uint32_t)CMP_CCR1_CMPOUT_INV_MASK)) | CMP_CCR1_CMPOUT_INV(eType)); +} + +/** + * @brief set CPM output filter/unfilter selection + * + * @param pCmp the CMP instance to use + * @param eType CPM output filter/unfilter type + */ +LOCAL_INLINE void CMP_HWA_SetCmpOutSel(CMP_Type *const pCmp, CMP_OutSelectType eType) +{ + uint32_t u32RegVal = pCmp->CCR1; + pCmp->CCR1 = ((u32RegVal & (~(uint32_t)CMP_CCR1_CMPOUT_SEL_MASK)) | CMP_CCR1_CMPOUT_SEL(eType)); +} + +/** + * @brief set comparator output pin enable + * + * @param pCmp the CMP instance to use + * @param bEnable enable/disable flag + */ +LOCAL_INLINE void CMP_HWA_SetEnCmpOutPack(CMP_Type *const pCmp, bool bEnable) +{ + uint32_t u32RegVal = pCmp->CCR1; + pCmp->CCR1 = ((u32RegVal & (~(uint32_t)CMP_CCR1_CMPOUT_PEN_MASK)) | CMP_CCR1_CMPOUT_PEN(bEnable)); +} + +/** + * @brief set CMPOUT_WIN level, when window is closed + * + * @param pCmp the CMP instance to use + * @param eType CMPOUT_WIN level type + */ +LOCAL_INLINE void CMP_HWA_SetCmpOutWinLevel(CMP_Type *const pCmp, CMP_OutWinLevelType eType) +{ + uint32_t u32RegVal = pCmp->CCR1; + pCmp->CCR1 = ((u32RegVal & (~(uint32_t)CMP_CCR1_CMPOUT_WIN_OWEN_MASK)) | CMP_CCR1_CMPOUT_WIN_OWEN(eType)); +} + +/** + * @brief set CMPOUT_WIN level in user-define mode, when window is closed + * + * @param pCmp the CMP instance to use + * @param eType user-define CMPOUT_WIN level type + */ +LOCAL_INLINE void CMP_HWA_SetCmpOutWin(CMP_Type *const pCmp, CMP_OutWinLevel_UserDefType eType) +{ + uint32_t u32RegVal = pCmp->CCR1; + pCmp->CCR1 = ((u32RegVal & (~(uint32_t)CMP_CCR1_CMPOUT_WIN_OW_MASK)) | CMP_CCR1_CMPOUT_WIN_OW(eType)); +} + +/** + * @brief set invert the WINDOW/SAMPLE signal enable or not + * + * @param pCmp the CMP instance to use + * @param bEnable enable/disable flag + */ +LOCAL_INLINE void CMP_HWA_SetEnWinSampleInvert(CMP_Type *const pCmp, bool bEnable) +{ + uint32_t u32RegVal = pCmp->CCR1; + pCmp->CCR1 = ((u32RegVal & (~(uint32_t)CMP_CCR1_WIN_INV_MASK)) | CMP_CCR1_WIN_INV(bEnable)); +} + +/** + * @brief WINDOW signal can or not be closed by CMPO event when window mode + * + * @param pCmp the CMP instance to use + * @param bEnable enable/disable flag + */ +LOCAL_INLINE void CMP_HWA_SetEnEventCloseWin(CMP_Type *const pCmp, bool bEnable) +{ + uint32_t u32RegVal = pCmp->CCR1; + pCmp->CCR1 = ((u32RegVal & (~(uint32_t)CMP_CCR1_WIN_CLS_MASK)) | CMP_CCR1_WIN_CLS(bEnable)); +} + +/** + * @brief set which CMPO event causes window close + * + * @param pCmp the CMP instance to use + * @param eType CMPO event type + */ +LOCAL_INLINE void CMP_HWA_SetEventCloseWin(CMP_Type *const pCmp, CMP_EventType eType) +{ + uint32_t u32RegVal = pCmp->CCR1; + pCmp->CCR1 = ((u32RegVal & (~(uint32_t)CMP_CCR1_EVT_SEL_MASK)) | CMP_CCR1_EVT_SEL(eType)); +} + +/** + * @brief set CMP power mode select + * + * @param pCmp the CMP instance to use + * @param eMod CMP power mode + */ +LOCAL_INLINE void CMP_HWA_SetSpeedMod(CMP_Type *const pCmp, CMP_SpeedModSelType eMod) +{ + uint32_t u32RegVal = pCmp->CCR2; + pCmp->CCR2 = ((u32RegVal & (~(uint32_t)CMP_CCR2_HPMD_MASK)) | CMP_CCR2_HPMD(eMod)); +} + +/** + * @brief set Comparator hard block hysteresis control + * + * @param pCmp the CMP instance to use + * @param eType CMP hysteresis control type + */ +LOCAL_INLINE void CMP_HWA_SetHystCtrl(CMP_Type *const pCmp, CMP_HystCtrlType eType) +{ + uint32_t u32RegVal = pCmp->CCR2; + pCmp->CCR2 = ((u32RegVal & (~(uint32_t)CMP_CCR2_HYSTCTR_MASK)) | CMP_CCR2_HYSTCTR(eType)); +} + +/** + * @brief set Comparator analog confifuration transition bypass + * + * @param pCmp the CMP instance to use + * @param Enable The status for Comparator analog confifuration transition bypass + */ +LOCAL_INLINE void CMP_HWA_SetAnalogConfTransByp(CMP_Type *const pCmp, bool Enable) +{ + uint32_t u32RegVal = pCmp->CCR3; + pCmp->CCR3 = ((u32RegVal & (~(uint32_t)CMP_CCR3_DAC_TRANS_BYP_MASK)) | CMP_CCR3_DAC_TRANS_BYP(Enable)); +} + +/** + * @brief set Comparator hard block hysteresis control + * + * @param pCmp the CMP instance to use + * @param Count Comparator analog confifuration transition bypass count + */ +LOCAL_INLINE void CMP_HWA_SetAnalogConfTransBypCnt(CMP_Type *const pCmp, uint16_t Count) +{ + uint32_t u32RegVal = pCmp->CCR3; + Count = Count & 0x3ff; + pCmp->CCR3 = ((u32RegVal & (~(uint32_t)CMP_CCR3_DAC_RDY_CNT_MASK)) | CMP_CCR3_DAC_RDY_CNT(Count)); +} + +/** + * @brief set which input is selected for the positive mux + * + * @param pCmp the CMP instance to use + * @param eType CMP positive mux type + */ +LOCAL_INLINE void CMP_HWA_SetPSelMux(CMP_Type *const pCmp, CMP_MuxSelType eType) +{ + uint32_t u32RegVal = pCmp->CCR2; + pCmp->CCR2 = ((u32RegVal & (~(uint32_t)CMP_CCR2_PSEL_MASK)) | CMP_CCR2_PSEL(eType)); +} + +/** + * @brief set which input is selected for the negative mux + * + * @param pCmp the CMP instance to use + * @param eType CMP negative mux type + */ +LOCAL_INLINE void CMP_HWA_SetNSelMux(CMP_Type *const pCmp, CMP_MuxSelType eType) +{ + uint32_t u32RegVal = pCmp->CCR2; + pCmp->CCR2 = ((u32RegVal & (~(uint32_t)CMP_CCR2_MSEL_MASK)) | CMP_CCR2_MSEL(eType)); +} + +/** + * @brief set the input to the positive port of the comparator + * + * @param pCmp the CMP instance to use + * @param eType CMP positive input source type(analog mux,dac) + */ +LOCAL_INLINE void CMP_HWA_SetINPSel(CMP_Type *const pCmp, CMP_INSrcSelType eType) +{ + uint32_t u32RegVal = pCmp->CCR2; + pCmp->CCR2 = ((u32RegVal & (~(uint32_t)CMP_CCR2_INPSEL_MASK)) | CMP_CCR2_INPSEL(eType)); +} + +/** + * @brief set the input to the negative port of the comparator + * + * @param pCmp the CMP instance to use + * @param eType CMP negative input source type(analog mux,dac) + */ +LOCAL_INLINE void CMP_HWA_SetINNSel(CMP_Type *const pCmp, CMP_INSrcSelType eType) +{ + uint32_t u32RegVal = pCmp->CCR2; + pCmp->CCR2 = ((u32RegVal & (~(uint32_t)CMP_CCR2_INMSEL_MASK)) | CMP_CCR2_INMSEL(eType)); +} + +/** + * @brief set CMP DAC enable + * + * @param pCmp the CMP instance to use + * @param bEnable enable/disable flag + */ +LOCAL_INLINE void CMP_HWA_SetEnDac(CMP_Type *const pCmp, bool bEnable) +{ + uint32_t u32RegVal = pCmp->DCR; + pCmp->DCR = ((u32RegVal & (~(uint32_t)CMP_DCR_DAC_EN_MASK)) | CMP_DCR_DAC_EN(bEnable)); +} + + +/** + * @brief set DAC reference voltage source + * + * @param pCmp the CMP instance to use + * @param eType CMP reference voltage source type + */ +LOCAL_INLINE void CMP_HWA_SetVinRefSel(CMP_Type *const pCmp, CMP_DacVinRefSelType eType) +{ + uint32_t u32RegVal = pCmp->DCR; + pCmp->DCR = ((u32RegVal & (~(uint32_t)CMP_DCR_VRSEL_MASK)) | CMP_DCR_VRSEL(eType)); +} + +/** + * @brief set CMP Dac output + * + * @param pCmp the CMP instance to use + * @param u8Data the Dac data + * @note output = (VinRef / 256) * (u8Data + 1) + */ +LOCAL_INLINE void CMP_HWA_SetDacData(CMP_Type *const pCmp, uint8_t u8Data) +{ + uint32_t u32RegVal = pCmp->DCR; + pCmp->DCR = ((u32RegVal & (~(uint32_t)CMP_DCR_DAC_DATA_MASK)) | CMP_DCR_DAC_DATA(u8Data)); +} + +/** + * @brief set comparator rising interrupt enable + * + * @param pCmp the CMP instance to use + * @param bEnable enable/disable flag + */ +LOCAL_INLINE void CMP_HWA_SetIntEn_Rising(CMP_Type *const pCmp, bool bEnable) +{ + uint32_t u32RegVal = pCmp->IER; + pCmp->IER = ((u32RegVal & (~(uint32_t)CMP_IER_CFR_IE_MASK)) | CMP_IER_CFR_IE(bEnable)); +} + +/** + * @brief get comparator rising interrupt enable status + * + * @param pCmp the CMP instance to use + * @return comparator rising interrupt status + */ +LOCAL_INLINE bool CMP_HWA_GetIntEn_Rising(CMP_Type *const pCmp) +{ + bool RetStatus = false; + uint32_t u32RegVal = pCmp->IER; + + RetStatus = (bool)((((u32RegVal & CMP_IER_CFR_IE_MASK) >> CMP_IER_CFR_IE_SHIFT) != 0U) ? true : false); + return RetStatus; +} + +/** + * @brief set comparator falling interrupt enable + * + * @param pCmp the CMP instance to use + * @param bEnable enable/disable flag + */ +LOCAL_INLINE void CMP_HWA_SetIntEn_Falling(CMP_Type *const pCmp, bool bEnable) +{ + uint32_t u32RegVal = pCmp->IER; + pCmp->IER = ((u32RegVal & (~(uint32_t)CMP_IER_CFF_IE_MASK)) | CMP_IER_CFF_IE(bEnable)); +} + +/** + * @brief get comparator falling interrupt enable status + * + * @param pCmp the CMP instance to use + * @return comparator falling interrupt status + */ +LOCAL_INLINE bool CMP_HWA_GetIntEn_Falling(CMP_Type *const pCmp) +{ + bool bRetStatus = false; + uint32_t u32RegVal = pCmp->IER; + + bRetStatus = (bool)((((u32RegVal & CMP_IER_CFF_IE_MASK) >> CMP_IER_CFF_IE_SHIFT) != 0U) ? true : false); + return bRetStatus; +} + +/** + * @brief set comparator channel scan interrupt enable + * + * @param pCmp the CMP instance to use + * @param bEnable enable/disable flag + */ +LOCAL_INLINE void CMP_HWA_SetIntEn_ChannelScan(CMP_Type *const pCmp, bool bEnable) +{ + uint32_t u32RegVal = pCmp->IER; + pCmp->IER = ((u32RegVal & (~(uint32_t)CMP_IER_CSF_IE_MASK)) | CMP_IER_CSF_IE(bEnable)); +} + +/** + * @brief get comparator channel scan interrupt enable status + * + * @param pCmp the CMP instance to use + * @return comparator channel scan interrupt status + */ +LOCAL_INLINE bool CMP_HWA_GetIntEn_ChannelScan(CMP_Type *const pCmp) +{ + bool bRetStatus = false; + uint32_t u32RegVal = pCmp->IER; + + bRetStatus = (bool)((((u32RegVal & CMP_IER_CSF_IE_MASK) >> CMP_IER_CSF_IE_SHIFT) != 0U) ? true : false); + return bRetStatus; +} + +/** + * @brief get CMP output rising edge status + * + * @param pCmp the CMP instance to use + * @return CMP rising edge status + */ +LOCAL_INLINE bool CMP_HWA_GetIntFlag_Rising(CMP_Type *const pCmp) +{ + bool bRetStatus = false; + uint32_t u32RegVal = pCmp->CSR; + + bRetStatus = (bool)((((u32RegVal & CMP_CSR_CFR_MASK) >> CMP_CSR_CFR_SHIFT) != 0U) ? true : false); + return bRetStatus; +} + +/** + * @brief get CMP output falling edge status + * + * @param pCmp the CMP instance to use + * @return CMP falling edge status + */ +LOCAL_INLINE bool CMP_HWA_GetIntFlag_Falling(CMP_Type *const pCmp) +{ + bool bRetStatus = false; + uint32_t u32RegVal = pCmp->CSR; + + bRetStatus = (bool)((((u32RegVal & CMP_CSR_CFF_MASK) >> CMP_CSR_CFF_SHIFT) != 0U) ? true : false); + return bRetStatus; +} + +/** + * @brief get CMP output channel scan status + * + * @param pCmp the CMP instance to use + * @return CMP channel scan status + */ +LOCAL_INLINE bool CMP_HWA_GetIntFlag_ChannelScan(CMP_Type *const pCmp) +{ + bool bRetStatus = false; + uint32_t u32RegVal = pCmp->CSR; + + bRetStatus = (bool)((((u32RegVal & CMP_CSR_CSF_MASK) >> CMP_CSR_CSF_SHIFT) != 0U) ? true : false); + return bRetStatus; +} + + +/** + * @brief clear rising interrupt flag + * + * @param pCmp the CMP instance to use + */ +LOCAL_INLINE void CMP_HWA_ClearIntFlag_Rising(CMP_Type *const pCmp) +{ + uint32_t u32RegVal = pCmp->CSR; + pCmp->CSR = ((u32RegVal & (~(uint32_t)CMP_CSR_CFR_MASK)) | CMP_CSR_CFR(true)); +} + +/** + * @brief clear falling interrupt flag + * + * @param pCmp the CMP instance to use + */ +LOCAL_INLINE void CMP_HWA_ClearIntFlag_Falling(CMP_Type *const pCmp) +{ + uint32_t u32RegVal = pCmp->CSR; + pCmp->CSR = ((u32RegVal & (~(uint32_t)CMP_CSR_CFF_MASK)) | CMP_CSR_CFF(true)); +} + +/** + * @brief clear channel scan interrupt flag + * + * @param pCmp the CMP instance to use + */ +LOCAL_INLINE void CMP_HWA_ClearIntFlag_ChannelScan(CMP_Type *const pCmp) +{ + uint32_t u32RegVal = pCmp->CSR; + pCmp->CSR = ((u32RegVal & (~(uint32_t)CMP_CSR_CSF_MASK)) | CMP_CSR_CSF(true)); +} + +/** + * @brief get CMP filtered output + * + * @param pCmp the CMP instance to use + * @return CMP filtered output + */ +LOCAL_INLINE bool CMP_HWA_GetCmpOut(CMP_Type *const pCmp) +{ + bool CmpOut; + uint32_t u32RegVal = pCmp->CSR; + CmpOut = ((u32RegVal & CMP_CSR_CMPOUT_FILTER_MASK) >> CMP_CSR_CMPOUT_FILTER_SHIFT) ? true : false; + return CmpOut; +} + +/** + * @brief set CMP and DAC initialization delay modulus + * + * @param pCmp the CMP instance to use + */ +LOCAL_INLINE void CMP_HWA_SetCSInitModulus(CMP_Type *const pCmp, uint8_t u8Modulus) +{ + uint32_t u32RegVal = pCmp->CSCR0; + pCmp->CSCR0 = ((u32RegVal & (~(uint32_t)CMP_CSCR0_CS_INITMOD_MASK)) | CMP_CSCR0_CS_INITMOD(u8Modulus)); +} + +/** + * @brief set number of clock cycles for sampling + * + * @param pCmp the CMP instance to use + * @param u8Nsam the sampling clocks value + */ +LOCAL_INLINE void CMP_HWA_SetCSNumOfSampleClocks(CMP_Type *const pCmp, uint8_t u8Nsam) +{ + uint32_t u32RegVal = pCmp->CSCR0; + pCmp->CSCR0 = ((u32RegVal & (~(uint32_t)CMP_CSCR0_CS_NSAM_MASK)) | CMP_CSCR0_CS_NSAM(u8Nsam)); +} + +/** + * @brief set CMP channel scan enable + * + * @param pCmp the CMP instance to use + */ +LOCAL_INLINE void CMP_HWA_CSEnable(CMP_Type *const pCmp) +{ + uint32_t u32RegVal = pCmp->CSCR0; + pCmp->CSCR0 = ((u32RegVal & (~(uint32_t)CMP_CSCR0_CS_EN_MASK)) | CMP_CSCR0_CS_EN(true)); +} + +/** + * @brief set CMP channel scan disable + * + * @param pCmp the CMP instance to use + */ +LOCAL_INLINE void CMP_HWA_CSDisable(CMP_Type *const pCmp) +{ + uint32_t u32RegVal = pCmp->CSCR0; + pCmp->CSCR0 = ((u32RegVal & (~(uint32_t)CMP_CSCR0_CS_EN_MASK)) | CMP_CSCR0_CS_EN(false)); +} + +/** + * @brief set channel scan fixed channel + * + * @param pCmp the CMP instance to use + * @param eChannel the fixed channel + */ +LOCAL_INLINE void CMP_HWA_SetCSFixedChannel(CMP_Type *const pCmp, CMP_MuxSelType eChannel) +{ + uint32_t u32RegVal = pCmp->CSCR1; + pCmp->CSCR1 = ((u32RegVal & (~(uint32_t)CMP_CSCR1_FIXCH_MASK)) | CMP_CSCR1_FIXCH(eChannel)); +} + +/** + * @brief set channel scan fixed port + * + * @param pCmp the CMP instance to use + * @param ePort the fixed port + */ +LOCAL_INLINE void CMP_HWA_SetCSFixedPort(CMP_Type *const pCmp, CMP_PortSelType ePort) +{ + uint32_t u32RegVal = pCmp->CSCR1; + pCmp->CSCR1 = ((u32RegVal & (~(uint32_t)CMP_CSCR1_FIXP_MASK)) | CMP_CSCR1_FIXP(ePort)); +} + +/** + * @brief set channel scan channel enabled + * + * @param pCmp the CMP instance to use + * @param eChannel the enabled channel + * @param bEnable enable/disable flag + */ +LOCAL_INLINE void CMP_HWA_SetCSChannelEn(CMP_Type *const pCmp, CMP_MuxSelType eChannel, bool bEnable) +{ + uint32_t u32RegVal = pCmp->CSCR1; + pCmp->CSCR1 = ((u32RegVal & (~(uint32_t)(1 << eChannel))) | (((uint32_t)bEnable) << eChannel)); +} + +/** + * @brief set channel scan channel enabled + * + * @param pCmp the CMP instance to use + * @param eChannel the enabled channel + * @param bPresetstate preset state for channel + */ +LOCAL_INLINE void CMP_HWA_SetCSChannelPresetstate(CMP_Type *const pCmp, CMP_MuxSelType eChannel, bool bPresetstate) +{ + uint32_t u32RegVal = pCmp->CSCSR; + pCmp->CSCSR = ((u32RegVal & (~(uint32_t)(1 << eChannel))) | (((uint32_t)bPresetstate) << eChannel)); +} + +/** + * @brief get channel scan channel current state + * + * @param pCmp the CMP instance to use + * @param eChannel the channel that want to get state + */ +LOCAL_INLINE bool CMP_HWA_GetCSChannelsOut(CMP_Type *const pCmp, CMP_MuxSelType eChannel) +{ + bool OutFlag; + uint32_t u32RegVal = pCmp->CSCSR; + OutFlag = (bool)((u32RegVal & ((uint32_t)(1 << eChannel))) >> eChannel); + + return OutFlag; +} + +/** + * @brief software clear channel scan comparison results + * + * @param pCmp the CMP instance to use + */ +LOCAL_INLINE void CMP_HWA_ClearCSComparisonResults(CMP_Type *const pCmp) +{ + uint32_t u32RegVal = pCmp->CSCSR; + pCmp->CSCSR = ((u32RegVal & (~(uint32_t)CMP_CSCSR_CS_SWCLR_MASK)) | CMP_CSCSR_CS_SWCLR(true)); +} + +/** + * @brief software clear channel scan comparison results + * + * @param pCmp the CMP instance to use + * @param bEnable enable/disable flag + */ +LOCAL_INLINE void CMP_HWA_SetCSComparisonResultsAutoClearEn(CMP_Type *const pCmp, bool bEnable) +{ + uint32_t u32RegVal = pCmp->CSCSR; + pCmp->CSCSR = ((u32RegVal & (~(uint32_t)CMP_CSCSR_CS_ACLR_MASK)) | CMP_CSCSR_CS_ACLR(bEnable)); +} + +/** + * @brief get channel scan comparison reuslt + * + * @param pCmp the CMP instance to use + * @param eChannel the enabled channel + * @return channel comparison result for a given channel + */ +LOCAL_INLINE uint32_t CMP_HWA_GetCSComparisonResult(CMP_Type *const pCmp, CMP_MuxSelType eChannel) +{ + uint32_t u32RegVal = pCmp->CSCSR; + u32RegVal = (u32RegVal & (1 << eChannel)) >> eChannel; + return u32RegVal; +} + +/** + * @brief set channel scan active + * + * @param pCmp the CMP instance to use + * @return status cmp channel whether is active + */ +LOCAL_INLINE bool CMP_HWA_GetCSActive(CMP_Type *const pCmp) +{ + bool status; + uint32_t u32RegVal = pCmp->CSSR; + status = ((u32RegVal & ((uint32_t)CMP_CSSR_CS_ACTIVE_MASK)) >> CMP_CSSR_CS_ACTIVE_SHIFT) ? true : false; + return status; +} + +/** + * @brief get channel scan comparison result changed flag + * + * @param pCmp the CMP instance to use + * @param eChannel the channel to get comparison result changed flag + * @return the comparison result changed flag for a given channel + */ +LOCAL_INLINE bool CMP_HWA_GetCSComparisonResultFlag(CMP_Type *const pCmp, CMP_MuxSelType eChannel) +{ + bool flag; + uint32_t u32RegVal = pCmp->CSSR; + flag = ((u32RegVal & (1 << eChannel)) >> eChannel) ? true : false; + return flag; +} + +#endif /* #ifndef _HWA_CMP_H_ */ diff --git a/MODULES/HwA_Flagchip_FC7240/Inc/HwA_cmu.h b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_cmu.h new file mode 100644 index 0000000..887dc31 --- /dev/null +++ b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_cmu.h @@ -0,0 +1,271 @@ +/** + * @file HwA_cmu.h + * @author Flagchip085 + * @brief FC7xxx CMU hardware access layer + * @version 0.1.0 + * @date 2024-01-12 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + * @details + */ +/* ******************************************************************************** +* Revision History: +* +* Version Date Initials CR# Descriptions +* --------- ---------- ------------ ---------- --------------- +* 0.1.0 2024-01-12 Flagchip085 N/A First version for FC7240 +******************************************************************************** */ + +#ifndef _HWA_CMU_H_ +#define _HWA_CMU_H_ + +#include "device_header.h" + +/********* Local inline function ************/ +/** + * @brief Set Reference Window value. + * @param pCmu CMU Instance. + * @param u32Value Ref Window value. +*/ +LOCAL_INLINE void CMU_HWA_SetRefWindow(CMU_Type *const pCmu, uint32_t u32Value) +{ + pCmu->REF_WINDOW = CMU_REF_WINDOW_REF_WINDOW(u32Value); +} + +/** + * @brief Get Reference Window value. + * @param pCmu CMU Instance. + * @return Reference Window value. + */ +LOCAL_INLINE uint32_t CMU_HWA_GetRefWindow(const CMU_Type *const pCmu) +{ + return (pCmu->REF_WINDOW & CMU_REF_WINDOW_REF_WINDOW_MASK) >> CMU_REF_WINDOW_REF_WINDOW_SHIFT; +} + +/** +* @brief Set Minimun Counter value + * @param pCmu CMU Instance. + * @param u32Value Min Count value. +*/ +LOCAL_INLINE void CMU_HWA_SetMinCnts(CMU_Type *const pCmu, uint32_t u32Value) +{ + pCmu->MIN = CMU_MIN_MIN(u32Value); +} + +/** + * @brief Get Minimun Counter value. + * @param pCmu CMU Instance. + * @return Min count value. + */ +LOCAL_INLINE uint32_t CMU_HWA_GetMinCnts(const CMU_Type *const pCmu) +{ + return (pCmu->MIN & CMU_MIN_MIN_MASK) >> CMU_MIN_MIN_SHIFT; +} + +/** + * @brief Set Maximun Counter value. + * @param pCmu CMU Instance. + * @param u32Value Max count value. +*/ +LOCAL_INLINE void CMU_HWA_SetMaxCnts(CMU_Type *const pCmu, uint32_t u32Value) +{ + pCmu->MAX = CMU_MAX_MAX(u32Value); +} + +/** + * @brief Get Maximun Counter value. + * @param pCmu CMU Instance. + * @return Max count value. + */ +LOCAL_INLINE uint32_t CMU_HWA_GetMaxCnts(const CMU_Type *const pCmu) +{ + return (pCmu->MAX & CMU_MAX_MAX_MASK) >> CMU_MAX_MAX_SHIFT; +} + +/** + * @brief Get Counter value. + * @param pCmu CMU Instance. + * @return Counter value. + */ +LOCAL_INLINE uint32_t CMU_HWA_GetCount(const CMU_Type *const pCmu) +{ + return (pCmu->MON_CNT & CMU_MON_CNT_MON_CNT_MASK) >> CMU_MON_CNT_MON_CNT_SHIFT; +} + +/** + * @brief Set period window Counter. + * @param pCmu CMU Instance. + * @param u32Value Period value. +*/ +LOCAL_INLINE void CMU_HWA_SetPeriodWindow(CMU_Type *const pCmu, uint32_t u32Value) +{ + pCmu->PERIOD = (pCmu->PERIOD & ~CMU_PERIOD_WINDOW_MASK) | CMU_PERIOD_WINDOW(u32Value); +} + +/** + * @brief Set period enble bit. +* + * @param pCmu CMU Instance. + * @param bEnable Set enable bit. +*/ +LOCAL_INLINE void CMU_HWA_SetPeriodEnable(CMU_Type *const pCmu, bool bEnable) +{ + pCmu->PERIOD = (pCmu->PERIOD & ~((uint32_t)CMU_PERIOD_EN_MASK)) | CMU_PERIOD_EN(bEnable); +} + +/** +* @brief Set control register value. + * + * @param pCmu CMU Instance. + * @param u32Value Control value. +*/ +LOCAL_INLINE void CMU_HWA_SETCTRL(CMU_Type *const pCmu, uint32_t u32Value) +{ + pCmu->CTRL = u32Value; +} + +/** +* @brief return control register value. + * + * @param pCmu CMU Instance. + * @return CMU Control register value +*/ +LOCAL_INLINE uint32_t CMU_HWA_GetCTRL(const CMU_Type *const pCmu) +{ + return pCmu->CTRL; +} + +/** + * @brief return status register value. + * @param pCmu CMU Instance. + * @return Status value. +*/ +LOCAL_INLINE uint32_t CMU_HWA_GetST(const CMU_Type *const pCmu) +{ + return pCmu->ST; +} + +/** + * @brief Clear clock monitor status + * @param pCmu CMU Instance. +*/ +LOCAL_INLINE void CMU_HWA_ClearST(CMU_Type *const pCmu) +{ + pCmu->ST = (uint32_t)(CMU_ST_MIS_MASK | CMU_ST_LOC_MASK); +} + +/** + * @brief Set the Divider for Reference Clock + * @param pCmu CMU Instance. + * @param eDivider The Divider of Reference Clock +*/ +LOCAL_INLINE void CMU_HWA_SetRefClockDiv(CMU_Type *const pCmu, uint8_t eDivider) +{ + pCmu->CTRL = (pCmu->CTRL & ~((uint32_t)CMU_CTRL_REF_DIV_MASK)) | CMU_CTRL_REF_DIV(eDivider); +} + +/** + * @brief Get the Divider for Reference Clock + * @param pCmu CMU Instance. + * @return The Divider of Reference Clock +*/ +LOCAL_INLINE uint8_t CMU_HWA_GetRefClockDiv(const CMU_Type *const pCmu) +{ + uint32_t u32Temp = (pCmu->CTRL & (uint32_t)CMU_CTRL_REF_DIV_MASK) >> CMU_CTRL_REF_DIV_SHIFT; + return (uint8_t)u32Temp; +} + +/** + * @brief Enable interrupt when LOC or MIS asserted + * @param pCmu CMU Instance. + * @param bEnable Enable or disable CMU interrupt +*/ +LOCAL_INLINE void CMU_HWA_IrqEnable(CMU_Type *const pCmu, bool bEnable) +{ + pCmu->CTRL = (pCmu->CTRL & (~((uint32_t)CMU_CTRL_IRQ_EN_MASK))) | CMU_CTRL_IRQ_EN(bEnable); +} + +/** + * @brief Get CMU interrupt enable flag + * @param pCmu CMU Instance. + * @return 1 : CMU interrupt enabled + * 0 : CMU interrupt disabled +*/ +LOCAL_INLINE uint8_t CMU_HWA_GetIrqEnableFlag(const CMU_Type *const pCmu) +{ + uint32_t u32Temp = (pCmu->CTRL & (uint32_t)CMU_CTRL_IRQ_EN_MASK) >> CMU_CTRL_IRQ_EN_SHIFT; + return (uint8_t)u32Temp; +} + +/** + * @brief Enable Standby mode + * @param pCmu CMU Instance. + * @param bEnable Enable mode +*/ +LOCAL_INLINE void CMU_HWA_StanbyModeEnable(CMU_Type *const pCmu, bool bEnable) +{ + pCmu->CTRL = (pCmu->CTRL & ~((uint32_t)CMU_CTRL_LP_EN_MASK)) | CMU_CTRL_LP_EN(bEnable); +} + +/** + * @brief Enable Stop mode + * @param pCmu CMU Instance. + * @param bEnable Enable mode +*/ +LOCAL_INLINE void CMU_HWA_StopModeEnable(CMU_Type *const pCmu, bool bEnable) +{ + pCmu->CTRL = (pCmu->CTRL & ~((uint32_t)CMU_CTRL_STOP_EN_MASK)) | CMU_CTRL_STOP_EN(bEnable); +} + +/** + * @brief Enable hardware restart CMU after exiting from the low-power mode + * @param pCmu CMU Instance. + * @param bEnable Enable mode +*/ +LOCAL_INLINE void CMU_HWA_LPRestartEnable(CMU_Type *const pCmu, bool bEnable) +{ + pCmu->CTRL = (pCmu->CTRL & ~((uint32_t)CMU_CTRL_RESTART_EN_MASK)) | CMU_CTRL_RESTART_EN(bEnable); +} + +/** + * @brief Software Reset the CMU + * @param pCmu CMU Instance. +*/ +LOCAL_INLINE void CMU_HWA_SoftwareReset(CMU_Type *const pCmu) +{ + pCmu->CTRL |= CMU_CTRL_SW_RST_MASK; +} + +/** + * @brief Enable the CMU + * @param pCmu CMU Instance. +*/ +LOCAL_INLINE void CMU_HWA_Enable(CMU_Type *const pCmu) +{ + pCmu->CTRL |= CMU_CTRL_ENABLE_MASK; +} + +/** + * @brief Disable the CMU + * @param pCmu CMU Instance. +*/ +LOCAL_INLINE void CMU_HWA_Disable(CMU_Type *const pCmu) +{ + pCmu->CTRL &= ~(CMU_CTRL_ENABLE_MASK | CMU_CTRL_IRQ_EN_MASK); + +} + +/** + * @brief Get the CMU enabled status + * @param pCmu CMU Instance. + * @return 1 : CMU is enabled + * 0 : CMU is disabled +*/ +LOCAL_INLINE uint8_t CMU_HWA_GetEnableStatus(const CMU_Type *const pCmu) +{ + uint32_t u32Temp = (pCmu->CTRL & (uint32_t)CMU_CTRL_ENABLE_MASK) >> CMU_CTRL_ENABLE_SHIFT; + return (uint8_t)u32Temp; +} + +#endif /* #ifndef _HWA_CMU_H_ */ diff --git a/MODULES/HwA_Flagchip_FC7240/Inc/HwA_cordic.h b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_cordic.h new file mode 100644 index 0000000..276a7b3 --- /dev/null +++ b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_cordic.h @@ -0,0 +1,134 @@ +/** + * @file HwA_cordic.h + * @author Flagchip + * @brief Hardware access layer for Cordic + * @version 0.1.0 + * @date 2024-01-11 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-01-11 Flagchip054 N/A First version for FC7240 + ******************************************************************************** */ +#ifndef _HWA_CORDIC_H_ +#define _HWA_CORDIC_H_ +#include "device_header.h" + +typedef enum +{ + CORDIC_Iteration_8 = 0, + CORDIC_Iteration_16, + CORDIC_Iteration_24 +}CORDIC_IterationType; + +typedef enum +{ + CORDIC_Trigonometric = 0, + CORDIC_Hyperbolic, + CORDIC_Linear +}CORDIC_SystemType; + +typedef enum +{ + CORDIC_Rotate = 0, + CORDIC_Vector +}CORDIC_ModeType; + + +#define CORDIC_CTR_VAL(s,a,b,c,d) (CORDIC_CTRL_SCALE(s) | CORDIC_CTRL_IE(a) | CORDIC_CTRL_ITER(b) | CORDIC_CTRL_OS(c) | CORDIC_CTRL_MODE(d)) +/** + * @brief Set Cordic module Ctrl register + * + * @param u32Value Ctrl register value + */ +LOCAL_INLINE void Cordic_HWA_SetCtrl(uint32_t u32Value) +{ + CORDIC->CTRL = u32Value; +} + +/** + * @brief Read Cordic module Ctrl register + * + * @return Ctrl register value + */ +LOCAL_INLINE uint32_t Cordic_HWA_GetCtrl(void) +{ + return (uint32_t)(CORDIC->CTRL); +} + +/** + * @brief Set Cordic module XInput register + * + * @param u32Value XInput register value + */ +LOCAL_INLINE void Cordic_HWA_Set_XInput(int32_t u32Value) +{ + CORDIC->X_INPUT = (uint32_t)u32Value; +} + +/** + * @brief Set Cordic module YInput register + * + * @param u32Value YInput register value + */ +LOCAL_INLINE void Cordic_HWA_Set_YInput(int32_t u32Value) +{ + CORDIC->Y_INPUT = (uint32_t)u32Value; +} + +/** + * @brief Set Cordic module ZInput register + * + * @param u32Value ZInput register value + */ +LOCAL_INLINE void Cordic_HWA_Set_ZInput(int32_t u32Value) +{ + CORDIC->Z_INPUT = (uint32_t)u32Value; +} + +/** + * @brief Read Cordic module XOutput register + * + * @return XOutput register value + */ +LOCAL_INLINE uint32_t Cordic_HWA_Get_XOutput(void) +{ + return (uint32_t)(CORDIC->X_OUTPUT); +} + +/** + * @brief Read Cordic module YOutput register + * + * @return YOutput register value + */ +LOCAL_INLINE uint32_t Cordic_HWA_Get_YOutput(void) +{ + return (uint32_t)(CORDIC->Y_OUTPUT); +} + +/** + * @brief Read Cordic module ZOutput register + * + * @return ZOutput register value + */ +LOCAL_INLINE uint32_t Cordic_HWA_Get_ZOutput(void) +{ + return (uint32_t)(CORDIC->Z_OUTPUT); +} + +/** + * @brief Read Cordic module state + * + * @return Cordic module current state + */ +LOCAL_INLINE bool Cordic_HWA_Get_Stat(void) +{ + return (bool)(CORDIC->STAT & CORDIC_STAT_DONE_MASK); +} + +#endif diff --git a/MODULES/HwA_Flagchip_FC7240/Inc/HwA_cpm.h b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_cpm.h new file mode 100644 index 0000000..a9904ed --- /dev/null +++ b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_cpm.h @@ -0,0 +1,350 @@ +/** + * @file HwA_cpm.h + * @author Flagchip + * @brief FC7xxx CPM register API + * @version 0.1.0 + * @date 2024-1-5 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-1-5 Flagchip120 N/A First version for FC7240 + ******************************************************************************** */ + +#ifndef HWA_INCLUDE_HWA_CPM_H_ +#define HWA_INCLUDE_HWA_CPM_H_ +#include "device_header.h" +/* ################################################################################## */ +/* ####################################### Macro #################################### */ + +/** FPSCR Bit Fields */ +#define FPSCR_IOC_MASK 0x00000001U +#define FPSCR_DZC_MASK 0x00000002U +#define FPSCR_OFC_MASK 0x00000004U +#define FPSCR_UFC_MASK 0x00000008U +#define FPSCR_IXC_MASK 0x00000010U +#define FPSCR_IDC_MASK 0x00000080U +#define CPM_FPU_INTFLAGMASK 0x0000003FU + +/** + * @defgroup HwA_cpm + * @ingroup fc7xxx_driver_cpm + * @{ + */ + +/** + * @brief FPU INTERRUPT type. + * + * This provides constants for FPU interrupt type for use in the FPU functions. + * Please refer to Reference Manual chapter 14 CPM, it introduce register FISCR for details. + * + */ + + +typedef enum +{ + CPM_FPU_FIO = 1U, /*!< in function CPM_FpuIntMode, set CPM_FISCR FIOCE bit; in function CPM_GetFpuIntStatus, get CPM_FISCR FIOC Status*/ + CPM_FPU_FDZ = 2U, /*!< in function CPM_FpuIntMode, set CPM_FISCR FDZCE bit; in function CPM_GetFpuIntStatus, get CPM_FISCR FDZC Status*/ + CPM_FPU_FUF = 4U, /*!< in function CPM_FpuIntMode, set CPM_FISCR FUFCE bit; in function CPM_GetFpuIntStatus, get CPM_FISCR FUFC Status*/ + CPM_FPU_FOF = 8U, /*!< in function CPM_FpuIntMode, set CPM_FISCR FOFCE bit; in function CPM_GetFpuIntStatus, get CPM_FISCR FOFC Status*/ + CPM_FPU_FID = 16U, /*!< in function CPM_FpuIntMode, set CPM_FISCR FIDCE bit; in function CPM_GetFpuIntStatus, get CPM_FISCR FIDC Status*/ + CPM_FPU_FIX = 32U /*!< in function CPM_FpuIntMode, set CPM_FISCR FIXCE bit; in function CPM_GetFpuIntStatus, get CPM_FISCR FIXC Status*/ +} FPU_IntType; + + +/** @brief Cpm return type. */ + +typedef enum +{ + CPM_STATUS_SUCCESS = 0U, /*!< CPM status success */ + CPM_STATUS_PARAM_INVALID = 1U /*!< CPM status parameter invalid */ +} CPM_RetType; + +/** + * @brief Get the value of CPM FISCR. + * + * This function returns FISCR value. + * + * @return uint32_t the value of the FISCR register. + */ +LOCAL_INLINE uint32_t CPM_HWA_GetFiscr(void) +{ + return CPM->FISCR; +} + +/** + * @brief Return CPM_FISCR FIOC value + * + * @return 0: No interrupt; 1: Interrupt occurred + */ +LOCAL_INLINE bool CPM_HWA_GetFpuFiocFlag(void) +{ + uint32_t u32TmpVal = CPM->FISCR; + u32TmpVal = (u32TmpVal & CPM_FISCR_FIOC_MASK) >> CPM_FISCR_FIOC_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Return CPM_FISCR FDZC value + * + * @return 0: No interrupt; 1: Interrupt occurred + */ +LOCAL_INLINE bool CPM_HWA_GetFpuFdzcFlag(void) +{ + uint32_t u32TmpVal = CPM->FISCR; + u32TmpVal = (u32TmpVal & CPM_FISCR_FDZC_MASK) >> CPM_FISCR_FDZC_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Return CPM_FISCR FOFC value + * + * @return 0: No interrupt; 1: Interrupt occurred + */ +LOCAL_INLINE bool CPM_HWA_GetFpuFofcFlag(void) +{ + uint32_t u32TmpVal = CPM->FISCR; + u32TmpVal = (u32TmpVal & CPM_FISCR_FOFC_MASK) >> CPM_FISCR_FOFC_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Return CPM_FISCR FUFC value + * + * @return 0: No interrupt; 1: Interrupt occurred + */ +LOCAL_INLINE bool CPM_HWA_GetFpuFufcFlag(void) +{ + uint32_t u32TmpVal = CPM->FISCR; + u32TmpVal = (u32TmpVal & CPM_FISCR_FUFC_MASK) >> CPM_FISCR_FUFC_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Return CPM_FISCR FIXC value + * + * @return 0: No interrupt; 1: Interrupt occurred + */ +LOCAL_INLINE bool CPM_HWA_GetFpuFixcFlag(void) +{ + uint32_t u32TmpVal = CPM->FISCR; + u32TmpVal = (u32TmpVal & CPM_FISCR_FIXC_MASK) >> CPM_FISCR_FIXC_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Return CPM_FISCR FIDC value + * + * @return 0: No interrupt; 1: Interrupt occurred + */ +LOCAL_INLINE bool CPM_HWA_GetFpuFidcFlag(void) +{ + uint32_t u32TmpVal = CPM->FISCR; + u32TmpVal = (u32TmpVal & CPM_FISCR_FIDC_MASK) >> CPM_FISCR_FIDC_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Set FIOCE interrupt + * + * @param bEnable 1: enable interrupt 0: disable interrupt + */ +LOCAL_INLINE void CPM_HWA_SetFioceInt(bool bEnable) +{ + CPM->FISCR = ((CPM->FISCR & (~CPM_FISCR_FIOCE_MASK)) | ((uint32_t)(bEnable ? 1U : 0U) << CPM_FISCR_FIOCE_SHIFT)); +} + +/** + * @brief Set FDZCE interrupt + * + * @param bEnable 1: enable interrupt 0: disable interrupt + */ +LOCAL_INLINE void CPM_HWA_SetFdzceInt(bool bEnable) +{ + CPM->FISCR = ((CPM->FISCR & (~CPM_FISCR_FDZCE_MASK)) | ((uint32_t)(bEnable ? 1U : 0U) << CPM_FISCR_FDZCE_SHIFT)); +} + +/** + * @brief Set FOFCE interrupt + * + * @param bEnable 1: enable interrupt 0: disable interrupt + */ +LOCAL_INLINE void CPM_HWA_SetFofceInt(bool bEnable) +{ + CPM->FISCR = ((CPM->FISCR & (~CPM_FISCR_FOFCE_MASK)) | ((uint32_t)(bEnable ? 1U : 0U) << CPM_FISCR_FOFCE_SHIFT)); +} + +/** + * @brief Set FUFCE interrupt + * + * @param bEnable 1: enable interrupt 0: disable interrupt + */ +LOCAL_INLINE void CPM_HWA_SetFufceInt(bool bEnable) +{ + CPM->FISCR = ((CPM->FISCR & (~CPM_FISCR_FUFCE_MASK)) | ((uint32_t)(bEnable ? 1U : 0U) << CPM_FISCR_FUFCE_SHIFT)); +} + +/** + * @brief Set FIXCE interrupt + * + * @param bEnable 1: enable interrupt 0: disable interrupt + */ +LOCAL_INLINE void CPM_HWA_SetFixceInt(bool bEnable) +{ + CPM->FISCR = ((CPM->FISCR & (~CPM_FISCR_FIXCE_MASK)) | ((uint32_t)(bEnable ? 1U : 0U) << CPM_FISCR_FIXCE_SHIFT)); +} + +/** + * @brief Set FIDCE interrupt + * + * @param bEnable 1: enable interrupt 0: disable interrupt + */ +LOCAL_INLINE void CPM_HWA_SetFidceInt(bool bEnable) +{ + CPM->FISCR = ((CPM->FISCR & (~CPM_FISCR_FIDCE_MASK)) | ((uint32_t)(bEnable ? 1U : 0U) << CPM_FISCR_FIDCE_SHIFT)); +} + +/** + * @brief Set FISCR value + * + * @param u32Val the value want to set the register + */ +LOCAL_INLINE void CPM_HWA_SetFiscr(uint32_t u32Val) +{ + CPM->FISCR = u32Val; +} + +/** + * @brief Get the value of CPM TCMRCR. + * + * This function returns TCMRCR value. + * + * @return uint32_t the value of the TCMRCR register. + */ +LOCAL_INLINE uint32_t CPM_HWA_GetTcmrcr(void) +{ + return CPM->TCMRCR; +} + +/** + * @brief Set DTCM1 retry buffer force clear + * + * @param bEnable 1:Force clear DTCM1 retry buffer 0: No operation + */ +LOCAL_INLINE void CPM_HWA_SetDTCM1BufClear(bool bEnable) +{ + CPM->FISCR = ((CPM->FISCR & (~CPM_TCMRCR_D1RBCLR_MASK)) | ((uint32_t)(bEnable ? 1U : 0U) << CPM_TCMRCR_D1RBCLR_SHIFT)); +} + +/** + * @brief Set DTCM0 retry buffer force clear + * + * @param bEnable 1:Force clear DTCM0 retry buffer 0: No operation + */ +LOCAL_INLINE void CPM_HWA_SetDTCM0BufClear(bool bEnable) +{ + CPM->FISCR = ((CPM->FISCR & (~CPM_TCMRCR_D0RBCLR_MASK)) | ((uint32_t)(bEnable ? 1U : 0U) << CPM_TCMRCR_D0RBCLR_SHIFT)); +} + +/** + * @brief Set ITCM retry buffer force clear + * + * @param bEnable 1:Force clear ITCM retry buffer 0: No operation + */ +LOCAL_INLINE void CPM_HWA_SetITCMBufClear(bool bEnable) +{ + CPM->FISCR = ((CPM->FISCR & (~CPM_TCMRCR_IRBCLR_MASK)) | ((uint32_t)(bEnable ? 1U : 0U) << CPM_TCMRCR_IRBCLR_SHIFT)); +} + +/** + * @brief Set DTCM1 retry buffer invalid + */ +LOCAL_INLINE void CPM_HWA_SetDTCM1BufInvalid(void) +{ + CPM->FISCR = ((CPM->FISCR & (~CPM_TCMRCR_D1RBVLD_MASK)) | (1U << CPM_TCMRCR_D1RBCLR_SHIFT)); +} + +/** + * @brief Set DTCM0 retry buffer invalid + */ +LOCAL_INLINE void CPM_HWA_SetDTCM0BufInvalid(void) +{ + CPM->FISCR = ((CPM->FISCR & (~CPM_TCMRCR_D0RBVLD_MASK)) | (1U << CPM_TCMRCR_D0RBCLR_SHIFT)); +} + +/** + * @brief Set ITCM retry buffer invalid + */ +LOCAL_INLINE void CPM_HWA_SetITCMBufInvalid(void) +{ + CPM->FISCR = ((CPM->FISCR & (~CPM_TCMRCR_IRBVLD_MASK)) | (1U << CPM_TCMRCR_IRBCLR_SHIFT)); +} + +/** + * @brief Set DTCM1 retry buffer timeout interrupt enable + * + * @param bEnable 1:Interrupt enable 0: No operation + */ +LOCAL_INLINE void CPM_HWA_SetDTCM1TimeoutInt(bool bEnable) +{ + CPM->FISCR = ((CPM->FISCR & (~CPM_TCMRCR_D1RBIE_MASK)) | ((uint32_t)(bEnable ? 1U : 0U) << CPM_TCMRCR_D1RBIE_SHIFT)); +} + +/** + * @brief Set DTCM0 retry buffer timeout interrupt enable + * + * @param bEnable 1:Interrupt enable 0: No operation + */ +LOCAL_INLINE void CPM_HWA_SetDTCM0TimeoutInt(bool bEnable) +{ + CPM->FISCR = ((CPM->FISCR & (~CPM_TCMRCR_D0RBIE_MASK)) | ((uint32_t)(bEnable ? 1U : 0U) << CPM_TCMRCR_D0RBIE_SHIFT)); +} + +/** + * @brief Set ITCM retry buffer timeout interrupt enable + * + * @param bEnable 1:Interrupt enable 0: No operation + */ +LOCAL_INLINE void CPM_HWA_SetITCMTimeoutInt(bool bEnable) +{ + CPM->FISCR = ((CPM->FISCR & (~CPM_TCMRCR_IRBIE_MASK)) | ((uint32_t)(bEnable ? 1U : 0U) << CPM_TCMRCR_IRBIE_SHIFT)); +} + +/** + * @brief Set DTCM1 retry buffer autoclear + * + * @param bEnable 1:Enable autoclear 0: No operation + */ +LOCAL_INLINE void CPM_HWA_SetDTCM1AutoClear(bool bEnable) +{ + CPM->FISCR = ((CPM->FISCR & (~CPM_TCMRCR_D1RBAC_MASK)) | ((uint32_t)(bEnable ? 1U : 0U) << CPM_TCMRCR_D1RBAC_SHIFT)); +} + +/** + * @brief Set DTCM0 retry buffer autoclear + * + * @param bEnable 1:Enable autoclear 0: No operation + */ +LOCAL_INLINE void CPM_HWA_SetDTCM0AutoClear(bool bEnable) +{ + CPM->FISCR = ((CPM->FISCR & (~CPM_TCMRCR_D0RBAC_MASK)) | ((uint32_t)(bEnable ? 1U : 0U) << CPM_TCMRCR_D0RBAC_SHIFT)); +} + +/** + * @brief Set ITCM retry buffer autoclear + * + * @param bEnable 1:Enable autoclear 0: No operation + */ +LOCAL_INLINE void CPM_HWA_SetITCMAutoClear(bool bEnable) +{ + CPM->FISCR = ((CPM->FISCR & (~CPM_TCMRCR_IRBAC_MASK)) | ((uint32_t)(bEnable ? 1U : 0U) << CPM_TCMRCR_IRBAC_SHIFT)); +} + +/** @}*/ + +#endif /* HWA_INCLUDE_HWA_CPM_H_ */ diff --git a/MODULES/HwA_Flagchip_FC7240/Inc/HwA_crc.h b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_crc.h new file mode 100644 index 0000000..8877410 --- /dev/null +++ b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_crc.h @@ -0,0 +1,313 @@ +/** + * @file HwA_crc.h + * @author Flagchip + * @brief FC7xxx CRC hardware access layer + * @version 0.1.0 + * @date 2024-01-12 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + * @details + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-01-12 Flagchip119 N/A First version for FC7240 + ******************************************************************************** */ + + +#ifndef _HWA_CRC_H_ +#define _HWA_CRC_H_ + +#include "device_header.h" + + +/********* Local typedef ************/ + +/** + * @brief The data swap for write + */ +typedef enum{ + WRITE_DATASWAP_NONE = 0U, /*!< none data swap for write */ + WRITE_DATASWAP_BIT = 1U, /*!< only bits data swap for write */ + WRITE_DATASWAP_BIT_BYTE = 2U, /*!< both bits and bytes data swap for write */ + WRITE_DATASWAP_BYTE = 3U /*!< only bytes data swap for write */ +} CRC_WriteDataSwapType; + +/** + * @brief The data swap for read + */ +typedef enum{ + READ_DATASWAP_NONE = 0U, /*!< none data swap for read */ + READ_DATASWAP_BIT = 1U, /*!< only bits data swap for read */ + READ_DATASWAP_BIT_BYTE = 2U, /*!< both bits and bytes data swap for read */ + READ_DATASWAP_BYTE = 3U /*!< only bytes data swap for read */ +} CRC_ReadDataSwapType; + +/** + * @brief The complement of reading crc data + */ +typedef enum{ + READ_DATA_NORMAL = 0U, /*!< none complement of reading crc data */ + READ_DATA_FXOR = 1U /*!< Invert or complement with 0xFFFFFFFF or 0xFFFF of crc data */ +} CRC_ReadDataFXORType; + +/** + * @brief The command type of write crc data or seed value + */ +typedef enum{ + WRITE_COMMAND_DATA = 0U, /*!< write crc data */ + WRITE_COMMAND_SEED = 1U /*!< write seed value(used to initialization crc calculation) */ +} CRC_WriteCommondType; + +/** + * @brief The crc mode select + */ +typedef enum{ + CRC_BIT_16 = 0U, /*!< crc 16 bit is selected */ + CRC_BIT_32 = 1U, /*!< crc 32 bit is selected */ + CRC_BIT_8 = 2U, + CRC_BIT_INVALID = 3U +} CRC_BitWidthType; + + +/********* Local inline function ************/ + +/** + * @brief set CRC CR register for writing data or seed + * + * @param pCrc CRC instance + * @param u32Mod WAS mode + */ +LOCAL_INLINE void CRC_HWA_SetDataOrSeed(CRC_Type *const pCrc, CRC_WriteCommondType u32Mod) +{ + uint32_t u32RegVal = pCrc->CR; + pCrc->CR = ((u32RegVal & (~(uint32_t)CRC_CR_WAS_MASK)) | CRC_CR_WAS(u32Mod)); +} + +/** + * @brief set polynomial value + * + * @param pCrc CRC instance + * @param u32Poly the polynomial value + */ +LOCAL_INLINE void CRC_HWA_SetPolyVal(CRC_Type *const pCrc, uint32_t u32Poly) +{ + pCrc->POLY = u32Poly; +} + +/** + * @brief set data register(32 bits) + * + * @param pCrc CRC instance + * @param u32Data data to be set + */ +LOCAL_INLINE void CRC_HWA_SetData_U32(CRC_Type *const pCrc, uint32_t u32Data) +{ + pCrc->DATA.uDATA = u32Data; +} + +/** + * @brief set data register(16 bits) + * + * @param pCrc CRC instance + * @param u16Data data to be set + */ +LOCAL_INLINE void CRC_HWA_SetData_U16(CRC_Type *const pCrc, uint16_t u16Data) +{ + pCrc->DATA.tDATA_16.L = u16Data; +} + +/** + * @brief set data register(low 8 bits) + * + * @param pCrc CRC instance + * @param u8Data data to be set + */ +LOCAL_INLINE void CRC_HWA_SetData_U8(CRC_Type *const pCrc, uint8_t u8Data) +{ + pCrc->DATA.tDATA_8.LL = u8Data; +} + +/** + * @brief get data register(32 bits) + * + * @param pCrc CRC instance + * + * @return 32-bit value + */ +LOCAL_INLINE uint32_t CRC_HWA_GetData_U32(CRC_Type *const pCrc) +{ + return (pCrc->DATA.uDATA); +} + +/** + * @brief get data register(high 8 bits) + * + * @param pCrc CRC instance + * + * @return high 8-bit value + */ +LOCAL_INLINE uint8 CRC_HWA_GetData_U8_H(CRC_Type *const pCrc) +{ + return (pCrc->DATA.tDATA_8.HL); +} + +/** + * @brief get data register(low 8 bits) + * + * @param pCrc CRC instance + * + * @return low 8-bit value + */ +LOCAL_INLINE uint8 CRC_HWA_GetData_U8_L(CRC_Type *const pCrc) +{ + return (pCrc->DATA.tDATA_8.LL); +} + +/** + * @brief get data register(high 16 bits) + * + * @param pCrc CRC instance + * + * @return high 16-bit value + */ +LOCAL_INLINE uint16_t CRC_HWA_GetData_U16_H(CRC_Type *const pCrc) +{ + return (pCrc->DATA.tDATA_16.H); +} + +/** + * @brief get data register(low 16 bits) + * + * @param pCrc CRC instance + * + * @return low 16-bit value + */ +LOCAL_INLINE uint16_t CRC_HWA_GetData_U16_L(CRC_Type *const pCrc) +{ + return (pCrc->DATA.tDATA_16.L); +} + +/** + * @brief set data swap for writes + * + * @param pCrc CRC instance + * @param eWrDataSwap the CRC_WriteDataSwapType type + */ +LOCAL_INLINE void CRC_HWA_SetWriteDataSwap(CRC_Type *const pCrc, CRC_WriteDataSwapType eWrDataSwap) +{ + uint32_t u32RegVal = pCrc->CR; + pCrc->CR = ((u32RegVal & (~(uint32_t)CRC_CR_DSW_MASK)) | CRC_CR_DSW(eWrDataSwap)); +} + +/** + * @brief set data swap for read + * + * @param pCrc CRC instance + * @param eRdDataSwap the eRdDataSwap type + */ +LOCAL_INLINE void CRC_HWA_SetReadDataSwap(CRC_Type *const pCrc, CRC_ReadDataSwapType eRdDataSwap) +{ + uint32_t u32RegVal = pCrc->CR; + pCrc->CR = ((u32RegVal & (~(uint32_t)CRC_CR_DSR_MASK)) | CRC_CR_DSR(eRdDataSwap)); +} + +/** + * @brief set complement read Of CRC data + * + * @param pCrc CRC instance + * @param eRdDataFXOR the CRC_ReadDataFXORType type + */ +LOCAL_INLINE void CRC_HWA_SetReadDataFXOR(CRC_Type *const pCrc, CRC_ReadDataFXORType eRdDataFXOR) +{ + uint32_t u32RegVal = pCrc->CR; + pCrc->CR = ((u32RegVal & (~(uint32_t)CRC_CR_FXOR_MASK)) | CRC_CR_FXOR(eRdDataFXOR)); +} + +/** + * @brief set width of CRC protocol + * + * @param pCrc CRC instance + * @param eWidth the CRC_BitWidthType type + */ +LOCAL_INLINE void CRC_HWA_SetBitWidth(CRC_Type *const pCrc, CRC_BitWidthType eWidth) +{ + uint32_t u32RegVal = pCrc->CR; + pCrc->CR = ((u32RegVal & (~(uint32_t)CRC_CR_TCRC_MASK)) | CRC_CR_TCRC(eWidth)); +} + +/** + * @brief set width of CRC protocol + * + * @param pCrc CRC instance + * @param eWidth the CRC_BitWidthType type + */ +LOCAL_INLINE void CRC_HWA_Set_8Bit_Width(CRC_Type *const pCrc, CRC_BitWidthType eWidth) +{ + uint32_t u32RegVal = pCrc->CR; + pCrc->CR = ((u32RegVal & (~(uint32_t)CRC_CR_TCRC8_MASK)) | CRC_CR_TCRC8(eWidth)); +} + +/** + * @brief get width of CRC protocol + * + * @param pCrc CRC instance + */ +LOCAL_INLINE CRC_BitWidthType CRC_HWA_GetBitWidth(CRC_Type *const pCrc) +{ + uint32_t u32TempVal = (pCrc->CR & ((uint32_t)CRC_CR_TCRC_MASK)) >> CRC_CR_TCRC_SHIFT; + return ((u32TempVal == 0U)?CRC_BIT_16:CRC_BIT_32); +} + +/** + * @brief get 8-bit width of CRC protocol + * + * @param pCrc CRC instance + */ +LOCAL_INLINE CRC_BitWidthType CRC_HWA_Get8BitWidth(CRC_Type *const pCrc) +{ + uint32 u32TempVal = (pCrc->CR & ((uint32)CRC_CR_TCRC8_MASK)) >> CRC_CR_TCRC8_SHIFT; + return ((u32TempVal == 1U)?CRC_BIT_8:CRC_BIT_INVALID); +} + +/** + * @brief get data swap type for read + * + * @param pCrc CRC instance + */ +LOCAL_INLINE CRC_ReadDataSwapType CRC_HWA_GetReadDataSwap(CRC_Type *const pCrc) +{ + CRC_ReadDataSwapType eRet = READ_DATASWAP_NONE; + uint32_t u32TempVal; + + u32TempVal = (pCrc->CR & ((uint32_t)CRC_CR_DSR_MASK))>>CRC_CR_DSR_SHIFT; + if (u32TempVal == 0U) + { + eRet = READ_DATASWAP_NONE; + } + else if (u32TempVal == 1U) + { + eRet = READ_DATASWAP_BIT; + } + else if (u32TempVal == 2U) + { + eRet = READ_DATASWAP_BIT_BYTE; + } + else if (u32TempVal == 3U) + { + eRet = READ_DATASWAP_BYTE; + } + else + { + /*Noting to do*/ + } + return eRet; +} + + + + +#endif /* #ifndef _HWA_CRC_H_ */ diff --git a/MODULES/HwA_Flagchip_FC7240/Inc/HwA_csc.h b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_csc.h new file mode 100644 index 0000000..c346294 --- /dev/null +++ b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_csc.h @@ -0,0 +1,1705 @@ +/** + * @file HwA_csc.h + * @author Flagchip085 + * @brief Hardware access layer for CSC + * @version 0.1.0 + * @date 2024-01-12 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-01-12 Flagchip085 N/A First version for FC7240 + ******************************************************************************** */ + +#ifndef _HWA_CSC_H_ +#define _HWA_CSC_H_ + +#include "device_header.h" + +#define CSC_STOP_PERIPH_GROUP_MAX 3U + +#define CSC_STOP_PERIPH_GROUP0_MASK (CSC0_STOP_MODER0_MASK & 0x00FFFFFFU) + +#define CSC_STOP_PERIPH_GROUP1_MASK (CSC0_STOP_MODER1_MASK & 0x00FFFFFFU) + +#define CSC_STOP_PERIPH_GROUP2_MASK (CSC0_STOP_MODER2_MASK & 0x00FFFFFFU) + +#define CSC_SMU_CTRL_GROUP0_MASK (CSC0_SMU_CTRL0_MASK & 0xFFFFFFFEU) + +#define CSC_SMU_CTRL_GROUP1_MASK (CSC0_SMU_CTRL1_MASK & 0xFFFFFFFEU) + +#define CSC_SMU_CTRL_GROUP4_MASK (CSC0_SMU_CTRL4_MASK & 0xFFFFFFFEU) + +#define CSC_SMU_CTRL_GROUP5_MASK (CSC0_SMU_CTRL5_MASK & 0xFFFFFFFEU) + + +/********* Local typedef ************/ + +/** + * @brief Control cpu type + * + */ +typedef enum +{ + CSC_WP_CPU_ALL = 0U, /*!< All CPUs are allowed to write this peripheral */ + CSC_WP_CPU_0 = 1U, /*!< Only CPU0 is allowed to control this peripheral */ + CSC_WP_CPU_NONE = 2U /*!< No CPU is allowed to control this peripheral */ +} CSC_WPB_CpuType; + +/** + * @brief Hand shake mode type + * + */ +typedef enum +{ + CSC_WAIT_ALL_ACK = 0U, /*!< follow other master stop acknowledge state */ + CSC_WAIT_REQ_ACK = 3U /*!< follow cpu stop acknowledge state */ +} CSC_HandShakeModeType; + +/** + * @brief CSC0 clock out divide ratio type + * + */ +typedef enum +{ + CSC0_CLKOUT_DIV_BY1 = 0U, /*!< Divided by 1 */ + CSC0_CLKOUT_DIV_BY2 = 1U, /*!< Divided by 2 */ + CSC0_CLKOUT_DIV_BY3 = 2U, /*!< Divided by 3 */ + CSC0_CLKOUT_DIV_BY4 = 3U, /*!< Divided by 4 */ + CSC0_CLKOUT_DIV_BY5 = 4U, /*!< Divided by 5 */ + CSC0_CLKOUT_DIV_BY6 = 5U, /*!< Divided by 6 */ + CSC0_CLKOUT_DIV_BY7 = 6U, /*!< Divided by 7 */ + CSC0_CLKOUT_DIV_BY8 = 7U /*!< Divided by 8 */ +} CSC0_ClockOutDivType; + +/** + * @brief CSC0 clock out source type + * + */ +typedef enum +{ + CSC0_CLKOUT_SCG_CLKOUT = 0U, /*!< SCG CLKOUT */ + CSC0_CLKOUT_FOSC_DIVM_CLK = 2U, /*!< FOSC DIVM CLK */ + CSC0_CLKOUT_SLOW_CLK = 3U, /*!< SLOW CLK */ + CSC0_CLKOUT_SIRC_DIVM_CLK = 4U, /*!< SIRC DIVM CLK */ + CSC0_CLKOUT_PLL1_DIVM_CLK = 5U, /*!< PLL1 DIVM CLK */ + CSC0_CLKOUT_FIRC_DIVM_CLK = 6U, /*!< FIRC DIVM CLK */ + CSC0_CLKOUT_CORE_CLK = 7U, /*!< CORE CLK */ + CSC0_CLKOUT_PLL0_DIVM_CLK = 8U, /*!< PLL0 DIVM CLK */ + CSC0_CLKOUT_BUS_CLK = 9U, /*!< BUS CLK */ + CSC0_CLKOUT_SIRC_128K_CLK = 10U, /*!< SIRC 128K CLK */ + CSC0_CLKOUT_AON_CLK = 12U, /*!< AON CLK */ + CSC0_CLKOUT_RTC_CLK = 14U /*!< RTC CLK */ +} CSC0_ClockOutSrcType; + +/** + * @brief Data type for CSC0_AONCLKSR[32KAONCLKSEL], set AON32KCLK source clock + * + */ +typedef enum +{ + CSC0_AON32K_SIRCDIV_32K_CLK = 1U, /*!< CSC0_AONCLKSR[32KAONCLKSEL], SIRCDIV_32K */ + CSC0_AON32K_SOSC32K_CLK = 2U, /*!< CSC0_AONCLKSR[32KAONCLKSEL], SOSC32K */ + CSC0_AON32K_SIRC32K_CLK = 3U /*!< CSC0_AONCLKSR[32KAONCLKSEL], SIRC32K */ +} CSC0_AON32KClkSrcType; + +/** + * @brief Data type for CSC0_RTCCLKSEL[RTCCLKSEL], set RTCCLK source clock + * + */ +typedef enum +{ + CSC0_RTC_FOSCDIVL_CLK = 0U, /*!< CSC0_RTCCLKSEL[RTCCLKSEL], FOSC_DIVL */ + CSC0_RTC_SIRCDIV_32K_CLK = 1U, /*!< CSC0_RTCCLKSEL[RTCCLKSEL], SIRC_DIV */ + CSC0_RTC_SOSC_CLK = 2U, /*!< CSC0_RTCCLKSEL[RTCCLKSEL], SOSC */ + CSC0_RTC_SIRC32K_CLK = 3U /*!< CSC0_RTCCLKSEL[RTCCLKSEL], SIRC_32K */ +} CSC0_RTCClkSrcType; + +/** + * @brief Data type for CSC0_AONCLKSEL[AONCLKSEL], set AONCLK source clock + * + */ +typedef enum +{ + CSC0_AON_SIRCDIV_128K_CLK = 0U, /*!< CSC0_AONCLKSEL[AONCLKSEL], SIRCDIV_128K */ + CSC0_AON_SIRC32K_CLK = 1U, /*!< CSC0_AONCLKSEL[AONCLKSEL], SIRC32K */ + CSC0_AON_SIRCDIV_32K_CLK = 2U, /*!< CSC0_AONCLKSEL[AONCLKSEL], SIRCDIV_32K */ + CSC0_AON_SIRC32_1K_CLK = 3U /*!< CSC0_AONCLKSEL[AONCLKSEL], SIRC32_1K */ +} CSC0_AONClkSrcType; + + +/** + * @brief Register 0 related peripheral(CSC0,CSC1,CSC2) + */ +typedef enum +{ + CSC_STOPMODE_FLEXCAN1 = (int)CSC0_STOP_MODER0_FLEXCAN1_MASK, /*!< Stop acknowledge function FLEXCAN1 */ + CSC_STOPMODE_FLEXCAN0 = (int)CSC0_STOP_MODER0_FLEXCAN0_MASK, /*!< Stop acknowledge function FLEXCAN0 */ + CSC_STOPMODE_FREQM = (int)CSC0_STOP_MODER0_FREQM_MASK, /*!< Stop acknowledge function FREQM */ + CSC_STOPMODE_FCUART3 = (int)CSC0_STOP_MODER0_FCUART3_MASK, /*!< Stop acknowledge function FCUART3 */ + CSC_STOPMODE_FCUART2 = (int)CSC0_STOP_MODER0_FCUART2_MASK, /*!< Stop acknowledge function FCUART2 */ + CSC_STOPMODE_FCUART1 = (int)CSC0_STOP_MODER0_FCUART1_MASK, /*!< Stop acknowledge function FCUART1 */ + CSC_STOPMODE_FCSPI2 = (int)CSC0_STOP_MODER0_FCSPI2_MASK, /*!< Stop acknowledge function FCSPI2 */ + CSC_STOPMODE_FCSPI1 = (int)CSC0_STOP_MODER0_FCSPI1_MASK, /*!< Stop acknowledge function FCSPI1 */ + CSC_STOPMODE_SENT0 = (int)CSC0_STOP_MODER0_SENT0_MASK, /*!< Stop acknowledge function SENT0 */ + CSC_STOPMODE_TMU = (int)CSC0_STOP_MODER0_TMU_MASK, /*!< Stop acknowledge function TMU */ + CSC_STOPMODE_ADC1 = (int)CSC0_STOP_MODER0_ADC1_MASK, /*!< Stop acknowledge function ADC1 */ + CSC_STOPMODE_ADC0 = (int)CSC0_STOP_MODER0_ADC0_MASK, /*!< Stop acknowledge function ADC0 */ + CSC_STOPMODE_CMU4 = (int)CSC0_STOP_MODER0_CMU4_MASK, /*!< Stop acknowledge function CMU4 */ + CSC_STOPMODE_WDOG0 = (int)CSC0_STOP_MODER0_WDOG0_MASK, /*!< Stop acknowledge function WDG0 */ + CSC_STOPMODE_ISM0 = (int)CSC0_STOP_MODER0_ISM0_MASK, /*!< Stop acknowledge function ISM0 */ + CSC_STOPMODE_DMA0 = (int)CSC0_STOP_MODER0_DMA0_MASK /*!< Stop acknowledge function DMA0 */ +} CSCx_Reg0_PeriphType; + +/** + * @brief Register 1 related peripheral(CSC0,CSC1,CSC2) + */ +typedef enum +{ + CSC_STOPMODE_FLEXCAN3 = (int)CSC0_STOP_MODER1_FLEXCAN3_MASK, /*!< Stop acknowledge function FLEXCAN3 */ + CSC_STOPMODE_FLEXCAN2 = (int)CSC0_STOP_MODER1_FLEXCAN2_MASK, /*!< Stop acknowledge function FLEXCAN2 */ + CSC_STOPMODE_MSC0 = (int)CSC0_STOP_MODER1_MSC0_MASK, /*!< Stop acknowledge function MSC0 */ + CSC_STOPMODE_FCUART7 = (int)CSC0_STOP_MODER1_FCUART7_MASK, /*!< Stop acknowledge function FCUART7 */ + CSC_STOPMODE_FCUART6 = (int)CSC0_STOP_MODER1_FCUART6_MASK, /*!< Stop acknowledge function FCUART6 */ + CSC_STOPMODE_FCUART5 = (int)CSC0_STOP_MODER1_FCUART5_MASK, /*!< Stop acknowledge function FCUART5 */ + CSC_STOPMODE_FCUART4 = (int)CSC0_STOP_MODER1_FCUART4_MASK, /*!< Stop acknowledge function FCUART4 */ + CSC_STOPMODE_FCIIC1 = (int)CSC0_STOP_MODER1_FCIIC1_MASK, /*!< Stop acknowledge function FCIIC1 */ + CSC_STOPMODE_FCSPI5 = (int)CSC0_STOP_MODER1_FCSPI5_MASK, /*!< Stop acknowledge function FCSPI5 */ + CSC_STOPMODE_FCSPI4 = (int)CSC0_STOP_MODER1_FCSPI4_MASK, /*!< Stop acknowledge function FCSPI4 */ + CSC_STOPMODE_FCSPI3 = (int)CSC0_STOP_MODER1_FCSPI3_MASK, /*!< Stop acknowledge function FCSPI3 */ + CSC_STOPMODE_WDOG1 = (int)CSC0_STOP_MODER1_WDOG1_MASK, /*!< Stop acknowledge function WDOG1 */ +} CSCx_Reg1_PeriphType; + +/** + * @brief Regsister 2 related peripheral(CSC0,CSC1,CSC2) + */ +typedef enum +{ + CSC_STOPMODE_FCUART0 = (int)CSC0_STOP_MODER2_FCUART0_MASK, /*!< Stop acknowledge function FCUART0 */ + CSC_STOPMODE_FCIIC0 = (int)CSC0_STOP_MODER2_FCIIC0_MASK, /*!< Stop acknowledge function FCIIC0 */ + CSC_STOPMODE_FCSPI0 = (int)CSC0_STOP_MODER2_FCSPI0_MASK, /*!< Stop acknowledge function FCSPI0 */ + CSC_STOPMODE_CMP1 = (int)CSC0_STOP_MODER2_CMP1_MASK, /*!< Stop acknowledge function CMP1 */ + CSC_STOPMODE_CMP0 = (int)CSC0_STOP_MODER2_CMP0_MASK, /*!< Stop acknowledge function CMP0 */ + CSC_STOPMODE_CMU3 = (int)CSC0_STOP_MODER2_CMU3_MASK, /*!< Stop acknowledge function CMU3 */ + CSC_STOPMODE_CMU2 = (int)CSC0_STOP_MODER2_CMU2_MASK, /*!< Stop acknowledge function CMU2 */ + CSC_STOPMODE_CMU1 = (int)CSC0_STOP_MODER2_CMU1_MASK, /*!< Stop acknowledge function CMU1 */ + CSC_STOPMODE_CMU0 = (int)CSC0_STOP_MODER2_CMU0_MASK /*!< Stop acknowledge function CMU0 */ +} CSCx_Reg2_PeriphType; + +/** + * @brief CCM stop clock type(CSC0,CSC1,CSC2) + */ +typedef enum +{ + CSC_CCM_STOPCLOCK_STATUS_SYS_SLAVE = (int)CSC0_CCM0_STATUS_CPU0_STOP_SYS_SLAVE_MASK, /*!< System Slave Clock */ + CSC_CCM_STOPCLOCK_STATUS_MASTER = (int)CSC0_CCM0_STATUS_CPU0_STOP_MASTER_MASK, /*!< Master Clock */ + CSC_CCM_STOPCLOCK_STATUS_SLOW_SLAVE = (int)CSC0_CCM0_STATUS_CPU0_STOP_SLOW_SLAVE_MASK, /*!< Slave Clock */ + CSC_CCM_STOPCLOCK_STATUS_BUS_SLAVE = (int)CSC0_CCM0_STATUS_CPU0_STOP_BUS_SLAVE_MASK /*!< Bus Slave Clock */ +} CSCx_CCM_StopClockType; + +/** + * @brief CSC0 SMU control group 0 + */ +typedef enum +{ + CSC_SMU_CMU4 = (int)CSC0_SMU_CTRL0_CMU4_MASK, /*!< CMU4 to FCSMU */ + CSC_SMU_PMC_MON = (int)CSC0_SMU_CTRL0_PMC_MON_MASK, /*!< PMC Monitor to FCSMU */ + CSC_SMU_CMU2 = (int)CSC0_SMU_CTRL0_CMU2_MASK, /*!< CMU2 to FCSMU */ + CSC_SMU_CMU1 = (int)CSC0_SMU_CTRL0_CMU1_MASK, /*!< CMU1 to FCSMU */ + CSC_SMU_PMC_LVD_HVD = (int)CSC0_SMU_CTRL0_PMC_LVD_HVD_MASK, /*!< PMC HVD/LVD to FCSMU */ + CSC_SMU_SRAM1_MON = (int)CSC0_SMU_CTRL0_SRAM1_MON_MASK, /*!< SRAM1 Decoder Monitor to FCSMU */ + CSC_SMU_SRAM0_MON = (int)CSC0_SMU_CTRL0_SRAM0_MON_MASK, /*!< SRAM0 Decoder Monitor to FCSMU */ + CSC_SMU_MCM = (int)CSC0_SMU_CTRL0_CPM_MON_MASK, /*!< CPU Private Module Monitor to FCSMU */ + CSC_SMU_MAM0_S5_DS_ECC = (int)CSC0_SMU_CTRL0_MAM0_S5_DS_ECC_MASK, /*!< MAM0 S5 Downsize ECC to FCSMU */ + CSC_SMU_MAM0_S8_DS = (int)CSC0_SMU_CTRL0_MAM0_S8_DS_MASK, /*!< MAM0 S8 Downsize Monitor to FCSMU */ + CSC_SMU_MAM0_S5_DS = (int)CSC0_SMU_CTRL0_MAM0_S5_DS_MASK, /*!< MAM0 S5 Downsize Monitor to FCSMU */ + CSC_SMU_DMA0 = (int)CSC0_SMU_CTRL0_DMA0_MASK, /*!< DMA0 ECC to FCSMU */ + CSC_SMU_HSM = (int)CSC0_SMU_CTRL0_HSM_MASK, /*!< HSM ECC to FCSMU */ + CSC_SMU_MAM0_S2F_MON = (int)CSC0_SMU_CTRL0_MAM0_S2F_MON_MASK, /*!< MAM0 S5 Slow to Fast AHBS Monitor to FCSMU */ + CSC_SMU_CPU0_AHBS = (int)CSC0_SMU_CTRL0_CPU0_AHBS_MASK, /*!< CPU0_AHBS ECC to FCSMU */ + CSC_SMU_MAM0_S8 = (int)CSC0_SMU_CTRL0_MAM0_S8_MASK, /*!< MAM0 S8 ECC to FCSMU */ + CSC_SMU_MAM0_S7 = (int)CSC0_SMU_CTRL0_MAM0_S7_MASK, /*!< MAM0 S7 ECC to FCSMU */ + CSC_SMU_MAM0_S6 = (int)CSC0_SMU_CTRL0_MAM0_S6_MASK, /*!< MAM0 S6 ECC to FCSMU */ + CSC_SMU_MAM0_S5 = (int)CSC0_SMU_CTRL0_MAM0_S5_MASK, /*!< MAM0 S5 ECC to FCSMU */ + CSC_SMU_MAM0_S4 = (int)CSC0_SMU_CTRL0_MAM0_S4_MASK, /*!< MAM0 S4 ECC to FCSMU */ + CSC_SMU_MAM0_S3 = (int)CSC0_SMU_CTRL0_MAM0_S3_MASK, /*!< MAM0 S3 ECC to FCSMU */ + CSC_SMU_MAM0_S2 = (int)CSC0_SMU_CTRL0_MAM0_S2_MASK, /*!< MAM0 S2 ECC to FCSMU */ + CSC_SMU_MAM0_S1 = (int)CSC0_SMU_CTRL0_MAM0_S1_MASK, /*!< MAM0 S1 ECC to FCSMU */ + CSC_SMU_MAM0_S0 = (int)CSC0_SMU_CTRL0_MAM0_S0_MASK /*!< MAM0 S0 ECC to FCSMU */ +} CSC_SMU_CtrlGrp0Type; + +/** + * @brief CSC0 SMU control group of CPUx(group1~3) + */ +typedef enum +{ + CSC_SMU_DTCM1_S_EN = (int)CSC0_SMU_CTRL1_CPU0_DTCM1_S_EN_MASK, /*!< CPU0 DTCM1 Single Bit Data to FCSMU */ + CSC_SMU_DTCM0_S_EN = (int)CSC0_SMU_CTRL1_CPU0_DTCM0_S_EN_MASK, /*!< CPU0 DTCM0 Single Bit Data to FCSMU */ + CSC_SMU_ITCM_S_EN = (int)CSC0_SMU_CTRL1_CPU0_ITCM_S_EN_MASK, /*!< CPU0 ITCM Single Bit Data to FCSMU */ + CSC_SMU_OVERLAY = (int)CSC0_SMU_CTRL1_CPU0_OVERLAY_MASK, /*!< CPU0 Overlay to FCSMU */ + CSC_SMU_DTCM1_MON = (int)CSC0_SMU_CTRL1_CPU0_DTCM1_MON_MASK, /*!< CPU0_DTCM1_MON to FCSMU */ + CSC_SMU_DTCM0_MON = (int)CSC0_SMU_CTRL1_CPU0_DTCM0_MON_MASK, /*!< CPU0_DTCM0_MON to FCSMU */ + CSC_SMU_ITCM_MON = (int)CSC0_SMU_CTRL1_CPU0_ITCM_MON_MASK, /*!< CPU0 ITCM Decoder Monitor to FCSMU */ + CSC_SMU_AHBM1_F2S = (int)CSC0_SMU_CTRL1_CPU0_AHBM1_F2S_MASK, /*!< CPU0 AHBM1 Fast to Slow Monitor to FCSMU */ + CSC_SMU_AHBM0_F2S = (int)CSC0_SMU_CTRL1_CPU0_AHBM0_F2S_MASK, /*!< CPU0 AHBM0 Fast to Slow Monitor to FCSMU */ + CSC_SMU_AHBP_F2S = (int)CSC0_SMU_CTRL1_CPU0_AHBP_F2S_MASK, /*!< CPU0 AHBP Fast to Slow Monito to FCSMU */ + CSC_SMU_DTCM1 = (int)CSC0_SMU_CTRL1_CPU0_DTCM1_MASK, /*!< CPU0 DTCM1 ECC to FCSMU */ + CSC_SMU_DTCM0 = (int)CSC0_SMU_CTRL1_CPU0_DTCM0_MASK, /*!< CPU0 DTCM0 ECC to FCSMU */ + CSC_SMU_ITCM = (int)CSC0_SMU_CTRL1_CPU0_ITCM_MASK, /*!< CPU0 ITCM ECC to FCSMU */ + CSC_SMU_DCACHE = (int)CSC0_SMU_CTRL1_CPU0_DCACHE_MASK, /*!< CPU0 Data CACHE to FCSMU */ + CSC_SMU_ICACHE = (int)CSC0_SMU_CTRL1_CPU0_ICACHE_MASK, /*!< CPU0 Code CACHE to FCSMU */ + CSC_SMU_AHBP = (int)CSC0_SMU_CTRL1_CPU0_AHBP_MASK, /*!< CPU0 AHBP ECC to FCSMU */ + CSC_SMU_AHBM = (int)CSC0_SMU_CTRL1_CPU0_AHBM_MASK /*!< CPU0 AHBM ECC to FCSMU */ +} CSC_SMU_Cpux_CtrlGrpType; + +/** + * @brief CSC0 SMU control group 4 + */ +typedef enum +{ + CSC_SMU_HSM_WDOG = (int)CSC0_SMU_CTRL4_HSM_WDOG_MASK, /*!< HSM WDOG Request Enable to FCSMU */ + CSC_SMU_FMC_ERR = (int)CSC0_SMU_CTRL4_FMC_ERR_MASK, /*!< FMC ECC Error Enable to FCSMU */ + CSC_SMU_ROM_S_EN = (int)CSC0_SMU_CTRL4_ROM_S_EN_MASK, /*!< ROM Single Bit Data Error Enable to FCSMU */ + CSC_SMU_SRAM1_EDC_MON_EN = (int)CSC0_SMU_CTRL4_SRAM1_EDC_MON_EN_MASK, /*!< SRAM1_EDC Monitor Error Enable to FCSMU */ + CSC_SMU_SRAM0_EDC_MON_EN = (int)CSC0_SMU_CTRL4_SRAM0_EDC_MON_EN_MASK, /*!< SRAM0_EDC Monitor Error Enable to FCSMU */ + CSC_SMU_SRAM1_S_EN = (int)CSC0_SMU_CTRL4_SRAM1_S_EN_MASK, /*!< SRAM1 Single Bit Data Error Enable to FCSMU */ + CSC_SMU_SRAM0_S_EN = (int)CSC0_SMU_CTRL4_SRAM0_S_EN_MASK, /*!< SRAM0 Single Bit Data Error Enable to FCSMU */ + CSC_SMU_FLASH_ECC_EN_S = (int)CSC0_SMU_CTRL4_FLASH_ECC_EN_S_MASK, /*!< FLASH Single Bit Error Enable to FCSMU */ + CSC_SMU_FLASH_ECC_EN = (int)CSC0_SMU_CTRL4_FLASH_ECC_EN_MASK, /*!< FLASH ECC Error Enable to FCSMU */ + CSC_SMU_AFCB1_MON = (int)CSC0_SMU_CTRL4_AFCB1_MON_MASK, /*!< AFCB1 Monitor Error Enable to FCSMU */ + CSC_SMU_AFCB0_MON = (int)CSC0_SMU_CTRL4_AFCB0_MON_MASK, /*!< AFCB0 Monitor Error Enable to FCSMU */ + CSC_SMU_SCF_RST = (int)CSC0_SMU_CTRL4_SCF_RST_EN_MASK, /*!< Self Check Feature Enable */ + CSC_SMU_SCF_IRQ = (int)CSC0_SMU_CTRL4_SCF_IRQ_EN_MASK, /*!< Self Check Feature Interrupt Request Enable */ + CSC_SMU_TMU = (int)CSC0_SMU_CTRL4_TMU_MASK, /*!< TMU Error Enable to FCSMU */ + CSC_SMU_SCM_CRC = (int)CSC0_SMU_CTRL4_SCM_CRC_MASK, /*!< SCM CRC Error Enable to FCSMU */ + CSC_SMU_SCG_CRC = (int)CSC0_SMU_CTRL4_SCG_CRC_MASK, /*!< SCG CRC Error Enable to FCSMU */ + CSC_SMU_SRAM1_ECC = (int)CSC0_SMU_CTRL4_SRAM1_ECC_MASK, /*!< SRAM1 ECC Error Enable to FCSMU */ + CSC_SMU_SRAM0_ECC = (int)CSC0_SMU_CTRL4_SRAM0_ECC_MASK, /*!< SRAM0 ECC Error Enable to FCSMU */ + CSC_SMU_MAM0_ERR = (int)CSC0_SMU_CTRL4_MAM0_ERR_MASK /*!< Matrix Access Monitor 0 Timeout Error Enable to FCSMU */ +} CSC_SMU_CtrlGrp4Type; + +/** + * @brief CSC0 SMU control group 5 + */ +typedef enum +{ + CSC_SMU_SRAM1_EDC = (int)CSC0_SMU_CTRL5_SRAM1_EDC_MASK, /*!< SRAM1 EDC Error Enable to FCSMU */ + CSC_SMU_SRAM0_EDC = (int)CSC0_SMU_CTRL5_SRAM0_EDC_MASK, /*!< SRAM0 EDC Error Enable to FCSMU */ + CSC_SMU_FLASH_EDC_P1_EN = (int)CSC0_SMU_CTRL5_FLASH_EDC_P1_EN_MASK,/*!< FLASH P1 EDC Error Enable to FCSMU */ + CSC_SMU_FLASH_EDC_P0_EN = (int)CSC0_SMU_CTRL5_FLASH_EDC_P0_EN_MASK,/*!< FLASH P0 EDC Error Enable to FCSMU */ + CSC_SMU_HSM_IRAM_S = (int)CSC0_SMU_CTRL5_HSM_IRAM_S_MASK, /*!< HSM IRAM Single Bit Data Error Enable to FCSMU */ + CSC_SMU_HSM_DRAM_S = (int)CSC0_SMU_CTRL5_HSM_DRAM_S_MASK, /*!< HSM DRAM Single Bit Data Error Enable to FCSMU */ + CSC_SMU_HSM_IRAM = (int)CSC0_SMU_CTRL5_HSM_IRAM_MASK, /*!< HSM IRAM ECC Error Enable to FCSMU */ + CSC_SMU_HSM_DRAM = (int)CSC0_SMU_CTRL5_HSM_DRAM_MASK, /*!< HSM DRAM ECC Error Enable to FCSMU */ + CSC_SMU_DMA0_ECC_S = (int)CSC0_SMU_CTRL5_DMA0_ECC_S_MASK, /*!< DMA0_CFG_ECC Single Bit Data Error Enable to FCSMU */ + CSC_SMU_DMA0_ECC = (int)CSC0_SMU_CTRL5_DMA0_ECC_MASK, /*!< DMA0 CFG ECC Error Enable to FCSMU */ + CSC_SMU_DMA0_LOCKSTEP = (int)CSC0_SMU_CTRL5_DMA0_LOCKSTEP_MASK, /*!< DMA0 lockstep Error Enable to FCSMU */ + CSC_SMU_FOSC_ERR = (int)CSC0_SMU_CTRL5_FOSC_ERR_MASK, /*!< FOSC Loss of Clock Error Enable to FCSMU */ + CSC_SMU_PLL1_ERR = (int)CSC0_SMU_CTRL5_PLL1_ERR_MASK, /*!< PLL1 Loss of Clock Error Enable to FCSMU */ + CSC_SMU_PLL0_ERR = (int)CSC0_SMU_CTRL5_PLL0_ERR_MASK, /*!< PLL0 Loss of Clock Error Enable to FCSMU */ + CSC_SMU_STCU_ERR = (int)CSC0_SMU_CTRL5_STCU_ERR_MASK, /*!< STCU Self Test Error Enable to FCSMU */ + CSC_SMU_NONUSER_ERR = (int)CSC0_SMU_CTRL5_NONUSER_ERR_MASK, /*!< STCU Non User Error Enable to FCSMU */ + CSC_SMU_NVR_ERR = (int)CSC0_SMU_CTRL5_NVR_ERR_MASK, /*!< NVR Error Enable to FCSMU */ +} CSC_SMU_CtrlGrp5Type; + +/** + * @brief CSC0 CMU control group + */ +typedef enum +{ + CSC_CMU_DMA0_CFG_S_EN_ADDR = (int)CSC0_CMU_CTRL_DMA0_CFG_S_EN_ADDR_MASK,/*!< Enable to Report Single Error When One Bit Address_ECC Error Inject */ + CSC_CMU_CMU3_FCSMU_RST = (int)CSC0_CMU_CTRL_CMU3_FCSMU_RST_MASK, /*!< CMU3 clcok error to assert reset request to RGM to reset System and FCSMU */ + CSC_CMU_CMU3_RST = (int)CSC0_CMU_CTRL_CMU3_RST_EN_MASK, /*!< CMU3 clock error to assert reset request to RGM to reset System */ + CSC_CMU_CMU4_LOC = (int)CSC0_CMU_CTRL_CMU4_LOC_EN_MASK /*!< Enable CMU4 Loss of clock error request to SCG */ +} CSC0_CMU_CtrlGrpType; + +/** + * @brief CSC0 Low Power Wakeup configuration group type + */ +typedef enum +{ + CSC_LP_WAKEUP_GROUP_0 = 0U, /*!< CSC0 Low Power Wakeup configuration group0 */ + CSC_LP_WAKEUP_GROUP_1 = 1U, /*!< CSC0 Low Power Wakeup configuration group1 */ + CSC_LP_WAKEUP_GROUP_2 = 2U, /*!< CSC0 Low Power Wakeup configuration group2 */ + CSC_LP_WAKEUP_GROUP_3 = 3U, /*!< CSC0 Low Power Wakeup configuration group3 */ + CSC_LP_WAKEUP_GROUP_4 = 4U /*!< CSC0 Low Power Wakeup configuration group4 */ +} CSC0_LPWakeupGrpType; + +/** + * @brief CSC0 Low Power Wakeup configuration source type + */ +typedef enum +{ + CSC_LP_WAKEUP_DISABLE = 0U, /*!< Disable */ + CSC_LP_WAKEUP_AONTIMER_TRIGGER = 1U, /*!< AONTIMER Trigger */ + CSC_LP_WAKEUP_RTC_TIME_ALARM = 2U, /*!< RTC Time Alarm */ + CSC_LP_WAKEUP_CPM0_OUTPUT = 3U, /*!< CPM0 output */ + CSC_LP_WAKEUP_CPM1_OUTPUT = 4U, /*!< CPM1 output */ + CSC_LP_WAKEUP_RESERVED = 5U, /*!< Reserved */ + CSC_LP_WAKEUP_PMC_RPM_ENTRY = 6U, /*!< PMC RPM Entry */ + CSC_LP_WAKEUP_WKU_INTERRUPT = 7U, /*!< WKU Interrupt */ + CSC_LP_WAKEUP_TSTMP0_PWM_TRIGGER0 = 8U, /*!< TSTMP0 PWM TRIGGER0 */ + CSC_LP_WAKEUP_TSTMP0_PWM_TRIGGER1 = 9U, /*!< TSTMP0 PWM TRIGGER1 */ + CSC_LP_WAKEUP_FCPIT0_PWM_TRIGGER0 = 10U, /*!< FCPT0 PWM TRIGGER0 */ + CSC_LP_WAKEUP_FCPIT0_PWM_TRIGGER1 = 11U, /*!< FCPT0 PWM TRIGGER1 */ + CSC_LP_WAKEUP_FCPIT0_TRIGGER_OUT0 = 12U, /*!< FCPIT0 Trigger out[0] */ + CSC_LP_WAKEUP_FCPIT0_TRIGGER_OUT1 = 13U, /*!< FCPIT0 Trigger out[1] */ + CSC_LP_WAKEUP_FCPIT0_TRIGGER_OUT2 = 14U, /*!< FCPIT0 Trigger out[2] */ + CSC_LP_WAKEUP_FCPIT0_TRIGGER_OUT3 = 15U /*!< FCPIT0 Trigger out[3] */ +} CSC0_LPWakeupSrcType; + +/** + * @brief CSC0 Low Power Wakeup polarity type + */ +typedef enum +{ + CSC_LP_WAKEUP_POL_KEEP = 0U, /*!< Keep the LP_WAKEUP CFGx */ + CSC_LP_WAKEUP_POL_INVERT = 1U, /*!< Invert the LP_WAKEUP CFGx */ +} CSC0_LPWakeupPolType; + + +/********* Local inline function ************/ +/****** Operation on CSC0_xxxRegister0 ******/ +/** + * @brief Lock the cpu to control stop mode register 0 + * + */ +LOCAL_INLINE void CSC0_HWA_MODER0_LockWritePermit(void) +{ + CSC0->STOP_MODER0 |= (uint32_t)CSC0_STOP_MODER0_WPB_LOCK_MASK; +} + +/** + * @brief Get the stop mode register 0 lock status + * + * @return Lock status + */ +LOCAL_INLINE uint32_t CSC0_HWA_MODER0_GetWPBLockStatus(void) +{ + return (CSC0->STOP_MODER0 & (uint32_t)CSC0_STOP_MODER0_WPB_LOCK_MASK); +} + +/** + * @brief Get the CPU type of writing permission + * + * @return CSC_WPB_CpuType The CPU which has the write permission + */ +LOCAL_INLINE CSC_WPB_CpuType CSC0_HWA_MODER0_GetCpuWritePermit(void) +{ + uint32_t u32RegVal = ((CSC0->STOP_MODER0 & (uint32_t)CSC0_STOP_MODER0_WPB_MASK)>>CSC0_STOP_MODER0_WPB_SHIFT); + return (CSC_WPB_CpuType)u32RegVal; +} + +/** + * @brief Set cpu to control this stop mode register 0 + * + * @param eCpuType Cpu allowed to control peripheral + */ +LOCAL_INLINE void CSC0_HWA_MODER0_SetCpuWritePermit(CSC_WPB_CpuType eCpuType) +{ + uint32_t u32RegVal = CSC0->STOP_MODER0; + CSC0->STOP_MODER0 = ((u32RegVal & (~(uint32_t)CSC0_STOP_MODER0_WPB_MASK)) | CSC0_STOP_MODER0_WPB(eCpuType)); +} + +/** + * @brief Enable the stop acknowledge function of register 0 group + * + * @param ePeriphType Peripheral to be set + */ +LOCAL_INLINE void CSC0_HWA_MODER0_EnableStopAck(CSCx_Reg0_PeriphType ePeriphType) +{ + CSC0->STOP_MODER0 |= (uint32_t)ePeriphType; +} + +/** + * @brief Disable the stop acknowledge function of register 0 group + * + * @param ePeriphType Peripheral to be set + */ +LOCAL_INLINE void CSC0_HWA_MODER0_DisableStopAck(CSCx_Reg0_PeriphType ePeriphType) +{ + CSC0->STOP_MODER0 &= ~(uint32_t)ePeriphType; +} + +/** + * @brief Set multiple stop ack enable/disable value + * + * @param u32Value the OR value of type CSCx_Reg0_PeriphType + */ +LOCAL_INLINE void CSC0_HWA_MODER0_SetMultiStopAck(uint32_t u32Value) +{ + CSC0->STOP_MODER0 = u32Value; +} + +/** + * @brief Clear multiple stop ack enable/disable value + * + * @param u32Value the OR value of type CSCx_Reg0_PeriphType + */ +LOCAL_INLINE void CSC0_HWA_MODER0_ClearMultiStopAck(uint32_t u32Value) +{ + CSC0->STOP_MODER0 = (CSC0->STOP_MODER0 & (~u32Value)); +} + +/** + * @brief Lock the cpu to control this stop request register 0 + * + * @param eLockType Cpu lock type + */ +LOCAL_INLINE void CSC0_HWA_REQR0_LockWritePermit(void) +{ + CSC0->STOP_REQR0 |= (uint32_t)CSC0_STOP_REQR0_WPB_LOCK_MASK; +} + +/** + * @brief Get the stop request register 0 lock status + * + * @return Lock status + */ +LOCAL_INLINE uint32_t CSC0_HWA_REQR0_GetWPBLockStatus(void) +{ + return (CSC0->STOP_REQR0 & (uint32_t)CSC0_STOP_REQR0_WPB_LOCK_MASK); +} + +/** + * @brief Get the CPU type of writing permission + * + * @return CSC_WPB_CpuType The CPU which has the write permission + */ +LOCAL_INLINE CSC_WPB_CpuType CSC0_HWA_REQR0_GetCpuWritePermit(void) +{ + uint32_t u32RegVal = ((CSC0->STOP_REQR0 & (uint32_t)CSC0_STOP_REQR0_WPB_MASK)>>CSC0_STOP_REQR0_WPB_SHIFT); + return (CSC_WPB_CpuType)u32RegVal; +} + +/** + * @brief Set cpu to control stop request register 0 + * + * @param eCpuType Cpu allowed to control peripheral + */ +LOCAL_INLINE void CSC0_HWA_REQR0_SetCpuWritePermit(CSC_WPB_CpuType eCpuType) +{ + uint32_t u32RegVal = CSC0->STOP_REQR0; + CSC0->STOP_REQR0 = ((u32RegVal & (~(uint32_t)CSC0_STOP_REQR0_WPB_MASK)) | CSC0_STOP_REQR0_WPB(eCpuType)); +} + +/** + * @brief Set stop request in register 0 + * + * @param ePeriphType Peripheral to be set + */ +LOCAL_INLINE void CSC0_HWA_REQR0_SetStopRequest(CSCx_Reg0_PeriphType ePeriphType) +{ + CSC0->STOP_REQR0 |= (uint32_t)ePeriphType; +} + +/** + * @brief Clear stop request in register 0 + * + * @param ePeriphType Peripheral to be cleared + */ +LOCAL_INLINE void CSC0_HWA_REQR0_ClearStopRequest(CSCx_Reg0_PeriphType ePeriphType) +{ + CSC0->STOP_REQR0 &= ~(uint32_t)ePeriphType; +} + +/** + * @brief Set multiple stop request enable/disable value + * + * @param u32Value the OR value of type CSCx_Reg0_PeriphType + */ +LOCAL_INLINE void CSC0_HWA_REQR0_SetMultiStopRequest(uint32_t u32Value) +{ + CSC0->STOP_REQR0 = u32Value; +} + +/** + * @brief Clear stop request in register 0 + * + * @param u32Value the OR value of type CSCx_Reg0_PeriphType + */ +LOCAL_INLINE void CSC0_HWA_REQR0_ClearMultiStopRequest(uint32_t u32Value) +{ + CSC0->STOP_REQR0 = (CSC0->STOP_REQR0 & (~u32Value)); +} + +/** + * @brief Get stop ack status in register 0 + * + * @param u32Value value to be set + * @return Stop ack status + */ +LOCAL_INLINE uint32_t CSC0_HWA_ACKR0_GetStopAckStatus(CSCx_Reg0_PeriphType ePeriphType) +{ + return (CSC0->STOP_ACKR0 & ((uint32_t)ePeriphType)); +} + +/** + * @brief Get multiple stop ack status in register 0 + * + * @param u32Value the OR value of type CSCx_Reg0_PeriphType + * @return Stop ack status + */ +LOCAL_INLINE uint32_t CSC0_HWA_ACKR0_GetMultiStopAckStatus(uint32_t u32Value) +{ + return (CSC0->STOP_ACKR0 & u32Value); +} + + + +/****** Operation on CSC0_xxxRegister1 ******/ +/** + * @brief Lock the cpu to control stop mode register 1 + * + */ +LOCAL_INLINE void CSC0_HWA_MODER1_LockWritePermit(void) +{ + CSC0->STOP_MODER1 |= (uint32_t)CSC0_STOP_MODER1_WPB_LOCK_MASK; +} + +/** + * @brief Get the stop mode register 1 lock status + * + * @return Lock status + */ +LOCAL_INLINE uint32_t CSC0_HWA_MODER1_GetWPBLockStatus(void) +{ + return (CSC0->STOP_MODER1 & (uint32_t)CSC0_STOP_MODER1_WPB_LOCK_MASK); +} + +/** + * @brief Set cpu to control this stop mode register 1 + * + * @param eCpuType Cpu allowed to control peripheral + */ +LOCAL_INLINE void CSC0_HWA_MODER1_SetCpuWritePermit(CSC_WPB_CpuType eCpuType) +{ + uint32_t u32RegVal = CSC0->STOP_MODER1; + CSC0->STOP_MODER1 = ((u32RegVal & (~(uint32_t)CSC0_STOP_MODER1_WPB_MASK)) | CSC0_STOP_MODER1_WPB(eCpuType)); +} + +/** + * @brief Get the CPU type of writing permission + * + * @return CSC_WPB_CpuType The Cpu which has the write permission + */ +LOCAL_INLINE CSC_WPB_CpuType CSC0_HWA_MODER1_GetCpuWritePermit(void) +{ + uint32_t u32RegVal = ((CSC0->STOP_MODER1 & (uint32_t)CSC0_STOP_MODER1_WPB_MASK)>>CSC0_STOP_MODER1_WPB_SHIFT); + return (CSC_WPB_CpuType)u32RegVal; +} + +/** + * @brief Enable the stop acknowledge function of register 1 group + * + * @param ePeriphType Peripheral to be set + */ +LOCAL_INLINE void CSC0_HWA_MODER1_EnableStopAck(CSCx_Reg1_PeriphType ePeriphType) +{ + CSC0->STOP_MODER1 |= (uint32_t)ePeriphType; +} + +/** + * @brief Disable the stop acknowledge function of register 1 group + * + * @param ePeriphType Peripheral to be set + */ +LOCAL_INLINE void CSC0_HWA_MODER1_DisableStopAck(CSCx_Reg1_PeriphType ePeriphType) +{ + CSC0->STOP_MODER1 &= ~(uint32_t)ePeriphType; +} + +/** + * @brief Set multiple stop ack enable/disable value + * + * @param u32Value the OR value of type CSCx_Reg1_PeriphType + */ +LOCAL_INLINE void CSC0_HWA_MODER1_SetMultiStopAck(uint32_t u32Value) +{ + CSC0->STOP_MODER1 = u32Value; +} + +/** + * @brief Clear multiple stop ack enable/disable value + * + * @param u32Value the OR value of type CSCx_Reg1_PeriphType + */ +LOCAL_INLINE void CSC0_HWA_MODER1_ClearMultiStopAck(uint32_t u32Value) +{ + CSC0->STOP_MODER1 = (CSC0->STOP_MODER1 & (~u32Value)); +} + +/** + * @brief Lock the cpu to control this stop request register 1 + * + */ +LOCAL_INLINE void CSC0_HWA_REQR1_LockWritePermit(void) +{ + CSC0->STOP_REQR1 |= (uint32_t)CSC0_STOP_REQR1_WPB_LOCK_MASK; +} + +/** + * @brief Get the stop request register 1 lock status + * + * @return Lock status + */ +LOCAL_INLINE uint32_t CSC0_HWA_REQR1_GetWPBLockStatus(void) +{ + return (CSC0->STOP_REQR1 & (uint32_t)CSC0_STOP_REQR1_WPB_LOCK_MASK); +} + +/** + * @brief Get the CPU type of writing permission + * + * @return CSC_WPB_CpuType CPU type which has the write permission + */ +LOCAL_INLINE CSC_WPB_CpuType CSC0_HWA_REQR1_GetCpuWritePermit(void) +{ + uint32_t u32RegVal = ((CSC0->STOP_REQR1 & (uint32_t)CSC0_STOP_REQR1_WPB_MASK)>>CSC0_STOP_REQR1_WPB_SHIFT); + return (CSC_WPB_CpuType)u32RegVal; +} + +/** + * @brief Set cpu to control stop request register 1 + * + * @param eCpuType Cpu allowed to control peripheral + */ +LOCAL_INLINE void CSC0_HWA_REQR1_SetCpuWritePermit(CSC_WPB_CpuType eCpuType) +{ + uint32_t u32RegVal = CSC0->STOP_REQR1; + CSC0->STOP_REQR1 |= ((u32RegVal & (~(uint32_t)CSC0_STOP_REQR1_WPB_MASK)) | CSC0_STOP_REQR1_WPB(eCpuType)); +} + +/** + * @brief Set stop request in register 1 + * + * @param ePeriphType Peripheral to be set + */ +LOCAL_INLINE void CSC0_HWA_REQR1_SetStopRequest(CSCx_Reg1_PeriphType ePeriphType) +{ + CSC0->STOP_REQR1 |= (uint32_t)ePeriphType; +} + +/** + * @brief Clear stop request in register 1 + * + * @param ePeriphType Peripheral to be cleared + */ +LOCAL_INLINE void CSC0_HWA_REQR1_ClearStopRequest(CSCx_Reg1_PeriphType ePeriphType) +{ + CSC0->STOP_REQR1 &= ~(uint32_t)ePeriphType; +} + +/** + * @brief Set multiple stop request enable/disable value + * + * @param u32Value the OR value of type CSCx_Reg1_PeriphType + */ +LOCAL_INLINE void CSC0_HWA_REQR1_SetMultiStopRequest(uint32_t u32Value) +{ + CSC0->STOP_REQR1 = u32Value; +} + +/** + * @brief Clear multiple stop request in register 0 + * + * @param u32Value the OR value of type CSCx_Reg1_PeriphType + */ +LOCAL_INLINE void CSC0_HWA_REQR1_ClearMultiStopRequest(uint32_t u32Value) +{ + CSC0->STOP_REQR1 = (CSC0->STOP_REQR1 & (~u32Value)); +} + +/** + * @brief Get stop ack status in register 1 + * + * @param u32Value value to be set + * @return Stop ack status + */ +LOCAL_INLINE uint32_t CSC0_HWA_ACKR1_GetStopAckStatus(CSCx_Reg1_PeriphType ePeriphType) +{ + return (CSC0->STOP_ACKR1 & (uint32_t)ePeriphType); +} + +/** + * @brief Get multiple stop ack status in register 1 + * + * @param u32Value the OR value of type CSCx_Reg1_PeriphType + * @return Stop ack status + */ +LOCAL_INLINE uint32_t CSC0_HWA_ACKR1_GetMultiStopAckStatus(uint32_t u32Value) +{ + return (CSC0->STOP_ACKR1 & u32Value); +} + +/****** Operation on CSC0_xxxRegister2 ******/ +/** + * @brief Lock the cpu to control stop mode register 2 + * + */ +LOCAL_INLINE void CSC0_HWA_MODER2_LockWritePermit(void) +{ + CSC0->STOP_MODER2 |= (uint32_t)CSC0_STOP_MODER2_WPB_LOCK_MASK; +} + +/** + * @brief Get the stop mode register 2 lock status + * + * @return Lock status + */ +LOCAL_INLINE uint32_t CSC0_HWA_MODER2_GetWPBLockStatus(void) +{ + return (CSC0->STOP_MODER2 & (uint32_t)CSC0_STOP_MODER2_WPB_LOCK_MASK); +} + +/** + * @brief Set cpu to control this stop mode register 2 + * + * @param eCpuType Cpu allowed to control peripheral + */ +LOCAL_INLINE void CSC0_HWA_MODER2_SetCpuWritePermit(CSC_WPB_CpuType eCpuType) +{ + uint32_t u32RegVal = CSC0->STOP_MODER2; + CSC0->STOP_MODER2 = ((u32RegVal & (~(uint32_t)CSC0_STOP_MODER2_WPB_MASK)) | CSC0_STOP_MODER2_WPB(eCpuType)); +} + +/** + * @brief Get the CPU type of writing permission + * + * @return CSC_WPB_CpuType The Cpu which has the write permission + */ +LOCAL_INLINE CSC_WPB_CpuType CSC0_HWA_MODER2_GetCpuWritePermit(void) +{ + uint32_t u32RegVal = ((CSC0->STOP_MODER2 & (uint32_t)CSC0_STOP_MODER2_WPB_MASK)>>CSC0_STOP_MODER2_WPB_SHIFT); + return (CSC_WPB_CpuType)u32RegVal; +} + + +/** + * @brief Enable the stop acknowledge function of register 2 group + * + * @param ePeriphType Peripheral to be set + */ +LOCAL_INLINE void CSC0_HWA_MODER2_EnableStopAck(CSCx_Reg2_PeriphType ePeriphType) +{ + CSC0->STOP_MODER2 |= (uint32_t)ePeriphType; +} + +/** + * @brief Disable the stop acknowledge function of register 1 group + * + * @param ePeriphType Peripheral to be set + */ +LOCAL_INLINE void CSC0_HWA_MODER2_DisableStopAck(CSCx_Reg2_PeriphType ePeriphType) +{ + CSC0->STOP_MODER2 &= ~(uint32_t)ePeriphType; +} + +/** + * @brief Set multiple stop ack enable/disable value + * + * @param u32Value value to be set + */ +LOCAL_INLINE void CSC0_HWA_MODER2_SetMultiStopAck(uint32_t u32Value) +{ + CSC0->STOP_MODER2 = u32Value; +} + +/** + * @brief Clear multiple stop ack enable/disable value + * + * @param u32Value value to be set + */ +LOCAL_INLINE void CSC0_HWA_MODER2_ClearMultiStopAck(uint32_t u32Value) +{ + CSC0->STOP_MODER2 = (CSC0->STOP_MODER2 & (~u32Value)); +} + +/** + * @brief Lock the cpu to control this stop request register 2 + * + */ +LOCAL_INLINE void CSC0_HWA_REQR2_LockWritePermit(void) +{ + CSC0->STOP_REQR2 |= (uint32_t)CSC0_STOP_REQR2_WPB_LOCK_MASK; +} + +/** + * @brief Get the stop request register 2 lock status + * + * @return Lock status + */ +LOCAL_INLINE uint32_t CSC0_HWA_REQR2_GetWPBLockStatus(void) +{ + return (CSC0->STOP_REQR2 & (uint32_t)CSC0_STOP_REQR2_WPB_LOCK_MASK); +} + +/** + * @brief Set cpu to control stop request register 2 + * + * @param eCpuType Cpu allowed to control peripheral + */ +LOCAL_INLINE void CSC0_HWA_REQR2_SetCpuWritePermit(CSC_WPB_CpuType eCpuType) +{ + uint32_t u32RegVal = CSC0->STOP_REQR2; + CSC0->STOP_REQR2 = ((u32RegVal & (~(uint32_t)CSC0_STOP_REQR2_WPB_MASK)) | CSC0_STOP_REQR2_WPB(eCpuType)); +} + +/** + * @brief Get the CPU type of writing permission + * + * @return CSC_WPB_CpuType The Cpu which has the write permission + */ +LOCAL_INLINE CSC_WPB_CpuType CSC0_HWA_REQR2_GetCpuWritePermit(void) +{ + uint32_t u32RegVal = ((CSC0->STOP_REQR2 & (uint32_t)CSC0_STOP_REQR2_WPB_MASK)>>CSC0_STOP_REQR2_WPB_SHIFT); + return (CSC_WPB_CpuType)u32RegVal; +} + + +/** + * @brief Set stop request in register 2 + * + * @param ePeriphType Peripheral to be set + */ +LOCAL_INLINE void CSC0_HWA_REQR2_SetStopRequest(CSCx_Reg2_PeriphType ePeriphType) +{ + CSC0->STOP_REQR2 |= (uint32_t)ePeriphType; +} + +/** + * @brief Clear stop request in register 2 + * + * @param ePeriphType Peripheral to be cleared + */ +LOCAL_INLINE void CSC0_HWA_REQR2_ClearStopRequest(CSCx_Reg2_PeriphType ePeriphType) +{ + CSC0->STOP_REQR2 &= ~(uint32_t)ePeriphType; +} + +/** + * @brief Set multiple stop request enable/disable value + * + * @param u32Value the OR value of type CSCx_Reg2_PeriphType + */ +LOCAL_INLINE void CSC0_HWA_REQR2_SetMultiStopRequest(uint32_t u32Value) +{ + CSC0->STOP_REQR2 = u32Value; +} + +/** + * @brief Clear multiple stop request in register 0 + * + * @param u32Value the OR value of type CSCx_Reg2_PeriphType + */ +LOCAL_INLINE void CSC0_HWA_REQR2_ClearMultiStopRequest(uint32_t u32Value) +{ + CSC0->STOP_REQR2 = (CSC0->STOP_REQR2 & (~u32Value)); +} + +/** + * @brief Get stop ack status in register 2 + * + * @param u32Value value to be set + * @return Stop ack status + */ +LOCAL_INLINE uint32_t CSC0_HWA_ACKR2_GetStopAckStatus(CSCx_Reg2_PeriphType ePeriphType) +{ + return (CSC0->STOP_ACKR2 & (uint32_t)ePeriphType); +} + +/** + * @brief Get multiple stop ack status in register 2 + * + * @param u32Value the OR value of type CSCx_Reg2_PeriphType + * @return Stop ack status + */ +LOCAL_INLINE uint32_t CSC0_HWA_ACKR2_GetMultiStopAckStatus(uint32_t u32Value) +{ + return (CSC0->STOP_ACKR2 & u32Value); +} + +/** + * @brief Lock the cpu to control CCM0 register + * + */ +LOCAL_INLINE void CSC0_HWA_CCM0_LockWritePermit(void) +{ + CSC0->CCM0_CFG |= (uint32_t)CSC0_CCM0_CFG_WPB_LOCK_MASK; +} + +/** + * @brief Unlock the cpu to control CCM0 register + * + * @return Lock status + */ +LOCAL_INLINE uint32_t CSC0_HWA_CCM0_GetWPBLockStatus(void) +{ + return (CSC0->CCM0_CFG & (uint32_t)CSC0_CCM0_CFG_WPB_LOCK_MASK); +} + +/** + * @brief Get the CPU type of writing permission + * + * @param CSC_WPB_CpuType The Cpu which has the write permission + */ +LOCAL_INLINE CSC_WPB_CpuType CSC0_HWA_CCM0_GetCpuWritePermit(void) +{ + uint32_t u32RegVal = (CSC0->CCM0_CFG & CSC0_CCM0_CFG_WPB_MASK) >> CSC0_CCM0_CFG_WPB_SHIFT; + return (CSC_WPB_CpuType)u32RegVal; +} + +/** + * @brief Set cpu to control this CCM0 register + * + * @param eCpuType Cpu allowed to control peripheral + */ +LOCAL_INLINE void CSC0_HWA_CCM0_SetCpuWritePermit(CSC_WPB_CpuType eCpuType) +{ + uint32_t u32RegVal = CSC0->CCM0_CFG; + CSC0->CCM0_CFG = ((u32RegVal & (~(uint32_t)CSC0_CCM0_CFG_WPB_MASK)) | CSC0_CCM0_CFG_WPB(eCpuType)); +} + +/** + * @brief Force enable HClock of cpu 0 + * + */ +LOCAL_INLINE bool CSC0_HWA_GetHClockEnFlag(void) +{ + return (bool)((CSC0->CCM0_CFG & CSC0_CCM0_CFG_CPU0_FORCE_HCLKEN_MASK) != 0U); +} + +/** + * @brief Force enable HClock of cpu 0 + * + */ +LOCAL_INLINE void CSC0_HWA_HClockEnable(bool bEnable) +{ + CSC0->CCM0_CFG = (CSC0->CCM0_CFG & (~(uint32_t)CSC0_CCM0_CFG_CPU0_FORCE_HCLKEN_MASK)) | + CSC0_CCM0_CFG_CPU0_FORCE_HCLKEN(bEnable); +} + +/** + * @brief Get CCM0 hand shake mode + * + * @param eHandShakeType CCM0 hand shake mode + */ +LOCAL_INLINE CSC_HandShakeModeType CSC0_HWA_GetHandShakeMode(void) +{ + uint32_t u32RegVal = (CSC0->CCM0_CFG & CSC0_CCM0_CFG_CCM0_HANDSHAKE_MODE_MASK) >> CSC0_CCM0_CFG_CCM0_HANDSHAKE_MODE_SHIFT; + return (CSC_HandShakeModeType)u32RegVal; +} + +/** + * @brief Set CCM0 hand shake mode + * + * @param eHandShakeType CCM0 hand shake mode + */ +LOCAL_INLINE void CSC0_HWA_SetHandShakeMode(CSC_HandShakeModeType eHandShakeType) +{ + uint32_t u32RegVal = CSC0->CCM0_CFG; + CSC0->CCM0_CFG = ((u32RegVal & (~(uint32_t)CSC0_CCM0_CFG_CCM0_HANDSHAKE_MODE_MASK)) | CSC0_CCM0_CFG_CCM0_HANDSHAKE_MODE(eHandShakeType)); +} + +/** + * @brief Get CCM0 clock status + * + * @param eStopClockType CCM0 stop clock type + * @return CCM0 clock status + */ +LOCAL_INLINE uint32_t CSC0_HWA_CCM0_GetClockStatus(CSCx_CCM_StopClockType eStopClockType) +{ + return (CSC0->CCM0_STATUS & (uint32_t)eStopClockType); +} + +/** + * @brief Enable SCG MAM stall + * + */ +LOCAL_INLINE void CSC0_HWA_EnalbeSCGStall(void) +{ + CSC0->SCG_MAM_STALL |= (uint32_t)CSC0_SCG_MAM_STALL_SCG_STALL_MASK; +} + +/** + * @brief Disable SCG MAM stall + * + */ +LOCAL_INLINE void CSC0_HWA_DisableSCGStall(void) +{ + CSC0->SCG_MAM_STALL &= ~(uint32_t)CSC0_SCG_MAM_STALL_SCG_STALL_MASK; +} + +/** + * @brief Lock SCG_MAM_STALL register status + * + */ +LOCAL_INLINE void CSC0_HWA_LockSCG_MAM_STALL(void) +{ + CSC0->SCG_MAM_STALL |= (uint32_t)CSC0_SCG_MAM_STALL_LOCK_MASK; +} + +/** + * @brief Get SCG_MAM_STALL register lock status + * + * @return Lock status + */ +LOCAL_INLINE uint32_t CSC0_HWA_SCG_MAM_STALL_GetLockStatus(void) +{ + return (CSC0->SCG_MAM_STALL & (uint32_t)CSC0_SCG_MAM_STALL_LOCK_MASK); +} + +/** + * @brief Lock the cpu to control CPU0_INT register + * + */ +LOCAL_INLINE void CSC0_HWA_CPU0INT_LockWritePermit(void) +{ + CSC0->CPU0_INT |= (uint32_t)CSC0_CPU0_INT_WPB_LOCK_MASK; +} + +/** + * @brief Get CPU0_INT register WPB lock status + * + * @return Lock status + */ +LOCAL_INLINE uint32_t CSC0_HWA_CPU0INT_GetWPBLockStatus(void) +{ + return (CSC0->CPU0_INT & (uint32_t)CSC0_CPU0_INT_WPB_LOCK_MASK); +} + +/** + * @brief Get the CPU type of writing permission + * + * @param CSC_WPB_CpuType The Cpu which has the write permission + */ +LOCAL_INLINE CSC_WPB_CpuType CSC0_HWA_CPU0INT_GetCpuWritePermit(void) +{ + uint32_t u32RegVal = (CSC0->CPU0_INT & CSC0_CPU0_INT_WPB_MASK) >> CSC0_CPU0_INT_WPB_SHIFT; + return (CSC_WPB_CpuType)u32RegVal; +} + +/** + * @brief Set cpu to control this CPU0_INT register + * + * @param eCpuType Cpu allowed to control peripheral + */ +LOCAL_INLINE void CSC0_HWA_CPU0INT_SetCpuWritePermit(CSC_WPB_CpuType eCpuType) +{ + uint32_t u32RegVal = CSC0->CPU0_INT; + CSC0->CPU0_INT = ((u32RegVal & (~(uint32_t)CSC0_CPU0_INT_WPB_MASK)) | CSC0_CPU0_INT_WPB(eCpuType)); +} + +/** + * @brief Enable cpu0 software interrupt + * + */ +LOCAL_INLINE void CSC0_HWA_CPU0INT_EnableSWInterrupt(void) +{ + CSC0->CPU0_INT |= (uint32_t)CSC0_CPU0_INT_SW_INT_MASK; +} + +/** + * @brief Disable cpu0 software interrupt + * + */ +LOCAL_INLINE void CSC0_HWA_CPU0INT_DisableSWInterrupt(void) +{ + CSC0->CPU0_INT &= ~(uint32_t)CSC0_CPU0_INT_SW_INT_MASK; +} + +/** + * @brief Enable CSC0 clock out + * + */ +LOCAL_INLINE void CSC0_HWA_EnableClockOut(void) +{ + CSC0->CLKOUT_CTRL |= (uint32_t)CSC0_CLKOUT_CTRL_CLKOUT_EN_MASK; +} + +/** + * @brief Disable CSC0 clock out + * + */ +LOCAL_INLINE void CSC0_HWA_DisableClockOut(void) +{ + CSC0->CLKOUT_CTRL &= ~(uint32_t)CSC0_CLKOUT_CTRL_CLKOUT_EN_MASK; +} + +/** + * @brief Get CLKOUT CSC0 clock out divider + * + * @return CSC0_ClockOutDivType CSC0 clock out divider + */ +LOCAL_INLINE CSC0_ClockOutDivType CSC0_HWA_GetClkOutDiv(void) +{ + uint32_t u32RegVal = (CSC0->CLKOUT_CTRL & CSC0_CLKOUT_CTRL_CLKOUT_DIV_MASK) >> CSC0_CLKOUT_CTRL_CLKOUT_DIV_SHIFT; + return (CSC0_ClockOutDivType)u32RegVal; +} + +/** + * @brief Set CLKOUTDIV + * + * @param eDivType CSC0 clock out divider + */ +LOCAL_INLINE void CSC0_HWA_SetClkOutDiv(CSC0_ClockOutDivType eDivType) +{ + uint32_t u32RegVal = CSC0->CLKOUT_CTRL; + CSC0->CLKOUT_CTRL = ((u32RegVal & (~(uint32_t)CSC0_CLKOUT_CTRL_CLKOUT_DIV_MASK)) | CSC0_CLKOUT_CTRL_CLKOUT_DIV(eDivType)); +} + +/** + * @brief Get CLKOUT source Select + * + * @return CSC0_ClockOutSrcType CSC0 clock out source + */ +LOCAL_INLINE CSC0_ClockOutSrcType CSC0_HWA_GetClkOutSel(void) +{ + uint32_t u32RegVal = (CSC0->CLKOUT_CTRL & CSC0_CLKOUT_CTRL_CLKOUT_SEL_MASK) >> CSC0_CLKOUT_CTRL_CLKOUT_SEL_SHIFT; + return (CSC0_ClockOutSrcType)u32RegVal; +} + +/** + * @brief Set CLKOUT source Select + * + * @param eClkSrcType CSC0 clock out source + */ +LOCAL_INLINE void CSC0_HWA_SetClkOutSel(CSC0_ClockOutSrcType eClkSrcType) +{ + uint32_t u32RegVal = CSC0->CLKOUT_CTRL; + CSC0->CLKOUT_CTRL = ((u32RegVal & (~(uint32_t)CSC0_CLKOUT_CTRL_CLKOUT_SEL_MASK)) | CSC0_CLKOUT_CTRL_CLKOUT_SEL(eClkSrcType)); +} + +/** + * @brief Lock CSC0_CLKOUT_CTRL register + * + */ +LOCAL_INLINE void CSC0_HWA_LockCLKOUT_CTRL(void) +{ + CSC0->CLKOUT_CTRL |= (uint32_t)CSC0_CLKOUT_CTRL_LOCK_MASK; +} + +/** + * @brief Get CSC0_CLKOUT_CTRL register lock status + * + * @return Lock status + */ +LOCAL_INLINE uint32_t CSC0_HWA_CLKOUT_CTRL_GetLockStatus(void) +{ + return (CSC0->CLKOUT_CTRL & (uint32_t)CSC0_CLKOUT_CTRL_LOCK_MASK); +} + +/** + * @brief Get AONCLKSR register status + * + * @return AONCLKSR register status + */ +LOCAL_INLINE uint32_t CSC0_HWA_GetStatus_AONCLKSR(void) +{ + return CSC0->AONCLKSR; +} + +/** + * @brief Get CSC0_AON32KCLK source clock + * + * @return CSC0_AON32KClkSrcType CSC0_AON32KCLK source type + */ +LOCAL_INLINE CSC0_AON32KClkSrcType CSC0_HWA_GetAON32kClkSrc(void) +{ + uint32_t u32RegVal = (CSC0->AONCLKSR & CSC0_AONCLKSR_AON32KCLKSEL_MASK) >> CSC0_AONCLKSR_AON32KCLKSEL_SHIFT; + return (CSC0_AON32KClkSrcType)u32RegVal; +} + +/** + * @brief Set CSC0_AON32KCLK source clock + * + * @param CSC0_AON32KClkSrcType CSC0_AON32KCLK source type + */ +LOCAL_INLINE void CSC0_HWA_SetAON32kClkSrc(CSC0_AON32KClkSrcType eClkSrcType) +{ + uint32_t u32RegVal = CSC0->AONCLKSR; + CSC0->AONCLKSR = ((u32RegVal & (~(uint32_t)CSC0_AONCLKSR_AON32KCLKSEL_MASK)) | CSC0_AONCLKSR_AON32KCLKSEL(eClkSrcType)); +} + +/** + * @brief Get CSC0_RTCCLK source clock + * + * @return CSC0_RTCClkSrcType CSC0_RTCCLK source type + */ +LOCAL_INLINE CSC0_RTCClkSrcType CSC0_HWA_GetRTCClkSrc(void) +{ + uint32_t u32RegVal = (CSC0->AONCLKSR & CSC0_AONCLKSR_RTCCLKSEL_MASK) >> CSC0_AONCLKSR_RTCCLKSEL_SHIFT; + return (CSC0_RTCClkSrcType)u32RegVal; +} + +/** + * @brief Set CSC0_RTCCLK source clock + * + * @param CSC0_RTCClkSrcType CSC0_RTCCLK source type + */ +LOCAL_INLINE void CSC0_HWA_SetRTCClkSrc(CSC0_RTCClkSrcType eClkSrcType) +{ + uint32_t u32RegVal = CSC0->AONCLKSR; + CSC0->AONCLKSR = ((u32RegVal & (~(uint32_t)CSC0_AONCLKSR_RTCCLKSEL_MASK)) | CSC0_AONCLKSR_RTCCLKSEL(eClkSrcType)); +} + +/** + * @brief Get CSC0_AONCLK source clock + * + * @return CSC0_AONClkSrcType CSC0_AONCLK source type + */ +LOCAL_INLINE CSC0_AONClkSrcType CSC0_HWA_GetAONClkSrc(void) +{ + uint32_t u32RegVal = (CSC0->AONCLKSR & CSC0_AONCLKSR_AONCLKSEL_MASK) >> CSC0_AONCLKSR_AONCLKSEL_SHIFT; + return (CSC0_AONClkSrcType)u32RegVal; +} + +/** + * @brief Set CSC0_AONCLK source clock + * + * @param CSC0_AONClkSrcType CSC0_AONCLK source type + */ +LOCAL_INLINE void CSC0_HWA_SetAONClkSrc(CSC0_AONClkSrcType eClkSrcType) +{ + uint32_t u32RegVal = CSC0->AONCLKSR; + CSC0->AONCLKSR = ((u32RegVal & (~(uint32_t)CSC0_AONCLKSR_AONCLKSEL_MASK)) | CSC0_AONCLKSR_AONCLKSEL(eClkSrcType)); +} + +/** + * @brief Enable CSC0_SIRCDIV32K clock out + * + */ +LOCAL_INLINE void CSC0_HWA_EnableSIRCDIV_32KClkOut(void) +{ + CSC0->AONCLKSR |= (uint32_t)CSC0_AONCLKSR_SIRCDIV32KEN_MASK; +} + +/** + * @brief Disable CSC0_SIRCDIV32K clock out + * + */ +LOCAL_INLINE void CSC0_HWA_DisableSIRCDIV_32KClkOut(void) +{ + CSC0->AONCLKSR &= ~(uint32_t)CSC0_AONCLKSR_SIRCDIV32KEN_MASK; +} + +/** + * @brief Enable CSC0_SIRC32_1K clock out + * + */ +LOCAL_INLINE void CSC0_HWA_EnableSIRC32_1KClkOut(void) +{ + CSC0->AONCLKSR |= (uint32_t)CSC0_AONCLKSR_AON1KCLKEN_MASK; +} + +/** + * @brief Disable CSC0_SIRC32_1K clock out + * + */ +LOCAL_INLINE void CSC0_HWA_DisableSIRC32_1KClkOut(void) +{ + CSC0->AONCLKSR &= ~(uint32_t)CSC0_AONCLKSR_AON1KCLKEN_MASK; +} + +/** + * @brief Lock CSC0_AONCLKSR register + * + */ +LOCAL_INLINE void CSC0_HWA_LockAONCLKSR(void) +{ + CSC0->AONCLKSR |= (uint32_t)CSC0_AONCLKSR_LOCK_MASK; +} + +/** + * @brief Get CSC0_AONCLKSR register lock status + * + * @return Lock status + */ +LOCAL_INLINE uint32_t CSC0_HWA_AONCLKSR_GetLockStaus(void) +{ + return (CSC0->AONCLKSR & (uint32_t)CSC0_AONCLKSR_LOCK_MASK); +} + +/** + * @brief Set count for reduce power mode exit + * + * @param u8Conut count to be set + */ +LOCAL_INLINE void CSC0_HWA_SetRpmExitCount(uint8_t u8Conut) +{ + uint32_t u32RegVal = CSC0->PCU_CTRL; + CSC0->PCU_CTRL = ((u32RegVal & (~(uint32_t)CSC0_PCU_CTRL_RPM_EXIT_CNT_MASK)) | CSC0_PCU_CTRL_RPM_EXIT_CNT(u8Conut)); +} + +/** + * @brief Get count of reduce power mode exit + * + * @return count be got + */ +LOCAL_INLINE uint8_t CSC0_HWA_GetRpmExitCount(void) +{ + return (uint8_t)((CSC0->PCU_CTRL & (uint32_t)CSC0_PCU_CTRL_RPM_EXIT_CNT_MASK)>>CSC0_PCU_CTRL_RPM_EXIT_CNT_SHIFT); +} + +/** + * @brief Set power domain 1 isolation enable hold + * + */ +LOCAL_INLINE void CSC0_HWA_SetPadIsoHold(void) +{ + CSC0->PCU_CTRL |= CSC0_PCU_CTRL_PAD_ISO_HOLD_MASK; +} + +/** + * @brief Power domain 1 isolation enable hold clear + * + */ +LOCAL_INLINE void CSC0_HWA_CLearPadIsoHold(void) +{ + CSC0->PCU_CTRL |= CSC0_PCU_CTRL_PAD_ISO_HOLD_CLR_MASK; +} + +/** + * @brief Lock CSC0_PCU_CTRL register + * + */ +LOCAL_INLINE void CSC0_HWA_LockPCU_CTRL(void) +{ + CSC0->PCU_CTRL |= (uint32_t)CSC0_PCU_CTRL_LOCK_MASK; +} + +/** + * @brief Unlock CSC0_PCU_CTRL register + * + * @return Lock status + */ +LOCAL_INLINE uint32_t CSC0_HWA_PCU_CTRL_GetLockStatus(void) +{ + return (CSC0->PCU_CTRL & (uint32_t)CSC0_PCU_CTRL_LOCK_MASK); +} + +/** + * @brief Enable CSC_SMU control group 0 + * + * @param eType CSC_SMU control group 0 type + */ +LOCAL_INLINE void CSC0_HWA_CTRL0_EnableReqToSMU(CSC_SMU_CtrlGrp0Type eType) +{ + CSC0->SMU_CTRL0 |= (uint32_t)eType; +} + +/** + * @brief Disable CSC_SMU control group 0 + * + * @param eType CSC_SMU control group 0 type + */ +LOCAL_INLINE void CSC0_HWA_CTRL0_DisableReqToSMU(CSC_SMU_CtrlGrp0Type eType) +{ + CSC0->SMU_CTRL0 &= ~(uint32_t)eType; +} + +/** + * @brief Set multiple CSC_SMU control group 0 + * + * @param u32Value The or value of CSC_SMU_CtrlGrp0Type + */ +LOCAL_INLINE void CSC0_HWA_CTRL0_SetMultiReqToSMU(uint32_t u32Value) +{ + CSC0->SMU_CTRL0 = u32Value; +} + +/** + * @brief Clear multiple CSC_SMU control group 0 + * + * @param u32Value The or value of CSC_SMU_CtrlGrp0Type + */ +LOCAL_INLINE void CSC0_HWA_CTRL0_ClearMultiReqToSMU(uint32_t u32Value) +{ + CSC0->SMU_CTRL0 &= ~u32Value; +} + +/** + * @brief Lock CSC0_SMU_CTRL0 register + * + */ +LOCAL_INLINE void CSC0_HWA_LockSMU_CTRL0(void) +{ + CSC0->SMU_CTRL0 |= (uint32_t)CSC0_SMU_CTRL0_LOCK_MASK; +} + +/** + * @brief Get CSC0_SMU_CTRL0 register lock status + * + * @return Lock status + */ +LOCAL_INLINE uint32_t CSC0_HWA_SMU_CTRL0_GetLockStatus(void) +{ + return (CSC0->SMU_CTRL0 & (uint32_t)CSC0_SMU_CTRL0_LOCK_MASK); +} + +/** + * @brief Enable CSC_SMU control group 1 + * + * @param eType CSC_SMU control group 1 type + */ +LOCAL_INLINE void CSC0_HWA_CTRL1_EnableReqToSMU(CSC_SMU_Cpux_CtrlGrpType eType) +{ + CSC0->SMU_CTRL1 |= (uint32_t)eType; +} + +/** + * @brief Disable CSC_SMU control group 1 + * + * @param eType CSC_SMU control group 1 type + */ +LOCAL_INLINE void CSC0_HWA_CTRL1_DisableReqToSMU(CSC_SMU_Cpux_CtrlGrpType eType) +{ + CSC0->SMU_CTRL1 &= ~(uint32_t)eType; +} + +/** + * @brief Set multiple CSC_SMU control group 1 + * + * @param u32Value The or value of CSC_SMU_Cpux_CtrlGrpType + */ +LOCAL_INLINE void CSC0_HWA_CTRL1_SetMultiReqToSMU(uint32_t u32Value) +{ + CSC0->SMU_CTRL1 = u32Value; +} + +/** + * @brief Clear multiple CSC_SMU control group 1 + * + * @param u32Value The or value of CSC_SMU_Cpux_CtrlGrpType + */ +LOCAL_INLINE void CSC0_HWA_CTRL1_ClearMultiReqToSMU(uint32_t u32Value) +{ + CSC0->SMU_CTRL1 &= ~u32Value; +} + +/** + * @brief Lock CSC0_SMU_CTRL1 register + * + */ +LOCAL_INLINE void CSC0_HWA_LockSMU_CTRL1(void) +{ + CSC0->SMU_CTRL1 |= (uint32_t)CSC0_SMU_CTRL1_LOCK_MASK; +} + +/** + * @brief Get CSC0_SMU_CTRL1 register lock status + * + * @return Lock status + */ +LOCAL_INLINE uint32_t CSC0_HWA_SMU_CTRL1_GetLockStatus(void) +{ + return (CSC0->SMU_CTRL1 & (uint32_t)CSC0_SMU_CTRL1_LOCK_MASK); +} + +/** + * @brief Enable CSC_SMU control group 4 + * + * @param eType CSC_SMU control group 4 type + */ +LOCAL_INLINE void CSC0_HWA_CTRL4_EnableReqToSMU(CSC_SMU_CtrlGrp4Type eType) +{ + CSC0->SMU_CTRL4 |= (uint32_t)eType; +} + +/** + * @brief Disable CSC_SMU control group 4 + * + * @param eType CSC_SMU control group 4 type + */ +LOCAL_INLINE void CSC0_HWA_CTRL4_DisableReqToSMU(CSC_SMU_CtrlGrp4Type eType) +{ + CSC0->SMU_CTRL4 &= ~(uint32_t)eType; +} + +/** + * @brief Set multiple CSC_SMU control group 4 + * + * @param u32Value The or value of CSC_SMU_CtrlGrp4Type + */ +LOCAL_INLINE void CSC0_HWA_CTRL4_SetMultiReqToSMU(uint32_t u32Value) +{ + CSC0->SMU_CTRL4 = u32Value; +} + +/** + * @brief Clear multiple CSC_SMU control group 4 + * + * @param u32Value The or value of CSC_SMU_CtrlGrp4Type + */ +LOCAL_INLINE void CSC0_HWA_CTRL4_ClearMultiReqToSMU(uint32_t u32Value) +{ + CSC0->SMU_CTRL4 &= ~u32Value; +} + +/** + * @brief Lock CSC0_SMU_CTRL4 register + * + */ +LOCAL_INLINE void CSC0_HWA_LockSMU_CTRL4(void) +{ + CSC0->SMU_CTRL4 |= (uint32_t)CSC0_SMU_CTRL4_LOCK_MASK; +} + +/** + * @brief Get CSC0_SMU_CTRL4 register lock status + * + * @return Lock status + */ +LOCAL_INLINE uint32_t CSC0_HWA_SMU_CTRL4_GetLockStatus(void) +{ + return (CSC0->SMU_CTRL4 & (uint32_t)CSC0_SMU_CTRL4_LOCK_MASK); +} + +/** + * @brief Enable CSC_SMU control group 5 + * + * @param eType CSC_SMU control group 5 type + */ +LOCAL_INLINE void CSC0_HWA_CTRL5_EnableReqToSMU(CSC_SMU_CtrlGrp5Type eType) +{ + CSC0->SMU_CTRL5 |= (uint32_t)eType; +} + +/** + * @brief Disable CSC_SMU control group 5 + * + * @param eType CSC_SMU control group 5 type + */ +LOCAL_INLINE void CSC0_HWA_CTRL5_DisableReqToSMU(CSC_SMU_CtrlGrp5Type eType) +{ + CSC0->SMU_CTRL5 &= ~(uint32_t)eType; +} + +/** + * @brief Set multiple CSC_SMU control group 5 + * + * @param u32Value The or value of CSC_SMU_CtrlGrp5Type + */ +LOCAL_INLINE void CSC0_HWA_CTRL5_SetMultiReqToSMU(uint32_t u32Value) +{ + CSC0->SMU_CTRL5 = u32Value; +} + +/** + * @brief Clear multiple CSC_SMU control group 5 + * + * @param u32Value The or value of CSC_SMU_CtrlGrp4Type + */ +LOCAL_INLINE void CSC0_HWA_CTRL5_ClearMultiReqToSMU(uint32_t u32Value) +{ + CSC0->SMU_CTRL5 &= ~u32Value; +} + +/** + * @brief Lock CSC0_SMU_CTRL5 register + * + */ +LOCAL_INLINE void CSC0_HWA_LockSMU_CTRL5(void) +{ + CSC0->SMU_CTRL5 |= (uint32_t)CSC0_SMU_CTRL5_LOCK_MASK; +} + +/** + * @brief Get CSC0_SMU_CTRL5 register lock status + * + * @return Lock status + */ +LOCAL_INLINE uint32_t CSC0_HWA_SMU_CTRL5_GetLockStatus(void) +{ + return (CSC0->SMU_CTRL5 & (uint32_t)CSC0_SMU_CTRL5_LOCK_MASK); +} + +/** + * @brief Enable CSC_CMU control group + * + * @param eType CSC_CMU control group type + */ +LOCAL_INLINE void CSC0_HWA_EnableReqToCMU(CSC0_CMU_CtrlGrpType eType) +{ + CSC0->CMU_CTRL |= (uint32_t)eType; +} + +/** + * @brief Disable CSC_CMU control group + * + * @param eType CSC_CMU control group type + */ +LOCAL_INLINE void CSC0_HWA_DisableReqToCMU(CSC0_CMU_CtrlGrpType eType) +{ + CSC0->CMU_CTRL &= ~(uint32_t)eType; +} + +/** + * @brief Lock CSC0_SMU_CTRL4 register + * + */ +LOCAL_INLINE void CSC0_HWA_LockCMU_CTRL(void) +{ + CSC0->CMU_CTRL |= (uint32_t)CSC0_CMU_CTRL_LOCK_MASK; +} + +/** + * @brief Get CSC0_SMU_CTRL4 register lock status + * + * @return Lock status + */ +LOCAL_INLINE uint32_t CSC0_HWA_CMU_CTRL_GetLockStatus(void) +{ + return (CSC0->CMU_CTRL & (uint32_t)CSC0_CMU_CTRL_LOCK_MASK); +} + +/** + * @brief Set low power wakeup PADx configure source + * + * @param eGroup Low power PADx group type + * @eSrc eSrc Low power wakeup PADx configure source + */ +LOCAL_INLINE void CSC0_HWA_SetLP_WAKEUPCfgSrc(CSC0_LPWakeupGrpType eGroup, CSC0_LPWakeupSrcType eSrc) +{ + CSC0->LP_WAKEUP = (CSC0->LP_WAKEUP & (~(CSC0_LP_WAKEUP_LP_WAKEUP_CFG0_MASK >> (4U * (uint32_t)eGroup)))) | + (CSC0_LP_WAKEUP_LP_WAKEUP_CFG0(eSrc) >> (4U * (uint32_t)eGroup)); +} + + +/** + * @brief Set low power wakeup PADx configure source polarity + * + * @param eGroup Low power PADx group type + * @eSrc eSrc Low power wakeup PADx configure source polarity + */ +LOCAL_INLINE void CSC0_HWA_SetLP_WAKEUPCfgPol(CSC0_LPWakeupGrpType eGroup, CSC0_LPWakeupPolType ePolarity) +{ + CSC0->LP_WAKEUP = (CSC0->LP_WAKEUP & (~(CSC0_LP_WAKEUP_LP0_POL_MASK >> (uint32_t)eGroup))) | + (CSC0_LP_WAKEUP_LP0_POL(ePolarity) >> (uint32_t)eGroup); +} + +/** + * @brief Lock low power wakeup register + * + */ +LOCAL_INLINE void CSC0_HWA_LockLP_WAKEUP(void) +{ + CSC0->LP_WAKEUP |= (uint32_t)CSC0_LP_WAKEUP_LOCK_MASK; +} + +/** + * @brief Get low power wakeup register lock status + * + * @return Lock status + */ +LOCAL_INLINE uint32_t CSC0_HWA_LP_WAKEUP_GetLockStatus(void) +{ + return (CSC0->LP_WAKEUP & (uint32_t)CSC0_LP_WAKEUP_LOCK_MASK); +} + +#endif /*#ifndef _HWA_CSC_H_*/ diff --git a/MODULES/HwA_Flagchip_FC7240/Inc/HwA_dma.h b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_dma.h new file mode 100644 index 0000000..03f7632 --- /dev/null +++ b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_dma.h @@ -0,0 +1,1514 @@ +/** + * @file HwA_dma.h + * @author Flagchip0126 + * @brief Hardware access layer for DMA + * @version 0.1.0 + * @date 2024-01-15 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-01-15 Flagchip0126 N/A First version for FC7240 + ******************************************************************************** */ + +#ifndef _HWA_DMA_H_ +#define _HWA_DMA_H_ + +#include "device_header.h" + +#define DMA_CH_TO_DCHPRI(x) ((x) ^ 3U) + +/** + * @defgroup HwA_dma + * @ingroup fc7xxx_driver_dma + * @{ + */ + +/** + * @brief DMA running status + * + */ +typedef enum +{ + DMA_RUNNING_STATUS_IDLE = 0x0U, /*!< The DMA engine is idle */ + DMA_RUNNING_STATUS_ACTIVE = 0x1U /*!< The DMA engine is transferring data */ +} DMA_RunningStatusType; + +/** + * @brief DMA channel arbitration algorithm used in the channel arbitration phase + * + */ +typedef enum +{ + DMA_ARBITRATION_ALGORITHM_FIXED_PRIORITY = 0U, /*!< Use the fixed priority for arbitration */ + DMA_ARBITRATION_ALGORITHM_ROUND_ROBIN = 1U /*!< Use the channel number for arbitration, + higher channel number has higher priority */ +} DMA_ArbitrationAlgorithmType; + +/** + * @brief Defines the size of data in one transfer + * + * One transfer can contain multiple block, and one block may contain multiple + * data, this parameter specifies the size of data which the DMA engine will + * access one time in the memory. + * + */ +typedef enum +{ + + DMA_TRANSFER_SIZE_1B = 0x0U, + DMA_TRANSFER_SIZE_2B = 0x1U, + DMA_TRANSFER_SIZE_4B = 0x2U, + DMA_TRANSFER_SIZE_8B = 0x3U, + DMA_TRANSFER_SIZE_32B = 0x5U +} DMA_TransferSizeType; + +/** + * @brief Get active status of the DMA instance + * + * @param pDma the base address of the DMA instance + * @return DMA_RUNNING_STATUS_ACTIVE DMA is executing a channel + * @return DMA_RUNNING_STATUS_IDLE DMA is idle + */ +LOCAL_INLINE DMA_RunningStatusType DMA_HWA_GetStatus(const DMA_Type *const pDma) +{ + uint32_t u32TmpVal = (pDma->CR & DMA_CR_ACTIVE_MASK) >> DMA_CR_ACTIVE_SHIFT; + return (DMA_RunningStatusType)u32TmpVal; +} + +/** + * @brief Get whether the DMA instance is cancelling + * + * @param pDma the base address of the DMA instance + * @return true cancel operation is requested and has not been finished + * @return false DMA is under normal operation + */ +LOCAL_INLINE bool DMA_HWA_GetCancelTransferStatus(const DMA_Type *const pDma) +{ + uint32_t u32TmpVal = (pDma->CR & DMA_CR_CX_MASK) >> DMA_CR_CX_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Cancel the remaining transfer of the DMA + * + * @param pDma the base address of the DMA instance + */ +LOCAL_INLINE void DMA_HWA_CancelTransfer(DMA_Type *const pDma) +{ + pDma->CR |= DMA_CR_CX_MASK; +} + +/** + * @brief Get whether the DMA instance is cancelling with error + * + * @param pDma the base address of the DMA instance + * @return true cancel operation is requested and has not been finished + * @return false DMA is under normal operation + */ +LOCAL_INLINE bool DMA_HWA_GetErrorCancelTransferStatus(const DMA_Type *const pDma) +{ + uint32_t u32TmpVal = (pDma->CR & DMA_CR_ECX_MASK) >> DMA_CR_ECX_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Set Channel Group 0 Priority + * + * @param pDma the base address of the DMA instance + */ +LOCAL_INLINE void DMA_HWA_SetGPR0PRI(DMA_Type *const pDma) +{ + pDma->CR = (pDma->CR & ~DMA_CR_GPR0PRI_MASK) | DMA_CR_GPR0PRI(1U); +} + +/** + * @brief Cancel the remaining transfer of the DMA and generate an error after finished cancelling + * + * @param pDma the base address of the DMA instance + */ +LOCAL_INLINE void DMA_HWA_ErrorCancelTransfer(DMA_Type *const pDma) +{ + pDma->CR |= DMA_CR_ECX_MASK; +} + +/** + * @brief Get whether inner loop mapping is enabled + * + * @param pDma the base address of the DMA instance + * @return true inner loop mapping is enabled + * @return false inner loop mapping is disabled + */ +LOCAL_INLINE bool DMA_HWA_GetInnerLoopMappingEnableFlag(const DMA_Type *const pDma) +{ + uint32_t u32TmpVal = (pDma->CR & DMA_CR_EILM_MASK) >> DMA_CR_EILM_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Set whether to enable inner loop mapping + * + * @note Only after enabling inner loop mapping, you can apply an offset to the source + * and/or destination address after the inner loop finishes. + * + * @param pDma the base address of the DMA instance + * @param bEnable whether to enable the inner loop mapping + */ +LOCAL_INLINE void DMA_HWA_SetInnerLoopMappingEnableFlag(DMA_Type *const pDma, bool bEnable) +{ + pDma->CR = (pDma->CR & ~DMA_CR_EILM_MASK) | DMA_CR_EILM(bEnable); +} + +/** + * @brief Get whether the continuous trig mode is enabled + * When continuous trig mode is enabled, channel arbitration is not used for a inner loop + * channel trig before being activated again. Upon inner loop completion, the channel + * activates again if that channel has a inner loop channel trig enabled and the trig + * channel is itself. This effectively applies the inner loop offsets and restarts the next + * inner loop. + * + * @param pDma the base address of the DMA instance + * @return true continuous trig mode is enabled + * @return false continuous trig mode is disabled + */ +LOCAL_INLINE bool DMA_HWA_GetContinuousTrigModeEnableFlag(const DMA_Type *const pDma) +{ + uint32_t u32TmpVal = (pDma->CR & DMA_CR_CTM_MASK) >> DMA_CR_CTM_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Set whether to enable the continuous trig mode + * + * @param pDma the base address of the DMA instance + * @param bEnable whether to enable the continuous trig mode + */ +LOCAL_INLINE void DMA_HWA_SetContinuousTrigModeEnableFlag(DMA_Type *const pDma, bool bEnable) +{ + pDma->CR = (pDma->CR & ~DMA_CR_CTM_MASK) | DMA_CR_CTM(bEnable); +} + +/** + * @brief Get whether the DMA is halted + * When the DMA is halted, it will ignore all service requests + * @param pDma the base address of the DMA instance + * @return true the DMA is halted + * @return true the DMA is not halted + */ +LOCAL_INLINE bool DMA_HWA_GetHatlStatus(const DMA_Type *const pDma) +{ + uint32_t u32TmpVal = (pDma->CR & DMA_CR_HALT_MASK) >> DMA_CR_HALT_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Halt the DMA operations + * + * @param pDma the base address of the DMA instance + */ +LOCAL_INLINE void DMA_HWA_HaltOperations(DMA_Type *const pDma) +{ + pDma->CR |= DMA_CR_HALT_MASK; +} + +/** + * @brief Clear the halt flag of the DMA instance + * After HALT is cleared, the DMA could continue to operate + * @param pDma the base address of the DMA instance + */ +LOCAL_INLINE void DMA_HWA_ClearHaltFlag(DMA_Type *const pDma) +{ + pDma->CR &= ~DMA_CR_HALT_MASK; +} + +/** + * @brief Get whether halt on error is enabled on the DMA instance + * + * @param pDma the base address of the DMA instance + * @return true halt on error is enabled, any error will cause HALT flag to be set + * @return false halt on error is disabled + */ +LOCAL_INLINE bool DMA_HWA_GetHaltOnErrorFlag(const DMA_Type *const pDma) +{ + uint32_t u32TmpVal = (pDma->CR & DMA_CR_HOE_MASK) >> DMA_CR_HOE_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Set whether to enable halt on error on the DMA instance + * + * @note Ff halt on error is enabled, any error will cause HALT flag to be set + * + * @param pDma the base address of the DMA instance + * @param bEnable whether to enable halt on error + */ +LOCAL_INLINE void DMA_HWA_SetHaltOnErrorFlag(DMA_Type *const pDma, bool bEnable) +{ + pDma->CR = (pDma->CR & ~DMA_CR_HOE_MASK) | DMA_CR_HOE(bEnable); +} + +/** + * @brief Get the DMA arbitration algorithm + * + * @param pDma the base address of the DMA instance + * @return DMA_ArbitrationAlgorithmType the DMA arbitration algorithm + */ +LOCAL_INLINE DMA_ArbitrationAlgorithmType DMA_HWA_GetArbitrationAlgorithm(const DMA_Type *const pDma) +{ + uint32_t u32TmpVal = (pDma->CR & DMA_CR_ERCA_MASK) >> DMA_CR_ERCA_SHIFT; + return (DMA_ArbitrationAlgorithmType)u32TmpVal; +} + +/** + * @brief Set the DMA arbitration algorithm + * + * @param pDma the base address of the DMA instance + * @param eAlgorithm the DMA arbitration algorithm + */ +LOCAL_INLINE void DMA_HWA_SetArbitrationAlgorithm(DMA_Type *const pDma, DMA_ArbitrationAlgorithmType eAlgorithm) +{ + pDma->CR = (pDma->CR & ~DMA_CR_ERCA_MASK) | DMA_CR_ERCA(eAlgorithm); +} + +/** + * @brief Get whether the DMA is configured to stop under debug mode + * + * @param pDma the base address of the DMA instance + * @return true the DMA is will stop under debug mode + * @return true the DMA is will continue to operate under debug mode + */ +LOCAL_INLINE bool DMA_HWA_GetDebugModeStopFlag(const DMA_Type *const pDma) +{ + uint32_t u32TmpVal = (pDma->CR & DMA_CR_DBGS_MASK) >> DMA_CR_DBGS_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get the control register of the DMA instance + * + * @param pDma the base address of the DMA instance + * @return uint32_t the control register settings + */ +LOCAL_INLINE uint32_t DMA_HWA_GetControlRegister(const DMA_Type *const pDma) +{ + return pDma->CR; +} + +/** + * @brief Set the control register of the DMA instance + * + * @param pDma the base address of the DMA instance + * @param u32Settings the settings of the DMA control register + */ +LOCAL_INLINE void DMA_HWA_SetControlRegister(DMA_Type *const pDma, uint32_t u32Settings) +{ + pDma->CR = u32Settings; +} + +/** + * @brief Set whether to stop DMA under debug mode + * + * @param pDma the base address of the DMA instance + * @param bEnable whether to stop DMA under debug mode + */ +LOCAL_INLINE void DMA_HWA_SetDebugModeStopFlag(DMA_Type *const pDma, bool bEnable) +{ + pDma->CR = (pDma->CR & ~DMA_CR_DBGS_MASK) | DMA_CR_DBGS(bEnable); +} + +/** + * @brief Get the DMA error status + * + * @param pDma the base address of the DMA instance + * @return uint32_t the DMA error status + */ +LOCAL_INLINE uint32_t DMA_HWA_GetErrorStatus(const DMA_Type *const pDma) +{ + return pDma->ES; +} + +/** + * @brief Get whether there is error occured on the specified channel + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + * @return true there is error on the specified channel + * @return false there is no error on the specified channel + */ +LOCAL_INLINE bool DMA_HWA_GetChannelErrorFlag(const DMA_Type *const pDma, uint8_t u8Channel) +{ + uint32_t u32TmpVal = (pDma->ERR & (1UL << u8Channel)) >> u8Channel; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get the channel error status, each bit represents a channel + * + * @param pDma the base address of the DMA instance + * @return uint16_t the channel error status + */ +LOCAL_INLINE uint16_t DMA_HWA_GetAllChannelErrorFlag(const DMA_Type *const pDma) +{ + uint32_t u32TmpVal = pDma->ERR; + return (uint16_t)u32TmpVal; +} + +/** + * @brief Get whether error interrupt is enabled on the specified channel + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + * @return true error interrupt is enabled on the specified channel + * @return false error interrupt is disabled on the specified channel + */ +LOCAL_INLINE bool DMA_HWA_GetChannelErrorInterruptEnableFlag(const DMA_Type *const pDma, uint8_t u8Channel) +{ + uint32_t u32TmpVal = (pDma->EEI & (1UL << u8Channel)) >> u8Channel; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get channel error interrupt enable status + * + * @param pDma the base address of the DMA instance + * @return uint16_t the channel error interrupt enable status + */ +LOCAL_INLINE uint16_t DMA_HWA_GetAllChannelErrorInterruptEnableFlag(const DMA_Type *const pDma) +{ + uint32_t u32TmpVal = pDma->EEI; + return (uint16_t)u32TmpVal; +} + +/** + * @brief Enable error interrupt for the specified channel + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + */ +LOCAL_INLINE void DMA_HWA_EnableChannelErrorInterrupt(DMA_Type *const pDma, uint8_t u8Channel) +{ + pDma->SEEI = DMA_SEEI_SEEI(u8Channel); +} + +/** + * @brief Enable error interrupt for all channels + * + * @param pDma the base address of the DMA instance + */ +LOCAL_INLINE void DMA_HWA_EnableAllChannelErrorInterrupt(DMA_Type *const pDma) +{ + pDma->SEEI = DMA_SEEI_SAEE_MASK; +} + +/** + * @brief Disable error interrupt for the specified channel + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + */ +LOCAL_INLINE void DMA_HWA_DisableChannelErrorInterrupt(DMA_Type *const pDma, uint8_t u8Channel) +{ + pDma->CEEI = DMA_CEEI_CEEI(u8Channel); +} + +/** + * @brief Disable error interrupt for all channels + * + * @param pDma the base address of the DMA instance + */ +LOCAL_INLINE void DMA_HWA_DisableAllChannelErrorInterrupt(DMA_Type *const pDma) +{ + pDma->CEEI = DMA_CEEI_CAEE_MASK; +} + +/** + * @brief Enable channel request for the specified channel + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + */ +LOCAL_INLINE void DMA_HWA_EnableChannelRequest(DMA_Type *const pDma, uint8_t u8Channel) +{ + pDma->SERQ = DMA_SERQ_SERQ(u8Channel); +} + +/** + * @brief Enable channel request for all channels + * + * @param pDma the base address of the DMA instance + */ +LOCAL_INLINE void DMA_HWA_EnableAllChannelRequest(DMA_Type *const pDma) +{ + pDma->SERQ = DMA_SERQ_SAER_MASK; +} + +/** + * @brief Disable channel request for the specified channel + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + */ +LOCAL_INLINE void DMA_HWA_DisableChannelRequest(DMA_Type *const pDma, uint8_t u8Channel) +{ + pDma->CERQ = DMA_CERQ_CERQ(u8Channel); +} + +/** + * @brief Disable channel request for all channels + * + * @param pDma the base address of the DMA instance + */ +LOCAL_INLINE void DMA_HWA_DisableAllChannelRequest(DMA_Type *const pDma) +{ + pDma->CERQ = DMA_CERQ_CAER_MASK; +} + +/** + * @brief Clear DONE bit for the specified channel + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + */ +LOCAL_INLINE void DMA_HWA_ClearChannelDoneStatus(DMA_Type *const pDma, uint8_t u8Channel) +{ + pDma->CDNE = DMA_CDNE_CDNE(u8Channel); +} + +/** + * @brief Clear DONE bit for the all channels + * + * @param pDma the base address of the DMA instance + */ +LOCAL_INLINE void DMA_HWA_ClearAllChannelDoneStatus(DMA_Type *const pDma) +{ + pDma->CDNE = DMA_CDNE_CADN_MASK; +} + +/** + * @brief Clear ERR bit for the specified channel + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + */ +LOCAL_INLINE void DMA_HWA_ClearChannelErrorFlag(DMA_Type *const pDma, uint8_t u8Channel) +{ + pDma->CERR = DMA_CERR_CERR(u8Channel); +} + +/** + * @brief Clear ERR bit for the all channels + * + * @param pDma the base address of the DMA instance + */ +LOCAL_INLINE void DMA_HWA_ClearAllChannelErrorFlag(DMA_Type *const pDma) +{ + pDma->CERR = DMA_CERR_CAEI_MASK; +} + +/** + * @brief Clear interrupt flag for the specified channel + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + */ +LOCAL_INLINE void DMA_HWA_ClearChannelInterruptFlag(DMA_Type *const pDma, uint8_t u8Channel) +{ + pDma->CINT = DMA_CINT_CINT(u8Channel); +} + +/** + * @brief Clear interrupt flag for the all channels + * + * @param pDma the base address of the DMA instance + */ +LOCAL_INLINE void DMA_HWA_ClearAllChannelInterruptFlag(DMA_Type *const pDma) +{ + pDma->CINT = DMA_CINT_CAIR_MASK; +} + +/** + * @brief Set start for the specified channel + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + */ +LOCAL_INLINE void DMA_HWA_SetChannelStart(DMA_Type *const pDma, uint8_t u8Channel) +{ + pDma->SSRT = DMA_SSRT_SSRT(u8Channel); +} + +/** + * @brief Set start for the all channels + * + * @param pDma the base address of the DMA instance + */ +LOCAL_INLINE void DMA_HWA_SetAllChannelStart(DMA_Type *const pDma) +{ + pDma->SSRT = DMA_SSRT_SAST_MASK; +} + +/** + * @brief Get whether source unalign modulo is enabled for the specified channel + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + */ +LOCAL_INLINE bool DMA_HWA_GetSrcUnalignModuloEnableFlag(const DMA_Type *const pDma, uint8_t u8Channel) +{ + uint32_t u32TmpVal = (pDma->DUME[u8Channel/16U] & ((uint32_t)DMA_DUME_SUME0_MASK << (2U * (u8Channel % 16U)))) >> + (DMA_DUME_SUME0_SHIFT + 2U * (u8Channel % 16U)); + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get whether destination unalign modulo is enabled for the specified channel + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + */ +LOCAL_INLINE bool DMA_HWA_GetDestUnalignModuloEnableFlag(const DMA_Type *const pDma, uint8_t u8Channel) +{ + uint32_t u32TmpVal = (pDma->DUME[u8Channel/16U] & ((uint32_t)DMA_DUME_DUME0_MASK << (2U * (u8Channel % 16U)))) >> + (DMA_DUME_DUME0_SHIFT + 2U * (u8Channel % 16U)); + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get whether to enable unalign modulo for the specified channel + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + * @param bEnableSrcModulo whether source unalign modulo is to be enabled + * @param bEnableDestModulo whether destination unalign modulo is to be enabled + */ +LOCAL_INLINE void DMA_HWA_SetUnalignModuloEnableFlag(DMA_Type *const pDma, uint8_t u8Channel, + bool bEnableSrcModulo, bool bEnableDestModulo) +{ + pDma->DUME[u8Channel/16U] = (pDma->DUME[u8Channel/16U] & ~((DMA_DUME_DUME0_MASK | DMA_DUME_SUME0_MASK) << (2U * (u8Channel % 16U)))) | + ((DMA_DUME_DUME0(bEnableDestModulo) | DMA_DUME_SUME0(bEnableSrcModulo)) << (2U * (u8Channel % 16U))); +} + +/** + * @brief Get the source unalign modulo of the index + * + * @param pDma the base address of the DMA instance + * @param u8Selection the index of the unalign modulo + * @return uint16_t the source unalign modulo + */ +LOCAL_INLINE uint16_t DMA_HWA_GetSrcUnalignModulo(const DMA_Type *const pDma, uint8_t u8Selection) +{ + uint32_t u32TmpVal = (pDma->DUMO[u8Selection] & DMA_DUMO_SUMO_MASK) >> DMA_DUMO_SUMO_SHIFT; + return (uint16_t)u32TmpVal; +} + +/** + * @brief Get the destination unalign modulo of the index + * + * @param pDma the base address of the DMA instance + * @param u8Selection the index of the unalign modulo + * @return uint16_t the destination unalign modulo + */ +LOCAL_INLINE uint16_t DMA_HWA_GetDestUnalignModulo(const DMA_Type *const pDma, uint8_t u8Selection) +{ + uint32_t u32TmpVal = (pDma->DUMO[u8Selection] & DMA_DUMO_DUMO_MASK) >> DMA_DUMO_DUMO_SHIFT; + return (uint16_t)u32TmpVal; +} + +/** + * @brief Set unalign modulo of the index + * + * @param pDma the base address of the DMA instance + * @param u8Selection the index of the unalign modulo + * @param u16SrcModulo the source unalign modulo + * @param u16DestModulo the destination unalign modulo + */ +LOCAL_INLINE void DMA_HWA_SetUnalignModulo(DMA_Type *const pDma, uint8_t u8Selection, + uint16_t u16SrcModulo, uint16_t u16DestModulo) +{ + pDma->DUMO[u8Selection] = DMA_DUMO_SUMO(u16SrcModulo) | DMA_DUMO_DUMO(u16DestModulo); +} + +/** + * @brief Get priority of the channel + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + * @return uint8_t the priority of the channel + */ +LOCAL_INLINE uint8_t DMA_HWA_GetPriority(const DMA_Type *const pDma, uint8_t u8Channel) +{ + uint8_t u8TmpVal = pDma->DCHPRI[DMA_CH_TO_DCHPRI(u8Channel)]; + return u8TmpVal; +} + +/** + * @brief Set priority of the channel + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + * @param u8Priority the priority of the channel + */ +LOCAL_INLINE void DMA_HWA_SetPriority(DMA_Type *const pDma, uint8_t u8Channel, uint8_t u8Priority) +{ + pDma->DCHPRI[DMA_CH_TO_DCHPRI(u8Channel)] = u8Priority; +} + +/** + * @brief Get the source address of the DMA channel + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + * @return uint32_t the source address of the DMA channel + */ +LOCAL_INLINE uint32_t DMA_HWA_GetSrcAddr(const DMA_Type *const pDma, uint8_t u8Channel) +{ + return pDma->CFG[u8Channel].SADDR; +} + +/** + * @brief Set the source address of the DMA channel + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + * @param u32SrcAddr the source address of the DMA channel + */ +LOCAL_INLINE void DMA_HWA_SetSrcAddr(DMA_Type *const pDma, uint8_t u8Channel, uint32_t u32SrcAddr) +{ + pDma->CFG[u8Channel].SADDR = u32SrcAddr; +} + +/** + * @brief Get the destination address of the DMA channel + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + * @return uint32_t the destination address of the DMA channel + */ +LOCAL_INLINE uint32_t DMA_HWA_GetDestAddr(const DMA_Type *const pDma, uint8_t u8Channel) +{ + return pDma->CFG[u8Channel].DADDR; +} + +/** + * @brief Set the destination address of the DMA channel + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + * @param u32DestAddr the destination address of the DMA channel + */ +LOCAL_INLINE void DMA_HWA_SetDestAddr(DMA_Type *const pDma, uint8_t u8Channel, uint32_t u32DestAddr) +{ + pDma->CFG[u8Channel].DADDR = u32DestAddr; +} + +/** + * @brief Get source data offset of the DMA channel + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + * @return int16_t the source data offset + */ +LOCAL_INLINE int16_t DMA_HWA_GetSrcOffset(const DMA_Type *const pDma, uint8_t u8Channel) +{ + return (int16_t)pDma->CFG[u8Channel].SOFF; +} + +/** + * @brief Set source data offset of the DMA channel + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + * @param s16Offset the source data offset + */ +LOCAL_INLINE void DMA_HWA_SetSrcOffset(DMA_Type *const pDma, uint8_t u8Channel, int16_t s16Offset) +{ + pDma->CFG[u8Channel].SOFF = (uint16_t)s16Offset; +} + +/** + * @brief Get destination data offset of the DMA channel + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + * @return int16_t the destination data offset + */ +LOCAL_INLINE int16_t DMA_HWA_GetDestOffset(const DMA_Type *const pDma, uint8_t u8Channel) +{ + return (int16_t)pDma->CFG[u8Channel].DOFF; +} + +/** + * @brief Set destination data offset of the DMA channel + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + * @param s16Offset the destination data offset + */ +LOCAL_INLINE void DMA_HWA_SetDestOffset(DMA_Type *const pDma, uint8_t u8Channel, int16_t s16Offset) +{ + pDma->CFG[u8Channel].DOFF = (uint16_t)s16Offset; +} + +/** + * @brief Get the source data size of the DMA channel + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + * @return DMA_TransferSizeType the source data size of the DMA channel + */ +LOCAL_INLINE DMA_TransferSizeType DMA_HWA_GetSrcDataSize(const DMA_Type *const pDma, uint8_t u8Channel) +{ + uint16_t u16TmpVal = (pDma->CFG[u8Channel].ATTR & DMA_CFG_ATTR_SSIZE_MASK) >> DMA_CFG_ATTR_SSIZE_SHIFT; + return (DMA_TransferSizeType)u16TmpVal; +} + +/** + * @brief Set the source data size of the DMA channel + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + * @param eDataSize the source data size of the DMA channel + */ +LOCAL_INLINE void DMA_HWA_SetSrcDataSize(DMA_Type *const pDma, uint8_t u8Channel, DMA_TransferSizeType eDataSize) +{ + pDma->CFG[u8Channel].ATTR = (pDma->CFG[u8Channel].ATTR & ~DMA_CFG_ATTR_SSIZE_MASK) | DMA_CFG_ATTR_SSIZE(eDataSize); +} + +/** + * @brief Get the destination data size of the DMA channel + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + * @return DMA_TransferSizeType the destination data size of the DMA channel + */ +LOCAL_INLINE DMA_TransferSizeType DMA_HWA_GetDestDataSize(const DMA_Type *const pDma, uint8_t u8Channel) +{ + uint16_t u16TmpVal = (pDma->CFG[u8Channel].ATTR & DMA_CFG_ATTR_DSIZE_MASK) >> DMA_CFG_ATTR_DSIZE_SHIFT; + return (DMA_TransferSizeType)u16TmpVal; +} + +/** + * @brief Set the destination data size of the DMA channel + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + * @param eDataSize the destination data size of the DMA channel + */ +LOCAL_INLINE void DMA_HWA_SetDestDataSize(DMA_Type *const pDma, uint8_t u8Channel, DMA_TransferSizeType eDataSize) +{ + pDma->CFG[u8Channel].ATTR = (pDma->CFG[u8Channel].ATTR & ~DMA_CFG_ATTR_DSIZE_MASK) | DMA_CFG_ATTR_DSIZE(eDataSize); +} + +/** + * @brief Get the source address aligned modulo of the DMA channel + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + * @return uint8_t the source address aligned modulo + */ +LOCAL_INLINE uint8_t DMA_HWA_GetSrcModulo(const DMA_Type *const pDma, uint8_t u8Channel) +{ + uint16_t u16TmpVal = (pDma->CFG[u8Channel].ATTR & DMA_CFG_ATTR_SMOD_MASK) >> DMA_CFG_ATTR_SMOD_SHIFT; + return (uint8_t)u16TmpVal; +} + +/** + * @brief Set the source address aligned modulo of the DMA channel + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + * @param u8SrcModulo the source address aligned modulo + */ +LOCAL_INLINE void DMA_HWA_SetSrcModulo(DMA_Type *const pDma, uint8_t u8Channel, uint8_t u8SrcModulo) +{ + pDma->CFG[u8Channel].ATTR = (pDma->CFG[u8Channel].ATTR & ~DMA_CFG_ATTR_SMOD_MASK) | DMA_CFG_ATTR_SMOD(u8SrcModulo); +} + +/** + * @brief Get the destination address aligned modulo of the DMA channel + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + * @return uint8_t the destination address aligned modulo + */ +LOCAL_INLINE uint8_t DMA_HWA_GetDestModulo(const DMA_Type *const pDma, uint8_t u8Channel) +{ + uint16_t u16TmpVal = (pDma->CFG[u8Channel].ATTR & DMA_CFG_ATTR_DMOD_MASK) >> DMA_CFG_ATTR_DMOD_SHIFT; + return (uint8_t)u16TmpVal; +} + +/** + * @brief Set the destination address aligned modulo of the DMA channel + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + * @param u8DestModulo the destination address aligned modulo + */ +LOCAL_INLINE void DMA_HWA_SetDestModulo(DMA_Type *const pDma, uint8_t u8Channel, uint8_t u8DestModulo) +{ + pDma->CFG[u8Channel].ATTR = (pDma->CFG[u8Channel].ATTR & ~DMA_CFG_ATTR_DMOD_MASK) | DMA_CFG_ATTR_DMOD(u8DestModulo); +} + +/** + * @brief Get the address adjustment applied to the source address after major loop finished + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + * @return int32_t the address adjustment applied to the source address after major loop finished + */ +LOCAL_INLINE int32_t DMA_HWA_GetSrcLastAddrAdjustment(const DMA_Type *const pDma, uint8_t u8Channel) +{ + return (int32_t)pDma->CFG[u8Channel].SLAST; +} + +/** + * @brief Set the address adjustment applied to the source address after major loop finished + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + * @param s32LastAdj the address adjustment applied to the source address after major loop finished + */ +LOCAL_INLINE void DMA_HWA_SetSrcLastAddrAdjustment(DMA_Type *const pDma, uint8_t u8Channel, int32_t s32LastAdj) +{ + pDma->CFG[u8Channel].SLAST = (uint32_t)s32LastAdj; +} + +/** + * @brief Get the address adjustment applied to the destination address after major loop finished + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + * @return int32_t the address adjustment applied to the destination address after major loop finished + */ +LOCAL_INLINE int32_t DMA_HWA_GetDestLastAddrAdjustment(const DMA_Type *const pDma, uint8_t u8Channel) +{ + return (int32_t)pDma->CFG[u8Channel].DLAST; +} + +/** + * @brief Set the address adjustment applied to the destination address after major loop finished + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + * @param s32LastAdj the address adjustment applied to the destination address after major loop finished + */ +LOCAL_INLINE void DMA_HWA_SetDestLastAddrAdjustment(DMA_Type *const pDma, uint8_t u8Channel, int32_t s32LastAdj) +{ + pDma->CFG[u8Channel].DLAST = (uint32_t)s32LastAdj; +} + +/** + * @brief Get whether source address inner loop offset is enabled + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + * @return true source address inner loop offset is enabled + * @return false source address inner loop offset is disabled + */ +LOCAL_INLINE bool DMA_HWA_GetInnerLoopSrcOffsetEnableFlag(const DMA_Type *const pDma, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + if (DMA_HWA_GetInnerLoopMappingEnableFlag(pDma) == false) + { + u32TmpVal = 0U; + } + else + { + u32TmpVal = (pDma->CFG[u8Channel].NBYTES.ILOFFNO & DMA_CFG_NBYTES_ILOFFNO_SILOE_MASK) >> + DMA_CFG_NBYTES_ILOFFNO_SILOE_SHIFT; + } + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get whether destination address inner loop offset is enabled + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + * @return true destination address inner loop offset is enabled + * @return false destination address inner loop offset is disabled + */ +LOCAL_INLINE bool DMA_HWA_GetInnerLoopDestOffsetEnableFlag(const DMA_Type *const pDma, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + if (DMA_HWA_GetInnerLoopMappingEnableFlag(pDma) == false) + { + u32TmpVal = 0U; + } + else + { + u32TmpVal = (pDma->CFG[u8Channel].NBYTES.ILOFFNO & DMA_CFG_NBYTES_ILOFFNO_DILOE_MASK) >> + DMA_CFG_NBYTES_ILOFFNO_DILOE_SHIFT; + } + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get the inner loop offset of the DMA channel + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + * @return int32_t the signed inner loop offset + */ +LOCAL_INLINE int32_t DMA_HWA_GetInnerLoopOffset(const DMA_Type *const pDma, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + if (DMA_HWA_GetInnerLoopMappingEnableFlag(pDma) == false) + { + u32TmpVal = 0U; + } + else + { + bool bDmaInnerLoopSrcOffsetEnable = DMA_HWA_GetInnerLoopSrcOffsetEnableFlag(pDma, u8Channel); + bool bDmaInnerLoopDestOffsetEnable = DMA_HWA_GetInnerLoopDestOffsetEnableFlag(pDma, u8Channel); + if ((bDmaInnerLoopSrcOffsetEnable == false) && (bDmaInnerLoopDestOffsetEnable == false)) + { + u32TmpVal = 0U; + } + else + { + u32TmpVal = (pDma->CFG[u8Channel].NBYTES.ILOFFYES & DMA_CFG_NBYTES_ILOFFYES_ILOFF_MASK) >> + DMA_CFG_NBYTES_ILOFFYES_ILOFF_SHIFT; + } + } + /* Convert sign-extended 20bit value to signed 32bit value */ + if ((u32TmpVal & (1U << 19U)) != 0U) + { + u32TmpVal |= 0xFFF00000U; + } + return (int32_t)u32TmpVal; +} + +/** + * @brief Get the transfer data size of the inner loop + * @note if inner loop mapping is disabled, the range is 0~2^31-1 + * if inner loop mapping is enabled and inner loop offset is disabled, the range is 0~2^30-1 + * if inner loop mapping is enabled and inner loop offset is enabled, the range is 0~2^10-1 + * 0 means 2^32 + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + * @return uint32_t the transfer data size of the inner loop + */ +LOCAL_INLINE uint32_t DMA_HWA_GetInnerLoopSize(const DMA_Type *const pDma, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + if (DMA_HWA_GetInnerLoopMappingEnableFlag(pDma) == false) + { + u32TmpVal = pDma->CFG[u8Channel].NBYTES.ILNO; + } + else + { + bool bDmaInnerLoopSrcOffsetEnable = DMA_HWA_GetInnerLoopSrcOffsetEnableFlag(pDma, u8Channel); + bool bDmaInnerLoopDestOffsetEnable = DMA_HWA_GetInnerLoopDestOffsetEnableFlag(pDma, u8Channel); + if ((bDmaInnerLoopSrcOffsetEnable == false) && (bDmaInnerLoopDestOffsetEnable == false)) + { + u32TmpVal = (pDma->CFG[u8Channel].NBYTES.ILOFFNO & DMA_CFG_NBYTES_ILOFFNO_NBYTES_MASK) >> + DMA_CFG_NBYTES_ILOFFNO_NBYTES_SHIFT; + } + else + { + u32TmpVal = (pDma->CFG[u8Channel].NBYTES.ILOFFYES & DMA_CFG_NBYTES_ILOFFYES_NBYTES_MASK) >> + DMA_CFG_NBYTES_ILOFFYES_NBYTES_SHIFT; + } + } + return u32TmpVal; +} + +/** + * @brief Set the inner loop offset of the DMA channel + * + * @note the inner loop offset can only be enabled when inner loop mapping is enabled + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + * @param bEnableSrcOffset whether to enable source address inner loop offset + * @param bEnableDestOffset whether to enable destination address inner loop offset + * @param s32Offset the inner loop offset + */ +LOCAL_INLINE void DMA_HWA_SetInnerLoopOffset(DMA_Type *const pDma, uint8_t u8Channel, bool bEnableSrcOffset, + bool bEnableDestOffset, int32_t s32Offset) +{ + if (DMA_HWA_GetInnerLoopMappingEnableFlag(pDma) == false) + { + //ignore the action + } + else + { + if ((bEnableSrcOffset == false) && (bEnableDestOffset == false)) + { + bool bDmaInnerLoopSrcOffsetEnable = DMA_HWA_GetInnerLoopSrcOffsetEnableFlag(pDma, u8Channel); + bool bDmaInnerLoopDestOffsetEnable = DMA_HWA_GetInnerLoopDestOffsetEnableFlag(pDma, u8Channel); + /* If inner loop offset is enabled, to disable inner loop offset, we should clear the inner + loop offset enable bit and meanwhile the inner loop offset bits */ + if ((bDmaInnerLoopSrcOffsetEnable == true) || (bDmaInnerLoopDestOffsetEnable == true)) + { + pDma->CFG[u8Channel].NBYTES.ILOFFNO &= ~(DMA_CFG_NBYTES_ILOFFNO_SILOE_MASK | DMA_CFG_NBYTES_ILOFFNO_DILOE_MASK | + DMA_CFG_NBYTES_ILOFFYES_ILOFF_MASK); + } + } + else + { + pDma->CFG[u8Channel].NBYTES.ILOFFYES = (pDma->CFG[u8Channel].NBYTES.ILOFFYES & ~(DMA_CFG_NBYTES_ILOFFYES_SILOE_MASK | + DMA_CFG_NBYTES_ILOFFYES_DILOE_MASK | DMA_CFG_NBYTES_ILOFFYES_ILOFF_MASK)) | + DMA_CFG_NBYTES_ILOFFYES_SILOE(bEnableSrcOffset) | + DMA_CFG_NBYTES_ILOFFYES_DILOE(bEnableDestOffset) | + DMA_CFG_NBYTES_ILOFFYES_ILOFF(s32Offset); + } + } +} + +/** + * @brief Set the transfer data size of the inner loop + * @note if inner loop mapping is disabled, the range is 0~2^31-1 + * if inner loop mapping is enabled and inner loop offset is disabled, the range is 0~2^30-1 + * if inner loop mapping is enabled and inner loop offset is enabled, the range is 0~2^10-1 + * 0 means 2^32 + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + * @param u32Size the transfer data size of the inner loop + */ +LOCAL_INLINE void DMA_HWA_SetInnerLoopSize(DMA_Type *const pDma, uint8_t u8Channel, uint32_t u32Size) +{ + if (DMA_HWA_GetInnerLoopMappingEnableFlag(pDma) == false) + { + pDma->CFG[u8Channel].NBYTES.ILNO = DMA_CFG_NBYTES_ILNO_NBYTES(u32Size); + } + else + { + bool bDmaInnerLoopSrcOffsetEnable = DMA_HWA_GetInnerLoopSrcOffsetEnableFlag(pDma, u8Channel); + bool bDmaInnerLoopDestOffsetEnable = DMA_HWA_GetInnerLoopDestOffsetEnableFlag(pDma, u8Channel); + if ((bDmaInnerLoopSrcOffsetEnable == false) && (bDmaInnerLoopDestOffsetEnable == false)) + { + pDma->CFG[u8Channel].NBYTES.ILOFFNO = (pDma->CFG[u8Channel].NBYTES.ILOFFNO & ~DMA_CFG_NBYTES_ILOFFNO_NBYTES_MASK) | + DMA_CFG_NBYTES_ILOFFNO_NBYTES(u32Size); + } + else + { + pDma->CFG[u8Channel].NBYTES.ILOFFYES = (pDma->CFG[u8Channel].NBYTES.ILOFFYES & ~DMA_CFG_NBYTES_ILOFFYES_NBYTES_MASK) | + DMA_CFG_NBYTES_ILOFFYES_NBYTES(u32Size); + } + } +} + +/** + * @brief Get whether current channel to channel trig is enabled when inner loop complete + * @note this field shall always be same with the beginning channel to channel trig enable flag + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + * @return true channel to channel trig is enabled when inner loop complete + * @return false channel to channel trig is disabled when inner loop complete + */ +LOCAL_INLINE bool DMA_HWA_GetCurrentChannelToChannelTrigEnableFlag(const DMA_Type *const pDma, uint8_t u8Channel) +{ + uint16_t u16TmpVal = (pDma->CFG[u8Channel].CLC.CHTRGENNO & DMA_CFG_CLC_CHTRGENNO_CHTRGEN_MASK) >> + DMA_CFG_CLC_CHTRGENNO_CHTRGEN_SHIFT; + return (bool)((u16TmpVal != 0U) ? true : false); +} + +/** + * @brief Get the target channel when current channel to channel trig is enabled + * @note this field shall always be same with the beginning traget channel trig field + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + * @return uint8_t the target channel + */ +LOCAL_INLINE uint8_t DMA_HWA_GetCurrentChannelToChannelTrigChannel(const DMA_Type *const pDma, uint8_t u8Channel) +{ + uint16_t u16TmpVal; + if (DMA_HWA_GetCurrentChannelToChannelTrigEnableFlag(pDma, u8Channel) == true) + { + u16TmpVal = (pDma->CFG[u8Channel].CLC.CHTRGENYES & DMA_CFG_CLC_CHTRGENYES_TRGCH_MASK) >> + DMA_CFG_CLC_CHTRGENYES_TRGCH_SHIFT; + } + else + { + u16TmpVal = 0U; + } + return (uint8_t)u16TmpVal; +} + +/** + * @brief Get the current loop count + * The current loop count is the same as the beginning loop count initially, and it will decrement + * each time a inner loop finishes + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + * @return uint16_t the current loop count + */ +LOCAL_INLINE uint16_t DMA_HWA_GetCurrentLoopCount(const DMA_Type *const pDma, uint8_t u8Channel) +{ + uint16_t u16TmpVal; + if (DMA_HWA_GetCurrentChannelToChannelTrigEnableFlag(pDma, u8Channel) == false) + { + u16TmpVal = (pDma->CFG[u8Channel].CLC.CHTRGENNO & DMA_CFG_CLC_CHTRGENNO_CLC_MASK) >> DMA_CFG_CLC_CHTRGENNO_CLC_SHIFT; + } + else + { + u16TmpVal = (pDma->CFG[u8Channel].CLC.CHTRGENYES & DMA_CFG_CLC_CHTRGENYES_CLC_MASK) >> DMA_CFG_CLC_CHTRGENYES_CLC_SHIFT; + } + return u16TmpVal; +} + +/** + * @brief Get whether beginning channel to channel trig is enabled when inner loop complete + * @note this field shall always be same with the current channel to channel trig enable flag + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + * @return true channel to channel trig is enabled when inner loop complete + * @return false channel to channel trig is disabled when inner loop complete + */ +LOCAL_INLINE bool DMA_HWA_GetBeginningChannelToChannelTrigEnableFlag(const DMA_Type *const pDma, uint8_t u8Channel) +{ + uint16_t u16TmpVal = (pDma->CFG[u8Channel].BLC.CHTRGENNO & DMA_CFG_BLC_CHTRGENNO_CHTRGEN_MASK) >> + DMA_CFG_BLC_CHTRGENNO_CHTRGEN_SHIFT; + return (bool)((u16TmpVal != 0U) ? true : false); +} + +/** + * @brief Get the target channel when beginning channel to channel trig is enabled + * @note this field shall always be same with the current traget channel trig field + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + * @return uint8_t the target channel + */ +LOCAL_INLINE uint8_t DMA_HWA_GetBeginningChannelToChannelTrigChannel(const DMA_Type *const pDma, uint8_t u8Channel) +{ + uint16_t u16TmpVal; + if (DMA_HWA_GetBeginningChannelToChannelTrigEnableFlag(pDma, u8Channel) == true) + { + u16TmpVal = (pDma->CFG[u8Channel].BLC.CHTRGENYES & DMA_CFG_BLC_CHTRGENYES_TRGCH_MASK) >> + DMA_CFG_BLC_CHTRGENYES_TRGCH_SHIFT; + } + else + { + u16TmpVal = 0U; + } + return (uint8_t)u16TmpVal; +} + +/** + * @brief Get the beginning loop count + * This field specifies how many inner loops will be executed in a DMA transfer + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + * @return uint16_t the beginning loop count + */ +LOCAL_INLINE uint16_t DMA_HWA_GetBeginningLoopCount(const DMA_Type *const pDma, uint8_t u8Channel) +{ + uint16_t u16TmpVal; + if (DMA_HWA_GetBeginningChannelToChannelTrigEnableFlag(pDma, u8Channel) == false) + { + u16TmpVal = (pDma->CFG[u8Channel].BLC.CHTRGENNO & DMA_CFG_BLC_CHTRGENNO_BLC_MASK) >> DMA_CFG_BLC_CHTRGENNO_BLC_SHIFT; + } + else + { + u16TmpVal = (pDma->CFG[u8Channel].BLC.CHTRGENYES & DMA_CFG_BLC_CHTRGENYES_BLC_MASK) >> DMA_CFG_BLC_CHTRGENYES_BLC_SHIFT; + } + return u16TmpVal; +} + +/** + * @brief Set channel to channel trig when inner loop complete + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + * @param bEnable whether to enbable channel to channel trig when inner loop complete + * @param u8TrigChannel the target channel + */ +LOCAL_INLINE void DMA_HWA_SetChannelToChannelTrig(DMA_Type *const pDma, uint8_t u8Channel, bool bEnable, + uint8_t u8TrigChannel) +{ + if (bEnable == false) + { + if (DMA_HWA_GetBeginningChannelToChannelTrigEnableFlag(pDma, u8Channel) == true) + { + pDma->CFG[u8Channel].BLC.CHTRGENNO &= ~(DMA_CFG_BLC_CHTRGENNO_CHTRGEN_MASK); + pDma->CFG[u8Channel].CLC.CHTRGENNO &= ~(DMA_CFG_CLC_CHTRGENNO_CHTRGEN_MASK); + } + } + else + { + pDma->CFG[u8Channel].BLC.CHTRGENYES = (pDma->CFG[u8Channel].BLC.CHTRGENYES & + ~(DMA_CFG_BLC_CHTRGENYES_CHTRGEN_MASK | DMA_CFG_BLC_CHTRGENYES_TRGCH_MASK)) | + DMA_CFG_BLC_CHTRGENYES_CHTRGEN(bEnable) | DMA_CFG_BLC_CHTRGENYES_TRGCH(u8TrigChannel); + pDma->CFG[u8Channel].CLC.CHTRGENYES = (pDma->CFG[u8Channel].CLC.CHTRGENYES & + ~(DMA_CFG_CLC_CHTRGENYES_CHTRGEN_MASK | DMA_CFG_CLC_CHTRGENYES_TRGCH_MASK)) | + DMA_CFG_CLC_CHTRGENYES_CHTRGEN(bEnable) | DMA_CFG_CLC_CHTRGENYES_TRGCH(u8TrigChannel); + } +} + +/** + * @brief Set the loop count of the DMA transfer + * This field specifies how many inner loops will be executed in a DMA transfer + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + * @param u16LoopCnt the inner loop count in a DMA transfer + */ +LOCAL_INLINE void DMA_HWA_SetLoopCount(DMA_Type *const pDma, uint8_t u8Channel, uint16_t u16LoopCnt) +{ + if (DMA_HWA_GetBeginningChannelToChannelTrigEnableFlag(pDma, u8Channel) == false) + { + pDma->CFG[u8Channel].BLC.CHTRGENNO = (pDma->CFG[u8Channel].BLC.CHTRGENNO & ~DMA_CFG_BLC_CHTRGENNO_BLC_MASK) | + DMA_CFG_BLC_CHTRGENNO_BLC(u16LoopCnt); + pDma->CFG[u8Channel].CLC.CHTRGENNO = (pDma->CFG[u8Channel].CLC.CHTRGENNO & ~DMA_CFG_CLC_CHTRGENNO_CLC_MASK) | + DMA_CFG_CLC_CHTRGENNO_CLC(u16LoopCnt); + } + else + { + pDma->CFG[u8Channel].BLC.CHTRGENYES = (pDma->CFG[u8Channel].BLC.CHTRGENYES & ~DMA_CFG_BLC_CHTRGENYES_BLC_MASK) | + DMA_CFG_BLC_CHTRGENYES_BLC(u16LoopCnt); + pDma->CFG[u8Channel].CLC.CHTRGENYES = (pDma->CFG[u8Channel].CLC.CHTRGENYES & ~DMA_CFG_CLC_CHTRGENYES_CLC_MASK) | + DMA_CFG_CLC_CHTRGENYES_CLC(u16LoopCnt); + } +} + +/** + * @brief Get the unalign modulo index selection + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + * @return uint8_t the unalign modulo index selection + */ +LOCAL_INLINE uint8_t DMA_HWA_GetUnalignModuloSel(const DMA_Type *const pDma, uint8_t u8Channel) +{ + uint16_t u16TmpVal = (pDma->CFG[u8Channel].CSR & DMA_CFG_CSR_UMS_MASK) >> DMA_CFG_CSR_UMS_SHIFT; + return (uint8_t)u16TmpVal; +} + +/** + * @brief Set the unalign modulo index selection + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + * @param u8UnalignModuloSel the unalign modulo index selection + */ +LOCAL_INLINE void DMA_HWA_SetUnalignModuloSel(DMA_Type *const pDma, uint8_t u8Channel, uint8_t u8UnalignModuloSel) +{ + pDma->CFG[u8Channel].CSR = (pDma->CFG[u8Channel].CSR & ~DMA_CFG_CSR_UMS_MASK) | DMA_CFG_CSR_UMS(u8UnalignModuloSel); +} + +/** + * @brief Get the target channel to trig when outer loop is completed + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + * @return uint8_t the target channel + */ +LOCAL_INLINE uint8_t DMA_HWA_GetOuterLoopTrigChannel(const DMA_Type *const pDma, uint8_t u8Channel) +{ + uint16_t u16TmpVal = (pDma->CFG[u8Channel].CSR & DMA_CFG_CSR_OTRGCH_MASK) >> DMA_CFG_CSR_OTRGCH_SHIFT; + return (uint8_t)u16TmpVal; +} + +/** + * @brief Set the target channel to trig when outer loop is completed + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + * @param u8TrigChannel the target channel + */ +LOCAL_INLINE void DMA_HWA_SetOuterLoopTrigChannel(DMA_Type *const pDma, uint8_t u8Channel, uint8_t u8TrigChannel) +{ + pDma->CFG[u8Channel].CSR = (pDma->CFG[u8Channel].CSR & ~DMA_CFG_CSR_OTRGCH_MASK) | DMA_CFG_CSR_OTRGCH(u8TrigChannel); +} + +/** + * @brief Get whether the transfer is done on the selected channel + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + * @return true the transfer is done + * @return false the transfer has not done + */ +LOCAL_INLINE bool DMA_HWA_GetChannelDoneStatus(const DMA_Type *const pDma, uint8_t u8Channel) +{ + uint16_t u16TmpVal = (pDma->CFG[u8Channel].CSR & DMA_CFG_CSR_DONE_MASK) >> DMA_CFG_CSR_DONE_SHIFT; + return (bool)((u16TmpVal != 0U) ? true : false); +} + +/** + * @brief Get the active status of the DMA channel + * This flag signals the channel is currently in execution. It is set when channel service begins, + * and is cleared by the DMA as the inner loop completes or when any error condition is detected + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + * @return true the channel is in execution + * @return false the channel is idle + */ +LOCAL_INLINE DMA_RunningStatusType DMA_HWA_GetChannelActiveStatus(const DMA_Type *const pDma, uint8_t u8Channel) +{ + uint16_t u16TmpVal = (pDma->CFG[u8Channel].CSR & DMA_CFG_CSR_ACTIVE_MASK) >> DMA_CFG_CSR_ACTIVE_SHIFT; + return (DMA_RunningStatusType)u16TmpVal; +} + +/** + * @brief Get channel to channel trig is enabled when outer loop is completed + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + * @return true the target channel will be trigged when outer loop is completed + * @return false the channel to channel trig when outer loop is completed is disabled + */ +LOCAL_INLINE bool DMA_HWA_GetOuterLoopTrigEnableFlag(const DMA_Type *const pDma, uint8_t u8Channel) +{ + uint16_t u16TmpVal = (pDma->CFG[u8Channel].CSR & DMA_CFG_CSR_OCHTRGEN_MASK) >> DMA_CFG_CSR_OCHTRGEN_SHIFT; + return (bool)((u16TmpVal != 0U) ? true : false); +} + +/** + * @brief Set whether to enable channel to channel trig when outer loop is completed + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + * @param bEnable whether to enable channel to channel trig when outer loop is completed + */ +LOCAL_INLINE void DMA_HWA_SetOuterLoopTrigEnableFlag(DMA_Type *const pDma, uint8_t u8Channel, bool bEnable) +{ + pDma->CFG[u8Channel].CSR = (pDma->CFG[u8Channel].CSR & ~DMA_CFG_CSR_OCHTRGEN_MASK) | DMA_CFG_CSR_OCHTRGEN(bEnable); +} + +/** + * @brief Get whether DMA request will be disabled automatically when outer loop is completed + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + * @return true DMA request will be disabled automatically when outer loop is completed + * @return false DMA request will not be cleared when outer loop is completed + */ +LOCAL_INLINE bool DMA_HWA_GetAutoDisableReuqestEnableFlag(const DMA_Type *const pDma, uint8_t u8Channel) +{ + uint16_t u16TmpVal = (pDma->CFG[u8Channel].CSR & DMA_CFG_CSR_DREQ_MASK) >> DMA_CFG_CSR_DREQ_SHIFT; + return (bool)((u16TmpVal != 0U) ? true : false); +} + +/** + * @brief Set whether to disable DMA request automatically when outer loop is completed + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + * @param bEnable whether to disable DMA request automatically when outer loop is completed + */ +LOCAL_INLINE void DMA_HWA_SetAutoDisableReuqestEnableFlag(DMA_Type *const pDma, uint8_t u8Channel, bool bEnable) +{ + pDma->CFG[u8Channel].CSR = (pDma->CFG[u8Channel].CSR & ~DMA_CFG_CSR_DREQ_MASK) | DMA_CFG_CSR_DREQ(bEnable); +} + +/** + * @brief Get whether DMA interrupt wiil be generated when the outer loop is half done + * @note When outer loop count is 1, do not enable half complete interrupt + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + * @return true DMA will generate interrupt when outer loop is half done + * @return true DMA will not generate interrupt when outer loop is half done + */ +LOCAL_INLINE bool DMA_HWA_GetHalfCompleteInterruptEnableFlag(const DMA_Type *const pDma, uint8_t u8Channel) +{ + uint16_t u16TmpVal = (pDma->CFG[u8Channel].CSR & DMA_CFG_CSR_INTHALF_MASK) >> DMA_CFG_CSR_INTHALF_SHIFT; + return (bool)((u16TmpVal != 0U) ? true : false); +} + +/** + * @brief Set whether to enable DMA interrupt when the outer loop is half done + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + * @param bEnable whether to enable DMA interrupt when the outer loop is half done + */ +LOCAL_INLINE void DMA_HWA_SetHalfCompleteInterruptEnableFlag(DMA_Type *const pDma, uint8_t u8Channel, bool bEnable) +{ + pDma->CFG[u8Channel].CSR = (pDma->CFG[u8Channel].CSR & ~DMA_CFG_CSR_INTHALF_MASK) | DMA_CFG_CSR_INTHALF(bEnable); +} + +/** + * @brief Get whether DMA interrupt is enabled when DMA transfer is completed + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + * @return true DMA will generate interrupt when outer loop is completed + * @return false DMA will not generate interrupt when outer loop is completed + */ +LOCAL_INLINE bool DMA_HWA_GetTransferCompleteInterruptEnableFlag(const DMA_Type *const pDma, uint8_t u8Channel) +{ + uint16_t u16TmpVal = (pDma->CFG[u8Channel].CSR & DMA_CFG_CSR_INTOUTER_MASK) >> DMA_CFG_CSR_INTOUTER_SHIFT; + return (bool)((u16TmpVal != 0U) ? true : false); +} + +/** + * @brief Enable DMA transfer complete interrupt + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + */ +LOCAL_INLINE void DMA_HWA_EnableTransferCompleteInterrupt(DMA_Type *const pDma, uint8_t u8Channel) +{ + pDma->CFG[u8Channel].CSR |= DMA_CFG_CSR_INTOUTER_MASK; +} + +/** + * @brief Disable DMA transfer complete interrupt + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + */ +LOCAL_INLINE void DMA_HWA_DisableTransferCompleteInterrupt(DMA_Type *const pDma, uint8_t u8Channel) +{ + pDma->CFG[u8Channel].CSR &= ~DMA_CFG_CSR_INTOUTER_MASK; +} + +/** + * @brief Get whether the DMA start is requested but has not been executed + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + * @return true the DMA start is requested but has not been executed + * @return false the DMA start is not requested or it has started execution + */ +LOCAL_INLINE bool DMA_HWA_GetWaitStartFlag(const DMA_Type *const pDma, uint8_t u8Channel) +{ + uint16_t u16TmpVal = (pDma->CFG[u8Channel].CSR & DMA_CFG_CSR_START_MASK) >> DMA_CFG_CSR_START_SHIFT; + return (bool)((u16TmpVal != 0U) ? true : false); +} + +/** + * @brief Get DMA channel control and status + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + * @return uint16_t control and status of the selected channel + */ +LOCAL_INLINE uint16_t DMA_HWA_GetChannelControlStatus(const DMA_Type *const pDma, uint8_t u8Channel) +{ + return pDma->CFG[u8Channel].CSR; +} + +/** + * @brief Set DMA channel control and status + * + * @param pDma the base address of the DMA instance + * @param u8Channel the selected channel + * @param u16Setting control settings of the selected channel + */ +LOCAL_INLINE void DMA_HWA_SetChannelControlStatus(DMA_Type *const pDma, uint8_t u8Channel, uint16_t u16Setting) +{ + pDma->CFG[u8Channel].CSR = u16Setting; +} + +/** @}*/ + +#endif /* _HWA_DMA_H_ */ diff --git a/MODULES/HwA_Flagchip_FC7240/Inc/HwA_dmamux.h b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_dmamux.h new file mode 100644 index 0000000..8c31777 --- /dev/null +++ b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_dmamux.h @@ -0,0 +1,210 @@ +/** + * @file HwA_dmamux.h + * @author Flagchip0126 + * @brief Hardware access layer for DMAMUX + * @version 0.1.0 + * @date 2024-01-15 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-01-15 Flagchip0126 N/A First version for FC7240 + ******************************************************************************** */ + +#ifndef _HWA_DMAMUX_H_ +#define _HWA_DMAMUX_H_ + +#include "device_header.h" + +/** + * @defgroup HwA_dmamux + * @ingroup fc7xxx_driver_dma + * @{ + */ + +/** + * @brief Structure for the DMA hardware request + * + * Defines the structure for the DMA hardware request collections. The user can configure the + * hardware request into DMAMUX to trigger the DMA transfer accordingly. The index + * of the hardware request varies according to the to SoC. + */ +typedef enum +{ + DMA_REQ_DISABLED = 0U, + DMA_REQ_FCIIC0_RX = 1U, + DMA_REQ_FCIIC0_TX = 2U, + DMA_REQ_FCIIC1_RX = 3U, + DMA_REQ_FCIIC1_TX = 4U, + DMA_REQ_FCSPI0_RX = 5U, + DMA_REQ_FCSPI0_TX = 6U, + DMA_REQ_FCSPI1_RX = 7U, + DMA_REQ_FCSPI1_TX = 8U, + DMA_REQ_FCSPI2_RX = 9U, + DMA_REQ_FCSPI2_TX = 10U, + DMA_REQ_FCSPI3_RX = 11U, + DMA_REQ_FCSPI3_TX = 12U, + DMA_REQ_FCSPI4_RX = 13U, + DMA_REQ_FCSPI4_TX = 14U, + DMA_REQ_FCSPI5_RX = 15U, + DMA_REQ_FCSPI5_TX = 16U, + /* 17 ~ 22 reserved */ + DMA_REQ_FLEXCAN0 = 23U, + DMA_REQ_FLEXCAN1 = 24U, + DMA_REQ_FLEXCAN2 = 25U, + DMA_REQ_FLEXCAN3 = 26U, + /* 27 ~ 32 reserved */ + DMA_REQ_ADC0 = 33U, + DMA_REQ_ADC1 = 34U, + /* 35 ~ 40 reserved */ + DMA_REQ_FCUART0_RX = 41U, + DMA_REQ_FCUART0_TX = 42U, + DMA_REQ_FCUART1_RX = 43U, + DMA_REQ_FCUART1_TX = 44U, + DMA_REQ_FCUART2_RX = 45U, + DMA_REQ_FCUART2_TX = 46U, + DMA_REQ_FCUART3_RX = 47U, + DMA_REQ_FCUART3_TX = 48U, + DMA_REQ_FCUART4_RX = 49U, + DMA_REQ_FCUART4_TX = 50U, + DMA_REQ_FCUART5_RX = 51U, + DMA_REQ_FCUART5_TX = 52U, + DMA_REQ_FCUART6_RX = 53U, + DMA_REQ_FCUART6_TX = 54U, + DMA_REQ_FCUART7_RX = 55U, + DMA_REQ_FCUART7_TX = 56U, + /* 57 ~ 58 reserved */ + DMA_REQ_TPU0 = 59U, + DMA_REQ_TPU1 = 60U, + DMA_REQ_TPU2 = 61U, + DMA_REQ_TPU3 = 62U, + DMA_REQ_TPU4 = 63U, + DMA_REQ_TPU5 = 64U, + DMA_REQ_TPU6 = 65U, + DMA_REQ_TPU7 = 66U, + DMA_REQ_TPU8 = 67U, + DMA_REQ_TPU9 = 68U, + DMA_REQ_TPU10 = 69U, + DMA_REQ_TPU11 = 70U, + DMA_REQ_TPU12 = 71U, + DMA_REQ_TPU13 = 72U, + DMA_REQ_TPU14 = 73U, + DMA_REQ_TPU15 = 74U, + DMA_REQ_TPU16TO23 = 75U, + DMA_REQ_TPU24TO31 = 76U, + DMA_REQ_PORTA = 77U, + DMA_REQ_PORTB = 78U, + DMA_REQ_PORTC = 79U, + DMA_REQ_PORTD = 80U, + DMA_REQ_PORTE = 81U, + /* 82 ~ 85 reserved */ + DMA_REQ_AONTIMER0 = 86U, + DMA_REQ_CMP0 = 87U, + DMA_REQ_CMP1 = 88U, + /* 89 reserved */ + DMA_REQ_PTIMER0 = 90U, + DMA_REQ_PTIMER1 = 91U, + /* 92 ~ 97 reserved */ + DMA_REQ_FTU0_ALL_CH_OR = 98U, + DMA_REQ_FTU1_ALL_CH_OR = 99U, + DMA_REQ_FTU2_ALL_CH_OR = 100U, + DMA_REQ_FTU3_ALL_CH_OR = 101U, + DMA_REQ_FTU4_ALL_CH_OR = 102U, + DMA_REQ_FTU5_ALL_CH_OR = 103U, + DMA_REQ_FTU6_ALL_CH_OR = 104U, + DMA_REQ_FTU7_ALL_CH_OR = 105U, + /* 106 ~ 109 reserved */ + DMA_REQ_SENT0_CH0_FAST = 110U, + DMA_REQ_SENT0_CH1_FAST = 111U, + DMA_REQ_SENT0_CH2_FAST = 112U, + DMA_REQ_SENT0_CH3_FAST = 113U, + /* 114 ~ 117 reserved */ + DMA_REQ_SENT0_CH0_SLOW = 118U, + DMA_REQ_SENT0_CH1_SLOW = 119U, + DMA_REQ_SENT0_CH2_SLOW = 120U, + DMA_REQ_SENT0_CH3_SLOW = 121U, + /* 122 ~ 125 reserved */ + DMA_REQ_ALWAYS_ENABLE_0 = 126U, + DMA_REQ_ALWAYS_ENABLE_1 = 127U +} DMA_RequestSourceType; + +/** + * @brief Get whether DMAMUX is enabled for the specified DMA channel + * + * @param pDmamux the base address of the DMAMUX instance + * @param u8Channel the selected DMA channel + * @return true DMAMUX is enabled for the specified DMA channel + * @return false DMAMUX is disabled for the specified DMA channel + */ +LOCAL_INLINE bool DMAMUX_HWA_GetEnableFlag(const DMAMUX_Type *const pDmamux, uint8_t u8Channel) +{ + uint8_t u8TmpVal = (pDmamux->CHCFG[u8Channel] & DMAMUX_CHCFG_ENBL_MASK) >> DMAMUX_CHCFG_ENBL_SHIFT; + return (bool)((u8TmpVal != 0U) ? true : false); +} + +/** + * @brief Get the request source for the specified DMA channel + * + * @param pDmamux the base address of the DMAMUX instance + * @param u8Channel the selected DMA channel + * @return DMA_RequestSourceType the request source of the specified DMA channel + */ +LOCAL_INLINE DMA_RequestSourceType DMAMUX_HWA_GetRequestSource(const DMAMUX_Type *const pDmamux, uint8_t u8Channel) +{ + uint8_t u8TmpVal = (pDmamux->CHCFG[u8Channel] & DMAMUX_CHCFG_SOURCE_MASK) >> DMAMUX_CHCFG_SOURCE_SHIFT; + return (DMA_RequestSourceType)u8TmpVal; +} + +/** + * @brief Set the request source for the specified DMA channel + * + * @param pDmamux the base address of the DMAMUX instance + * @param u8Channel the selected DMA channel + * @param bEnable whether to enable DMAMUX for the specified DMA channel + * @param eReqSrc the request source to set for the specified DMA channel + */ +LOCAL_INLINE void DMAMUX_HWA_SetRequestSource(DMAMUX_Type *const pDmamux, uint8_t u8Channel, bool bEnable, + DMA_RequestSourceType eReqSrc) +{ + pDmamux->CHCFG[u8Channel] = (pDmamux->CHCFG[u8Channel] & ~(DMAMUX_CHCFG_ENBL_MASK | DMAMUX_CHCFG_SOURCE_MASK)) | + DMAMUX_CHCFG_ENBL(bEnable) | DMAMUX_CHCFG_SOURCE(eReqSrc); +} + +/** + * @brief Get whether periodic trig is enabled for the specified DMA channel + * + * @note Only DMA channel 0~3 supports periodic trig + * + * @param pDmamux the base address of the DMAMUX instance + * @param u8Channel the selected DMA channel + * @return true periodic trig is enabled for the specified DMA channel + * @return true periodic trig is disabled for the specified DMA channel + */ +LOCAL_INLINE bool DMAMUX_HWA_GetPeriodicTrigFlag(const DMAMUX_Type *const pDmamux, uint8_t u8Channel) +{ + uint8_t u8TmpVal = (pDmamux->CHTRG & (DMAMUX_CHTRG_TRIG_MASK << u8Channel)) >> u8Channel; + return (bool)((u8TmpVal != 0U) ? true : false); +} + +/** + * @brief Set whether to enable periodic trig for the specified DMA channel + * + * @note Only DMA channel 0~3 supports periodic trig + * + * @param pDmamux the base address of the DMAMUX instance + * @param u8Channel the selected DMA channel + * @param bEnable whether to enable periodic trig for the specified DMA channel + */ +LOCAL_INLINE void DMAMUX_HWA_SetPeriodicTrigFlag(DMAMUX_Type *const pDmamux, uint8_t u8Channel, bool bEnable) +{ + pDmamux->CHTRG = (pDmamux->CHTRG & ~(DMAMUX_CHTRG_TRIG_MASK << u8Channel)) | (DMAMUX_CHTRG_TRIG(bEnable) << u8Channel); +} + +/** @}*/ + +#endif /* _HWA_DMAMUX_H_ */ diff --git a/MODULES/HwA_Flagchip_FC7240/Inc/HwA_eim.h b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_eim.h new file mode 100644 index 0000000..073a970 --- /dev/null +++ b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_eim.h @@ -0,0 +1,276 @@ +/** + * @file HwA_eim.h + * @author Flagchip + * @brief FC7xxx FCEim register API + * @version 0.1.0 + * @date 2024-01-14 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-01-14 qxw0100 N/A FC7240 Eim first version + *********************************************************************************/ + +#ifndef HWA_INCLUDE_HWA_EIM_H_ +#define HWA_INCLUDE_HWA_EIM_H_ +#include "device_header.h" +#define EIM_MAXCHANNEL 76U /*!< EIM max channel support */ + +/** + * @defgroup HwA_eim + * @ingroup HwA_eim + * @{ + */ + +/** @brief EIM channel number configuration type */ +typedef enum +{ + EIM_MAM0_S0 = 0U, /*!< Channel 0 SCM Matrix Access Monitor Error Inection0(MAM0_S0) */ + EIM_MAM0_S1 = 1U, /*!< Channel 1 SCM Matrix Access Monitor Error Inection1(MAM0_S1) */ + EIM_MAM0_S2 = 2U, /*!< Channel 2 SCM Matrix Access Monitor Error Inection2(MAM0_S2) */ + EIM_MAM0_S3 = 4U, /*!< Channel 4 SCM Matrix Access Monitor Error Inection3(MAM0_S3) */ + EIM_MAM0_S4 = 5U, /*!< Channel 5 SCM Matrix Access Monitor Error Inection4(MAM0_S4) */ + EIM_MAM0_S5 = 7U, /*!< Channel 7 SCM Matrix Access Monitor Error Inection5(MAM0_S5) */ + EIM_MAM0_S6 = 8U, /*!< Channel 8 SCM Matrix Access Monitor Error Inection6(MAM0_S6) */ + EIM_MAM0_S7 = 9U, /*!< Channel 9 SCM Matrix Access Monitor Error Inection7(MAM0_S7) */ + EIM_MAM0_S8 = 10U, /*!< Channel 10 SCM Matrix Access Monitor Error Inection8(MAM0_S8) */ + EIM_CPU0_AHBM = 11U, /*!< Channel 11 SCM Matrix Access Monitor Error Inection9(CPU0_AHBM) */ + EIM_CPU0_AHBP = 12U, /*!< Channel 12 SCM Matrix Access Monitor Error Inection10(CPU0_AHBP) */ + EIM_HSM = 18U, /*!< Channel 18 SCM Matrix Access Monitor Error Inection12(HSM) */ + EIM_DMA0 = 19U, /*!< Channel 19 SCM Matrix Access Monitor Error Inection13(DMA0) */ + EIM_CPU0_AHBS = 21U, /*!< Channel 21 SCM Matrix Access Monitor Error Inection11(CPU0_AHBS) */ + EIM_CPU0_ITCM = 24U, /*!< Channel 24 CPU0_ITCM */ + EIM_CPU0_DTCM0 = 25U, /*!< Channel 25 CPU0_DTCM0 */ + EIM_CPU0_DTCM1 = 26U, /*!< Channel 26 CPU0_DTCM1 */ + EIM_SRAM0 = 33U, /*!< Channel 33 SRAM0_INJECTION */ + EIM_SRAM1 = 34U, /*!< Channel 34 SRAM1_INJECTION */ + EIM_CPU0DCACHE_DATA0_01 = 36U, /*!< Channel 36 CPU0_DCACHE_DATA0_01 Injection */ + EIM_CPU0DCACHE_DATA0_23 = 37U, /*!< Channel 37 CPU0_DCACHE_DATA0_23 Injection */ + EIM_CPU0DCACHE_DATA1_01 = 38U, /*!< Channel 38 CPU0_DCACHE_DATA1_01 Injection */ + EIM_CPU0DCACHE_DATA1_23 = 39U, /*!< Channel 39 CPU0_DCACHE_DATA1_23 Injection */ + EIM_CPU0DCACHE_TAG_01 = 40U, /*!< Channel 40 CPU0_DCACHE_TAG_01 Injection */ + EIM_CPU0DCACHE_TAG_23 = 41U, /*!< Channel 41 CPU0_DCACHE_TAG_23 Injection */ + EIM_CPU0ICACHE_DATA0 = 42U, /*!< Channel 42 CPU0_ICACHE_DATA0 Injection */ + EIM_CPU0ICACHE_DATA1 = 43U, /*!< Channel 43 CPU0_ICACHE_DATA1 Injection */ + EIM_CPU0ICACHE_TAG = 44U, /*!< Channel 44 CPU0_ICACHE_TAG Injection */ + EIM_SCM_S5_DOWNSIZE = 63U, /*!< Channel 63 SCM S5 64:32 DownSize Monitor Error Injection */ + EIM_DMA0_CFG = 65U, /*!< Channel 65 DMA0_CFG_ECC Injection */ + EIM_ROM_ECC = 67U, /*!< Channel 67 ROM_ECC Injection */ + EIM_SCM_S5_DOWNSIZE_AHBS = 68U, /*!< Channel 68 SCM S5 DownSize ECC Check with AHBS Error Injection */ + EIM_CPU0AHBP_AHBS_MONITOR = 70U, /*!< Channel 70 SCM CPU0 AHBP and AHBS gasket Monitor Error Injection */ + EIM_SCM_S8_DOWNSIZE_MONITOR = 75U, /*!< Channel 75 SCM S8 64:32 DownSize Monitor Error Injection */ + EIM_RAM_DECODER_MONITOR = 77U, /*!< Channel 77 RAM Decoder Monitor Error Injection */ + EIM_AFCB0_MONITOR = 78U, /*!< Channel 78 AFCB0 Monitor Error Injection */ + EIM_AFCB1_MONITOR = 79U, /*!< Channel 79 AFCB1 Monitor Error Injection */ + EIM_CPU0_OVERLAY_MONITOR = 80U, /*!< Channel 80 CPU0 Overlay Monitor */ + EIM_HSM_DRAM = 82U, /*!< Channel 82 HSM DRAM ECC Error Injection */ + EIM_HSM_IRAM = 83U, /*!< Channel 83 HSM IRAM ECC Error Injection */ +} EIM_ChannelType; + +/** @brief EIM Lockstep channel configuration type */ +typedef enum +{ + EIM_CPU0_LOCKSTEP, /*!< CPU0 LOCKSTEP Injection */ + EIM_CHNTYPE_RESVD, + EIM_DMA0_LOCKSTEP, /*!< DMA0 LOCKSTEP Injection */ +} EIM_CPU_ChnType; + +/** @brief EIM CPU monitor configuration type */ +typedef enum +{ + EIM_MONITOR0, /*!< CPU0 LOCKSTEP monitor0 Injection */ + EIM_MONITOR1, /*!< CPU0 LOCKSTEP monitor1 Injection */ +} EIM_MONType; + +/** @brief Eim return type. */ + +typedef enum +{ + EIM_STATUS_SUCCESS = 0U, /*!< EIM status success */ + EIM_STATUS_PARAM_INVALID = 1U /*!< EIM status parameter invalid */ +} EIM_RetType; + +/** + * @brief Select the EIM DWP mode + * + */ +typedef enum +{ + EIM_CPU0ALLOWED_0 = 0U, /**< cpu0 is allowed */ + EIM_CPU0ALLOWED_1 = 1U, /**< cpu0 is allowed */ +} EIM_DWPType; + +/** + * @brief Select error injection bus sel + * + */ +typedef enum +{ + EIM_BUSREG0 = 0U, /**< Sel bus REG0 to injection */ + EIM_BUSREG1 = 1U, /**< Sel bus REG1 to injection */ + EIM_BUSREG2 = 2U, /**< Sel bus REG2 to injection */ + EIM_BUSREG3 = 3U /**< Sel bus REG3 to injection */ +} EIM_BUSChnType; +/** + * @brief Select the EIM InitType + * + */ +typedef struct +{ + uint8_t u8EimChn; + uint8_t u8BusSelIdx; + uint8_t u8Attreenable; + uint8_t u8AttrPosition; + uint8_t u8Addreenable; + uint8_t u8AddrePosition; + uint8_t u8Data0enable; + uint8_t u8Data0Val; + uint8_t u8Data1enable; + uint8_t u8Data1Val; +} EIM_InitType; + +/** + * @brief Select the CPU Lockstep InitType + * + */ +typedef struct +{ + uint8_t u8CpuChn; + uint8_t u8Monitor0Set; + uint8_t u8Monitor0Clr; + uint8_t u8Monitor1Set; + uint8_t u8Monitor1Clr; +} EIM_CpuLockType; + + +/** + * @brief Enable EIM Global Error Injection + * + */ +LOCAL_INLINE void EIM_HWA_EnableGlobalErrorInjection(void) +{ + EIM->CR = 1U; +} + +/** + * @brief Disable EIM Global Error Injection + * + */ +LOCAL_INLINE void EIM_HWA_DisableGlobalErrorInjection(void) +{ + EIM->CR &= ~(uint32_t) EIM_CR_GEIEN_MASK; +} + +/** + * @brief get EIM channel N control register, N:0~82 + * + * @return EIM channel N control register value + */ +LOCAL_INLINE uint32_t EIM_HWA_Get_CtrlRegn(uint8_t idx) +{ + uint32_t u32RegValue; + u32RegValue = EIM->CTRL_REG[idx]; + return u32RegValue; +} + +/** + * @brief get EIM bus register, idx:0~3 + * + * @return EIM bus register value + */ +LOCAL_INLINE uint32_t EIM_HWA_Get_BUSRegn(uint8_t idx) +{ + uint32_t u32RegValue; + u32RegValue = EIM->BUS_REG[idx]; + return u32RegValue; +} + +/** + * @brief Get EIM_CTRL_GEGn register DWP lock status + * @param u8idx index (0~82) + * @return Lock status + */ +LOCAL_INLINE uint8_t EIM_HWA_GetCtrlDWPLockStatus(uint8_t u8idx) +{ + uint32_t u32RegValue; + u32RegValue = EIM->CTRL_REG[u8idx]; + u32RegValue = (u32RegValue & EIM_CTRL_REG_DWP_LOCK_MASK) >> EIM_CTRL_REG_DWP_LOCK_SHIFT; + return (uint8_t)((u32RegValue != 0U) ? true : false); +} + +/** + * @brief set EIM_CTRL_GEGn register DWP lock mode, idx:0~76 + * + * @param u8idx index (0~82) + * @param u8DwpMode DWP mode + */ +LOCAL_INLINE void EIM_HWA_Set_CtrlLockMode(uint8_t u8idx, uint8_t u8DwpMode) +{ + uint32_t u32Value = EIM->CTRL_REG[u8idx]; + EIM->CTRL_REG[u8idx] = ((u32Value & (~(uint32_t)EIM_CTRL_REG_DWP_MASK)) | EIM_CTRL_REG_DWP(u8DwpMode)); +} + +/** + * @brief set EIM_CTRL_GEGn register DWP lock status, idx:0~76 + * + * @param u8idx index (0~82) + * @param u8Enable enable or disable + */ +LOCAL_INLINE void EIM_HWA_CtrlRegnWritePermit(uint8_t u8idx) +{ + uint32_t u32Value = EIM->CTRL_REG[u8idx]; + EIM->CTRL_REG[u8idx] = (u32Value | EIM_CTRL_REG_DWP_LOCK_MASK); +} + +/** + * @brief set eim channel N control register + * + * @param idx index (0~82) + * @param u32RegValue access control value + */ +LOCAL_INLINE void EIM_HWA_Set_CtrlRegn(uint8_t idx, uint32_t u32RegValue) +{ + EIM->CTRL_REG[idx] = u32RegValue; +} + +/** + * @brief set EIM CPU LOCKSTEP error injection register, idx:0~2 + * + * @param idx index (0~2) + * @param u32RegValue access control value + */ +LOCAL_INLINE void EIM_HWA_Set_CPULockstep(uint8_t idx, uint32_t u32RegValue) +{ + *((volatile uint32_t *)(&(EIM->CPU0_LOCKSTEP) + (int32_t)idx)) = u32RegValue; +} + +/** + * @brief set EIM CPU LOCKSTEP error injection register, idx:0~2 + * + * @param idx index (0~2) + * @return access control value + */ +LOCAL_INLINE uint32_t EIM_HWA_Get_CPULockstep(uint8_t idx) +{ + return *((volatile uint32_t *)(&(EIM->CPU0_LOCKSTEP) + (int32_t)idx)); +} + +/** + * @brief set EIM bus register, idx:0~3 + * + * @param idx index (0~3) + * @param u32RegValue access control value + */ +LOCAL_INLINE void EIM_HWA_Set_BUSRegn(uint8_t idx, uint32_t u32RegValue) +{ + EIM->BUS_REG[idx] |= u32RegValue; +} + + +/** @}*/ +#endif /* HWA_INCLUDE_HWA_EIM_H_ */ diff --git a/MODULES/HwA_Flagchip_FC7240/Inc/HwA_erm.h b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_erm.h new file mode 100644 index 0000000..b114c70 --- /dev/null +++ b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_erm.h @@ -0,0 +1,119 @@ +/** + * @file HwA_erm.h + * @author Flagchip + * @brief FC7xxx erm driver type definition and API + * @version 0.1.0 + * @date 2024-01-14 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-01-14 qxw0100 N/A FC7240 Erm first version + ******************************************************************************** */ + +#ifndef HWA_INCLUDE_HWA_ERM_H_ +#define HWA_INCLUDE_HWA_ERM_H_ +#include "device_header.h" + +#define ERM_SR_MASK 0xCCCCCCCCu + + +/** + * @defgroup HwA_erm + * @ingroup HwA_erm + * @{ + */ + +/** @brief ERM configuration type */ +typedef enum +{ + ERM_NONE_CORRECTABLE = 1U, /*!< select Non-correctable interrupt report */ + ERM_SINGLE_BIT = 2U /*!< select single correction interrupt report */ +} ERM_InterruptType; + + +/** @brief ERM configuration type */ +typedef enum +{ + ERM_PFLASH0_ECC = 1U, /*!< PFlash0 ECC Error */ + ERM_PFLASH1_ECC = 2U, /*!< PFlash1 ECC Error */ + ERM_DFLASH_ECC = 3U, /*!< DFlash ECC error */ + ERM_DMACFG0_ECC = 4U, /*!< DMACFG0 ECC Error */ + ERM_ROM_ECC = 6U, /*!< ROM ECC Error */ + ERM_SYSRAM0_ECC = 8U, /*!< SysRAM0 ECC ERROR */ + ERM_SYSRAM1_ECC = 9U, /*!< SysRAM1 ECC ERROR */ + ERM_CPU0ITCM_ECC = 11U, /*!< CPU0 ITCM ECC Error */ + ERM_CPU0DTCM0_ECC = 12U, /*!< CPU0 DTCM0 ECC Error */ + ERM_CPU0DTCM1_ECC = 13U, /*!< CPU0 DTCM1 ECC Error */ + ERM_CPU0ICACHE_ECC = 14U, /*!< CPU0 ICACHE ECC Error */ + ERM_CPU0DCACHE_ECC = 15U, /*!< CPU0 DCACHE ECC Error */ + ERM_HSMDRAM_ECC = 26U, /*!< HSM DRAM ECC Error */ + ERM_HSMIRAM_ECC = 27U, /*!< HSM IRAM ECC Error */ +} ERM_ChannelType; + + +/** + * @brief get ERM configuration register 0~3 + * + * @return ERM CRn value + */ +LOCAL_INLINE uint32_t ERM_HWA_Get_CRn(uint8_t idx) +{ + uint32_t u32RegValue; + u32RegValue = *((volatile uint32_t *)(&(ERM->CR0) + (uint32_t)idx)); + return u32RegValue; +} + +/** + * @brief get ERM status register 0~3 + * + * @return ERM SRn value + */ +LOCAL_INLINE uint32_t ERM_HWA_Get_SRn(uint8_t idx) +{ + uint32_t u32RegValue; + u32RegValue = *((volatile uint32_t *)(&(ERM->SR0) + (uint32_t)idx)); + return u32RegValue; +} + +/** + * @brief get ERM error address register 0~25 + * + * @return ERM error address register value + */ +LOCAL_INLINE uint32_t ERM_HWA_Get_EARn(uint8_t idx) +{ + uint32_t u32RegValue; + u32RegValue = *((const volatile uint32_t *)(&(ERM->EAR0) + (uint32_t)idx * 0x10UL/4UL)); + + return u32RegValue; +} + +/** + * @brief set erm configuration register + * + * @param idx index (0~3) + * @param u32RegValue access control value + */ +LOCAL_INLINE void ERM_HWA_Set_CRn(uint8_t idx, uint32_t u32RegValue) +{ + *((volatile uint32_t *)(&(ERM->CR0) + (int32_t)idx)) = u32RegValue; +} +/** + * @brief set erm error address register + * + * @param idx index (0~3) + * @param u32RegValue access control value + */ +LOCAL_INLINE void ERM_HWA_Set_SRn(uint8_t idx, uint32_t u32RegValue) +{ + *((volatile uint32_t *)(&(ERM->SR0) + (int32_t)idx)) = u32RegValue; +} + +/** @}*/ +#endif /* HWA_INCLUDE_HWA_ERM_H_ */ diff --git a/MODULES/HwA_Flagchip_FC7240/Inc/HwA_fciic.h b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_fciic.h new file mode 100644 index 0000000..c10014e --- /dev/null +++ b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_fciic.h @@ -0,0 +1,542 @@ +/** + * @file HwA_fciic.h + * @author Flagchip + * @brief FC7xxx FCIIC hardware access layer + * @version 0.2.0 + * @date 2023-2-14 + * + * @copyright Copyright (c) 2022 Flagchip Semiconductors Co., Ltd. + * + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2022/12/31 qxw0052 N/A First version for FC7300 + * 0.2.0 2023/02/14 qxw0052 N/A Fix MISRA issues + ******************************************************************************** */ + +#ifndef _HWA_FCIIC_H_ +#define _HWA_FCIIC_H_ + +#include "device_header.h" + + +/** + * @addtogroup HwA_fciic + * @{ + */ + + +/* ################################################################################## */ +/* ################################### type define ################################## */ + + +/** + * \brief IIC Command Type Enumeration + * + */ +typedef enum +{ + FCIIC_TX_CMD_TRANSMIT = 0, /**< FCIIC_TX_CMD_TRANSMIT transmit command */ + FCIIC_TX_CMD_RECEIVE, /**< FCIIC_TX_CMD_RECEIVE receive command*/ + FCIIC_TX_CMD_STOP, /**< FCIIC_TX_CMD_STOP stop command */ + FCIIC_TX_CMD_RECANDDISCARD, /**< FCIIC_TX_CMD_RECANDDISCARD receive and discard data command*/ + FCIIC_TX_CMD_STARTANDTRANSMIT, /**< FCIIC_TX_CMD_STARTANDTRANSMIT start and then transmit data */ + FCIIC_TX_CMD_STARTANDTRANSMIT_WITHNAK/**< FCIIC_TX_CMD_STARTANDTRANSMIT_WITHNAK start and then transmit and don't care ACK */ + +} FCIIC_TX_CMDType; + + +/** + * \brief IIC Master status type enumeration + * + */ +typedef enum +{ + FCIIC_MSR_BBF_STATUS = 25U, /**< FCIIC_MSR_BBF_STATUS Bus Busy Flag */ + FCIIC_MSR_MBF_STATUS = 24U, /**< FCIIC_MSR_MBF_STATUS Master Busy Flag */ + FCIIC_MSR_DMF_STATUS = 14U, /**< FCIIC_MSR_DMF_STATUS Data Match Flag */ + FCIIC_MSR_PLTF_STATUS = 13U, /**< FCIIC_MSR_PLTF_STATUS Pin Low Timeout Flag */ + FCIIC_MSR_FEF_STATUS = 12U, /**< FCIIC_MSR_FEF_STATUS FIFO Error Flag */ + FCIIC_MSR_ALF_STATUS = 11U, /**< FCIIC_MSR_ALF_STATUS Arbitration Lost Flag */ + FCIIC_MSR_NDF_STATUS = 10U, /**< FCIIC_MSR_NDF_STATUS NACK Detect Flag */ + FCIIC_MSR_SDF_STATUS = 9U, /**< FCIIC_MSR_SDF_STATUS STOP Detect Flag */ + FCIIC_MSR_EPF_STATUS = 8U, /**< FCIIC_MSR_EPF_STATUS End Packet Flag */ + FCIIC_MSR_RXFPEF_STATUS = 3U, /**< FCIIC_MSR_EPF_STATUS RX FIFO Parity Error Flag */ + FCIIC_MSR_TXFPEF_STATUS = 2U, /**< FCIIC_MSR_EPF_STATUS TX FIFO Parity Error Flag */ + FCIIC_MSR_RDF_STATUS = 1U, /**< FCIIC_MSR_RDF_STATUS Receive Data Flag */ + FCIIC_MSR_TDF_STATUS = 0U /**< FCIIC_MSR_TDF_STATUS Transmit Data Flag */ +} FCIIC_MasterStatusType; + + + +/** + * \brief IIC Slave status type enumeration + * + */ +typedef enum +{ + FCIIC_SSR_BBF_STATUS = 25U, /**< FCIIC_SSR_BBF_STATUS Bus Busy Flag */ + FCIIC_SSR_SBF_STATUS = 24U, /**< FCIIC_SSR_SBF_STATUS Slave Busy Flag */ + FCIIC_SSR_SARF_STATUS = 15U, /**< FCIIC_SSR_SARF_STATUS SMBus Alert Response Flag */ + FCIIC_SSR_GCF_STATUS = 14U, /**< FCIIC_SSR_GCF_STATUS General Call Flag */ + FCIIC_SSR_AM1F_STATUS = 13U, /**< FCIIC_SSR_AM1F_STATUS Address Match 1 Flag */ + FCIIC_SSR_AM0F_STATUS = 12U, /**< FCIIC_SSR_AM0F_STATUS Address Match 0 Flag */ + FCIIC_SSR_TREF_STATUS = 11U, /**< FCIIC_SSR_TREF_STATUS FIFO Error Flag */ + FCIIC_SSR_BEF_STATUS = 10U, /**< FCIIC_SSR_BEF_STATUS Bit Error Flag */ + FCIIC_SSR_SDF_STATUS = 9U, /**< FCIIC_SSR_SDF_STATUS STOP Detect Flag */ + FCIIC_SSR_RSF_STATUS = 8U, /**< FCIIC_SSR_RSF_STATUS Repeated Start Flag */ + FCIIC_SSR_TAF_STATUS = 3U, /**< FCIIC_SSR_TAF_STATUS Transmit ACK Flag */ + FCIIC_SSR_AVF_STATUS = 2U, /**< FCIIC_SSR_AVF_STATUS Address Valid Flag */ + FCIIC_SSR_RDF_STATUS = 1U, /**< FCIIC_SSR_RDF_STATUS Receive Data Flag */ + FCIIC_SSR_TDF_STATUS = 0U, /**< FCIIC_SSR_TDF_STATUS Transmit Data Flag */ +} FCIIC_SlaveStatusType; + + +/** + * \brief Master Transmit Data + * + * \param pFciic IIC instance value + * \param tCmdType is command type + * \param u8Data to transmit + */ +LOCAL_INLINE void FCIIC_Master_HWA_Transmit(FCIIC_Type *pFciic, FCIIC_TX_CMDType tCmdType, uint8_t u8Data) +{ + pFciic->MTDR = FCIIC_MTDR_CMD(tCmdType) | FCIIC_MTDR_DATA(u8Data); +} + +/** + * \brief Master Receive Data + * + * \param pFciic IIC instance value + * \return the data received + */ +LOCAL_INLINE uint8_t FCIIC_Master_HWA_Receive(FCIIC_Type *pFciic) +{ + /* copy data */ + return (uint8_t)((uint8_t)(pFciic->MRDR) & 0xFFU); +} + +/** + * \brief Get and clear IIC master status + * + * \param pFciic is IIC instance value + * \param eStatus is status type + */ +LOCAL_INLINE void FCIIC_Master_HwA_CheckClearStatus(FCIIC_Type *pFciic, FCIIC_MasterStatusType eStatus) +{ + uint32_t u32RetVal; + + u32RetVal = (pFciic->MSR >> eStatus) & 0x01U; + + + if (u32RetVal != 0U) + { + pFciic->MSR |= (1UL << eStatus); /* w1c */ + } +} + +/** + * \brief This Function is used to get master status + * + * \param pFciic is IIC instance value + * \param eStatus is status type enumeration + * \return Status value 0 or 1 and 1 is OK + */ +LOCAL_INLINE uint8_t FCIIC_Master_HWA_GetStatus(FCIIC_Type *pFciic, FCIIC_MasterStatusType eStatus) +{ + uint32_t u32RetVal; + + u32RetVal = (pFciic->MSR >> (uint32_t)eStatus) & 0x01U; + + return (uint8_t)(u32RetVal == 1U ? 1U : 0U); +} + +/** + * \brief This Function is used to clear master status + * + * \param pFciic is IIC instance value + * \param u32Value is the clear bits + */ +LOCAL_INLINE void FCIIC_Master_HWA_ClrStatus(FCIIC_Type *pFciic, uint32_t u32Value) +{ + pFciic->MSR |= u32Value; +} + +/** + * \brief This Function is used to get slave status + * + * \param pFciic is IIC instance value + * \param eStatus is status type enumeration + * \return Status value 0 or 1 and 1 is OK + */ +LOCAL_INLINE uint8_t FCIIC_Slave_HWA_GetStatus(FCIIC_Type *pFciic, FCIIC_SlaveStatusType eStatus) +{ + uint32_t u32RetVal; + + u32RetVal = (pFciic->SSR >> (uint32_t)eStatus) & 0x01U; + + return (uint8_t)(u32RetVal == 1U ? 1U : 0U); +} + +/** + * \brief This Function is used to clear slave status + * + * \param pFciic is IIC instance value + * \param u32Value is the clear bits value + */ +LOCAL_INLINE void FCIIC_Slave_HWA_ClrStatus(FCIIC_Type *pFciic, uint32_t u32Value) +{ + pFciic->SSR |= u32Value; +} + +/** + * \brief Slave Transmit Data + * + * \param pFciic IIC instance value + * \param u8Data to transmit + */ +LOCAL_INLINE void FCIIC_Slave_HWA_Transmit(FCIIC_Type *pFciic, uint8_t u8Data) +{ + pFciic->STDR = FCIIC_STDR_DATA(u8Data); +} + + +/** + * \brief Slave Get Data + * + * \param pFciic IIC instance value + * \return the data value + */ +LOCAL_INLINE uint8_t FCIIC_Slave_HWA_Receive(FCIIC_Type *pFciic) +{ + /* copy data */ + return (uint8_t)((uint8_t)(pFciic->SRDR) & 0xFFU); +} + +/** + * \brief Enable Receive Interrupt + * + * \param pFciic IIC instance value + */ +LOCAL_INLINE void FCIIC_Master_HWA_EnableReceiveInterrupt(FCIIC_Type *pFciic) +{ + pFciic->MIER |= FCIIC_MIER_RDIE_MASK; +} + +/** + * \brief Disable Receive Interrupt + * + * \param pFciic IIC instance value + */ +LOCAL_INLINE void FCIIC_Master_HWA_DisableReceiveInterrupt(FCIIC_Type *pFciic) +{ + pFciic->MIER &= ~FCIIC_MIER_RDIE_MASK; +} + +/** + * \brief Enable Error Interrupt + * + * \param pFciic IIC instance value + */ +LOCAL_INLINE void FCIIC_Master_HWA_EnableErrorInterrupt(FCIIC_Type *pFciic) +{ + pFciic->MIER |= FCIIC_MIER_FEIE_MASK; +} + +/** + * \brief Disable Error Interrupt + * + * \param pFciic IIC instance value + */ +LOCAL_INLINE void FCIIC_Master_HWA_DisableErrorInterrupt(FCIIC_Type *pFciic) +{ + pFciic->MIER &= FCIIC_MIER_FEIE_MASK; +} + +/** + * \brief Get Error Flag + * + * \param pFciic IIC instance value + */ +LOCAL_INLINE uint32_t FCIIC_Master_HWA_GetErrorFlag(FCIIC_Type *pFciic) +{ + return pFciic->MSR & FCIIC_MSR_FEF_MASK; +} + +/** + * \brief Clr Error Flag + * + * \param pFciic IIC instance value + */ +LOCAL_INLINE void FCIIC_Master_HWA_ClrErrorFlag(FCIIC_Type *pFciic) +{ + pFciic->MSR |= FCIIC_MSR_FEF_MASK; +} + +/** + * \brief Enable Transmit Interrupt + * + * \param pFciic IIC instance value + */ +LOCAL_INLINE void FCIIC_Master_HWA_EnableTransmitInterrupt(FCIIC_Type *pFciic) +{ + pFciic->MIER |= FCIIC_MIER_TDIE_MASK; +} + +/** + * \brief Disable Transmit Interrupt + * + * \param pFciic IIC instance value + */ +LOCAL_INLINE void FCIIC_Master_HWA_DisableTransmitInterrupt(FCIIC_Type *pFciic) +{ + pFciic->MIER &= ~FCIIC_MIER_TDIE_MASK; +} + + +/** + * \brief Enable Receive Interrupt + * + * \param pFciic IIC instance value + */ +LOCAL_INLINE void FCIIC_Slave_HWA_EnableReceiveInterrupt(FCIIC_Type *pFciic) +{ + pFciic->SIER |= FCIIC_SIER_RDIE_MASK; +} + +/** + * \brief Disable Receive Interrupt + * + * \param pFciic IIC instance value + */ +LOCAL_INLINE void FCIIC_Slave_HWA_DisableReceiveInterrupt(FCIIC_Type *pFciic) +{ + pFciic->SIER &= ~FCIIC_SIER_RDIE_MASK; +} + +/** + * \brief Enable Error Interrupt + * + * \param pFciic IIC instance value + */ +LOCAL_INLINE void FCIIC_Slave_HWA_EnableErrorInterrupt(FCIIC_Type *pFciic) +{ + pFciic->SIER |= FCIIC_SIER_TREIE_MASK | FCIIC_SIER_BEIE_MASK ; +} + +/** + * \brief Disable Error Interrupt + * + * \param pFciic IIC instance value + */ +LOCAL_INLINE void FCIIC_Slave_HWA_DisableErrorInterrupt(FCIIC_Type *pFciic) +{ + pFciic->SIER &= ~(FCIIC_SIER_TREIE_MASK | FCIIC_SIER_BEIE_MASK); +} + +/** + * \brief Get Error Flag + * + * \param pFciic IIC instance value + */ +LOCAL_INLINE uint32_t FCIIC_Slave_HWA_GetErrorFlag(FCIIC_Type *pFciic) +{ + return pFciic->SSR & (FCIIC_SSR_TREF_MASK | FCIIC_SSR_BEF_MASK); +} + +/** + * \brief Clear Error Flag + * + * \param pFciic IIC instance value + */ +LOCAL_INLINE void FCIIC_Slave_HWA_ClrErrorFlag(FCIIC_Type *pFciic) +{ + pFciic->SSR |= (FCIIC_SSR_TREF_MASK | FCIIC_SSR_BEF_MASK); +} + +/** + * \brief Enable Transmit Interrupt + * + * \param pFciic IIC instance value + */ +LOCAL_INLINE void FCIIC_Slave_HWA_EnableTransmitInterrupt(FCIIC_Type *pFciic) +{ + pFciic->SIER |= FCIIC_SIER_TDIE_MASK; +} + +/** + * \brief FCIIC Disable Transmit Interrupt + * + * \param pFciic IIC instance value + */ +LOCAL_INLINE void FCIIC_Slave_HWA_DisableTransmitInterrupt(FCIIC_Type *pFciic) +{ + pFciic->SIER &= ~FCIIC_SIER_TDIE_MASK; /* Receive Interrupt Enable */ +} + + +/** + * \brief Set FCIIC MCR register + * + * \param pFciic FCIIC instance value + * \param u32Value written value + */ +LOCAL_INLINE void FCIIC_HWA_SetMcr(FCIIC_Type *pFciic, uint32_t u32Value) +{ + pFciic->MCR = u32Value; +} + +/** + * \brief Attach FCIIC MCR register + * + * \param pFciic FCIIC instance value + * \param u32Value written value + */ +LOCAL_INLINE void FCIIC_HWA_AttachMcr(FCIIC_Type *pFciic, uint32_t u32Value) +{ + pFciic->MCR |= u32Value; +} + + +/** + * \brief Set FCIIC MDER register + * + * \param pFciic FCIIC instance value + * \param u32Value written value + */ +LOCAL_INLINE void FCIIC_HWA_SetMder(FCIIC_Type *pFciic, uint32_t u32Value) +{ + pFciic->MDER = u32Value; +} + +/** + * \brief Set FCIIC MCFGR0 register + * + * \param pFciic FCIIC instance value + * \param u32Value written value + */ +LOCAL_INLINE void FCIIC_HWA_SetMCFGR0(FCIIC_Type *pFciic, uint32_t u32Value) +{ + pFciic->MCFGR0 = u32Value; +} + +/** + * \brief Set FCIIC MCFGR1 register + * + * \param pFciic FCIIC instance value + * \param u32Value written value + */ +LOCAL_INLINE void FCIIC_HWA_SetMCFGR1(FCIIC_Type *pFciic, uint32_t u32Value) +{ + pFciic->MCFGR1 = u32Value; +} + +/** + * \brief Set FCIIC MCFGR2 register + * + * \param pFciic FCIIC instance value + * \param u32Value written value + */ +LOCAL_INLINE void FCIIC_HWA_SetMCFGR2(FCIIC_Type *pFciic, uint32_t u32Value) +{ + pFciic->MCFGR2 = u32Value; +} + +/** + * \brief Set FCIIC MCFGR3 register + * + * \param pFciic FCIIC instance value + * \param u32Value written value + */ +LOCAL_INLINE void FCIIC_HWA_SetMCFGR3(FCIIC_Type *pFciic, uint32_t u32Value) +{ + pFciic->MCFGR3 = u32Value; +} + +/** + * \brief Set FCIIC MFCR register + * + * \param pFciic FCIIC instance value + * \param u32Value written value + */ +LOCAL_INLINE void FCIIC_HWA_SetMFCR(FCIIC_Type *pFciic, uint32_t u32Value) +{ + pFciic->MFCR = u32Value; +} + +/** + * \brief Set FCIIC MCCR register + * + * \param pFciic FCIIC instance value + * \param u32Value written value + */ +LOCAL_INLINE void FCIIC_HWA_SetMCCR(FCIIC_Type *pFciic, uint32_t u32Value) +{ + pFciic->MCCR = u32Value; +} + +/** + * \brief Set FCIIC SDER register + * + * \param pFciic FCIIC instance value + * \param u32Value written value + */ +LOCAL_INLINE void FCIIC_HWA_SetSDER(FCIIC_Type *pFciic, uint32_t u32Value) +{ + pFciic->SDER = u32Value; +} + + + +/** + * \brief Set FCIIC SCFGR1 register + * + * \param pFciic FCIIC instance value + * \param u32Value written value + */ +LOCAL_INLINE void FCIIC_HWA_SetSCFGR1(FCIIC_Type *pFciic, uint32_t u32Value) +{ + pFciic->SCFGR1 = u32Value; +} + +/** + * \brief Set FCIIC MCCR register + * + * \param pFciic FCIIC instance value + * \param u32Value written value + */ +LOCAL_INLINE void FCIIC_HWA_SetSCFGR2(FCIIC_Type *pFciic, uint32_t u32Value) +{ + pFciic->SCFGR2 = u32Value; +} + +/** + * \brief Set FCIIC MCCR register + * + * \param pFciic FCIIC instance value + * \param u32Value written value + */ +LOCAL_INLINE void FCIIC_HWA_SetSAMR(FCIIC_Type *pFciic, uint32_t u32Value) +{ + pFciic->SAMR = u32Value; +} + +/** + * \brief Set FCIIC MCCR register + * + * \param pFciic FCIIC instance value + * \param u32Value written value + */ +LOCAL_INLINE void FCIIC_HWA_SetSCR(FCIIC_Type *pFciic, uint32_t u32Value) +{ + pFciic->SCR = u32Value; +} + + + +/** @}*/ + +#endif /* end for #ifndef _HWA_FCIIC_H_ */ diff --git a/MODULES/HwA_Flagchip_FC7240/Inc/HwA_fcpit.h b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_fcpit.h new file mode 100644 index 0000000..6991ab2 --- /dev/null +++ b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_fcpit.h @@ -0,0 +1,412 @@ +/** + * @file HwA_fcpit.h + * @author Flagchip + * @brief FC7xxx FCPIT hardware access layer + * @version 0.1.0 + * @date 2024-01-10 + * + * @copyright Copyright (c) 2023 Flagchip Semiconductors Co., Ltd. + * + * @details + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-01-10 Flagchip076 N/A First version for FC7240 + ******************************************************************************** */ + +#ifndef _HWA_FCPIT_H_ +#define _HWA_FCPIT_H_ + +#include "device_header.h" +/********* Local typedef ************/ +/** @brief Fcpit counter mode, the default mode is 32bit periodic count mode */ +typedef enum +{ + FCPIT_32PERIODIC_COUNTER = 0, + FCPIT_DUAL_16PERIODIC_COUNTER, + FCPIT_ACCUMULATOR, + FCPIT_32InputCaptue, +} FCPIT_TimerModeType; + +/** @brief Fcpit channel number */ +typedef enum +{ + FCPIT_CHANNEL_0 = 0U, + FCPIT_CHANNEL_1, + FCPIT_CHANNEL_2, + FCPIT_CHANNEL_3 +} FCPIT_ChannelType; +/********* Local inline function ************/ +/** + * @brief Set FCPIT channel value + * + * @param eChannel FCPIT channel number + * @param u32RegValue Timer value + */ +LOCAL_INLINE void FCPIT_HWA_SetChannelValue(FCPIT_Type *pFcpit, FCPIT_ChannelType eChannel, uint32_t u32RegValue) +{ + pFcpit->CONTROLS[eChannel].TVAL = u32RegValue; +} + + +/** + * @brief read FCPIT channel value + * + * @param eChannel FCPIT channel number + * @return Timer value + */ +LOCAL_INLINE uint32_t FCPIT_HWA_ReadChannelValue(FCPIT_Type *pFcpit, FCPIT_ChannelType eChannel) +{ + return (uint32_t)(pFcpit->CONTROLS[eChannel].TVAL ); +} + +/** + * @brief Configure FCPIT channel + * + * @param eChannel FCPIT channel number + * @param u32RegValue TCTRL register value + */ +LOCAL_INLINE void FCPIT_HWA_ConfigChannel(FCPIT_Type *pFcpit, FCPIT_ChannelType eChannel, uint32_t u32RegValue) +{ + pFcpit->CONTROLS[eChannel].TCTRL = u32RegValue; +} + +/** + * @brief Configure FCPIT module + * + * @param u32RegValue MCR register value + */ +LOCAL_INLINE void FCPIT_HWA_ConfigModule(FCPIT_Type *pFcpit, uint32_t u32RegValue) +{ + pFcpit->MCR = u32RegValue; +} + + +/** + * @brief Read FCPIT module enable + * + * @return MCR register with FCPIT_MCR_M_CEN_MASK + */ +LOCAL_INLINE uint32_t FCPIT_HWA_ReadModuleEnable(FCPIT_Type *pFcpit) +{ + return (uint32_t)(pFcpit->MCR & FCPIT_MCR_M_CEN_MASK); +} + +/** + * @brief Read FCPIT channel + * + * @param eChannel Channel number + * @return TCTRL register with FCPIT_TCTRL_T_EN_MASK + */ +LOCAL_INLINE uint32_t FCPIT_HWA_ReadChannelEnable(FCPIT_Type *pFcpit, FCPIT_ChannelType eChannel) +{ + return (uint32_t)(pFcpit->CONTROLS[eChannel].TCTRL & FCPIT_TCTRL_T_EN_MASK); +} + +/** + * @brief Read FCPIT active interrupt flag + * + * @return FCPIT active interrupt flag + */ +LOCAL_INLINE uint32_t FCPIT_HWA_ReadInterruptFlag(FCPIT_Type *pFcpit) +{ + return (pFcpit->MSR); +} + +/** + * @brief Read FCPIT enable interrupt flag + * + * @return FCPIT enable interrupt flag + */ +LOCAL_INLINE uint32_t FCPIT_HWA_ReadEnableInterruptFlag(FCPIT_Type *pFcpit) +{ + return (pFcpit->MIER); +} + +/** + * @brief Set FCPIT channel running on debug mode + * + */ +LOCAL_INLINE void FCPIT_HWA_SetChannelRunOnDebug(FCPIT_Type *pFcpit) +{ + pFcpit->MCR |= FCPIT_MCR_DBG_EN_MASK; +} + +/** + * @brief Set FCPIT channel running on low power mode + * + */ +LOCAL_INLINE void FCPIT_HWA_SetChannelRunOnLpm(FCPIT_Type *pFcpit) +{ + pFcpit->MCR |= FCPIT_MCR_LPM_EN_MASK; +} + +/** + * @brief Enable FCPIT module + * + */ +LOCAL_INLINE void FCPIT_HWA_EnableModule(FCPIT_Type *pFcpit) +{ + pFcpit->MCR |= FCPIT_MCR_M_CEN_MASK; +} + +/** + * @brief Enable FCPIT channel(n) interrupt + * + * @param u32RegValue u32RegValue 0-3 bit indicate TIE0-TIE3 + */ +LOCAL_INLINE void FCPIT_HWA_EnableChannelsInterrupt(FCPIT_Type *pFcpit, uint32_t u32RegValue) +{ + pFcpit->MIER |= u32RegValue; +} + +/** + * @brief Enable FCPIT channel + * + * @param eChannel FCPIT channel number + */ +LOCAL_INLINE void FCPIT_HWA_EnableChannel(FCPIT_Type *pFcpit, FCPIT_ChannelType eChannel) +{ + pFcpit->CONTROLS[eChannel].TCTRL |= FCPIT_TCTRL_T_EN_MASK; +} + +/** + * @brief Enable FCPIT channel + * + * @param eChannel FCPIT channel number + */ +LOCAL_INLINE void FCPIT_HWA_SetTimerEnable(FCPIT_Type *pFcpit, FCPIT_ChannelType eChannel) +{ + pFcpit->SETTEN |= (FCPIT_SETTEN_SET_T_EN_0_MASK << (uint32_t)eChannel); +} + + +/** + * @brief Disable FCPIT channel + * + * @param eChannel FCPIT channel number + */ +LOCAL_INLINE void FCPIT_HWA_ClearTimerEnable(FCPIT_Type *pFcpit, FCPIT_ChannelType eChannel) +{ + pFcpit->CLRTEN |= (FCPIT_CLRTEN_CLR_T_EN_0_MASK << (uint32_t)eChannel); +} + +/** + * @brief Enable FCPIT channel(n) chain mode + * + * @param eChannel FCPIT channel number + */ +LOCAL_INLINE void FCPIT_HWA_EnableChannelChainMode(FCPIT_Type *pFcpit, FCPIT_ChannelType eChannel) +{ + pFcpit->CONTROLS[eChannel].TCTRL |= FCPIT_TCTRL_CHAIN_MASK; +} + +/** + * @brief Configure FCPIT channel operation mode + * + * @param eChannel FCPIT channel number + * @param eMode FCPIT operation mode + */ +LOCAL_INLINE void FCPIT_HWA_ConfigChannelMode(FCPIT_Type *pFcpit, FCPIT_ChannelType eChannel, FCPIT_TimerModeType eMode) +{ + uint32_t u32RegValue = pFcpit->CONTROLS[eChannel].TCTRL; + pFcpit->CONTROLS[eChannel].TCTRL = (u32RegValue & ~(uint32_t)FCPIT_TCTRL_MODE_MASK) | FCPIT_TCTRL_MODE(eMode); +} + +/** + * @brief Set FCPIT channel start on trigger + * + * @param eChannel FCPIT channel number + */ +LOCAL_INLINE void FCPIT_HWA_SetChannelStartOnTrig(FCPIT_Type *pFcpit, FCPIT_ChannelType eChannel) +{ + pFcpit->CONTROLS[eChannel].TCTRL |= FCPIT_TCTRL_TSOT_MASK; +} + +/** + * @brief Set FCPIT channel stop on interrupt + * + * @param eChannel FCPIT channel number + */ +LOCAL_INLINE void FCPIT_HWA_SetChannelStopOnInterrupt(FCPIT_Type *pFcpit, FCPIT_ChannelType eChannel) +{ + pFcpit->CONTROLS[eChannel].TCTRL |= FCPIT_TCTRL_TSOI_MASK; +} + +/** + * @brief Set FCPIT channel reload on trigger + * + * @param eChannel FCPIT channel number + */ +LOCAL_INLINE void FCPIT_HWA_SetChannelReloadOnTrig(FCPIT_Type *pFcpit, FCPIT_ChannelType eChannel) +{ + pFcpit->CONTROLS[eChannel].TCTRL |= FCPIT_TCTRL_TROT_MASK; +} + +/** + * @brief Set FCPIT channel trigger source + * + * @param eChannel FCPIT channel number + */ +LOCAL_INLINE void FCPIT_HWA_SetChannelTriggerSrc(FCPIT_Type *pFcpit, FCPIT_ChannelType eChannel) +{ + pFcpit->CONTROLS[eChannel].TCTRL |= FCPIT_TCTRL_TRG_SRC_MASK; +} + +/** + * @brief Select FCPIT channel trigger + * + * @param eChannel FCPIT channel number + * @param u8SelChannel Select channel, range is 0-3 + */ +LOCAL_INLINE void FCPIT_HWA_SelectChannelTrigger(FCPIT_Type *pFcpit, FCPIT_ChannelType eChannel, uint8_t u8SelChannel) +{ + uint32_t u32RegValue = pFcpit->CONTROLS[eChannel].TCTRL; + pFcpit->CONTROLS[eChannel].TCTRL = (u32RegValue & ~(uint32_t)FCPIT_TCTRL_TRG_SEL_MASK) | + FCPIT_TCTRL_TRG_SEL(u8SelChannel); +} + +/** + * @brief Set FCPIT channel stop on debug mode + * + */ +LOCAL_INLINE void FCPIT_HWA_SetChannelStopOnDebug(FCPIT_Type *pFcpit) +{ + pFcpit->MCR &= ~(uint32_t)FCPIT_MCR_DBG_EN_MASK; +} + +/** + * @brief Set FCPIT channel stop on low power mode + * + */ +LOCAL_INLINE void FCPIT_HWA_SetChannelStopOnLpm(FCPIT_Type *pFcpit) +{ + pFcpit->MCR &= ~(uint32_t)FCPIT_MCR_LPM_EN_MASK; +} + +/** + * @brief Disable FCPIT module + * + */ +LOCAL_INLINE void FCPIT_HWA_DisableModule(FCPIT_Type *pFcpit) +{ + pFcpit->MCR &= ~(uint32_t)FCPIT_MCR_M_CEN_MASK; +} + +/** + * @brief Clear FCPIT channel(n) interrupt flag + * + * @param u32RegValue 0-3 bit indicate TIF0-TIF3 + */ +LOCAL_INLINE void FCPIT_HWA_ClearChannelsInterruptFlag(FCPIT_Type *pFcpit, uint32_t u32RegValue) +{ + pFcpit->MSR |= u32RegValue; +} + +/** + * @brief Disable FCPIT channel(n) interrupt + * + * @param u32RegValue u32RegValue 0-3 bit indicate TIE0-TIE3 + */ +LOCAL_INLINE void FCPIT_HWA_DisableChannelsInterrupt(FCPIT_Type *pFcpit, uint32_t u32RegValue) +{ + pFcpit->MIER &= ~u32RegValue; +} + +/** + * @brief Disable FCPIT channel + * + * @param eChannel FCPIT channel number + */ +LOCAL_INLINE void FCPIT_HWA_DisableChannel(FCPIT_Type *pFcpit, FCPIT_ChannelType eChannel) +{ + pFcpit->CONTROLS[eChannel].TCTRL &= ~(uint32_t)FCPIT_TCTRL_T_EN_MASK; +} + +/** + * @brief Disable FCPIT channel chain mode + * + * @param eChannel FCPIT channel number + */ +LOCAL_INLINE void FCPIT_HWA_DisableChannelChainMode(FCPIT_Type *pFcpit, FCPIT_ChannelType eChannel) +{ + pFcpit->CONTROLS[eChannel].TCTRL &= ~(uint32_t)FCPIT_TCTRL_CHAIN_MASK; +} + +/** + * @brief Clear FCPIT channel operation mode + * + * @param eChannel FCPIT channel number + */ +LOCAL_INLINE void FCPIT_HWA_ClearChannelMode(FCPIT_Type *pFcpit, FCPIT_ChannelType eChannel) +{ + pFcpit->CONTROLS[eChannel].TCTRL &= ~(uint32_t)FCPIT_TCTRL_MODE_MASK; +} + +/** + * @brief read FCPIT channel operation mode + * + * @param eChannel FCPIT channel number + */ + +LOCAL_INLINE uint32 FCPIT_HWA_ReadChannelMode(FCPIT_Type *pFcpit, FCPIT_ChannelType eChannel) +{ + return (uint32) ((pFcpit->CONTROLS[eChannel].TCTRL & (uint32_t)FCPIT_TCTRL_MODE_MASK) >>FCPIT_TCTRL_MODE_SHIFT); +} + + +/** + * @brief Clear FCPIT channel start on trigger + * + * @param eChannel FCPIT channel number + */ +LOCAL_INLINE void FCPIT_HWA_ClearChannelStartOnTrig(FCPIT_Type *pFcpit, FCPIT_ChannelType eChannel) +{ + pFcpit->CONTROLS[eChannel].TCTRL &= ~(uint32_t)FCPIT_TCTRL_TSOT_MASK; +} + +/** + * @brief Clear FCPIT channel stop on interrupt + * + * @param eChannel FCPIT channel number + */ +LOCAL_INLINE void FCPIT_HWA_ClearChannelStopOnInterrupt(FCPIT_Type *pFcpit, FCPIT_ChannelType eChannel) +{ + pFcpit->CONTROLS[eChannel].TCTRL &= ~(uint32_t)FCPIT_TCTRL_TSOI_MASK; +} + +/** + * @brief Clear FCPIT channel reload on trigger + * + * @param eChannel FCPIT channel number + */ +LOCAL_INLINE void FCPIT_HWA_ClearChannelReloadOnTrig(FCPIT_Type *pFcpit, FCPIT_ChannelType eChannel) +{ + pFcpit->CONTROLS[eChannel].TCTRL &= ~(uint32_t)FCPIT_TCTRL_TROT_MASK; +} + +/** + * @brief Clear FCPIT channel trigger source + * + * @param eChannel FCPIT channel number + */ +LOCAL_INLINE void FCPIT_HWA_ClearChannelTriggerSrc(FCPIT_Type *pFcpit, FCPIT_ChannelType eChannel) +{ + pFcpit->CONTROLS[eChannel].TCTRL &= ~(uint32_t)FCPIT_TCTRL_TRG_SRC_MASK; +} + +/** + * @brief Clear FCPIT channel trigger select + * + * @param eChannel FCPIT channel number + */ +LOCAL_INLINE void FCPIT_HWA_ClearChannelTriggerSelect(FCPIT_Type *pFcpit, FCPIT_ChannelType eChannel) +{ + pFcpit->CONTROLS[eChannel].TCTRL &= ~(uint32_t)FCPIT_TCTRL_TRG_SEL_MASK; +} + + +#endif /* #ifndef _HWA_FCPIT_H_ */ diff --git a/MODULES/HwA_Flagchip_FC7240/Inc/HwA_fcsmu.h b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_fcsmu.h new file mode 100644 index 0000000..68d99a3 --- /dev/null +++ b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_fcsmu.h @@ -0,0 +1,671 @@ +/** + * @file HwA_fcsmu.h + * @author Flagchip + * @brief FC7xxx FCSMU hardware access layer + * @version 0.1.0 + * @date 2024-01-14 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + * @details + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-01-14 qxw0100 N/A First version for FC7240 + ******************************************************************************** */ +#ifndef _HWA_FCSMU_H_ +#define _HWA_FCSMU_H_ + +#include "device_header.h" + +/** + * @addtogroup HwA_fcsmu + * @{ + * + */ +/********* macros ************/ +typedef enum +{ + FCSMU_OPC_NONE = 0U, /*!< FCSMU operation code none */ + FCSMU_OPC_MOVE_TO_CONFIG = 1U, /*!< FCSMU operation code move to configuration state */ + FCSMU_OPC_MOVE_TO_NORMAL = 2U, /*!< FCSMU operation code move to normal state */ + FCSMU_OPC_CLEAR_FAULT_IMFO = 13U, /*!< FCSMU operation code clear fault channel information register */ + FCSMU_OPC_CLEAR_OPS_TO_IDLE = 15U, /*!< FCSMU operation code clear ops to idle */ + FCSMU_OPC_LOAD_NVR_CONFIG = 31U /*!< FCSMU operation code load configuration from nvr */ +} FCSMU_OperationCodeType; + +typedef enum +{ + FCSMU_Crc_STATE_IDLE = 0U, /*!< FCSMU crc status idle */ + FCSMU_Crc_STATE_BUSY = 1U /*!< FCSMU crc status busy */ +} FCSMU_CrcStatusType; +/********* Local typedef ************/ + +/********* Local inline function ************/ + +/********* FCSMU Register interface ************/ + +/** + * @brief Set the fcsmu CTRL register + * + * @param pFcsmu FCSMU Instance + * @param u32Value The register value + */ +LOCAL_INLINE void FCSMU_HWA_SetCrtl(FCSMU_Type *const pFcsmu, uint32_t u32Value) +{ + pFcsmu->CTRL = u32Value; +} + +/** + * @brief Get the fcsmu CTRL register + * + * @param pFcsmu FCSMU Instance + * @return CTRL register value + */ +LOCAL_INLINE uint32_t FCSMU_HWA_GetCtrl(FCSMU_Type *const pFcsmu) +{ + return pFcsmu->CTRL; +} + +/** + * @brief Get the fcsmu CTRL register OPS + * + * @param pFcsmu FCSMU Instance + * @return CTRL register OPS value + */ +LOCAL_INLINE uint32_t FCSMU_HWA_GetCtrlOps(FCSMU_Type *const pFcsmu) +{ + return ((pFcsmu->CTRL & FCSMU_CTRL_OPS_MASK) >> FCSMU_CTRL_OPS_SHIFT); +} + +/** + * @brief Set the fcsmu OPRK register + * + * @param pFcsmu FCSMU Instance + * @param u32Value The register value + */ +LOCAL_INLINE void FCSMU_HWA_SetOprk(FCSMU_Type *const pFcsmu, uint32_t u32Value) +{ + pFcsmu->OPRK = u32Value; +} + + +/** + * @brief Set the fcsmu SOCTRL register + * + * @param pFcsmu FCSMU Instance + * @param u32Value The register value + */ +LOCAL_INLINE void FCSMU_HWA_SetSoctrl(FCSMU_Type *const pFcsmu, uint32_t u32Value) +{ + pFcsmu->SOCTRL = u32Value; +} + +/** + * @brief Get the fcsmu SOCTRL register + * + * @param pFcsmu FCSMU Instance + * @return SOCTRL register value + */ +LOCAL_INLINE uint32_t FCSMU_HWA_GetSoctrl(FCSMU_Type *const pFcsmu) +{ + return pFcsmu->SOCTRL; +} + +/** + * @brief Set the fcsmu FCCR0 register + * + * @param pFcsmu FCSMU Instance + * @param u32Value FCCR0 register value + */ +LOCAL_INLINE void FCSMU_HWA_SetFccr0(FCSMU_Type *const pFcsmu, uint32_t u32Value) +{ + pFcsmu->FCCR0 = u32Value; +} + +/** + * @brief Get the fcsmu FCCR0 register + * + * @param pFcsmu FCSMU Instance + * @return FCCR0 register value + */ +LOCAL_INLINE uint32_t FCSMU_HWA_GetFccr0(FCSMU_Type *const pFcsmu) +{ + return pFcsmu->FCCR0; +} + +/** + * @brief Set the fcsmu FRST0 register + * + * @param pFcsmu FCSMU Instance + * @param u32Value FRST0 register value + */ +LOCAL_INLINE void FCSMU_HWA_SetFRST0(FCSMU_Type *const pFcsmu, uint32_t u32Value) +{ + pFcsmu->FRST0 = u32Value; +} + +/** + * @brief Get the fcsmu FRST0 register + * + * @param pFcsmu FCSMU Instance + * @return FRST0 register value + */ +LOCAL_INLINE uint32_t FCSMU_HWA_GetFRST0(FCSMU_Type *const pFcsmu) +{ + return pFcsmu->FRST0; +} + +/** + * @brief Set the fcsmu FST0 register + * + * @param pFcsmu FCSMU Instance + * @param u32Value FST0 register value + */ +LOCAL_INLINE void FCSMU_HWA_SetFst0(FCSMU_Type *const pFcsmu, uint32_t u32Value) +{ + pFcsmu->FST0 = u32Value; +} + +/** + * @brief Get the fcsmu FST0 register + * + * @param pFcsmu FCSMU Instance + * @return FST0 register value + */ +LOCAL_INLINE uint32_t FCSMU_HWA_GetFst0(FCSMU_Type *const pFcsmu) +{ + return pFcsmu->FST0; +} + +/** + * @brief Set the fcsmu FST_UNLK register + * + * @param pFcsmu FCSMU Instance + * @param u32Value FST_UNLK register value + */ +LOCAL_INLINE void FCSMU_HWA_SetFunlk(FCSMU_Type *const pFcsmu, uint32_t u32Value) +{ + pFcsmu->FST_UNLK = u32Value; +} + +/** + * @brief Set the fcsmu FE0 register + * + * @param pFcsmu FCSMU Instance + * @param u32Value FE0 register value + */ +LOCAL_INLINE void FCSMU_HWA_SetFe0(FCSMU_Type *const pFcsmu, uint32_t u32Value) +{ + pFcsmu->FE0 = u32Value; +} + +/** + * @brief Get the fcsmu FE0 register + * + * @param pFcsmu FCSMU Instance + * @return FE0 register value + */ +LOCAL_INLINE uint32_t FCSMU_HWA_GetFE0(FCSMU_Type *const pFcsmu) +{ + return pFcsmu->FE0; +} + +/** + * @brief Set the fcsmu WARNING_EN0 register + * + * @param pFcsmu FCSMU Instance + * @param u32Value WARNING_EN0 register value + */ +LOCAL_INLINE void FCSMU_HWA_SetWarningEn0(FCSMU_Type *const pFcsmu, uint32_t u32Value) +{ + pFcsmu->WARNING_EN0 = u32Value; +} + +/** + * @brief Get the fcsmu WARNING_EN0 register + * + * @param pFcsmu FCSMU Instance + * @return WARNING_EN0 register value + */ +LOCAL_INLINE uint32_t FCSMU_HWA_GetWarningEn0(FCSMU_Type *const pFcsmu) +{ + return pFcsmu->WARNING_EN0; +} + +/** + * @brief Set the fcsmu WARNING_TO register + * + * @param pFcsmu FCSMU Instance + * @param u32Value WARNING_TO register value + */ +LOCAL_INLINE void FCSMU_HWA_SetWaringTo(FCSMU_Type *const pFcsmu, uint32_t u32Value) +{ + pFcsmu->WARNING_TO = u32Value; +} + +/** + * @brief Get the fcsmu WARNING_TO register + * + * @param pFcsmu FCSMU Instance + * @return WARNING_TO register value + */ +LOCAL_INLINE uint32_t FCSMU_HWA_GetWaringTo(FCSMU_Type *const pFcsmu) +{ + return pFcsmu->WARNING_TO; +} + +/** + * @brief Set the fcsmu CFG_TO register + * + * @param pFcsmu FCSMU Instance + * @param u32Value CFG_TO register value + */ +LOCAL_INLINE void FCSMU_HWA_SetCfgTo(FCSMU_Type *const pFcsmu, uint32_t u32Value) +{ + pFcsmu->CFG_TO = u32Value; +} + +/** + * @brief Get the fcsmu CFG_TO register + * + * @param pFcsmu FCSMU Instance + * @return CFG_TO register value + */ +LOCAL_INLINE uint32_t FCSMU_HWA_GetCfgTo(FCSMU_Type *const pFcsmu) +{ + return pFcsmu->CFG_TO; +} + +/** + * @brief Set the fcsmu SOUT_DIAG register + * + * @param pFcsmu FCSMU Instance + * @param u32Value SOUT_DIAG register value + */ +LOCAL_INLINE void FCSMU_HWA_SetSoutDiag(FCSMU_Type *const pFcsmu, uint32_t u32Value) +{ + pFcsmu->SOUT_DIAG = u32Value; +} + +/** + * @brief Get the fcsmu SOUT_DIAG register + * + * @param pFcsmu FCSMU Instance + * @return SOUT_DIAG register value + */ +LOCAL_INLINE uint32_t FCSMU_HWA_GetSoutDiag(FCSMU_Type *const pFcsmu) +{ + return pFcsmu->SOUT_DIAG; +} + +/** + * @brief Get the fcsmu STATUS register + * + * @param pFcsmu FCSMU Instance + * @return STATUS register value + */ +LOCAL_INLINE uint32_t FCSMU_HWA_GetStatus(FCSMU_Type *const pFcsmu) +{ + return pFcsmu->STATUS; +} + +/** + * @brief Get the fcsmu STATUS register FIF value + * + * @param pFcsmu FCSMU Instance + * @return STATUS register FIF value + */ +LOCAL_INLINE bool FCSMU_HWA_GetFaultState(FCSMU_Type *const pFcsmu) +{ + return (pFcsmu->STATUS & FCSMU_STATUS_FIF_MASK) == FCSMU_STATUS_FIF_MASK ? true : false; +} + +/** + * @brief Get the fcsmu STATUS register STAT value + * + * @param pFcsmu FCSMU Instance + * @return STATUS register STAT value + */ +LOCAL_INLINE uint32_t FCSMU_HWA_GetState(FCSMU_Type *const pFcsmu) +{ + return (pFcsmu->STATUS & FCSMU_STATUS_STAT_MASK) >> FCSMU_STATUS_STAT_SHIFT; +} + +/** + * @brief Get the fcsmu NTW register + * + * @param pFcsmu FCSMU Instance + * @return NTW register value + */ +LOCAL_INLINE uint32_t FCSMU_HWA_GetNtw(FCSMU_Type *const pFcsmu) +{ + return pFcsmu->NTW; +} + +/** + * @brief Get the fcsmu WTF register + * + * @param pFcsmu FCSMU Instance + * @return WTF register value + */ +LOCAL_INLINE uint32_t FCSMU_HWA_GetWtf(FCSMU_Type *const pFcsmu) +{ + return pFcsmu->WTF; +} + +/** + * @brief Get the fcsmu NTF register + * + * @param pFcsmu FCSMU Instance + * @return NTF register value + */ +LOCAL_INLINE uint32_t FCSMU_HWA_GetNtf(FCSMU_Type *const pFcsmu) +{ + return pFcsmu->NTF; +} + +/** + * @brief Get the fcsmu FTW register + * + * @param pFcsmu FCSMU Instance + * @return FTW register value + */ +LOCAL_INLINE uint32_t FCSMU_HWA_GetFtw(FCSMU_Type *const pFcsmu) +{ + return pFcsmu->FTW; +} + +/** + * @brief Set the fcsmu INJECT register + * + * @param pFcsmu FCSMU Instance + * @param u32Value INJECT register value + */ +LOCAL_INLINE void FCSMU_HWA_SetInject(FCSMU_Type *const pFcsmu, uint32_t u32Value) +{ + pFcsmu->INJECT = u32Value; +} + +/** + * @brief Get the fcsmu IRQ_STAT register + * + * @param pFcsmu FCSMU Instance + * @return IRQ_STAT register value + */ +LOCAL_INLINE uint32_t FCSMU_HWA_GetIrqStat(FCSMU_Type *const pFcsmu) +{ + return pFcsmu->IRQ_STAT; +} + +/** + * @brief Set the fcsmu IRQ_STAT register + * + * @param pFcsmu FCSMU Instance + * @param u32Value IRQ_STAT register value + */ +LOCAL_INLINE void FCSMU_HWA_ClearCfgToIrq(FCSMU_Type *const pFcsmu) +{ + pFcsmu->IRQ_STAT |= FCSMU_IRQ_STAT_CFG_TO_IRQ_MASK; +} + + +/** + * @brief Set the fcsmu IRQ_EN register + * + * @param pFcsmu FCSMU Instance + * @param bEnable IRQ_EN register value + */ +LOCAL_INLINE void FCSMU_HWA_EnableCfgToIrq(FCSMU_Type *const pFcsmu, bool bEnable) +{ + pFcsmu->IRQ_EN = (pFcsmu->IRQ_EN & ~FCSMU_IRQ_STAT_CFG_TO_IRQ_MASK) | FCSMU_IRQ_EN_CFG_TO_IEN(bEnable); +} + +/** + * @brief Set the fcsmu TEMP_UNLK register + * + * @param pFcsmu FCSMU Instance + * @param u32Value TEMP_UNLK register value + */ +LOCAL_INLINE void FCSMU_HWA_SetTempUnlk(FCSMU_Type *const pFcsmu, uint32_t u32Value) +{ + pFcsmu->TEMP_UNLK = u32Value; +} + +/** + * @brief Set the fcsmu PERMNT_LOCK register + * + * @param pFcsmu FCSMU Instance + * @param u32Value PERMNT_LOCK register value + */ +LOCAL_INLINE void FCSMU_HWA_SetPermntLock(FCSMU_Type *const pFcsmu, uint32_t u32Value) +{ + pFcsmu->PERMNT_LOCK = u32Value; +} + +/** + * @brief Set the fcsmu STMR register + * + * @param pFcsmu FCSMU Instance + * @param u32Value STMR register value + */ +LOCAL_INLINE void FCSMU_HWA_SetStmr(FCSMU_Type *const pFcsmu, uint32_t u32Value) +{ + pFcsmu->STMR = u32Value; +} + + +/** + * @brief Set the fcsmu WARNING_IEN0 register + * + * @param pFcsmu FCSMU Instance + * @param u32Value WARNING_IEN0 register value + */ +LOCAL_INLINE void FCSMU_HWA_SetWarningIen(FCSMU_Type *const pFcsmu, uint32_t u32Value) +{ + pFcsmu->WARNING_IEN0 = u32Value; +} + +/** + * @brief Set the fcsmu FAULT_IEN0 register + * + * @param pFcsmu FCSMU Instance + * @param u32Value FAULT_IEN0 register value + */ +LOCAL_INLINE void FCSMU_HWA_SetFaultIen(FCSMU_Type *const pFcsmu, uint32_t u32Value) +{ + pFcsmu->FAULT_IEN0 = u32Value; +} + +/** + * @brief Set the fcsmu SOUT_EN0 register + * + * @param pFcsmu FCSMU Instance + * @param u32Value SOUT_EN0 register value + */ +LOCAL_INLINE void FCSMU_HWA_SetSoutEn(FCSMU_Type *const pFcsmu, uint32_t u32Value) +{ + pFcsmu->SOUT_EN0 = u32Value; +} + +/** + * @brief Get the fcsmu WARNING_TMR register + * + * @param pFcsmu FCSMU Instance + * @return WARNING_TMR register value + */ +LOCAL_INLINE uint32_t FCSMU_HWA_GetWarningTmr(FCSMU_Type *const pFcsmu) +{ + return pFcsmu->WARNING_TMR; +} + +/** + * @brief Get the fcsmu SM_TMR register + * + * @param pFcsmu FCSMU Instance + * @return SM_TMR register value + */ +LOCAL_INLINE uint32_t FCSMU_HWA_GetSafeModeTmr(FCSMU_Type *const pFcsmu) +{ + return pFcsmu->SM_TMR; +} + +/** + * @brief Get the fcsmu CFG_TMR register + * + * @param pFcsmu FCSMU Instance + * @return CFG_TMR register value + */ +LOCAL_INLINE uint32_t FCSMU_HWA_GetConfigTmr(FCSMU_Type *const pFcsmu) +{ + return pFcsmu->CFG_TMR; +} + +/** + * @brief Get the fcsmu SOUT_TMR register + * + * @param pFcsmu FCSMU Instance + * @return SOUT_TMR register value + */ +LOCAL_INLINE uint32_t FCSMU_HWA_GetSoutTmr(FCSMU_Type *const pFcsmu) +{ + return pFcsmu->SOUT_TMR; +} + +/** + * @brief Set the fcsmu CRC_CTRL register + * + * @param pFcsmu FCSMU Instance + * @param u32Value CRC_CTRL register value + */ +LOCAL_INLINE void FCSMU_HWA_SetCrcCtrl(FCSMU_Type *const pFcsmu, uint32_t u32Value) +{ + pFcsmu->CRC_CTRL = u32Value; +} + +/** + * @brief Get the fcsmu CRC_CTRL register BUSY value + * + * @param pFcsmu FCSMU Instance + * @return BUSY value + */ +LOCAL_INLINE bool FCSMU_HWA_GetCrcBusy(FCSMU_Type *const pFcsmu) +{ + return (pFcsmu->CRC_CTRL & FCSMU_CRC_CTRL_BUSY_MASK) == FCSMU_CRC_CTRL_BUSY_MASK ? true : false; +} + +/** + * @brief Get the fcsmu CRC_CTRL register EF value + * + * @param pFcsmu FCSMU Instance + * @return EF value + */ +LOCAL_INLINE bool FCSMU_HWA_GetCrcErrorFlag(FCSMU_Type *const pFcsmu) +{ + return (pFcsmu->CRC_CTRL & FCSMU_CRC_CTRL_EF_MASK) == FCSMU_CRC_CTRL_EF_MASK ? true : false; +} + +/** + * @brief Clear the fcsmu CRC_CTRL register EF + * + * @param pFcsmu FCSMU Instance + * @param u32Value CRC_CTRL register value + */ +LOCAL_INLINE void FCSMU_HWA_ClearCrcErrorFlag(FCSMU_Type *const pFcsmu) +{ + pFcsmu->CRC_CTRL |= FCSMU_CRC_CTRL_EF_MASK; +} + +/** + * @brief Set the fcsmu CRC_CTRL register + * + * @param pFcsmu FCSMU Instance + * @param u32Value CRC_CTRL register value + */ +LOCAL_INLINE void FCSMU_HWA_EnableErrorOutput(FCSMU_Type *const pFcsmu, bool bEnable) +{ + pFcsmu->CRC_CTRL = (pFcsmu->CRC_CTRL & ~FCSMU_CRC_CTRL_EOEN_MASK) | FCSMU_CRC_CTRL_EOEN(bEnable); +} + +/** + * @brief Get the fcsmu CRC_CTRL register EOEN value + * + * @param pFcsmu FCSMU Instance + * @return EOEN value + */ +LOCAL_INLINE bool FCSMU_HWA_GetCrcErrorOutputEnable(FCSMU_Type *const pFcsmu) +{ + return (pFcsmu->CRC_CTRL & FCSMU_CRC_CTRL_EOEN_MASK) == FCSMU_CRC_CTRL_EOEN_MASK ? true : false; +} + +/** + * @brief Set the fcsmu CRC_CTRL register + * + * @param pFcsmu FCSMU Instance + * @param bEnable CRC_CTRL register value + */ +LOCAL_INLINE void FCSMU_HWA_EnableCrcChecker(FCSMU_Type *const pFcsmu, bool bEnable) +{ + pFcsmu->CRC_CTRL = (pFcsmu->CRC_CTRL & ~FCSMU_CRC_CTRL_CHKEN_MASK) | FCSMU_CRC_CTRL_CHKEN(bEnable); +} + +/** + * @brief Get the fcsmu CRC_CTRL register CHKEN value + * + * @param pFcsmu FCSMU Instance + * @return CHKEN value + */ +LOCAL_INLINE bool FCSMU_HWA_GetCrcCheckerEnable(FCSMU_Type *const pFcsmu) +{ + return (pFcsmu->CRC_CTRL & FCSMU_CRC_CTRL_CHKEN_MASK) == FCSMU_CRC_CTRL_CHKEN_MASK ? true : false; +} + +/** + * @brief Set the fcsmu CRC_CTRL register + * + * @param pFcsmu FCSMU Instance + * @param bEnable CRC_CTRL register value + */ +LOCAL_INLINE void FCSMU_HWA_EnableTrigger(FCSMU_Type *const pFcsmu, bool bEnable) +{ + pFcsmu->CRC_CTRL = (pFcsmu->CRC_CTRL & ~FCSMU_CRC_CTRL_TRGEN_MASK) | FCSMU_CRC_CTRL_TRGEN(bEnable); +} + +/** + * @brief Get the fcsmu CRC_CTRL register TRGEN value + * + * @param pFcsmu FCSMU Instance + * @return TRGEN value + */ +LOCAL_INLINE bool FCSMU_HWA_GetTriggerEnable(FCSMU_Type *const pFcsmu) +{ + return (pFcsmu->CRC_CTRL & FCSMU_CRC_CTRL_TRGEN_MASK) == FCSMU_CRC_CTRL_TRGEN_MASK ? true : false; +} + +/** + * @brief Set the fcsmu CRC_CTRL register + * + * @param pFcsmu FCSMU Instance + */ +LOCAL_INLINE void FCSMU_HWA_GenerateCrc(FCSMU_Type *const pFcsmu) +{ + pFcsmu->CRC_CTRL |= FCSMU_CRC_CTRL_GEN(true); +} + +/** + * @brief Get the fcsmu CRC_RES register + * + * @param pFcsmu FCSMU Instance + * @return CRC_RES register value + */ +LOCAL_INLINE uint32_t FCSMU_HWA_GetCrcResult(FCSMU_Type *const pFcsmu) +{ + return pFcsmu->CRC_RES; +} + +/** @}*/ /* HwA_fcsmu */ + +#endif /* #ifndef _HWA_FCSMU_H_ */ diff --git a/MODULES/HwA_Flagchip_FC7240/Inc/HwA_fcspi.h b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_fcspi.h new file mode 100644 index 0000000..3c204cc --- /dev/null +++ b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_fcspi.h @@ -0,0 +1,478 @@ +/** + * @file HwA_fcspi.h + * @author Flagchip + * @brief FC7xxx FCSPI hardware access layer + * @version 0.1.0 + * @date 2024-01-13 + * + * @copyright Copyright (c) 2023 Flagchip Semiconductors Co., Ltd. + * + * @details + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-01-12 Flagchip071 N/A First version for FC7240 + ******************************************************************************** */ + +#ifndef _HWA_FCSPI_H_ +#define _HWA_FCSPI_H_ + +#include "device_header.h" + +/** + * @addtogroup HwA_fcspi + * @{ + */ + +/** + * @brief Boolean false value definition for type FCSPI_AtomicBoolType used by FCSPI to ensure read/write atomic + * + */ +#define FCSPI_FALSE ((uint8_t)0) + +/** + * @brief Boolean true value definition for type FCSPI_AtomicBoolType used by FCSPI to ensure read/write atomic + * + */ +#define FCSPI_TRUE ((uint8_t)1) + +/********* Local typedef ************/ +/** + * @brief FCSPI Mode type, master or slave. + */ +typedef enum { + FCSPI_MODE_SLAVE = 0, + FCSPI_MODE_MASTER = 1 +} FCSPI_MasterSlaveModeType; + +/** + * @brief Boolean type for FCSpi + */ +typedef uint8_t FCSPI_AtomicBoolType; + +/********* Local inline function ************/ + +/** + * @brief Read the FCSPI CTRL register value for all. + * + * @param pFCSPI FCSPI instance, e.g. FCSPI0, FCSPI1. + * @return FCSPI CTRL regsiter value. + */ +LOCAL_INLINE uint32_t FCSPI_HWA_GetCtrlValue(FCSPI_Type *pFCSPI) +{ + return pFCSPI->CTRL; +} + +/** + * @brief Set FCSPI CTRL value, users should write the whole value to this register. + * + * @param pFCSPI FCSPI instance, e.g. FCSPI0, FCSPI1. + * @param u32Value the value which will be written to the CTRL register. + */ +LOCAL_INLINE void FCSPI_HWA_SetCtrlValue(FCSPI_Type *pFCSPI, uint32_t u32Value) +{ + pFCSPI->CTRL = u32Value; +} + +/** + * @brief Enable the feature of FCSPI hardware, only for starting the feature of SPI module. + * + * @param pFCSPI FCSPI instance, e.g. FCSPI0, FCSPI1. + */ +LOCAL_INLINE void FCSPI_HWA_ModuleEnable(FCSPI_Type *pFCSPI) +{ + pFCSPI->CTRL |= FCSPI_CTRL_M_EN(1); +} + +/** + * @brief Disable the feature of FCSPI, and shutdown the FCSPI module. + * + * @param pFCSPI FCSPI instance, e.g. FCSPI0, FCSPI1. + */ +LOCAL_INLINE void FCSPI_HWA_ModuleDisable(FCSPI_Type *pFCSPI) +{ + pFCSPI->CTRL &= (~(FCSPI_CTRL_M_EN_MASK)); +} + +/** + * @brief Getting the FCSPI transfer status by reading the STATUS register. + * + * @param pFCSPI FCSPI instance, e.g. FCSPI0, FCSPI1. + * @return the whole status of FCSPI transfer, which can be read in STATUS register. + */ +LOCAL_INLINE uint32_t FCSPI_HWA_GetStatus(FCSPI_Type *pFCSPI) +{ + return pFCSPI->STATUS; +} + +/** + * @brief Clear FCSPI STATUS register for certain function. + * + * @param pFCSPI FCSPI instance, e.g. FCSPI0, FCSPI1. + * @param u32Value the value write to the register. + */ +LOCAL_INLINE void FCSPI_HWA_ClearStatus(FCSPI_Type *pFCSPI, uint32_t u32Value) +{ + pFCSPI->STATUS = u32Value; +} + +/** + * @brief Get FCSPI INT_EN register value for checking which interrupt is enabled. + * + * @param pFCSPI FCSPI instance, e.g. FCSPI0, FCSPI1. + * @return FCSPI INT_EN regsiter value will be returned. + */ +LOCAL_INLINE uint32_t FCSPI_HWA_GetIntrruptEnableReg(FCSPI_Type *pFCSPI) +{ + return pFCSPI->INT_EN; +} + +/** + * @brief Set the FCSPI INT_EN register value for enable or disable some interrupts. + * + * @param pFCSPI FCSPI instance, e.g. FCSPI0, FCSPI1. + * @param u32Value the value write to the register. + */ +LOCAL_INLINE void FCSPI_HWA_SetInterruptEnableReg(FCSPI_Type *pFCSPI, uint32_t u32Value) +{ + pFCSPI->INT_EN = u32Value; +} + +/** + * @brief Getting the DMA enabled status through the regsiter FCSPI DMA_EN value. + * + * @param pFCSPI FCSPI instance, e.g. FCSPI0, FCSPI1. + * @return FCSPI DMA_EN regsiter value + */ +LOCAL_INLINE uint32_t FCSPI_HWA_GetDMAEnableReg(FCSPI_Type *pFCSPI) +{ + return pFCSPI->DMA_EN; +} + +/** + * @brief Enable or disable the DMA feature by setting the FCSPI DMA_EN register value. + * + * @param pFCSPI FCSPI instance, e.g. FCSPI0, FCSPI1. + * @param u32Value the value write to the register. + */ +LOCAL_INLINE void FCSPI_HWA_SetDMAEnableReg(FCSPI_Type *pFCSPI, uint32_t u32Value) +{ + pFCSPI->DMA_EN = u32Value; +} + +/** + * @brief Get FCSPI CFG0 register value. + * + * @param pFCSPI FCSPI instance, e.g. FCSPI0, FCSPI1. + * @return FCSPI CFG0 regsiter value + */ +LOCAL_INLINE uint32_t FCSPI_HWA_GetCFG0Reg(FCSPI_Type *pFCSPI) +{ + return pFCSPI->CFG0; +} + +/** + * @brief Set FCSPI CFG0 register value. + * + * @param pFCSPI FCSPI instance, e.g. FCSPI0, FCSPI1. + * @param u32Value the value write to the register. + */ +LOCAL_INLINE void FCSPI_HWA_SetCFG0Reg(FCSPI_Type *pFCSPI, uint32_t u32Value) +{ + pFCSPI->CFG0 = u32Value; +} + +/** + * @brief Get FCSPI CFG1 register value. + * + * @param pFCSPI FCSPI instance, e.g. FCSPI0, FCSPI1. + * @return FCSPI CFG1 regsiter value + */ +LOCAL_INLINE uint32_t FCSPI_HWA_GetCFG1Reg(FCSPI_Type *pFCSPI) +{ + return pFCSPI->CFG1; +} + +/** + * @brief Set FCSPI CFG1 register value. + * + * @param pFCSPI FCSPI instance, e.g. FCSPI0, FCSPI1. + * @param u32Value the value write to the register. + */ +LOCAL_INLINE void FCSPI_HWA_SetCFG1Reg(FCSPI_Type *pFCSPI, uint32_t u32Value) +{ + pFCSPI->CFG1 = u32Value; +} + +/** + * @brief Set the FCSPI to master mode. + * + * @param pFCSPI FCSPI instance, e.g. FCSPI0, FCSPI1. + */ +LOCAL_INLINE void FCSPI_HWA_SetMasterMode(FCSPI_Type *pFCSPI) +{ + pFCSPI->CFG1 |= FCSPI_CFG1_MASTER(1); +} + +/** + * @brief Set FCSPI to slave mode. + * + * @param pFCSPI FCSPI instance, e.g. FCSPI0, FCSPI1. + */ +LOCAL_INLINE void FCSPI_HWA_SetSlaveMode(FCSPI_Type *pFCSPI) +{ + pFCSPI->CFG1 &= (~(FCSPI_CFG1_MASTER_MASK)); +} + +/** + * @brief Check the current mode status, master or slave. + * + * @param pFCSPI FCSPI instance, e.g. FCSPI0, FCSPI1. + * @return the mode type of FCSPI, FCSPI_MODE_MASTER or FCSPI_MODE_SLAVE + */ +LOCAL_INLINE FCSPI_MasterSlaveModeType FCSPI_HWA_CheckMode(FCSPI_Type *pFCSPI) +{ + FCSPI_MasterSlaveModeType eRet = FCSPI_MODE_SLAVE; + + if ((pFCSPI->CFG1 & FCSPI_CFG1_MASTER_MASK) == FCSPI_CFG1_MASTER(1)) + { + eRet = FCSPI_MODE_MASTER; + } + + return eRet; +} + +/** + * @brief Get FCSPI MATCH0 register value. + * + * @param pFCSPI FCSPI instance, e.g. FCSPI0, FCSPI1. + * @return FCSPI MATCH0 regsiter value + */ +LOCAL_INLINE uint32_t FCSPI_HWA_GetMatch0Value(FCSPI_Type *pFCSPI) +{ + return pFCSPI->DATA_MATCH0; +} + +/** + * @brief Set FCSPI MATCH0 register value. + * + * @param pFCSPI FCSPI instance, e.g. FCSPI0, FCSPI1. + * @param u32Value the value write to the register. + */ +LOCAL_INLINE void FCSPI_HWA_SetMatch0Value(FCSPI_Type *pFCSPI, uint32_t u32Value) +{ + pFCSPI->DATA_MATCH0 = u32Value; +} + +/** + * @brief Get FCSPI MATCH1 register value. + * + * @param pFCSPI FCSPI instance, e.g. FCSPI0, FCSPI1. + * @return FCSPI MATCH1 regsiter value + */ +LOCAL_INLINE uint32_t FCSPI_HWA_GetMatch1Value(FCSPI_Type *pFCSPI) +{ + return pFCSPI->DATA_MATCH1; +} + +/** + * @brief Set FCSPI MATCH1 register value. + * + * @param pFCSPI FCSPI instance, e.g. FCSPI0, FCSPI1. + * @param u32Value the value write to the register. + */ +LOCAL_INLINE void FCSPI_HWA_SetMatch1Value(FCSPI_Type *pFCSPI, uint32_t u32Value) +{ + pFCSPI->DATA_MATCH1 = u32Value; +} + +/** + * @brief Get FCSPI CLK_CFG register value. + * + * @param pFCSPI FCSPI instance, e.g. FCSPI0, FCSPI1. + * @return FCSPI CLK_CFG regsiter value + */ +LOCAL_INLINE uint32_t FCSPI_HWA_GetClockConfig(FCSPI_Type *pFCSPI) +{ + return pFCSPI->CLK_CFG; +} + +/** + * @brief Set FCSPI CLK_CFG register value. + * + * @param pFCSPI FCSPI instance, e.g. FCSPI0, FCSPI1. + * @param u32Value the value write to the register. + */ +LOCAL_INLINE void FCSPI_HWA_SetClockConfig(FCSPI_Type *pFCSPI, uint32_t u32Value) +{ + pFCSPI->CLK_CFG = u32Value; +} + +/** + * @brief Get FCSPI FIFO_WTM register value. + * + * @param pFCSPI FCSPI instance, e.g. FCSPI0, FCSPI1. + * @return FCSPI FIFO_WTM regsiter value + */ +LOCAL_INLINE uint32_t FCSPI_HWA_GetFIFOWaterMark(FCSPI_Type *pFCSPI) +{ + return pFCSPI->FIFO_WTM; +} + +/** + * @brief Set FCSPI FIFO_WTM register value. + * + * @param pFCSPI FCSPI instance, e.g. FCSPI0, FCSPI1. + * @param u8RxWatermark the rx water mark value. + * @param u8TxWatermark the tx water mark value. + */ +LOCAL_INLINE void FCSPI_HWA_SetWatermark(FCSPI_Type *pFCSPI, uint8_t u8RxWatermark, uint8_t u8TxWatermark) +{ + uint32_t u32Flag = 0U; + + u32Flag |= ((uint32_t)u8RxWatermark << FCSPI_FIFO_WTM_RXWATER_SHIFT); + u32Flag |= ((uint32_t)u8TxWatermark << FCSPI_FIFO_WTM_TXWATER_SHIFT); + + pFCSPI->FIFO_WTM = u32Flag; +} + +/** + * @brief Get FCSPI RX FIFO count. + * + * @param pFCSPI FCSPI instance, e.g. FCSPI0, FCSPI1. + * @return the real count value of rx fifo. + */ +LOCAL_INLINE uint8_t FCSPI_HWA_GetRxFifoStoredCount(FCSPI_Type *pFCSPI) +{ + return (uint8_t)(((pFCSPI->FIFO_STATUS) & FCSPI_FIFO_STATUS_RXCNT_MASK) >> FCSPI_FIFO_STATUS_RXCNT_SHIFT); +} + +/** + * @brief Get FCSPI TX FIFO count value. + * + * @param pFCSPI FCSPI instance, e.g. FCSPI0, FCSPI1. + * @return the real count of tx fifo. + */ +LOCAL_INLINE uint8_t FCSPI_HWA_GetTxFifoStoredCount(FCSPI_Type *pFCSPI) +{ + return (uint8_t)(((pFCSPI->FIFO_STATUS) & FCSPI_FIFO_STATUS_TXCNT_MASK) >> FCSPI_FIFO_STATUS_TXCNT_SHIFT); +} + +/** + * @brief Get FCSPI TR_CTRL register value. + * + * @param pFCSPI FCSPI instance, e.g. FCSPI0, FCSPI1. + * @return FCSPI TR_CTRL regsiter value + */ +LOCAL_INLINE uint32_t FCSPI_HWA_GetTxRxControl(FCSPI_Type *pFCSPI) +{ + return pFCSPI->TR_CTRL; +} + +/** + * @brief Set FCSPI TR_CTRL register value. + * + * @param pFCSPI FCSPI instance, e.g. FCSPI0, FCSPI1. + * @param u32Value the value write to the register. + */ +LOCAL_INLINE void FCSPI_HWA_SetTxRxControl(FCSPI_Type *pFCSPI, uint32_t u32Value) +{ + pFCSPI->TR_CTRL = u32Value; +} + +/** + * @brief Set RX enable status in register FCSPI TR_CTRL. + * + * @param pFCSPI FCSPI instance, e.g. FCSPI0, FCSPI1. + * @param eEnable FCSPI_TRUE for enabled, FCSPI_FALSE for disable. + */ +LOCAL_INLINE void FCSPI_HWA_EnableRxDataMask(FCSPI_Type *pFCSPI, FCSPI_AtomicBoolType eEnable) +{ + if (FCSPI_FALSE == eEnable) + { + pFCSPI->TR_CTRL |= FCSPI_TR_CTRL_RX_MSK_MASK; + } + else + { + pFCSPI->TR_CTRL &= (~(FCSPI_TR_CTRL_RX_MSK_MASK)); + } +} + +/** + * @brief Set TX enable status in register FCSPI TR_CTRL. + * + * @param pFCSPI FCSPI instance, e.g. FCSPI0, FCSPI1. + * @param eEnable FCSPI_TRUE for enabled, FCSPI_FALSE for disable. + */ +LOCAL_INLINE void FCSPI_HWA_EnableTxDataMask(FCSPI_Type *pFCSPI, FCSPI_AtomicBoolType eEnable) +{ + if (FCSPI_FALSE == eEnable) + { + pFCSPI->TR_CTRL |= FCSPI_TR_CTRL_TX_MSK_MASK; + } + else + { + pFCSPI->TR_CTRL &= (~(FCSPI_TR_CTRL_TX_MSK_MASK)); + } +} + +/** + * @brief Set FCSPI TX_DATA register value. + * + * @param pFCSPI FCSPI instance, e.g. FCSPI0, FCSPI1. + * @param u32Value the value write to the register. + */ +LOCAL_INLINE void FCSPI_HWA_WriteData(FCSPI_Type *pFCSPI, uint32_t u32Value) +{ + pFCSPI->TX_DATA = u32Value; +} + +/** + * @brief Get the address of FCSPI TX_DATA register,return value is the pointer address of TX_DATA. + * + * @param pFCSPI FCSPI instance,e.g. FCSPI0, FCSPI1. + * @return FCSPI TX_DATA address. + */ +LOCAL_INLINE uint32_t volatile *FCSPI_HWA_GetTxDataAddr(FCSPI_Type *pFCSPI) +{ + return (uint32_t volatile *)&(pFCSPI->TX_DATA); +} + +/** + * @brief Read FCSPI RX_STATUS register value. + * + * @param pFCSPI FCSPI instance, e.g. FCSPI0, FCSPI1. + * @return FCSPI RX_STATUS regsiter value + */ +LOCAL_INLINE uint32_t FCSPI_HWA_GetRxStatus(FCSPI_Type *pFCSPI) +{ + return pFCSPI->RX_STATUS; +} + +/** + * @brief Read FCSPI RX_DATA register value. + * + * @param pFCSPI FCSPI instance, e.g. FCSPI0, FCSPI1. + * @return FCSPI RX_DATA regsiter value + */ +LOCAL_INLINE uint32_t FCSPI_HWA_ReadData(FCSPI_Type *pFCSPI) +{ + return pFCSPI->RX_DATA; +} + +/** + * @brief Get the address of FCSPI RX_DATA register,return value is the pointer address of RX_DATA. + * + * @param pFCSPI FCSPI instance,e.g. FCSPI0, FCSPI1. + * @return FCSPI RX_DATA address. + */ +LOCAL_INLINE uint32_t volatile const *FCSPI_HWA_GetRxDataAddr(FCSPI_Type *pFCSPI) +{ + return &(pFCSPI->RX_DATA); +} + + +#endif /* #ifndef _HWA_FCPIT_H_ */ diff --git a/MODULES/HwA_Flagchip_FC7240/Inc/HwA_fcuart.h b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_fcuart.h new file mode 100644 index 0000000..1cb80a5 --- /dev/null +++ b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_fcuart.h @@ -0,0 +1,830 @@ +/** + * @file HwA_fcuart.h + * @author Flagchip + * @brief FC7xxx FCUart register API + * @version 0.1.0 + * @date 2024-01-14 + * + * @copyright Copyright (c) 2022 Flagchip Semiconductors Co., Ltd. + * + */ +/******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-01-14 Flagchip0122 N/A FC7xxx internal release version + ********************************************************************************/ + +#ifndef _HWA_FCUART_H_ +#define _HWA_FCUART_H_ + +#include "device_header.h" + + +/** + * @addtogroup HwA_fcuart + * @{ + */ + + +/********* Local typedef ************/ + +/** + * @brief UART STAT register flag + * + */ +typedef enum +{ + FCUART_STAT_LBKDIF = (int32_t)FCUART_STAT_LBKDIF_MASK, /**< FCUART_STAT_LBKDIF LIN Break Detect Interrupt Flag, w1c */ + FCUART_STAT_RPAEIF = (int32_t)FCUART_STAT_RPAEIF_MASK, /**< FCUART_STAT_RPAEIF RXD Pin Active Edge Interrupt Flag, w1c */ + FCUART_STAT_MSBF = (int32_t)FCUART_STAT_MSBF_MASK, /**< FCUART_STAT_MSBF MSB First, RW */ + FCUART_STAT_RXINV = (int32_t)FCUART_STAT_RXINV_MASK, /**< FCUART_STAT_RXINV Receive Data Inversion, RW */ + FCUART_STAT_RWUID = (int32_t)FCUART_STAT_RWUID_MASK, /**< FCUART_STAT_RWUID Receive Wake Up Idle Detect, RW */ + FCUART_STAT_BCGL = (int32_t)FCUART_STAT_BCGL_MASK, /**< FCUART_STAT_BCGL Break Character Generation Length, RW */ + FCUART_STAT_LBKDE = (int32_t)FCUART_STAT_LBKDE_MASK, /**< FCUART_STAT_LBKDE LIN Break Detection Enable, RW */ + FCUART_STAT_RAF = (int32_t)FCUART_STAT_RAF_MASK, /**< FCUART_STAT_RAF Receiver Active Flag, RO */ + FCUART_STAT_TDREF = (int32_t)FCUART_STAT_TDREF_MASK, /**< FCUART_STAT_TDREF Transmit Data Register Empty Flag, RO */ + FCUART_STAT_TCF = (int32_t)FCUART_STAT_TCF_MASK, /**< FCUART_STAT_TCF Transmission Complete Flag, RO */ + FCUART_STAT_RDRFF = (int32_t)FCUART_STAT_RDRFF_MASK, /**< FCUART_STAT_RDRFF Receive Data Register Full Flag, RO */ + FCUART_STAT_IDLEF = (int32_t)FCUART_STAT_IDLEF_MASK, /**< FCUART_STAT_IDLEF Idle Line Flag, w1c */ + FCUART_STAT_RORF = (int32_t)FCUART_STAT_RORF_MASK, /**< FCUART_STAT_RORF Receiver Overrun Flag, w1c */ + FCUART_STAT_NF = (int32_t)FCUART_STAT_NF_MASK, /**< FCUART_STAT_NF Noise Flag, w1c */ + FCUART_STAT_FEF = (int32_t)FCUART_STAT_FEF_MASK, /**< FCUART_STAT_FEF Frame Error Flag, w1c */ + FCUART_STAT_PEF = (int32_t)FCUART_STAT_PEF_MASK, /**< FCUART_STAT_PEF Parity Error Flag, w1c */ + FCUART_STAT_M0F = (int32_t)FCUART_STAT_M0F_MASK, /**< FCUART_STAT_M0F Match address 0 Flag, w1c */ + FCUART_STAT_M1F = (int32_t)FCUART_STAT_M1F_MASK, /**< FCUART_STAT_M1F Match address 1 Flag, w1c */ + FCUART_STAT_RPEF = (int32_t)FCUART_STAT_RPEF_MASK, /**< FCUART_STAT_RPEF Receive Data Parity Error Flag, w1c */ + FCUART_STAT_TPEF = (int32_t)FCUART_STAT_TPEF_MASK /**< FCUART_STAT_TPEF Transmit Data Parity Error Flag, w1c */ +} FCUART_StatType; + +/** + * @brief UART data bit length mode + * + */ +typedef enum +{ + UART_BITMODE_8 = 0, /**< UART_BITMODE_8 */ + UART_BITMODE_9 /**< UART_BITMODE_9 */ +} FCUART_BitModeType; + +/** + * @brief UART stop bits number + * + */ +typedef enum +{ + UART_STOPBIT_NUM_1 = 0, /**< UART_STOPBIT_NUM_1 */ + UART_STOPBIT_NUM_2 /**< UART_STOPBIT_NUM_2 */ +} FCUART_StopBitNumType; + +/** + * @brief UART parity check type + * + */ +typedef enum +{ + UART_PARITY_EVEN = 0, /**< UART_PARITY_EVEN */ + UART_PARITY_ODD /**< UART_PARITY_ODD */ +} FCUART_ParityType; + + + + +/********* Local inline function ************/ +/** + * @brief Get Stat Flag + * + * @param pUart UART instance value + */ +LOCAL_INLINE void FCUART_HWA_SetSoftWareReset(FCUART_Type *pUart) +{ + pUart->RST |= FCUART_RST_RST_MASK; + pUart->RST &= ~FCUART_RST_RST_MASK; +} + +/** + * @brief Get Stat Flag + * + * @param pUart UART instance value + * @param eStatusType stat type + * @return FCUART STAT status flag + */ +LOCAL_INLINE uint32_t FCUART_HWA_GetStatus(FCUART_Type *pUart, FCUART_StatType eStatusType) +{ + return (pUart->STAT & (uint32_t)eStatusType); +} + +/** + * @brief Clear Stat Flag + * + * @param pUart UART instance value + * @param u32StatusType stat type + */ +LOCAL_INLINE void FCUART_HWA_ClearStatus(FCUART_Type *pUart, uint32_t u32StatusType) +{ + pUart->STAT |= u32StatusType; +} + +/** + * @brief Enable Interrupt + * + * @param pUart UART instance value + */ +LOCAL_INLINE void FCUART_HWA_EnableInterrupt(FCUART_Type *pUart, uint32 u32Value) +{ + pUart->CTRL |= u32Value; /* Interrupt Enable */ +} + +/** + * @brief Disable Interrupt + * + * @param pUart UART instance value + */ +LOCAL_INLINE void FCUART_HWA_DisableInterrupt(FCUART_Type *pUart, uint32 u32Value) +{ + pUart->CTRL &= ~u32Value; /* Interrupt Disable */ +} + +/** + * @brief Enable Receive Interrupt + * + * @param pUart UART instance value + */ +LOCAL_INLINE void FCUART_HWA_EnableReceiveInterrupt(FCUART_Type *pUart) +{ + pUart->CTRL |= FCUART_CTRL_RIE_MASK; /* Receive Interrupt Enable */ +} + +/** + * @brief Disable Receive Interrupt + * + * @param pUart UART instance value + */ +LOCAL_INLINE void FCUART_HWA_DisableReceiveInterrupt(FCUART_Type *pUart) +{ + pUart->CTRL &= ~FCUART_CTRL_RIE_MASK; /* Receive Interrupt Enable */ + +} + +/** + * @brief Enable Error Interrupt + * + * @param pUart UART instance value + */ +LOCAL_INLINE void FCUART_HWA_EnableErrorInterrupt(FCUART_Type *pUart) +{ + pUart->CTRL |= FCUART_CTRL_ORIE_MASK | /* Overrun Interrupt Enable */ + FCUART_CTRL_NEIE_MASK | /* Noise Error Interrupt Enable */ + FCUART_CTRL_FEIE_MASK | /* Frame Error Interrupt Enable */ + FCUART_CTRL_PEIE_MASK; /* Parity Error Interrupt Enable */ +} + +/** + * @brief Disable Error Interrupt + * + * @param pUart UART instance value + */ +LOCAL_INLINE void FCUART_HWA_DisableErrorInterrupt(FCUART_Type *pUart) +{ + pUart->CTRL &= ~(FCUART_CTRL_ORIE_MASK | /* Overrun Interrupt Enable */ + FCUART_CTRL_NEIE_MASK | /* Noise Error Interrupt Enable */ + FCUART_CTRL_FEIE_MASK | /* Frame Error Interrupt Enable */ + FCUART_CTRL_PEIE_MASK); /* Parity Error Interrupt Enable */ + +} + +/** + * @brief Set FCUART Ctrl register + * + * @param pUart UART instance value + * @param u32Value written value + */ +LOCAL_INLINE void FCUART_HWA_SetCtrl(FCUART_Type *pUart, uint32_t u32Value) +{ + pUart->CTRL = u32Value; +} + +/** + * @brief Get FCUART Ctrl register + * + * @param pUart UART instance value + * @return Register value + */ +LOCAL_INLINE uint32_t FCUART_HWA_GetCtrl(FCUART_Type *pUart) +{ + return pUart->CTRL; +} + +/** + * @brief Attach FCUART Ctrl register + * + * @param pUart UART instance value + * @param u32Value written value + */ +LOCAL_INLINE void FCUART_HWA_AttachCtrl(FCUART_Type *pUart, uint32_t u32Value) +{ + pUart->CTRL |= u32Value; +} + +/** + * @brief Set FCUART Baud register + * + * @param pUart UART instance value + * @param u32Value written value + */ +LOCAL_INLINE void FCUART_HWA_SetBaud(FCUART_Type *pUart, uint32_t u32Value) +{ + pUart->BAUD = u32Value; +} + +/** + * @brief Get FCUART baud register + * + * @param pUart UART instance value + * @return Register value + */ +LOCAL_INLINE uint32_t FCUART_HWA_GetBaud(FCUART_Type *pUart) +{ + return pUart->BAUD; +} + +/** + * @brief Attach FCUART Baud register + * + * @param pUart UART instance value + * @param u32Value written value + */ +LOCAL_INLINE void FCUART_HWA_AttachBaud(FCUART_Type *pUart, uint32_t u32Value) +{ + pUart->BAUD |= u32Value; +} + +/** + * @brief Set FCUART Fifo register + * + * @param pUart UART instance value + * @param u32Value written value + */ +LOCAL_INLINE void FCUART_HWA_SetFifo(FCUART_Type *pUart, uint32_t u32Value) +{ + pUart->FIFO = u32Value; +} + +/** + * @brief Get FCUART fifo register + * + * @param pUart UART instance value + * @return Register value + */ +LOCAL_INLINE uint32_t FCUART_HWA_GetFifo(FCUART_Type *pUart) +{ + return pUart->FIFO; +} + +/** + * @brief Get FCUART fifo register + * + * @param pUart UART instance value + * @return Register value + */ +LOCAL_INLINE bool FCUART_HWA_GetEnStatusRxFifo(FCUART_Type *pUart) +{ + return ((((pUart->FIFO & FCUART_FIFO_RXFEN_MASK) >> FCUART_FIFO_RXFEN_SHIFT) == 1U) ? true: false); +} + +/** + * @brief Get FCUART fifo register + * + * @param pUart UART instance value + * @return Register value + */ +LOCAL_INLINE bool FCUART_HWA_GetEnStatusTxFifo(FCUART_Type *pUart) +{ + return ((((pUart->FIFO & FCUART_FIFO_TXFEN_MASK) >> FCUART_FIFO_TXFEN_SHIFT) == 1U) ? true: false); +} + +/** + * @brief Attach FCUART Fifo register + * + * @param pUart UART instance value + * @param u32Value written value + */ +LOCAL_INLINE void FCUART_HWA_AttachFifo(FCUART_Type *pUart, uint32_t u32Value) +{ + pUart->FIFO |= u32Value; +} + +/** + * @brief Set FCUART WaterMark register + * + * @param pUart UART instance value + * @param u32Value written value + */ +LOCAL_INLINE void FCUART_HWA_SetWaterMark(FCUART_Type *pUart, uint32_t u32Value) +{ + pUart->WATERMARK = u32Value; +} + +/** + * @brief Get FCUART Rx WaterMark + * + * @param pUart UART instance value + * @return Rxcount value + */ +LOCAL_INLINE uint8_t FCUART_HWA_GetRxWaterMark(FCUART_Type *pUart) +{ + return ((uint8_t)(((pUart->WATERMARK) & FCUART_WATERMARK_RXWATER_MASK) >> FCUART_WATERMARK_RXWATER_SHIFT)); +} + +/** + * @brief Get FCUART Tx WaterMark + * + * @param pUart UART instance value + * @return Rxcount value + */ +LOCAL_INLINE uint8_t FCUART_HWA_GetTxWaterMark(FCUART_Type *pUart) +{ + return ((uint8_t)(((pUart->WATERMARK) & FCUART_WATERMARK_TXWATER_MASK) >> FCUART_WATERMARK_TXWATER_SHIFT)); +} + +/** + * @brief Get FCUART WaterMark Rxcount + * + * @param pUart UART instance value + * @return Rxcount value + */ +LOCAL_INLINE uint8_t FCUART_HWA_GetFifoRxCount(FCUART_Type *pUart) +{ + return ((uint8_t)(((pUart->WATERMARK) & FCUART_WATERMARK_RXCOUNT_MASK) >> FCUART_WATERMARK_RXCOUNT_SHIFT)); +} + +/** + * @brief Get FCUART WaterMark Txcount + * + * @param pUart UART instance value + * @return Rxcount value + */ +LOCAL_INLINE uint8_t FCUART_HWA_GetFifoTxCount(FCUART_Type *pUart) +{ + return ((uint8_t)(((pUart->WATERMARK) & FCUART_WATERMARK_TXCOUNT_MASK) >> FCUART_WATERMARK_TXCOUNT_SHIFT)); +} + +/** + * @brief Attach FCUART WaterMark register + * + * @param pUart UART instance value + * @param u32Value written value + */ +LOCAL_INLINE void FCUART_HWA_AttachWaterMark(FCUART_Type *pUart, uint32_t u32Value) +{ + pUart->WATERMARK |= u32Value; +} + +/** + * @brief Set FCUART Match register + * + * @param pUart UART instance value + * @param u32Value written value + */ +LOCAL_INLINE void FCUART_HWA_SetMatch(FCUART_Type *pUart, uint32_t u32Value) +{ + pUart->MATCH = u32Value; +} + +/** + * @brief Attach FCUART Match register + * + * @param pUart UART instance value + * @param u32Value written value + */ +LOCAL_INLINE void FCUART_HWA_AttachMatch(FCUART_Type *pUart, uint32_t u32Value) +{ + pUart->MATCH |= u32Value; +} + +/** + * @brief Get FCUART Match register + * + * @param pUart UART instance value + * @return Register value + */ +LOCAL_INLINE uint32_t FCUART_HWA_GetMatch(FCUART_Type *pUart) +{ + return pUart->MATCH; +} + +/** + * @brief Read FCUART STAT register + * + * @param pUart UART instance value + * @return STAT read value + */ +LOCAL_INLINE uint32_t FCUART_HWA_GetSTAT(FCUART_Type *pUart) +{ + return pUart->STAT; +} + +/** + * @brief Write 1 Clear FCUART STAT register + * + * @param pUart UART instance value + * @param u32Value written value + */ +LOCAL_INLINE void FCUART_HWA_WriteClearSTAT(FCUART_Type *pUart, uint32_t u32Value) +{ + pUart->STAT |= u32Value; +} + +/** + * @brief Set Bit Mode and Parity + * + * @param pUart UART instance value + * @param eBitMode is bit mode, 8 or 9 bits + */ +LOCAL_INLINE void FCUART_HWA_SetBitMode(FCUART_Type *pUart, FCUART_BitModeType eBitMode) +{ + uint32_t u32RegVal = pUart->CTRL; + pUart->CTRL = ((u32RegVal & (~ FCUART_CTRL_BMSEL_MASK)) | FCUART_CTRL_BMSEL(eBitMode)); +} + +/** + * @brief Set Bit Mode and Parity + * + * @param pUart UART instance value + * @param bParityEnable If enable Parity, set 1U, or set 0U + * @param eParityType Parity type, odd-even + */ +LOCAL_INLINE void FCUART_HWA_SetParity(FCUART_Type *pUart, FCUART_ParityType eParityType, bool bParityEnable) +{ + uint32_t u32RegVal = pUart->CTRL; + pUart->CTRL = ((u32RegVal & (~ FCUART_CTRL_PE_MASK | FCUART_CTRL_PT_MASK)) | + FCUART_CTRL_PE(bParityEnable) | + FCUART_CTRL_PT(eParityType) ); +} + +/** + * @brief Set Bit Mode and Parity + * + * @param pUart UART instance value + * @param eStopBit stop bits number 1 or 2 bits + */ +LOCAL_INLINE void FCUART_HWA_SetStopBit(FCUART_Type *pUart, FCUART_StopBitNumType eStopBit) +{ + uint32_t u32RegVal = pUart->BAUD; + pUart->BAUD = ((u32RegVal & (~ FCUART_BAUD_SBNS_MASK)) | FCUART_BAUD_SBNS(eStopBit)); +} + +/** + * @brief Enable Receive DMA + * + * @param pUart UART instance value + */ +LOCAL_INLINE void FCUART_HWA_EnableReceiveDMA(FCUART_Type *pUart) +{ + pUart->BAUD |= FCUART_BAUD_RDMAEN_MASK; +} + +/** + * @brief Disable Receive DMA + * + * @param pUart UART instance value + */ +LOCAL_INLINE void FCUART_HWA_DisableReceiveDMA(FCUART_Type *pUart) +{ + pUart->BAUD &= ~FCUART_BAUD_RDMAEN_MASK; + +} + +/** + * @brief Enable Receive FIFO + * + * @param pUart UART instance value + */ +LOCAL_INLINE void FCUART_HWA_EnableReceiveFIFO(FCUART_Type *pUart) +{ + pUart->FIFO |= FCUART_FIFO_RXFEN_MASK; +} + +/** + * @brief Disable Receive FIFO + * + * @param pUart UART instance value + */ +LOCAL_INLINE void FCUART_HWA_DisableReceiveFIFO(FCUART_Type *pUart) +{ + pUart->FIFO &= ~FCUART_FIFO_RXFEN_MASK; + +} + +/** + * @brief Clear Fifo Overflow/Underflow flag + * + * @param pUart UART instance value + */ +LOCAL_INLINE void FCUART_HWA_ClearFIFOErrorFlag(FCUART_Type *pUart) +{ + pUart->FIFO |= FCUART_FIFO_TXOF_MASK | FCUART_FIFO_RXUF_MASK; +} + + +/** + * @brief Set Data Value + * + * @param pUart UART instance value + * @param u32Data Set data + */ +LOCAL_INLINE void FCUART_HWA_SetData(FCUART_Type *pUart, uint32_t u32Data) +{ + pUart->DATA = u32Data; /* data 32 bit */ +} + +/** + * @brief Get Data Value + * + * @param pUart UART instance value + * @return the data value + */ +LOCAL_INLINE uint8_t FCUART_HWA_GetData(FCUART_Type *pUart) +{ + uint8_t u8Data; + + u8Data = *((volatile uint8_t *)&pUart->DATA); /* data 32 bit */ + + return u8Data; +} + +/** + * @brief Set R8T9 bit + * + * @param pUart UART instance value + * @return the data value + */ +LOCAL_INLINE void FCUART_HWA_SetR8T9(FCUART_Type *pUart, uint8_t u8Data) +{ + uint32_t u32RegVal = pUart->CTRL; + pUart->CTRL = ((u32RegVal & (~ FCUART_CTRL_R8T9_MASK)) | FCUART_CTRL_R8T9(u8Data)); +} + +/** + * @brief Get R8T9 bit + * + * @param pUart UART instance value + * @return the data value + */ +LOCAL_INLINE uint8_t FCUART_HWA_GetR8T9(FCUART_Type *pUart) +{ + return (uint8_t)((pUart->CTRL & FCUART_CTRL_R8T9_MASK) >> FCUART_CTRL_R8T9_SHIFT); +} + +/** + * @brief Set R9T8 bit + * + * @param pUart UART instance value + * @return the data value + */ +LOCAL_INLINE void FCUART_HWA_SetR9T8(FCUART_Type *pUart, uint8_t u8Data) +{ + uint32_t u32RegVal = pUart->CTRL; + pUart->CTRL = ((u32RegVal & (~ FCUART_CTRL_R9T8_MASK)) | FCUART_CTRL_R9T8(u8Data)); +} + +/** + * @brief Get R9T8 bit + * + * @param pUart UART instance value + * @return the data value + */ +LOCAL_INLINE uint8_t FCUART_HWA_GetR9T8(FCUART_Type *pUart) +{ + return (uint8_t)((pUart->CTRL & FCUART_CTRL_R9T8_MASK) >> FCUART_CTRL_R9T8_SHIFT); +} + +/** + * @brief Reset the instance by software. + * + * @param pUart UART instance value + */ +LOCAL_INLINE void FCUART_HWA_SoftwareReset(FCUART_Type *pUart) +{ + pUart->RST |= FCUART_RST_RST_MASK; + pUart->RST &= ~FCUART_RST_RST_MASK; +} + +/** + * @brief Set fcuart TX Transfer enable or disable. + * + * @param pUart UART instance value + * @param bEnable Enable cmd, false for disable, true for enable. + */ +LOCAL_INLINE void FCUART_HWA_SetTxTransfer(FCUART_Type *pUart, bool bEnable) +{ + if (true == bEnable) + { + pUart->CTRL |= FCUART_CTRL_TE_MASK; + } + else + { + pUart->CTRL &= ~FCUART_CTRL_TE_MASK; + } +} + +/** + * @brief Set fcuart RX Transfer enable or disable. + * + * @param pUart UART instance value + * @param bEnable Enable cmd, false for disable, true for enable. + */ +LOCAL_INLINE void FCUART_HWA_SetRxTransfer(FCUART_Type *pUart, bool bEnable) +{ + if (true == bEnable) + { + pUart->CTRL |= FCUART_CTRL_RE_MASK; + } + else + { + pUart->CTRL &= ~FCUART_CTRL_RE_MASK; + } +} + +/** + * @brief Set lin break detect interrupt. + * + * @param pUart UART instance value + * @param bEnable Enable cmd, false for disable, true for enable. + */ +LOCAL_INLINE void FCUART_HWA_SetLinBreakDetectInterrupt(FCUART_Type *pUart, bool bEnable) +{ + if (true == bEnable) + { + pUart->BAUD |= FCUART_BAUD_LBKDIE_MASK; + } + else + { + pUart->BAUD &= ~FCUART_BAUD_LBKDIE_MASK; + } +} + +/** + * @brief Set lin break detect feature enable. + * + * @param pUart UART instance value + * @param bEnable Enable cmd, false for disable, true for enable. + */ +LOCAL_INLINE void FCUART_HWA_SetLinBreakDetectEnable(FCUART_Type *pUart, bool bEnable) +{ + if (true == bEnable) + { + pUart->STAT |= (FCUART_STAT_LBKDE_MASK | FCUART_STAT_BCGL_MASK); + } + else + { + pUart->STAT &= ~(FCUART_STAT_LBKDE_MASK | FCUART_STAT_BCGL_MASK); + } +} + +/** + * @brief Send a lin break field. + * + * @param pUart UART instance value + */ +LOCAL_INLINE void FCUART_HWA_SendBreakField(FCUART_Type *pUart) +{ + pUart->DATA |= FCUART_DATA_FETSC_MASK; +} + +/** + * @brief Set uart receive active interrupt. + * + * @param pUart UART instance value + * @param bEnable Enable cmd, false for disable, true for enable. + */ +LOCAL_INLINE void FCUART_HWA_SetReceiveActiveInterrupt(FCUART_Type *pUart, bool bEnable) +{ + if (true == bEnable) + { + pUart->BAUD |= FCUART_BAUD_RIAEIE_MASK; + } + else + { + pUart->BAUD &= ~FCUART_BAUD_RIAEIE_MASK; + } +} + +/** + * @brief Set uart receive active interrupt. + * + * @param pUart UART instance value + * @param return false for disable, true for enable. + */ +LOCAL_INLINE bool FCUART_HWA_GetReceiveActiveInterrupt(FCUART_Type *pUart) +{ + bool bRetVal = false; + + if (0U != (pUart->BAUD & FCUART_BAUD_RIAEIE_MASK)) + { + bRetVal = true; + } + + return bRetVal; +} + +/** + * @brief Set FCUART inverse feature. + * + * @param pUart UART instance value + * @param bEnable false for disable, true for enable. + */ +LOCAL_INLINE void FCUART_HWA_SetReceiveDataInverse(FCUART_Type *pUart, bool bEnable) +{ + if (true == bEnable) + { + pUart->STAT |= FCUART_STAT_RXINV_MASK; + } + else + { + pUart->STAT &= ~FCUART_STAT_RXINV_MASK; + } +} + +/** + * @brief Get the FCUART inverse bit value. + * + * @param pUart UART instance value + * @param return false for disable, true for enable. + */ +LOCAL_INLINE bool FCUART_HWA_GetReceiveDataInverse(FCUART_Type *pUart) +{ + bool bRetVal = false; + + if (0U != (pUart->STAT & FCUART_STAT_RXINV_MASK)) + { + bRetVal = true; + } + + return bRetVal; +} + +/** + * @brief Set the FCUART frame error interrupt. + * + * @param pUart UART instance value + * @param bEnable false for disable, true for enable. + */ +LOCAL_INLINE void FCUART_HWA_SetFrameErrorInterrupt(FCUART_Type *pUart, bool bEnable) +{ + if (true == bEnable) + { + pUart->CTRL |= FCUART_CTRL_FEIE_MASK; + } + else + { + pUart->CTRL &= ~FCUART_CTRL_FEIE_MASK; + } +} + +/** + * @brief Enable the FCUART loop mode. + * + * @param pUart UART instance value + */ +LOCAL_INLINE void FCUART_HWA_EnableLoopMode(FCUART_Type *pUart) +{ + pUart->CTRL |= FCUART_CTRL_LOOPMS_MASK; +} + +/** + * @brief Disable the FCUART loop mode. + * + * @param pUart UART instance value + */ +LOCAL_INLINE void FCUART_HWA_DisableLoopMode(FCUART_Type *pUart) +{ + pUart->CTRL &= ~FCUART_CTRL_LOOPMS_MASK; +} + +/** + * \brief Set FCUART MODIR value + * + * \param pUart UART instance value + * \param u32Data Set data + */ +LOCAL_INLINE void FCUART_HWA_SetModir(FCUART_Type *pUart, uint32_t u32Data) +{ + pUart->MODIR = u32Data; /* data 32 bit */ +} + +/** + * \brief Get FCUART MODIR value + * + * \param pUart UART instance value + * \param u32Data Get data + */ +LOCAL_INLINE uint32_t FCUART_HWA_GetModir(FCUART_Type *pUart) +{ + return pUart->MODIR ; +} + +/** @}*/ + +#endif /* end for #ifndef _HWA_FCUART_H_ */ diff --git a/MODULES/HwA_Flagchip_FC7240/Inc/HwA_flexcan.h b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_flexcan.h new file mode 100644 index 0000000..0a3d69b --- /dev/null +++ b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_flexcan.h @@ -0,0 +1,1001 @@ +/** + * @file fc7xxx_driver_flexcan.h + * @author Flagchip + * @brief FC7xxx FlexCAN register API + * @version 0.1.0 + * @date 2024-1-13 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + */ + +/* ******************************************************************************** + * Revision History: + * + * Version Date Author Descriptions + * --------- ---------- ------------ --------------- + * 0.1.0 2024-1-13 Flagchip0112 First version for FC7240 + ******************************************************************************** */ + +#ifndef _HWA_FLEXCAN_H_ +#define _HWA_FLEXCAN_H_ + +#include "device_header.h" + + + + + +/* ################################################################################## */ +/* ####################################### Macro #################################### */ + +/* ****************************** Message Buffer Structure ************************************* */ + +/* ************************************************ 8bytes data ******************************************************* */ +/* 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 */ +/* 0x00 | EDL | BRS | ESI | | CODE | | SRR | IDE | RTR | DLC | TIME STAMP | */ +/* 0x04 | PRIO | ID (STD/EXT high 11bits) | ID (EXT low 18bits) | */ +/* 0x08 | Data Byte 0 | Data Byte 1 | Data Byte 2 | Data Byte 3 | */ +/* 0x0C | Data Byte 4 | Data Byte 5 | Data Byte 6 | Data Byte 7 | */ + + +/* ************************************************ 16bytes data ****************************************************** */ +/* 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 */ +/* 0x00 | EDL | BRS | ESI | | CODE | | SRR | IDE | RTR | DLC | TIME STAMP | */ +/* 0x04 | PRIO | ID (STD/EXT high 11bits) | ID (EXT low 18bits) | */ +/* 0x08 | Data Byte 0 | Data Byte 1 | Data Byte 2 | Data Byte 3 | */ +/* 0x0C | Data Byte 4 | Data Byte 5 | Data Byte 6 | Data Byte 7 | */ +/* ................................ */ +/* 0x1C | Data Byte 12 | Data Byte 13 | Data Byte 14 | Data Byte 15| */ + + +/* ************************************************ 32bytes data ****************************************************** */ +/* 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 */ +/* 0x00 | EDL | BRS | ESI | | CODE | | SRR | IDE | RTR | DLC | TIME STAMP | */ +/* 0x04 | PRIO | ID (STD/EXT high 11bits) | ID (EXT low 18bits) | */ +/* 0x08 | Data Byte 0 | Data Byte 1 | Data Byte 2 | Data Byte 3 | */ +/* 0x0C | Data Byte 4 | Data Byte 5 | Data Byte 6 | Data Byte 7 | */ +/* ................................ */ +/* 0x30 | Data Byte 28 | Data Byte 29 | Data Byte 30 | Data Byte 31| */ + + +/* ************************************************ 64bytes data ****************************************************** */ +/* 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 */ +/* 0x00 | EDL | BRS | ESI | | CODE | | SRR | IDE | RTR | DLC | TIME STAMP | */ +/* 0x04 | PRIO | ID (STD/EXT high 11bits) | ID (EXT low 18bits) | */ +/* 0x08 | Data Byte 0 | Data Byte 1 | Data Byte 2 | Data Byte 3 | */ +/* 0x0C | Data Byte 4 | Data Byte 5 | Data Byte 6 | Data Byte 7 | */ +/* ................................ */ +/* 0x44 | Data Byte 60 | Data Byte 61 | Data Byte 62 | Data Byte 63| */ + + +/** + * @addtogroup HwA_flexcan + * @{ + */ + + +/** Register address with offset */ +#define FLEXCAN_REGISTER_WITHOFFSET(reg,offset1,offset2) ((uint32_t)(reg)+(uint32_t)(offset1)+(uint32_t)(offset2)) +/** Get register value */ +#define FLEXCAN_REG32_CONTENT(reg) (*((uint32_t*)(reg))) + + + + +/** U32 value around */ +#define FLEXCAN_U32MACRO(var) ((uint32_t)(var)) +#define FLEXCAN_U32SHIFT(var,mask,shift) ((uint32_t)((((uint32_t)(var))&(mask))<<(shift))) +#define FLEXCAN_U32NOTSHIFT(mask,shift) ((uint32_t)(~(((uint32_t)(mask))<<(shift)))) + + +/* legacy message buffer */ + +/** Legacy/EnHanced Message Buffer Header */ +#define FLEXCAN_MB_HEADER_BYTELEN 8UL +/** Legacy Message Buffer Address */ +#define FLEXCAN_MB_ADDR(mbOffset, mbIndex, dataLen) FLEXCAN_U32MACRO(FLEXCAN_U32MACRO(mbOffset)+FLEXCAN_U32MACRO(mbIndex)*(FLEXCAN_U32MACRO(dataLen)+FLEXCAN_MB_HEADER_BYTELEN)) + + +/** Legacy Message Buffer word n Address */ +#define FLEXCAN_MB_WORDN_ADDR(mbOffset, mbIndex, dataLen, offset) (FLEXCAN_MB_ADDR((mbOffset), (mbIndex), (dataLen))+FLEXCAN_U32MACRO(offset)) + +/** Legacy Message Buffer Data Address */ +/* #define FLEXCAN_MB_DATA_ADDR_GET(mbOffset, mbIndex, dataLen) (FLEXCAN_MB_WORDN_ADDR((mbOffset), (mbIndex), (dataLen),2U)) */ + +/** Legacy Message Buffer EDL Get */ +#define FLEXCAN_MB_EDL_GET(edlAddr) ((FLEXCAN_REG32_CONTENT(edlAddr)>>31)&0x01U) +/** Legacy Message Buffer EDL Clear */ +#define FLEXCAN_MB_EDL_CLR(edlAddr) (FLEXCAN_REG32_CONTENT(edlAddr) &= FLEXCAN_U32NOTSHIFT(0x01U,31)) +/** Legacy Message Buffer EDL Attach */ +#define FLEXCAN_MB_EDL_ATTACH(edlAddr,var) (FLEXCAN_REG32_CONTENT(edlAddr) |= FLEXCAN_U32SHIFT(var,0x01U,31)) +/** Legacy Message Buffer EDL Set */ +#define FLEXCAN_MB_EDL_SET(edlAddr,var) FLEXCAN_MB_EDL_CLR(edlAddr); FLEXCAN_MB_EDL_ATTACH(edlAddr,var) + + +/** Legacy Message Buffer BRS Get */ +#define FLEXCAN_MB_BRS_GET(brsAddr) (((FLEXCAN_REG32_CONTENT(brsAddr))>>30)&0x01U) +/** Legacy Message Buffer BRS Clear */ +#define FLEXCAN_MB_BRS_CLR(brsAddr) (FLEXCAN_REG32_CONTENT(brsAddr) &= FLEXCAN_U32NOTSHIFT(0x01U,30)) +/** Legacy Message Buffer BRS Attach */ +#define FLEXCAN_MB_BRS_ATTACH(brsAddr,var) (FLEXCAN_REG32_CONTENT(brsAddr) |= FLEXCAN_U32SHIFT(var,0x01U,30)) +/** Legacy Message Buffer BRS set */ +#define FLEXCAN_MB_BRS_SET(brsAddr,var) FLEXCAN_MB_BRS_CLR(brsAddr); FLEXCAN_MB_BRS_ATTACH(brsAddr,var) + +/** Legacy Message Buffer ESI Get */ +#define FLEXCAN_MB_ESI_GET(esiAddr) (((FLEXCAN_REG32_CONTENT(esiAddr))>>29)&0x01U) +/** Legacy Message Buffer ESI Clear */ +#define FLEXCAN_MB_ESI_CLR(esiAddr) (FLEXCAN_REG32_CONTENT(esiAddr) &= FLEXCAN_U32NOTSHIFT(0x01U,29)) +/** Legacy Message Buffer ESI Attach */ +#define FLEXCAN_MB_ESI_ATTACH(esiAddr,var) (FLEXCAN_REG32_CONTENT(esiAddr) |= FLEXCAN_U32SHIFT(var,0x01U,29)) +/** Legacy Message Buffer ESI Set */ +#define FLEXCAN_MB_ESI_SET(esiAddr,var) FLEXCAN_MB_ESI_CLR(esiAddr); FLEXCAN_MB_ESI_ATTACH(esiAddr,var) + +/** Legacy Message Buffer CODE Get */ +#define FLEXCAN_MB_CODE_GET(codeAddr) (((FLEXCAN_REG32_CONTENT(codeAddr))>>24)&0x0FU) +/** Legacy Message Buffer CODE Clear */ +#define FLEXCAN_MB_CODE_CLR(codeAddr) (FLEXCAN_REG32_CONTENT(codeAddr) &= FLEXCAN_U32NOTSHIFT(0x0FU,24)) +/** Legacy Message Buffer CODE Attach */ +#define FLEXCAN_MB_CODE_ATTACH(codeAddr,var) (FLEXCAN_REG32_CONTENT(codeAddr) |= FLEXCAN_U32SHIFT(var,0x0FU,24)) +/** Legacy Message Buffer CODE set */ +#define FLEXCAN_MB_CODE_SET(codeAddr,var) FLEXCAN_MB_CODE_CLR(codeAddr); FLEXCAN_MB_CODE_ATTACH(codeAddr,var) + + +/** Legacy Message Buffer SRR Get */ +#define FLEXCAN_MB_SRR_GET(srrAddr) (((FLEXCAN_REG32_CONTENT(srrAddr)) >>22)&0x01U) +/** Legacy Message Buffer SRR Clear */ +#define FLEXCAN_MB_SRR_CLR(srrAddr) (FLEXCAN_REG32_CONTENT(srrAddr) &= FLEXCAN_U32NOTSHIFT(0x01U,22)) +/** Legacy Message Buffer SRR Attach */ +#define FLEXCAN_MB_SRR_ATTACH(srrAddr,var) (FLEXCAN_REG32_CONTENT(srrAddr) |= FLEXCAN_U32SHIFT(var,0x01U,22)) +/** Legacy Message Buffer SRR set */ +#define FLEXCAN_MB_SRR_SET(srrAddr,var) FLEXCAN_MB_SRR_CLR(srrAddr); FLEXCAN_MB_SRR_ATTACH(srrAddr,var) + +/** Legacy Message Buffer IDE Get */ +#define FLEXCAN_MB_IDE_GET(ideAddr) (((FLEXCAN_REG32_CONTENT(ideAddr))>>21)&0x01U) +/** Legacy Message Buffer IDE Clear */ +#define FLEXCAN_MB_IDE_CLR(ideAddr) (FLEXCAN_REG32_CONTENT(ideAddr) &= FLEXCAN_U32NOTSHIFT(0x01U,21)) +/** Legacy Message Buffer IDE Attach */ +#define FLEXCAN_MB_IDE_ATTACH(ideAddr,var) (FLEXCAN_REG32_CONTENT(ideAddr) |= FLEXCAN_U32SHIFT(var,0x01U,21)) +/** Legacy Message Buffer IDE set */ +#define FLEXCAN_MB_IDE_SET(ideAddr,var) FLEXCAN_MB_IDE_CLR(ideAddr); FLEXCAN_MB_IDE_ATTACH(ideAddr,var) + + +/** Legacy Message Buffer RTR Get */ +#define FLEXCAN_MB_RTR_GET(rtrAddr) (((FLEXCAN_REG32_CONTENT(rtrAddr))>>20)&0x01U) +/** Legacy Message Buffer RTR Clear */ +#define FLEXCAN_MB_RTR_CLR(rtrAddr) (FLEXCAN_REG32_CONTENT(rtrAddr) &= FLEXCAN_U32NOTSHIFT(0x01U,20)) +/** Legacy Message Buffer RTR Attach */ +#define FLEXCAN_MB_RTR_ATTACH(rtrAddr,var) (FLEXCAN_REG32_CONTENT(rtrAddr) |= FLEXCAN_U32SHIFT(var,0x01U,20)) +/** Legacy Message Buffer RTR set */ +#define FLEXCAN_MB_RTR_SET(rtrAddr,var) FLEXCAN_MB_RTR_CLR(rtrAddr); FLEXCAN_MB_RTR_ATTACH(rtrAddr,var) + +/** Legacy Message Buffer DLC Get */ +#define FLEXCAN_MB_DLC_GET(dlcAddr) (((FLEXCAN_REG32_CONTENT(dlcAddr))>>16)&0x0FU) +/** Legacy Message Buffer DLC Clear */ +#define FLEXCAN_MB_DLC_CLR(dlcAddr) (FLEXCAN_REG32_CONTENT(dlcAddr) &= FLEXCAN_U32NOTSHIFT(0x0FU,16)) +/** Legacy Message Buffer DLC Attach */ +#define FLEXCAN_MB_DLC_ATTACH(dlcAddr,var) (FLEXCAN_REG32_CONTENT(dlcAddr) |= FLEXCAN_U32SHIFT(var,0x0FU,16)) +/** Legacy Message Buffer DLC Set */ +#define FLEXCAN_MB_DLC_SET(dlcAddr,var) FLEXCAN_MB_DLC_CLR(dlcAddr); FLEXCAN_MB_DLC_ATTACH(dlcAddr,var) + +/** Legacy Message Buffer TIME STAMP Get */ +#define FLEXCAN_MB_TIMESTAMP_GET(timestampAddr) (FLEXCAN_REG32_CONTENT(timestampAddr)&0xFFFFU) +/** Legacy Message Buffer TIME STAMP Clear */ +#define FLEXCAN_MB_TIMESTAMP_CLR(timestampAddr) (FLEXCAN_REG32_CONTENT(timestampAddr) &= FLEXCAN_U32NOTSHIFT(0xFFFFU,0)) +/** Legacy Message Buffer TIME STAMP Attach */ +#define FLEXCAN_MB_TIMESTAMP_ATTACH(timestampAddr,var) (FLEXCAN_REG32_CONTENT(timestampAddr) |= FLEXCAN_U32SHIFT(var,0xFFFFU,0)) +/** Legacy Message Buffer TIME STAMP Set */ +#define FLEXCAN_MB_TIMESTAMP_SET(timestampAddr,var) FLEXCAN_MB_TIMESTAMP_CLR(timestampAddr); FLEXCAN_MB_TIMESTAMP_ATTACH(timestampAddr,var) + +/** Legacy Message Buffer PRIO Get */ +#define FLEXCAN_MB_PRIO_GET(prioAddr) (((FLEXCAN_REG32_CONTENT(prioAddr))>>29)&0x07U) +/** Legacy Message Buffer PRIO Clear */ +#define FLEXCAN_MB_PRIO_CLR(prioAddr) (FLEXCAN_REG32_CONTENT(prioAddr) &= FLEXCAN_U32NOTSHIFT(0x07U,29)) +/** Legacy Message Buffer PRIO Attach */ +#define FLEXCAN_MB_PRIO_ATTACH(prioAddr,var) (FLEXCAN_REG32_CONTENT(prioAddr) |= FLEXCAN_U32SHIFT(var,0x07U,29)) +/** Legacy Message Buffer PRIO Set */ +#define FLEXCAN_MB_PRIO_SET(prioAddr,var) FLEXCAN_MB_PRIO_CLR(prioAddr); FLEXCAN_MB_PRIO_ATTACH(prioAddr,var) + +/** Legacy Message Buffer STD ID Get */ +#define FLEXCAN_MB_STDID_GET(stdidAddr) (((FLEXCAN_REG32_CONTENT(stdidAddr))>>18)&0x7FFU) +/** Legacy Message Buffer STD ID CLR */ +#define FLEXCAN_MB_STDID_CLR(stdidAddr) (FLEXCAN_REG32_CONTENT(stdidAddr) &= FLEXCAN_U32NOTSHIFT(0x7FFU,18)) +/** Legacy Message Buffer STD ID Attach */ +#define FLEXCAN_MB_STDID_ATTACH(stdidAddr,var) (FLEXCAN_REG32_CONTENT(stdidAddr) |= FLEXCAN_U32SHIFT(var,0x7FFU,18)) +/** Legacy Message Buffer STD ID set */ +#define FLEXCAN_MB_STDID_SET(stdidAddr,var) FLEXCAN_MB_STDID_CLR(stdidAddr); FLEXCAN_MB_STDID_ATTACH(stdidAddr,var) + +/** Legacy Message Buffer EXT ID Get */ +#define FLEXCAN_MB_EXTID_GET(extidAddr) ((FLEXCAN_REG32_CONTENT(extidAddr))&0x1FFFFFFF) +/** Legacy Message Buffer EXT ID Clear */ +#define FLEXCAN_MB_EXTID_CLR(extidAddr) (FLEXCAN_REG32_CONTENT(extidAddr) &= FLEXCAN_U32NOTSHIFT(0x1FFFFFFF,0)) +/** Legacy Message Buffer EXT ID Attach */ +#define FLEXCAN_MB_EXTID_ATTACH(extidAddr,var) (FLEXCAN_REG32_CONTENT(extidAddr) |= FLEXCAN_U32SHIFT(var,0x1FFFFFFF,0)) +/** Legacy Message Buffer EXT ID set */ +#define FLEXCAN_MB_EXTID_SET(extidAddr,var) FLEXCAN_MB_EXTID_CLR(extidAddr); FLEXCAN_MB_EXTID_ATTACH(extidAddr,var) + +/* enhanced fifo message buffer */ + +/** Enhanced FIFO Message Buffer EDL Get */ +#define FLEXCAN_EFIFOMB_EDL_GET() ((pCan->ERX_FIFO[0U]>>31)&0x01U) + +/** Enhanced FIFO Message Buffer BRS Get */ +#define FLEXCAN_EFIFOMB_BRS_GET() ((pCan->ERX_FIFO[0U]>>30)&0x01U) + +/** Enhanced FIFO Message Buffer ESI Get */ +#define FLEXCAN_EFIFOMB_ESI_GET() ((pCan->ERX_FIFO[0U]>>29)&0x01U) + +/** Enhanced FIFO Message Buffer SRR Get */ +#define FLEXCAN_EFIFOMB_SRR_GET() ((pCan->ERX_FIFO[0U] >>22)&0x01U) + +/** Enhanced FIFO Message Buffer IDE Get */ +#define FLEXCAN_EFIFOMB_IDE_GET() ((pCan->ERX_FIFO[0U]>>21)&0x01U) + +/** Enhanced FIFO Message Buffer RTR Get */ +#define FLEXCAN_EFIFOMB_RTR_GET() ((pCan->ERX_FIFO[0U]>>20)&0x01U) + +/** Enhanced FIFO Message Buffer DLC Get */ +#define FLEXCAN_EFIFOMB_DLC_GET() ((pCan->ERX_FIFO[0U]>>16)&0x0FU) + +/** Enhanced FIFO Message Buffer TIME STAMP Get */ +#define FLEXCAN_EFIFOMB_TIMESTAMP_GET() (pCan->ERX_FIFO[0U]&0xFFU) + +/** Enhanced FIFO Message Buffer STD ID Get */ +#define FLEXCAN_EFIFOMB_STDID_GET() ((pCan->ERX_FIFO[1U]>>18)&0x7FFU) + +/** Enhanced FIFO Message Buffer EXT ID Get */ +#define FLEXCAN_EFIFOMB_EXTID_GET() (pCan->ERX_FIFO[1U]&0x1FFFFFFF) + +/** Enhanced FIFO Message Buffer Data Get */ +#define FLEXCAN_EFIFOMB_DATAADDR_GET(wordIndex) (&(pCan->ERX_FIFO[2U+(wordIndex)])) + +/** Enhanced FIFO Message Buffer IDHIT Get */ +#define FLEXCAN_EFIFOMB_IDHIT_GET(dataWordLen) ((pCan->ERX_FIFO[2U+(dataWordLen)])&0x1FFU) + +/** Enhanced FIFO Message Buffer HR Time Stamp Get */ +#define FLEXCAN_EFIFOMB_HRTIMESTAMP_GET(dataWordLen) (pCan->ERX_FIFO[3U+(dataWordLen)]) + +/* enhanced fifo message buffer from user buffer*/ + +/** Enhanced FIFO Message Buffer EDL Get */ +#define FLEXCAN_EFIFOMB_EDL_GET_FROM_BUFFER(Addr) ((((uint32_t*)Addr)[0U]>>31)&0x01U) + +/** Enhanced FIFO Message Buffer BRS Get */ +#define FLEXCAN_EFIFOMB_BRS_GET_FROM_BUFFER(Addr) ((((uint32_t*)Addr)[0U]>>30)&0x01U) + +/** Enhanced FIFO Message Buffer ESI Get */ +#define FLEXCAN_EFIFOMB_ESI_GET_FROM_BUFFER(Addr) ((((uint32_t*)Addr)[0U]>>29)&0x01U) + +/** Enhanced FIFO Message Buffer SRR Get */ +#define FLEXCAN_EFIFOMB_SRR_GET_FROM_BUFFER(Addr) ((((uint32_t*)Addr)[0U] >>22)&0x01U) + +/** Enhanced FIFO Message Buffer IDE Get */ +#define FLEXCAN_EFIFOMB_IDE_GET_FROM_BUFFER(Addr) ((((uint32_t*)Addr)[0U]>>21)&0x01U) + +/** Enhanced FIFO Message Buffer RTR Get */ +#define FLEXCAN_EFIFOMB_RTR_GET_FROM_BUFFER(Addr) ((((uint32_t*)Addr)[0U]>>20)&0x01U) + +/** Enhanced FIFO Message Buffer DLC Get */ +#define FLEXCAN_EFIFOMB_DLC_GET_FROM_BUFFER(Addr) ((((uint32_t*)Addr)[0U]>>16)&0x0FU) + +/** Enhanced FIFO Message Buffer TIME STAMP Get */ +#define FLEXCAN_EFIFOMB_TIMESTAMP_GET_FROM_BUFFER(Addr) (((uint32_t*)Addr)[0U]&0xFFU) + +/** Enhanced FIFO Message Buffer STD ID Get */ +#define FLEXCAN_EFIFOMB_STDID_GET_FROM_BUFFER(Addr) ((((uint32_t*)Addr)[1U]>>18)&0x7FFU) + +/** Enhanced FIFO Message Buffer EXT ID Get */ +#define FLEXCAN_EFIFOMB_EXTID_GET_FROM_BUFFER(Addr) (((uint32_t*)Addr)[1U]&0x1FFFFFFF) + +/** Enhanced FIFO Message Buffer Data Get */ +#define FLEXCAN_EFIFOMB_DATAADDR_GET_FROM_BUFFER(Addr, wordIndex) (&(((uint32_t*)Addr)[2U+(wordIndex)])) + +/** Enhanced FIFO Message Buffer IDHIT Get */ +#define FLEXCAN_EFIFOMB_IDHIT_GET_FROM_BUFFER(Addr, dataWordLen) ((((uint32_t*)Addr)[2U+(dataWordLen)])&0x1FFU) + +/** Enhanced FIFO Message Buffer HR Time Stamp Get */ +#define FLEXCAN_EFIFOMB_HRTIMESTAMP_GET_FROM_BUFFER(Addr, dataWordLen) (((uint32_t*)Addr)[3U+(dataWordLen)]) + +/* ################################################################################## */ +/* ################################### Type define ################################## */ + +/** + * \brief FLEXCAN Clock Source Select Enumeration + * + */ +typedef enum +{ + FLEXCAN_CLOCK_FUNCTION = 0x00U,/**< FLEXCAN_CLOCK_FUNCTION clock from asynchronous clock */ + FLEXCAN_CLOCK_MODULE = 0x01U /**< FLEXCAN_CLOCK_MODULE clock from peripheral clock */ +} FLEXCAN_ClockSrcType; + + + +/* ################################################################################## */ +/* ################################## Local Inline ################################## */ + + + +/** + * \brief Set Module Disable + * + * \param pCan FLEXCAN instance value + * \param bDisable set whether disable + */ +LOCAL_INLINE void FLEXCAN_HWA_SetMcrDisable(FLEXCAN_Type *const pCan, uint8_t bDisable) +{ + if (bDisable == TRUE) + { + pCan->MCR |= FLEXCAN_MCR_MDIS_MASK; /* bitMDIS=1: Disable module before selecting clock */ + } + else + { + pCan->MCR &= ~FLEXCAN_MCR_MDIS_MASK; + } +} + +/** + * \brief Set Module Freeze + * + * \param pCan FLEXCAN instance value + * \param bFreeze set whether freeze + */ +LOCAL_INLINE void FLEXCAN_HWA_SetMcrFreeze(FLEXCAN_Type *const pCan, uint8_t bFreeze) +{ + if (bFreeze == TRUE) + { + pCan->MCR |= FLEXCAN_MCR_FRZ_MASK; /* bitMDIS=1: Disable module before selecting clock */ + } + else + { + pCan->MCR &= ~FLEXCAN_MCR_FRZ_MASK; + } +} + + +/** + * \brief Set Module Halt and Freeze + * + * \param pCan FLEXCAN instance value + * \param bFreeze set whether freeze + */ +LOCAL_INLINE void FLEXCAN_HWA_SetHaltFreeze(FLEXCAN_Type *const pCan) +{ + pCan->MCR |= FLEXCAN_MCR_FRZ_MASK | FLEXCAN_MCR_HALT_MASK; +} + +/** + * \brief Wait FLEXCAN Module Enter Freezen mode + * + * \param pCan FLEXCAN instance value + * \param u32TimeoutTick Timeout tick + * \return 0U is really in freezen mode + */ +LOCAL_INLINE uint32_t FLEXCAN_HWA_WaitMcrFreezen(FLEXCAN_Type *const pCan, uint32_t u32TimeoutTick) +{ + /* wait for bitFRZACK=1 on freeze mode entry/exit */ + while ( (!((pCan->MCR & FLEXCAN_MCR_FRZACK_MASK) >> FLEXCAN_MCR_FRZACK_SHIFT)) && (u32TimeoutTick-->0U) ) + { + + } + + return (u32TimeoutTick==0U); +} + +/** + * \brief Wait FLEXCAN Module Exit Freezen mode + * + * \param pCan FLEXCAN instance value + * \param u32TimeoutTick Timeout tick + * \return 1U is really in freezen mode + */ +LOCAL_INLINE uint32_t FLEXCAN_HWA_WaitMcrExitFreezen(FLEXCAN_Type *const pCan, uint32_t u32TimeoutTick) +{ + while ( ((pCan->MCR & FLEXCAN_MCR_FRZACK_MASK) >> FLEXCAN_MCR_FRZACK_SHIFT) && (u32TimeoutTick-->0U) ) + {} + /* wait for bitFRZACK to clear (not in freeze mode) */ + + return (u32TimeoutTick==0U); +} + +/** + * \brief Wait FLEXCAN Module Ready + * + * \param pCan FLEXCAN instance value + * \param u32TimeoutTick Timeout tick + * \return 1U is really ready + */ +LOCAL_INLINE uint32_t FLEXCAN_HWA_WaitMcrReady(FLEXCAN_Type *const pCan, uint32_t u32TimeoutTick) +{ + while ( ((pCan->MCR & FLEXCAN_MCR_NOTRDY_MASK) >> FLEXCAN_MCR_NOTRDY_SHIFT) && (u32TimeoutTick-->0U) ) + {} + /* wait for bitNOTRDY to clear (module ready) */ + + return (u32TimeoutTick==0U); +} + +/** + * \brief Wait FLEXCAN Module Not Ready + * + * \param pCan FLEXCAN instance value + * \param u32TimeoutTick Timeout tick + * \return 1U is really not ready + */ +LOCAL_INLINE uint32_t FLEXCAN_HWA_WaitMcrNoReady(FLEXCAN_Type *const pCan, uint32_t u32TimeoutTick) +{ + while ( (!((pCan->MCR & FLEXCAN_MCR_NOTRDY_MASK) >> FLEXCAN_MCR_NOTRDY_SHIFT)) && (u32TimeoutTick-->0U) ) + {} + /* wait for bitNOTRDY to set (module ready) */ + + return (u32TimeoutTick==0U); +} + +/** + * \brief Set FLEXCAN MCR value + * + * \param pCan FLEXCAN instance value + * \param u32Value write value + */ +LOCAL_INLINE void FLEXCAN_HWA_SetMCR(FLEXCAN_Type *const pCan, uint32_t u32Value) +{ + pCan->MCR = u32Value; +} + +/** + * \brief Get FLEXCAN MCR value + * + * \param pCan FLEXCAN instance value + * \return MCR value + */ +LOCAL_INLINE uint32_t FLEXCAN_HWA_GetMCR(FLEXCAN_Type *const pCan) +{ + return (uint32_t)pCan->MCR; +} + +/** + * \brief Attach FLEXCAN MCR value + * + * \param pCan FLEXCAN instance value + * \param u32Value attached value + */ +LOCAL_INLINE void FLEXCAN_HWA_AttachMCR(FLEXCAN_Type *const pCan, uint32_t u32Value) +{ + pCan->MCR |= u32Value; +} + + +/** + * \brief Set FLEXCAN baudrate clock source + * + * \param pCan FLEXCAN instance value + * \param tBaudClk Baudrate clock source + */ +LOCAL_INLINE void FLEXCAN_HWA_SetCtrl1BaudSrc(FLEXCAN_Type *const pCan, FLEXCAN_ClockSrcType tBaudClk) +{ + if (tBaudClk == FLEXCAN_CLOCK_MODULE) + { + pCan->CTRL1 |= FLEXCAN_CTRL1_CLKSRC_MASK; + } + else + { + pCan->CTRL1 &= ~FLEXCAN_CTRL1_CLKSRC_MASK; + } +} + +/** + * \brief Set FLEXCAN ctrl1 value + * + * \param pCan FLEXCAN instance value + * \param u32Value write value + */ +LOCAL_INLINE void FLEXCAN_HWA_SetCtrl1(FLEXCAN_Type *const pCan, uint32_t u32Value) +{ + pCan->CTRL1 = u32Value; +} + +/** + * \brief Attach FLEXCAN ctrl1 value + * + * \param pCan FLEXCAN instance value + * \param u32Value attached value + */ +LOCAL_INLINE void FLEXCAN_HWA_AttachCtrl1(FLEXCAN_Type *const pCan, uint32_t u32Value) +{ + pCan->CTRL1 |= u32Value; +} + + +/** + * \brief Get IFLAG1 Flag + * + * \param pCan FLEXCAN instance value + * \return flag1 value + */ +LOCAL_INLINE uint32_t FLEXCAN_HWA_GetFlag1(FLEXCAN_Type *const pCan) +{ + return pCan->IFLAG1; +} + + +/** + * \brief Clear IFLAG1 Flag + * + * \param pCan FLEXCAN instance value + * \param u32W1cFlag write clear value + */ +LOCAL_INLINE void FLEXCAN_HWA_SetFlag1(FLEXCAN_Type *const pCan, uint32_t u32W1cFlag) +{ + pCan->IFLAG1 = u32W1cFlag; +} + +/** + * \brief Clear Rx Flag and unlock MB + * + * \param pCan FLEXCAN instance value + * \param u32MbIndex Message Buffer Index + */ +LOCAL_INLINE void FLEXCAN_HWA_UnlockMbNoFifoFlag(FLEXCAN_Type *const pCan, uint32_t u32MbIndex) +{ + (void)pCan->TIMER; /* Read TIMER to unlock message buffers */ + pCan->IFLAG1 = 1U << u32MbIndex; +} + +/** + * \brief Clear MB Flag + * + * \param pCan FLEXCAN instance value + * \param u32MbIndex Message Buffer Index + */ +LOCAL_INLINE void FLEXCAN_HWA_W1cFlag1NoFifoFlag(FLEXCAN_Type *const pCan, uint32_t u32MbIndex) +{ + pCan->IFLAG1 = 1U << u32MbIndex; +} + +/** + * \brief Get MB Flag + * + * \param pCan FLEXCAN instance value + * \param u32MbIndex Message Buffer Index + * \return flag value + */ +LOCAL_INLINE uint32_t FLEXCAN_HWA_GetFlag1NoFifoFlag(FLEXCAN_Type *const pCan, uint32_t u32MbIndex) +{ + return (pCan->IFLAG1 >> u32MbIndex) & 0x01U; +} + +/** + * \brief Get Legacy Fifo Rx Flag + * + * \param pCan FLEXCAN instance value + * \return flag fifo value + */ +LOCAL_INLINE uint32_t FLEXCAN_HWA_GetIFLAG1FifoFlag(FLEXCAN_Type *const pCan) +{ + /* IFLAG1[BIT5] (Frames available in Rx FIFO) is asserted when there is at least one frame available to be read from the FIFO. */ + return (pCan->IFLAG1 >> 5) & 0x01U; +} + +/** + * \brief Clear Legacy Fifo Rx Flag + * + * \param pCan FLEXCAN instance value + */ +LOCAL_INLINE void FLEXCAN_HWA_ClearIFLAG1FifoFlag(FLEXCAN_Type *const pCan) +{ + /* Read TIMER to unlock message buffers */ + (void)pCan->TIMER; + + pCan->IFLAG1 = 1U << 5; +} + +/** + * \brief Set special message buffer interrupt + * + * \param pCan FLEXCAN instance value + * \param u32Mask Message Buffer interrupt mask value + */ +LOCAL_INLINE void FLEXCAN_HWA_SetMaskMbInterrupt(FLEXCAN_Type *const pCan, uint32_t u32Mask) +{ + pCan->IMASK1 = u32Mask; +} + +/** + * \brief Attach special message buffer interrupt + * + * \param pCan FLEXCAN instance value + * \param u32MbIndex Message Buffer index + */ +LOCAL_INLINE void FLEXCAN_HWA_AttachMaskMbInterrupt(FLEXCAN_Type *const pCan, uint32_t u32Mask) +{ + pCan->IMASK1 |= u32Mask; +} + +/** + * \brief Attach special message buffer interrupt + * + * \param pCan FLEXCAN instance value + * \param u32MbIndex Message Buffer index + */ +LOCAL_INLINE void FLEXCAN_HWA_AttachMbIndexInterrupt(FLEXCAN_Type *const pCan, uint32_t u32MbIndex) +{ + pCan->IMASK1 |= 1U << u32MbIndex; +} + +/** + * \brief Set Legacy Fifo Rx interrupt + * + * \param pCan FLEXCAN instance value + */ +LOCAL_INLINE void FLEXCAN_HWA_SetMaskFifoInterrupt(FLEXCAN_Type *const pCan) +{ + pCan->IMASK1 = 1U << 5U; +} + +/** + * \brief Set CTRL2 value + * + * \param pCan FLEXCAN instance value + * \param u32Value write value + */ +LOCAL_INLINE void FLEXCAN_HWA_SetCtrl2(FLEXCAN_Type *const pCan, uint32_t u32Value) +{ + pCan->CTRL2 = u32Value; +} + +/** + * \brief Attach FLEXCAN ctrl2 value + * + * \param pCan FLEXCAN instance value + * \param u32Value attached value + */ +LOCAL_INLINE void FLEXCAN_HWA_AttachCtrl2(FLEXCAN_Type *const pCan, uint32_t u32Value) +{ + pCan->CTRL2 |= u32Value; +} + +/** + * \brief Set CBT value + * + * \param pCan FLEXCAN instance value + * \param u32Value write value + */ +LOCAL_INLINE void FLEXCAN_HWA_SetCBT(FLEXCAN_Type *const pCan, uint32_t u32Value) +{ + pCan->CBT = u32Value; +} + +/** + * \brief Set FDCBT value + * + * \param pCan FLEXCAN instance value + * \param u32Value write value + */ +LOCAL_INLINE void FLEXCAN_HWA_SetFDCBT(FLEXCAN_Type *const pCan, uint32_t u32Value) +{ + pCan->FDCBT = u32Value; +} + +/** + * \brief Set FDCTRL value + * + * \param pCan FLEXCAN instance value + * \param u32Value write value + */ +LOCAL_INLINE void FLEXCAN_HWA_SetFDCTRL(FLEXCAN_Type *const pCan, uint32_t u32Value) +{ + pCan->FDCTRL = u32Value; +} + + +/** + * \brief This Function is used to get FLEXCAN rx timestamp + * + * \param pCan is FLEXCAN instance value + * \return timestamp Register Value + */ +LOCAL_INLINE uint32_t FLEXCAN_HWA_GetTimeStamp(FLEXCAN_Type *const pCan) +{ + return pCan->TIMER; +} + +/** + * \brief This Function is used to get FLEXCAN error + * + * \param pCan is FLEXCAN instance value + * \return ESR1 Register Value + */ +LOCAL_INLINE uint32_t FLEXCAN_HWA_GetErrorInfo(FLEXCAN_Type *const pCan) +{ + return pCan->ESR1; +} + +/** + * \brief This Function is used to get FLEXCAN error with interrupt + * + * \param pCan is FLEXCAN instance value + * \return ESR1 Register Value with interrupt mask + */ +LOCAL_INLINE uint32_t FLEXCAN_HWA_GetErrorIntInfo(FLEXCAN_Type *const pCan) +{ + uint32_t u32IntMask = 0U; + + u32IntMask = ((0U == (pCan->CTRL1 & FLEXCAN_CTRL1_ERRMSK_MASK))?0U:FLEXCAN_ESR1_ERRINT_MASK); + u32IntMask |= ((0U == (pCan->CTRL1 & FLEXCAN_CTRL1_BOFFMSK_MASK))?0U:FLEXCAN_ESR1_BOFFINT_MASK); + u32IntMask |= ((0U == (pCan->CTRL2 & FLEXCAN_CTRL2_ERRMSK_FAST_MASK))?0U:FLEXCAN_ESR1_ERRINT_FAST_MASK); + u32IntMask |= ((0U == (pCan->CTRL2 & FLEXCAN_CTRL2_BOFFDONEMSK_MASK))?0U:FLEXCAN_ESR1_BOFFDONEINT_MASK); + + return (pCan->ESR1 & u32IntMask); +} + +/** + * \brief Clear Error Info + * + * \param pCan FLEXCAN instance value + * \param u32ErrorEsr1 is read from FLEXCAN_GetErrorInfo + */ +LOCAL_INLINE void FLEXCAN_HWA_ClrErrorInfo(FLEXCAN_Type *const pCan, uint32_t u32ErrorEsr1) +{ + pCan->ESR1 = u32ErrorEsr1; +} + +/** + * \brief This Function is used to get FLEXCAN error count + * + * \param pCan is FLEXCAN instance value + * \return ECR Register Value + */ +LOCAL_INLINE uint32_t FLEXCAN_HWA_GetErrorCount(FLEXCAN_Type *const pCan) +{ + return pCan->ECR; +} + +/** + * \brief Enable FLEXCAN Legacy Fifo + * + * \param pCan FLEXCAN instance value + */ +LOCAL_INLINE void FLEXCAN_HWA_EnableLegacyFifo(FLEXCAN_Type *const pCan) +{ + /* if enable legacy fifo, FD fifo must be disabled */ + pCan->MCR |= FLEXCAN_MCR_RFEN_MASK; /* set legacy fifo */ +} + +/** + * \brief Disable FLEXCAN Legacy Fifo + * + * \param pCan FLEXCAN instance value + */ +LOCAL_INLINE void FLEXCAN_HWA_DisableLegacyFifo(FLEXCAN_Type *const pCan) +{ + /* if enable legacy fifo, FD fifo must be disabled */ + pCan->MCR &= ~FLEXCAN_MCR_RFEN_MASK; /* clear legacy fifo */ +} + +/** + * \brief Enable FLEXCAN FD Fifo + * + * \param pCan FLEXCAN instance value + */ +LOCAL_INLINE void FLEXCAN_HWA_EnableFDFifo(FLEXCAN_Type *const pCan) +{ + /* if enable fd fifo, legacy fifo must be disabled */ + pCan->ERFCR |= FLEXCAN_ERFCR_ERFEN_MASK; /* set enhanced fifo */ +} + +/** + * \brief Disable FLEXCAN FD Fifo + * + * \param pCan FLEXCAN instance value + */ +LOCAL_INLINE void FLEXCAN_HWA_DisableFDFifo(FLEXCAN_Type *const pCan) +{ + /* if enable fd fifo, legacy fifo must be disabled */ + pCan->ERFCR &= ~FLEXCAN_ERFCR_ERFEN_MASK; /* clear enhanced fifo */ +} + + + +/** + * \brief Check FLEXCAN legacy fifo if enabled + * + * \param pCan FLEXCAN instance value + * \return 1 is legacy fifo enabled, 0 is disabled + */ +LOCAL_INLINE uint8_t FLEXCAN_HWA_CheckLegacyFifoEnabled(FLEXCAN_Type *const pCan) +{ + uint8_t u8RetVal; + uint32_t u32Value; + + /* get legacy fifo */ + u32Value = (pCan->MCR & FLEXCAN_MCR_RFEN_MASK) >> FLEXCAN_MCR_RFEN_SHIFT; + + u8RetVal = u32Value == 0U ? (uint8_t)0x0U : (uint8_t)0x1U; + + return u8RetVal; +} + +/** + * \brief Check FLEXCAN FD fifo if enabled + * + * \param pCan FLEXCAN instance value + * \return 1 is legacy fifo enabled, 0 is disabled + */ +LOCAL_INLINE uint8_t FLEXCAN_HWA_CheckFdFifoEnabled(FLEXCAN_Type *const pCan) +{ + uint8_t u8RetVal; + uint32_t u32Value; + /* get enhanced fifo */ + u32Value = (pCan->ERFCR & FLEXCAN_ERFCR_ERFEN_MASK) >> FLEXCAN_ERFCR_ERFEN_SHIFT; + + u8RetVal = u32Value == 0U ? (uint8_t)0x0U : (uint8_t)0x1U; + + return u8RetVal; +} + +/** + * \brief Set legacy fifo filter number number + * + * \param pCan FLEXCAN instance value + * \param u32FilterNum is total filter number + */ +LOCAL_INLINE void FLEXCAN_HWA_SetLegacyFifoFilterNum(FLEXCAN_Type *const pCan, uint32_t u32FilterNum) +{ + pCan->CTRL2 &= ~FLEXCAN_CTRL2_RFFN_MASK; /* clear fifo filter number */ + pCan->CTRL2 |= ((u32FilterNum - 1U) << FLEXCAN_CTRL2_RFFN_SHIFT)&FLEXCAN_CTRL2_RFFN_MASK; +} + + +/** + * \brief Check FLEXCAN FD enable + * + * \param pCan FLEXCAN instance value + * \return 1 is fd enabled, 0 is disabled + */ +LOCAL_INLINE uint8_t FLEXCAN_HWA_CheckFd(FLEXCAN_Type *const pCan) +{ + uint8_t u8RetVal; + uint32_t u32Value; + + /* get fd enable */ + u32Value = (pCan->MCR & FLEXCAN_MCR_FDEN_MASK) >> FLEXCAN_MCR_FDEN_SHIFT; + + u8RetVal = u32Value == 0U ? (uint8_t)0x0U : (uint8_t)0x1U; + + return u8RetVal; +} + + +/** + * \brief Set RXIMR for FLEXCAN + * + * \param pCan FLEXCAN instance value + * \param u32MbIndex Message Buffer Index + * \param u32Mask ID Mask + */ +LOCAL_INLINE void FLEXCAN_HWA_SetIndividualMask(FLEXCAN_Type *const pCan, uint32_t u32MbIndex, uint32_t u32Mask) +{ + pCan->RXIMR[u32MbIndex] = u32Mask; +} + +/** + * \brief Set global mask value + * + * \param pCan FLEXCAN instance value + * \param u32Mask mask value + */ +LOCAL_INLINE void FLEXCAN_HWA_SetGlobalMask(FLEXCAN_Type *const pCan, uint32_t u32Mask) +{ + pCan->RXMGMASK = u32Mask; +} + +/** + * \brief Set rx14 mask value + * + * \param pCan FLEXCAN instance value + * \param u32Mask mask value + */ +LOCAL_INLINE void FLEXCAN_HWA_SetRx14Mask(FLEXCAN_Type *const pCan, uint32_t u32Mask) +{ + pCan->RX14MASK = u32Mask; +} + +/** + * \brief Set rx15 mask value + * + * \param pCan FLEXCAN instance value + * \param u32Mask mask value + */ +LOCAL_INLINE void FLEXCAN_HWA_SetRx15Mask(FLEXCAN_Type *const pCan, uint32_t u32Mask) +{ + pCan->RX15MASK = u32Mask; +} + +/** + * \brief Set value to FLEXCAN RAM + * + * \param pCan FLEXCAN instance value + * \param u32RamIndex RAM index for FLEXCAN + * \param u32Value written value + */ +LOCAL_INLINE void FLEXCAN_HWA_MbRam(FLEXCAN_Type *const pCan, uint32_t u32RamIndex, uint32_t u32Value) +{ + pCan->RAM[u32RamIndex] = u32Value; +} + + +/** + * \brief Set ERFCR value + * + * \param pCan FLEXCAN instance value + * \param u32Value written value + */ +LOCAL_INLINE void FLEXCAN_HWA_SetERFCR(FLEXCAN_Type *const pCan, uint32_t u32Value) +{ + pCan->ERFCR = u32Value; +} + +/** + * \brief Reset Enhanced FIFO Engine + * + * \param pCan FLEXCAN instance value + */ +LOCAL_INLINE void FLEXCAN_HWA_ERFSRResetEnhancedFifo(FLEXCAN_Type *const pCan) +{ + /* Write one to ERFSR[ERFCLR] to reset Enhanced Rx FIFO engine */ + pCan->ERFSR |= FLEXCAN_ERFSR_ERFCLR_MASK; +} + + +/** + * \brief Clear Enhanced Fifo Flag with mask + * + * \param pCan FLEXCAN instance value + * \param u32Shift flag shift + * \param u32Mask flag mask + * \return flag value + */ +LOCAL_INLINE uint32_t FLEXCAN_HWA_ERFSRGetEnhancedFifoFlag(FLEXCAN_Type *const pCan, uint32_t u32Shift, uint32_t u32Mask) +{ + /* Write one clear status */ + return ((pCan->ERFSR & u32Mask) >> u32Shift); +} + +/** + * \brief Clear Enhanced Fifo status + * + * \param pCan FLEXCAN instance value + * \param u32ClearMask clear mask value + */ +LOCAL_INLINE void FLEXCAN_HWA_ERFSRClearEnhancedFifoFlag(FLEXCAN_Type *const pCan, uint32_t u32ClearMask) +{ + /* Write one clear status */ + pCan->ERFSR |= u32ClearMask; +} + + + +/** + * \brief Set Enhance Fifo interrupt value + * + * \param pCan FLEXCAN instance value + */ +LOCAL_INLINE void FLEXCAN_HWA_SetERFIERDataInterrupt(FLEXCAN_Type *const pCan) +{ + pCan->ERFIER |= FLEXCAN_ERFIER_ERFDAIE_MASK; +} + +/** + * \brief Set Enhanced Fifo filter value + * + * \param pCan FLEXCAN instance value + * \param u32FilterIndex Filter index + * \param u32Value filter value + */ +LOCAL_INLINE void FLEXCAN_HWA_EnhancedFifoFilter(FLEXCAN_Type *const pCan, uint32_t u32FilterIndex, uint32_t u32Value) +{ + pCan->ERFFEL[u32FilterIndex] = u32Value; +} + +/** @}*/ + +#endif diff --git a/MODULES/HwA_Flagchip_FC7240/Inc/HwA_fmc.h b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_fmc.h new file mode 100644 index 0000000..bd9b913 --- /dev/null +++ b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_fmc.h @@ -0,0 +1,402 @@ +/** + * @file HwA_cpm.h + * @author Flagchip + * @brief FC7xxx FMC register API + * @version 0.1.0 + * @date 2024-1-5 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-1-5 Flagchip120 N/A First version for FC7240 + ******************************************************************************** */ + +#ifndef HWA_INCLUDE_HWA_FMC_H_ +#define HWA_INCLUDE_HWA_FMC_H_ +#include "device_header.h" +/* ################################################################################## */ +/* ####################################### Macro #################################### */ + + + +/** + * @brief Read the FMC FAPC0 register value for all. + * + * @param pFMC FMC instance. + * @return FMC FAPC0 regsiter value. + */ +LOCAL_INLINE uint32_t FMC_HWA_GetFAPC0Value(FMC_Type *pFMC) +{ + return pFMC->FAPC0; +} + +/** + * @brief Set FMC FAPC0 value, users should write the whole value to this register. + * + * @param pFMC FMC instance. + * @param u32Value the value which will be written to the FAPC0 register. + */ +LOCAL_INLINE void FMC_HWA_SetFAPC0Value(FMC_Type *pFMC, uint32_t u32Value) +{ + pFMC->FAPC0 = u32Value; +} + +/** + * @brief Set FAPC0 data bus prefetch enable + * + * @param bEnable 0:Data prefetching is disabled. 1:Data prefetching is enabled. + */ +LOCAL_INLINE void FMC_HWA_SetFAPC0DataPrefechEnable(FMC_Type *pFMC, bool bEnable) +{ + pFMC->FAPC0 = ((pFMC->FAPC0 & (~FMC_FAPC0_DBPEN_MASK)) | ((uint32_t)(bEnable ? 1U : 0U) << FMC_FAPC0_DBPEN_SHIFT)); +} + +/** + * @brief Set FAPC0 code bus prefetch enable + * + * @param bEnable 0:Code prefetching is disabled. 1:Code prefetching is disabled. + */ +LOCAL_INLINE void FMC_HWA_SetFAPC0CodePrefechEnable(FMC_Type *pFMC, bool bEnable) +{ + pFMC->FAPC0 = ((pFMC->FAPC0 & (~FMC_FAPC0_CBPEN_MASK)) | ((uint32_t)(bEnable ? 1U : 0U) << FMC_FAPC0_CBPEN_SHIFT)); +} + +/** + * @brief Set FAPC0 data bus read buffers enable + * + * @param bEnable 0:Read data buffers are disabled. 1:Read data buffers are enabled. + */ +LOCAL_INLINE void FMC_HWA_SetFAPC0DataBuffersEnable(FMC_Type *pFMC, bool bEnable) +{ + pFMC->FAPC0 = ((pFMC->FAPC0 & (~FMC_FAPC0_DBBEN_MASK)) | ((uint32_t)(bEnable ? 1U : 0U) << FMC_FAPC0_DBBEN_SHIFT)); +} + +/** + * @brief Set FAPC0 code bus read buffers enable + * + * @param bEnable 0:Read code buffers are disabled. 1:Read code buffers are enabled. + */ +LOCAL_INLINE void FMC_HWA_SetFAPC0CodeBuffersEnable(FMC_Type *pFMC, bool bEnable) +{ + pFMC->FAPC0 = ((pFMC->FAPC0 & (~FMC_FAPC0_CBBEN_MASK)) | ((uint32_t)(bEnable ? 1U : 0U) << FMC_FAPC0_CBBEN_SHIFT)); +} + +/** + * @brief Set FAPC1 data bus prefetch enable + * + * @param bEnable 0:Data prefetching is disabled. 1:Data prefetching is enabled. + */ +LOCAL_INLINE void FMC_HWA_SetFAPC1DataPrefechEnable(FMC_Type *pFMC, bool bEnable) +{ + pFMC->FAPC1 = ((pFMC->FAPC1 & (~FMC_FAPC1_DBPEN_MASK)) | ((uint32_t)(bEnable ? 1U : 0U) << FMC_FAPC1_DBPEN_SHIFT)); +} + +/** + * @brief Set FAPC1 code bus prefetch enable + * + * @param bEnable 0:Code prefetching is disabled. 1:Code prefetching is disabled. + */ +LOCAL_INLINE void FMC_HWA_SetFAPC1CodePrefechEnable(FMC_Type *pFMC, bool bEnable) +{ + pFMC->FAPC1 = ((pFMC->FAPC1 & (~FMC_FAPC1_CBPEN_MASK)) | ((uint32_t)(bEnable ? 1U : 0U) << FMC_FAPC1_CBPEN_SHIFT)); +} + +/** + * @brief Set FAPC1 data bus read buffers enable + * + * @param bEnable 0:Read data buffers are disabled. 1:Read data buffers are enabled. + */ +LOCAL_INLINE void FMC_HWA_SetFAPC1DataBuffersEnable(FMC_Type *pFMC, bool bEnable) +{ + pFMC->FAPC1 = ((pFMC->FAPC1 & (~FMC_FAPC1_DBBEN_MASK)) | ((uint32_t)(bEnable ? 1U : 0U) << FMC_FAPC1_DBBEN_SHIFT)); +} + +/** + * @brief Set FAPC1 code bus read buffers enable + * + * @param bEnable 0:Read code buffers are disabled. 1:Read code buffers are enabled. + */ +LOCAL_INLINE void FMC_HWA_SetFAPC1CodeBuffersEnable(FMC_Type *pFMC, bool bEnable) +{ + pFMC->FAPC1 = ((pFMC->FAPC1 & (~FMC_FAPC1_CBBEN_MASK)) | ((uint32_t)(bEnable ? 1U : 0U) << FMC_FAPC1_CBBEN_SHIFT)); +} + +/** + * @brief Set FAPC2 data bus prefetch enable + * + * @param bEnable 0:Data prefetching is disabled. 1:Data prefetching is enabled. + */ +LOCAL_INLINE void FMC_HWA_SetFAPC2DataPrefechEnable(FMC_Type *pFMC, bool bEnable) +{ + pFMC->FAPC2 = ((pFMC->FAPC2 & (~FMC_FAPC2_DBPEN_MASK)) | ((uint32_t)(bEnable ? 1U : 0U) << FMC_FAPC2_DBPEN_SHIFT)); +} + +/** + * @brief Set FAPC2 code bus prefetch enable + * + * @param bEnable 0:Code prefetching is disabled. 1:Code prefetching is disabled. + */ +LOCAL_INLINE void FMC_HWA_SetFAPC2CodePrefechEnable(FMC_Type *pFMC, bool bEnable) +{ + pFMC->FAPC2 = ((pFMC->FAPC2 & (~FMC_FAPC2_CBPEN_MASK)) | ((uint32_t)(bEnable ? 1U : 0U) << FMC_FAPC2_CBPEN_SHIFT)); +} + +/** + * @brief Set FAPC2 data bus read buffers enable + * + * @param bEnable 0:Read data buffers are disabled. 1:Read data buffers are enabled. + */ +LOCAL_INLINE void FMC_HWA_SetFAPC2DataBuffersEnable(FMC_Type *pFMC, bool bEnable) +{ + pFMC->FAPC2 = ((pFMC->FAPC2 & (~FMC_FAPC2_DBBEN_MASK)) | ((uint32_t)(bEnable ? 1U : 0U) << FMC_FAPC2_DBBEN_SHIFT)); +} + +/** + * @brief Set FAPC2 code bus read buffers enable + * + * @param bEnable 0:Read code buffers are disabled. 1:Read code buffers are enabled. + */ +LOCAL_INLINE void FMC_HWA_SetFAPC2CodeBuffersEnable(FMC_Type *pFMC, bool bEnable) +{ + pFMC->FAPC2 = ((pFMC->FAPC2 & (~FMC_FAPC2_CBBEN_MASK)) | ((uint32_t)(bEnable ? 1U : 0U) << FMC_FAPC2_CBBEN_SHIFT)); +} + +/** + * @brief Read the FMC FEEC register value for all. + * + * @param pFMC FMC instance. + * @return FMC FEEC regsiter value. + */ +LOCAL_INLINE uint32_t FMC_HWA_GetFEECValue(FMC_Type *pFMC) +{ + return pFMC->FEEC; +} + +/** + * @brief Set FMC FEEC value, users should write the whole value to this register. + * + * @param pFMC FMC instance. + * @param u32Value the value which will be written to the FEEC register. + */ +LOCAL_INLINE void FMC_HWA_SetFEECValue(FMC_Type *pFMC, uint32_t u32Value) +{ + pFMC->FEEC = u32Value; +} + +/** + * @brief Read the FMC FEIPC register value for all. + * + * @param pFMC FMC instance. + * @return FMC FEIPC regsiter value. + */ +LOCAL_INLINE uint32_t FMC_HWA_GetFEIPCValue(FMC_Type *pFMC) +{ + return pFMC->FEIPC; +} + +/** + * @brief Set the date error position 1 & position 2 + * + * @param pFMC FMC instance. + * @param u32Position1 Data error position 1 + * @param u32Position2 Data error position 2 + */ +LOCAL_INLINE void FMC_HWA_SetInjectPositon(FMC_Type *pFMC, uint32_t u32Position1, uint32_t u32Position2) +{ + pFMC->FEIPC = (pFMC->FEIPC & ~FMC_FEIPC_EDATA_POS1_MASK) | FMC_FEIPC_EDATA_POS1(u32Position1); + pFMC->FEIPC = (pFMC->FEIPC & ~FMC_FEIPC_EDATA_POS2_MASK) | FMC_FEIPC_EDATA_POS2(u32Position2); +} + +/** + * @brief Read the FMC FPESA_L register value for all. + * + * @param pFMC FMC instance. + * @return FMC FPESA_L regsiter value. + */ +LOCAL_INLINE uint32_t FMC_HWA_GetFPESALValue(FMC_Type *pFMC) +{ + return pFMC->FPESA_L; +} + +/** + * @brief Set FMC FPESA_L value. + * + * @param pFMC FMC instance. + * @param u32Value the value which will be written to the FPESA_L register. + */ +LOCAL_INLINE void FMC_HWA_SetFPESALValue(FMC_Type *pFMC, uint32_t u32Value) +{ + pFMC->FPESA_L = u32Value; +} + +/** + * @brief Read the FMC FPESA_P register value for all. + * + * @param pFMC FMC instance. + * @return FMC FPESA_P regsiter value. + */ +LOCAL_INLINE uint32_t FMC_HWA_GetFPESAPValue(FMC_Type *pFMC) +{ + return pFMC->FPESA_P; +} + +/** + * @brief Read the FMC FB_FPELCK register value for all. + * + * @param pFMC FMC instance. + * @param u8SeqGroupIndex the index of the sequence group + * @return FMC FB_FPELCK regsiter value. + */ +LOCAL_INLINE uint32_t FMC_HWA_GetFBFPELCKValue(FMC_Type *pFMC, uint8_t u8SeqGroupIndex) +{ + return pFMC->FB_FPELCK[u8SeqGroupIndex]; +} + +/** + * @brief Set FMC FB_FPELCK value. + * + * @param pFMC FMC instance. + * @param u8SeqGroupIndex the index of the sequence group + * @param u32Value the value which will be written to the FB_FPELCK register. + */ +LOCAL_INLINE void FMC_HWA_SetFBFPELCKValue(FMC_Type *pFMC, uint8_t u8SeqGroupIndex, uint32_t u32Value) +{ + pFMC->FB_FPELCK[u8SeqGroupIndex] = u32Value; +} + +/** + * @brief NVI program erase Lock + * + * @param bEnable 0:unlock. 1:locked. + */ +LOCAL_INLINE void FMC_HWA_SetNVRLocked(FMC_Type *pFMC, bool bEnable) +{ + pFMC->FN_FPELCK = ((pFMC->FN_FPELCK & (~FMC_FN_FPELCK_FPELCK_MASK)) | ((uint32_t)(bEnable ? 1U : 0U) << FMC_FN_FPELCK_FPELCK_SHIFT)); +} + +/** + * @brief Get NVR lock status. + * + * @param pFCSPI FCSPI instance, e.g. FCSPI0, FCSPI1. + * @return the NVR status(1:locked 0:unlocked). + */ +LOCAL_INLINE uint8_t FCSPI_HWA_GetNVRLockedStatus(FMC_Type *pFMC) +{ + return (uint8_t)(((pFMC->FN_FPELCK) & FMC_FN_FPELCK_FPELCK_MASK) >> FMC_FN_FPELCK_FPELCK_SHIFT); +} + +/** + * @brief Read the FMC FB_CPELCK register value for all. + * + * @param pFMC FMC instance. + * @param u8SeqGroupIndex the index of the sequence group + * @return FMC FB_CPELCK regsiter value. + */ +LOCAL_INLINE uint32_t FMC_HWA_GetFBCPELCKValue(FMC_Type *pFMC, uint8_t u8SeqGroupIndex) +{ + return pFMC->FB_CPELCK[u8SeqGroupIndex]; +} + +/** + * @brief Set FMC FB_CPELCK value. + * + * @param pFMC FMC instance. + * @param u8SeqGroupIndex the index of the sequence group + * @param u32Value the value which will be written to the FB_CPELCK register. + */ +LOCAL_INLINE void FMC_HWA_SetFBCPELCKValue(FMC_Type *pFMC, uint8_t u8SeqGroupIndex, uint32_t u32Value) +{ + pFMC->FB_CPELCK[u8SeqGroupIndex] = u32Value; +} + +/** + * @brief Set OTA register lock + * + * @param pFMC FMC instance. + * @param u8SeqGroupIndex the index of the sequence group + * @param bEnable 0:OTA_CTRL can be written. 1:OTA_CTRL is locked. + */ +LOCAL_INLINE void FMC_HWA_SetOTALock(FMC_Type *pFMC, uint8_t u8SeqGroupIndex, bool bEnable) +{ + pFMC->OTA_CTRL[u8SeqGroupIndex] = ((pFMC->OTA_CTRL[u8SeqGroupIndex] & (~FMC_OTA_CTRL_OTA_LOCK_MASK)) | ((uint32_t)(bEnable ? 1U : 0U) << FMC_OTA_CTRL_OTA_LOCK_SHIFT)); +} + +/** + * @brief Set OTA active block + * + * @param pFMC FMC instance. + * @param u8SeqGroupIndex the index of the sequence group + * @param bEnable 0: block0 is the currently active OTA region. 1: block1 is the currently active OTA region. + */ +LOCAL_INLINE void FMC_HWA_SetOTAActive(FMC_Type *pFMC, uint8_t u8SeqGroupIndex, bool bEnable) +{ + pFMC->OTA_CTRL[u8SeqGroupIndex] = ((pFMC->OTA_CTRL[u8SeqGroupIndex] & (~FMC_OTA_CTRL_OTA_ACTIVE_MASK)) | ((uint32_t)(bEnable ? 1U : 0U) << FMC_OTA_CTRL_OTA_ACTIVE_SHIFT)); +} + +/** + * @brief Enable OTA + * + * @param pFMC FMC instance. + * @param u8SeqGroupIndex the index of the sequence group + */ +LOCAL_INLINE void FMC_HWA_SetOTAEnable(FMC_Type *pFMC, uint8_t u8SeqGroupIndex) +{ + pFMC->OTA_CTRL[u8SeqGroupIndex] = ((pFMC->OTA_CTRL[u8SeqGroupIndex] & (~FMC_OTA_CTRL_OTA_EN_MASK)) | FMC_OTA_CTRL_OTA_EN(0xA)); +} + +/** + * @brief Disable OTA + * + * @param pFMC FMC instance. + * @param u8SeqGroupIndex the index of the sequence group + */ +LOCAL_INLINE void FMC_HWA_SetOTADisable(FMC_Type *pFMC, uint8_t u8SeqGroupIndex) +{ + pFMC->OTA_CTRL[u8SeqGroupIndex] = ((pFMC->OTA_CTRL[u8SeqGroupIndex] & (~FMC_OTA_CTRL_OTA_EN_MASK)) | FMC_OTA_CTRL_OTA_EN(0x15)); +} + +/** + * @brief Read the FMC OTA_CTRL register value for all. + * + * @param pFMC FMC instance. + * @param u8SeqGroupIndex the index of the sequence group + * @return FMC OTA_CTRL regsiter value. + */ +LOCAL_INLINE uint32_t FMC_HWA_GetOTACtrlValue(FMC_Type *pFMC, uint8_t u8SeqGroupIndex) +{ + return pFMC->OTA_CTRL[u8SeqGroupIndex]; +} + +/** + * @brief Read the FMC OTA_VER_LOC register value for all. + * + * @param pFMC FMC instance. + * @param u8SeqGroupIndex the index of the sequence group + * @return FMC OTA_VER_LOC regsiter value. + */ +LOCAL_INLINE uint32_t FMC_HWA_GetOTAVerLocValue(FMC_Type *pFMC, uint8_t u8SeqGroupIndex) +{ + return pFMC->OTA_VER_LOC[u8SeqGroupIndex]; +} + +/** + * @brief Read the FMC OTA_ACT_VER register value for all. + * + * @param pFMC FMC instance. + * @param u8SeqGroupIndex the index of the sequence group + * @return FMC OTA_ACT_VER regsiter value. + */ +LOCAL_INLINE uint32_t FMC_HWA_GetOTAActVerValue(FMC_Type *pFMC, uint8_t u8SeqGroupIndex) +{ + return pFMC->OTA_ACT_VER[u8SeqGroupIndex]; +} + + +/** @}*/ + +#endif /* HWA_INCLUDE_HWA_FMC_H_ */ diff --git a/MODULES/HwA_Flagchip_FC7240/Inc/HwA_fpu.h b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_fpu.h new file mode 100644 index 0000000..f7fcb0d --- /dev/null +++ b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_fpu.h @@ -0,0 +1,52 @@ +/** + * @file HwA_fpu.h + * @author Flagchip051 + * @brief FC4xxx FPU hardware access layer + * @version 0.1.0 + * @date 2024-01-11 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-01-11 Flagchip054 N/A First version for FC7240 + ******************************************************************************** */ + +#ifndef _HWA_FPU_H_ +#define _HWA_FPU_H_ + +#include "device_header.h" + +/* CPACR Bit Fields */ +#define FC7240_SCB_CPACR_CP10_MASK 0x300000u +#define FC7240_SCB_CPACR_CP10_SHIFT 20u +#define FC7240_SCB_CPACR_CP10_WIDTH 2u +#define FC7240_SCB_CPACR_CP10(x) (((uint32_t)(((uint32_t)(x))<CPACR |= (FC7240_SCB_CPACR_CP10(3) | FC7240_SCB_CPACR_CP11(3)); /* set CP10 and CP11 Full Access */ +} + +/** + * @brief disable fpu + * + */ +LOCAL_INLINE void FPU_HWA_Disable(void) +{ + SCB->CPACR &= ~((FC7240_SCB_CPACR_CP10(3) | FC7240_SCB_CPACR_CP11(3))); /* Access denied. Any attempted access generates a NOCP UsageFault */ +} + + +#endif /* HWA_INCLUDE_HWA_FPU_H_ */ diff --git a/MODULES/HwA_Flagchip_FC7240/Inc/HwA_freqm.h b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_freqm.h new file mode 100644 index 0000000..de384e9 --- /dev/null +++ b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_freqm.h @@ -0,0 +1,229 @@ +/** + * @file HwA_freqm.h + * @author Flagchip + * @brief FC7xxx freqm hardware access layer + * @version 0.1.0 + * @date 2024-01-14 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + * @details + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-01-14 qxw0100 N/A First version for FC7240 + ******************************************************************************** */ + +#ifndef _HWA_FREQM_H_ +#define _HWA_FREQM_H_ + +#include "device_header.h" + +/** + * @brief Select the measured clock + * + */ +typedef enum +{ + MES_RSVD00 = 0U, + MES_SLOW_CLK = 1U, + MES_PLL1_FEEDBACK = 2U, + MES_PLL0_FEEDBACK = 3U, + MES_SCG_CLKOUT = 4U, + MES_RTC_CLK = 5U, + MES_AON_CLK = 6U, + MES_SIRC128K_CLK = 7U, + MES_RSVD01 = 8U, + MES_RSVD02 = 9U, + MES_FCPIT0_FUN_CLK = 10U, + MES_RSVD03 = 11U, + MES_RSVD04 = 12U, + MES_FCSPI0_FUN_CLK = 13U, + MES_FCSPI1_FUN_CLK = 14U, + MES_FCSPI2_FUN_CLK = 15U, + MES_RSVD05 = 16U, + MES_FCUART0_FUN_CLK = 17U, + MES_FCUART1_FUN_CLK = 18U, + MES_FCUART2_FUN_CLK = 19U, + MES_RSVD06 = 20U, + MES_TRGSEL1_OUT4 = 21U, + MES_FTU0_FUN_CLK = 22U, + MES_FTU1_FUN_CLK = 23U, + MES_RSVD07 = 24U, + MES_FTU2_FUN_CLK = 25U, + MES_FTU3_FUN_CLK = 26U, + MES_ADC0_FUN_CLK = 27U, + MES_RSVD08 = 28U, + MES_ADC1_FUN_CLK = 29U, + MES_RSVD09 = 30U, + MES_RSVD10 = 31U, + MES_RSVD11 = 32U, + MES_FOSC_DIVL = 33U, + MES_SIRC_DIVL = 34U, + MES_FIRC_DIVL = 35U, + MES_RSVD12 = 36U, + MES_PLL1_DIVL = 37U, + MES_PLL0_DIVL = 38U, + MES_RSVD13 = 39U, + MES_RSVD14 = 40U, + MES_FOSC_DIVM = 41U, + MES_SIRC_DIVM = 42U, + MES_FIRC_DIVM = 43U, + MES_RSVD15 = 44U, + MES_PLL1_DIVM = 45U, + MES_PLL0_DIVM = 46U, + MES_RSVD16 = 47U, + MES_RSVD17 = 48U, + MES_FOSC_DIVH = 49U, + MES_SIRC_DIVH = 50U, + MES_FIRC_DIVH = 51U, + MES_RSVD18 = 52U, + MES_PLL1_DIVH = 53U, + MES_PLL0_DIVH = 54U, + MES_RSVD19 = 55U, + MES_RSVD20 = 56U, + MES_SENT0_FUN_CLK = 57U, + MES_FLEXCAN0_FUN_CLK = 58U, + MES_FLEXCAN1_FUN_CLK = 59U, + MES_RSVD21 = 60U, + MES_MSC0_FUN_CLK = 61U, + MES_TPU_FUN_CLK = 62U, + MES_RSVD22 = 63U, +} FREQM_MesClkSelType; + +/** + * @brief Set the clock selection + * + * @param pFreqm the base address of the FREQM + * @param eClkSel the clock selection index + */ +LOCAL_INLINE void FREQM_HWA_MesClkSel(FREQM_Type *pFreqm,FREQM_MesClkSelType eClkSel) +{ + pFreqm->CTRL &= ~FREQM_CTRL_MES_CLK_SEL_MASK; + pFreqm->CTRL |= FREQM_CTRL_MES_CLK_SEL((uint32_t)eClkSel); +} + +/** + * @brief Set the clock selection + * + * @param pFreqm the base address of the FREQM + * @param u8PredivVal the measure clock prediv value + */ +LOCAL_INLINE void FREQM_HWA_MesClk_PreDiv(FREQM_Type *pFreqm,uint8_t u8PredivVal) +{ + pFreqm->CTRL &= ~FREQM_CTRL_MES_CLK_PREDIV_MASK; + pFreqm->CTRL |= FREQM_CTRL_MES_CLK_PREDIV(u8PredivVal); +} + +/** + * @brief Enable count event interrupt + * + * @param pFreqm the base address of the FREQM + */ +LOCAL_INLINE void FREQM_HWA_EnableCntEventInterrupt(FREQM_Type *pFreqm) +{ + pFreqm->CTRL |= FREQM_CTRL_CNT_EVENT_IE_MASK; +} + +/** + * @brief Disable count event interrupt + * + * @param pFreqm the base address of the FREQM + */ +LOCAL_INLINE void FREQM_HWA_DisableCntEventInterrupt(FREQM_Type *pFreqm) +{ + pFreqm->CTRL &= ~((uint32_t)FREQM_CTRL_CNT_EVENT_IE_MASK); +} + +/** + * @brief Set counting length of measure counter + * + * @param pFreqm the base address of the FREQM + * @param u32MesLen counting length of measure counter + */ +LOCAL_INLINE void FREQM_HWA_SetMesLength(FREQM_Type *pFreqm,uint32_t u32MesLen) +{ + pFreqm->MES_LENGTH = u32MesLen; +} + +/** + * @brief Set timeout value of reference counter + * + * @param pFreqm the base address of the FREQM + * @param u32RefTo timeout value of reference counter + */ +LOCAL_INLINE void FREQM_HWA_SetRefTimeout(FREQM_Type *pFreqm,uint32_t u32RefTo) +{ + pFreqm->REF_TIMEOUT = u32RefTo; +} + +/** + * @brief Set value of reference counter + * + * @param pFreqm the base address of the FREQM + * @param u32RefCnt value of reference counter + */ +LOCAL_INLINE void FREQM_HWA_SetRefCnt(FREQM_Type *pFreqm,uint32_t u32RefCnt) +{ + pFreqm->REF_CNT = u32RefCnt; +} + +/** + * @brief Clear counter event interrupt flag + * + * @param pFreqm the base address of the FREQM + */ +LOCAL_INLINE void FREQM_HWA_ClearInterruptFlag(FREQM_Type *pFreqm) +{ + pFreqm->CNT_STATUS |= FREQM_CNT_STATUS_CNT_EVENT_MASK; +} + +/** + * @brief Get counter event interrupt flag + * + * @param pFreqm the base address of the FREQM + * @param return false for disable, true for enable. + */ +LOCAL_INLINE bool FREQM_HWA_GetInterruptFlag(FREQM_Type *pFreqm) +{ + return ((pFreqm->CNT_STATUS & FREQM_CNT_STATUS_CNT_EVENT_MASK) == FREQM_CNT_STATUS_CNT_EVENT_MASK) ? true : false; +} + +/** + * @brief Get counter status + * + * @param pFreqm the base address of the FREQM + * @param return Counter status. + */ +LOCAL_INLINE uint32_t FREQM_HWA_GetCntStatus(FREQM_Type *pFreqm) +{ + uint32_t u32Mask = (FREQM_CNT_STATUS_MES_CNT_START_MASK|FREQM_CNT_STATUS_MES_CNT_STOP_MASK|FREQM_CNT_STATUS_REF_CNT_STOP_MASK); + return (pFreqm->CNT_STATUS & u32Mask); +} + +/** + * @brief Set value of measure counter + * + * @param pFreqm the base address of the FREQM + * @param u32MesCnt value of measure counter + */ +LOCAL_INLINE void FREQM_HWA_SetMesCnt(FREQM_Type *pFreqm,uint32_t u32MesCnt) +{ + pFreqm->MES_CNT = u32MesCnt; +} + +/** + * @brief Get saved reference counter value + * + * @param pFreqm the base address of the FREQM + * @param return saved reference counter value. + */ +LOCAL_INLINE uint32_t FREQM_HWA_GetRefCntSave(FREQM_Type *pFreqm) +{ + return pFreqm->REF_CNT_SAVE; +} + +#endif /* #ifndef _HWA_FREQM_H_ */ diff --git a/MODULES/HwA_Flagchip_FC7240/Inc/HwA_ftu.h b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_ftu.h new file mode 100644 index 0000000..db782eb --- /dev/null +++ b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_ftu.h @@ -0,0 +1,1924 @@ +/** + * @file HwA_ftu.h + * @author Flagchip070 + * @brief FC7xxx FTU hardware access layer + * @version 0.1.0 + * @date 2022-11-15 + * + * @copyright Copyright (c) 2022 Flagchip Semiconductors Co., Ltd. + * + * @details + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2022-11-15 Flagchip070 N/A First version for FC7300 + ******************************************************************************** */ + +#ifndef _HWA_FTU_H_ +#define _HWA_FTU_H_ + +#include "device_header.h" +/********* Local typedef ************/ +/** + * @brief The definition of enable the deadtime of channel and channel+1 + * + */ +#define FTU_CHCTRL_DEADTIME_CHANNEL(channel) (uint32_t)((uint32_t)1U << ((((uint32_t)(channel) >> 1U) << 3U) + 4U)) +/** + * @brief The definition of enable the complement of channel + * + */ +#define FTU_CHCTRL_COMPLEMENT_CHANNEL(channel) (uint32_t)((uint32_t)1U << ((((uint32_t)(channel) >> 1U) << 3U) + 1U)) +/** + * @brief The definition of enable the synchronization for channel and channel+1 + * + */ +#define FTU_CHCTRL_SYNCEN_CHANNEL(channel) (uint32_t)((uint32_t)1U << ((((uint32_t)(channel) >> 1U) << 3U) + 5U)) +/** + * @brief The definition of enable the Phase shift mode for channel and channel+1 + * + */ +#define FTU_CHCTRL_PHASE_CHANNEL(channel) (uint32_t)((uint32_t)1U << (((uint32_t)(channel) >> 1U) << 3U)) +/** + * @brief The definition of enable the Enhanced Phase shift mode for channel and channel+1 + * + */ +#define FTU_CHCTRL_EPHASE_CHANNEL(channel) (uint32_t)((uint32_t)1U << ((((uint32_t)(channel) >> 1U) << 3U) + 7U)) +/** + * @brief The definition of enable the fault control in channel and channel+1 + * + */ +#define FTU_CHCTRL_FAULT_CHANNEL(channel) (uint32_t)((uint32_t)1U << ((((uint32_t)(channel) >> 1U) << 3U) + 6U)) + +/********* Local typedef ************/ +/** + * @brief Select the FTU Debug Mode + * + */ +typedef enum +{ + FTU_DBG_COUNTER_STOP_CHN_WORKS = 0U, /*!< FTU counter stopped, channel works as function mode. */ + FTU_DBG_COUNTER_STOP_CHN_FORCE_SAFE = 1U, /*!< FTU counter stopped, channel output force to safe state. */ + FTU_DBG_COUNTER_STOP_CHN_FROZEN = 2U, /*!< FTU counter stopped, channel output is frozen. */ + FTU_DBG_COUNTER_WORKS_CHN_WORKS = 3U /*!< FTU counter works as function mode, channel works as function mode. */ +} FTU_DebugModeType; + +typedef enum +{ + FTU_CHANNEL_MODE_INPUT = 0u, + FTU_CHANNEL_MODE_OUTPUT_COMPARE = 1u, + FTU_CHANNEL_MODE_EDGE_ALIGN_PWM = 2u, + FTU_CHANNEL_MODE_DO_NOT_CARE = 3u, +} FTU_ChannelModeType; + +typedef enum +{ + FTU_CHANNEL_EDGE_NOT_USED = 0u, + FTU_CHANNEL_EDGE_RISING = 1u, + FTU_CHANNEL_EDGE_FALLING = 2u, + FTU_CHANNEL_EDGE_BOTH = 3u, + FTU_CHANNEL_OC_TOGGLE = 1u, + FTU_CHANNEL_OC_CLEAR = 2u, + FTU_CHANNEL_OC_SET = 3u, + FTU_CHANNEL_PWM_HIGH_TRUE = 2u, + FTU_CHANNEL_PWM_LOW_TRUE = 3u, +} FTU_ChannelEdgeLevelType; +/** + * @brief Select the prescaler of the FTU + * + */ +typedef enum +{ + FTU_DIV_1 = 0U, + FTU_DIV_2, + FTU_DIV_4, + FTU_DIV_8, + FTU_DIV_16, + FTU_DIV_32, + FTU_DIV_64, + FTU_DIV_128 +} FTU_PrescalerType; + +/** + * @brief Select the prescaler of the FTU filter + * + */ +typedef enum +{ + FTU_FLT_DIV_1 = 0U, + FTU_FLT_DIV_2, + FTU_FLT_DIV_3, + FTU_FLT_DIV_4, + FTU_FLT_DIV_5, + FTU_FLT_DIV_6, + FTU_FLT_DIV_7, + FTU_FLT_DIV_8, + FTU_FLT_DIV_9, + FTU_FLT_DIV_10, + FTU_FLT_DIV_11, + FTU_FLT_DIV_12, + FTU_FLT_DIV_13, + FTU_FLT_DIV_14, + FTU_FLT_DIV_15, + FTU_FLT_DIV_16 +} FTU_FilterPrescalerType; + +/** + * @brief selects the encoding mode used in the Quadrature Decoder mode + * + */ +typedef enum +{ + FTU_QUADMODE_PHA_PHB_ENCODING_MODE = 0U, /*!< Phase A and phase B encoding mode */ + FTU_QUADMODE_COUNT_DIR_ENCODING_MODE, /*!< Count and direction encoding mode */ +} FTU_QuadratureModeType; + +/** + * @brief FTU Counter Direction In Quadrature Decoder Mode + * + */ +typedef enum +{ + FTU_QUADIR_DECREMENT = 0U, /*!< FTU counter decrement */ + FTU_QUADIR_INCREMENT, /*!< FTU counter increment */ +} FTU_QuadratureDirectionType; + +/** + * @brief Timer Overflow Direction In Quadrature Decoder Mode + * + */ +typedef enum +{ + FTU_TOFDIR_TOF_SET_ON_BOTTOM = 0U, /*!< TOF bit was set on the bottom of counting */ + FTU_TOFDIR_TOF_SET_ON_TOP, /*!< TOF bit was set on the top of counting */ +}FTU_TimerOverflowDirectionType; + +/** + * @brief register bit status + * + */ +typedef enum +{ + FTU_BIT_LOW = 0U, + FTU_BIT_HIGH +} FTU_BitStatusType; + +/** + * @brief Ftu module clock source + * + */ +typedef enum +{ + FTU_MODULE_NO_CLK = 0U, /*!< No clock selected */ + FTU_MODULE_INTERNAL_CLK = 1U, /*!< FTU input clock */ + FTU_MODULE_EXTERNAL_CLK = 3U, /*!< External pin input clock */ +} FTU_ModuleClkSrcType; + +/** + * @brief Disable channel match trigger/interrupt when count-up/down in CPWM/QUAD mode + * + */ +typedef enum +{ + FTU_DISABLE_TRIG_INTR_NONE = 0U, /*!< No effect */ + FTU_DISABLE_TRIG_INTR_CNT_DOWN = 1U, /*!< Disable trigger/interrupt when count-down */ + FTU_DISABLE_TRIG_INTR_CNT_UP = 2U, /*!< Disable trigger/interrupt when count-up */ + FTU_DISABLE_TRIG_INTR_CNT_UP_DOWN = 3U, /*!< Disable trigger/interrupt when count-up/down */ +}FTU_UpDownDisableType; + +/** + * @brief hardware trig(n) mode + * + */ +typedef enum +{ + FTU_CLEARS_TRIG_WHEN_DETECTED = 0x0U, /*!< FTU clears the TRIG(n) bit when the hardware trigger j is detected, where n = 0, 1,2. */ + FTU_NOT_CLEARS_TRIG_WHEN_DETECTED = 0x01U /*!< FTU does not clear the TRIG(n) bit when the hardware trigger j is detected, where n = 0, 1,2. */ +} FTU_TrigModeType; + +/** + * @brief fault mode enumeration + * + */ +typedef enum +{ + FTU_FAULT_MODE_DISABLED = 0x00U, /*!< Fault control is disabled for all channels */ + FTU_FAULT_MODE_EVEN_CHANNEL = 0x01U, /*!< Fault control is enabled for even channels only (channels 0, 2, 4, and 6), and the selected mode is the manual fault clearing */ + FTU_FAULT_MODE_CHANNEL_ALL = 0x02U, /*!< Fault control is enabled for all channels, and the selected mode is the manual fault clearing */ + FTU_FAULT_MODE_AUTO = 0x03U /*!< Fault control is enabled for all channels, and the selected mode is the automatic fault clearing */ +} FTU_FaultModeType; + +/** + * @brief external clock enumeration + * + */ +typedef enum +{ + FTU_TCLK0_USED = 0U, /*!< FTU_TCLK0 pin as FTU external clock */ + FTU_TCLK1_USED = 1U, /*!< FTU_TCLK1 pin as FTU external clock */ + FTU_TCLK2_USED = 2U, /*!< FTU_TCLK2 pin as FTU external clock */ + FTU_NO_CLK_USED = 3U, /*!< No clock input */ +} FTU_TclkSelType; + +/** + * @brief Deadtime Prescaler Value + * + */ +typedef enum +{ + FTU_DEADTIME_PRESCALER_DIV_1 = 0U, /*!< Divide the FTU input clock by 1 */ + FTU_DEADTIME_PRESCALER_DIV_4 = 2U, /*!< Divide the FTU input clock by 4 */ + FTU_DEADTIME_PRESCALER_DIV_16 = 3U, /*!< Divide the FTU input clock by 16 */ +} FTU_DeadTimePrescalerType; + +/** + * @brief Trigger output control + * + */ +typedef enum +{ + FTU_TRIG_OUTPUT_AS_CHANNEL_MODE = 0U, /*!< channel outputs will be controlled by channel mode */ + FTU_TRIG_OUTPUT_AS_TRIGGER = 1U, /*!< If a match in the channel occurs, channel output will be a trigger */ +}FTU_TrigOutputModeType; + +/** + * @brief Fault disable channel output delay value selection + * + */ +typedef enum +{ + FTU_FAULT_DISABLE_DELAY_NO_DELAY = 0u, /*!< Select no delay */ + FTU_FAULT_DISABLE_DELAY_VALUE_0 = 1u, /*!< Select delay value 0 */ + FTU_FAULT_DISABLE_DELAY_VALUE_1 = 2u /*!< Select delay value 1 */ +}FTU_FaultDisableDelayType; + +/** + * @brief Input Capture Measurement Mode + * + */ +typedef enum +{ + FTU_MEASURE_MODE_OFF = 0u, /*!< Do not use measurement mode */ + FTU_MEASURE_MODE_DUTY_CYCLE = 1u, /*!< Duty-cycle Measure */ + FTU_MEASURE_MODE_PERIOD = 2u, /*!< Period Measure */ + FTU_MEASURE_EDGE_NUMBER = 3u, /*!< Edge Number Measure */ + FTU_MEASURE_EXPECT_EDGE_NUMBER = 4u, /*!< Expect Edge Number Measure */ + FTU_MEASURE_ICENM_WIND_WRITE = 7u, /*!< Configure ICENM Window */ +}FTU_MeasurementModeType; + +/********* Local inline function ************/ + +/** + * @brief Clear FTU module registers + * + * @param pFtu FTU instance + */ +LOCAL_INLINE void FTU_HWA_ClearModuleRegister(FTU_Type *pFtu) +{ + uint32_t u32Loop; + pFtu->SC &= 0U; + pFtu->CNT = 0U; + pFtu->MOD = 0U; + for(u32Loop = 0u; u32Loop < FTU_CHANNEL_CONTROLS_COUNT; u32Loop++) + { + pFtu->CONTROLS[u32Loop].CSCn = (uint32_t)0u; + pFtu->CONTROLS[u32Loop].CVn = (uint32_t)0u; + } + pFtu->CNTIN = 0U; + pFtu->STATUS |= FTU_STATUS_CHNF_MASK; + pFtu->MODE = 0x00000004U; + pFtu->SYNC = 0U; + pFtu->OUTINIT = 0U; + pFtu->OUTMASK = 0U; + pFtu->CHCTRL = 0U; + pFtu->DEADTIME = 0U; + pFtu->TRIGCONF = 0U; + pFtu->POL = 0U; + pFtu->FMS &= 0U; + pFtu->FILTER = 0U; + pFtu->FLTCTRL = 0U; + pFtu->QDCTRL = 0U; + pFtu->CONF = FTU_CONF_DBG(3u); + pFtu->FLTPOL = 0U; + pFtu->SYNCONF = 0U; + pFtu->INVCTRL = 0U; + pFtu->SWOCTRL = 0U; + pFtu->PWMLOAD = 0U; + pFtu->PAIRDEADTIME0 = 0U; + pFtu->PAIRDEADTIME1 = 0U; + pFtu->PAIRDEADTIME2 = 0U; + pFtu->PAIRDEADTIME3 = 0U; +} + +/** + * @brief Disable Global Time Base Enable + * + * @param pFtu the base address of the FTU instance + */ +LOCAL_INLINE void FTU_HWA_DisableGlobalTimeBase(FTU_Type *pFtu) +{ + pFtu->CONF &= ~FTU_CONF_GTBEEN_MASK; +} + +/** + * @brief Enable Global Time Base Enable + * + * @param pFtu the base address of the FTU instance + */ +LOCAL_INLINE void FTU_HWA_EnableGlobalTimeBase(FTU_Type *pFtu) +{ + pFtu->CONF |= FTU_CONF_GTBEEN_MASK; +} + +/** + * @brief Set the LDOK flag + * + * @param pFtu the base address of the FTU instance + */ +LOCAL_INLINE void FTU_HWA_SetPwmLoadEnable(FTU_Type *pFtu) +{ + pFtu->PWMLOAD |= FTU_PWMLOAD_LDOK_MASK; +} + +/** + * @brief Clear the LDOK flag + * + * @param pFtu the base address of the FTU instance + */ +LOCAL_INLINE void FTU_HWA_ClearPwmLoadEnable(FTU_Type *pFtu) +{ + pFtu->PWMLOAD &= ~FTU_PWMLOAD_LDOK_MASK; +} + +/** + * @brief Set the CNTINC flag + * + * @param pFtu the base address of the FTU instance + */ +LOCAL_INLINE void FTU_HWA_SetCntinSync(FTU_Type *pFtu) +{ + pFtu->SYNCONF |= FTU_SYNCONF_CNTINC_MASK; +} + +/** + * @brief Clear the CNTINC flag + * + * @param pFtu the base address of the FTU instance + */ +LOCAL_INLINE void FTU_HWA_ClearCntinSync(FTU_Type *pFtu) +{ + pFtu->SYNCONF &= ~FTU_SYNCONF_CNTINC_MASK; +} + +/** + * @brief Set the SYNCEN flag + * + * @param pFtu the base address of the FTU instance + * @param u32Index the index of SYNCEN + */ +LOCAL_INLINE void FTU_HWA_SetChannelSyncEnable(FTU_Type *pFtu, uint32_t u32Index) +{ + const uint32_t u32MaskTab[4] = {FTU_CHCTRL_SYNCEN0_MASK, FTU_CHCTRL_SYNCEN1_MASK, + FTU_CHCTRL_SYNCEN2_MASK, FTU_CHCTRL_SYNCEN3_MASK}; + pFtu->CHCTRL |= u32MaskTab[u32Index]; +} + +/** + * @brief Clear the SYNCEN flag + * + * @param pFtu the base address of the FTU instance + * @param u32Index the index of SYNCEN + */ +LOCAL_INLINE void FTU_HWA_ClearChannelSyncEnable(FTU_Type *pFtu, uint32_t u32Index) +{ + const uint32_t u32MaskTab[4] = {FTU_CHCTRL_SYNCEN0_MASK, FTU_CHCTRL_SYNCEN1_MASK, + FTU_CHCTRL_SYNCEN2_MASK, FTU_CHCTRL_SYNCEN3_MASK}; + pFtu->CHCTRL &= ~u32MaskTab[u32Index]; +} + +/** + * @brief Set the PWMSYNC flag + * + * @param pFtu the base address of the FTU instance + */ +LOCAL_INLINE void FTU_HWA_SetPwmSyncMode(FTU_Type *pFtu) +{ + pFtu->MODE |= FTU_MODE_PWMSYNC_MASK; +} + +/** + * @brief Clear the PWMSYNC flag + * + * @param pFtu the base address of the FTU instance + */ +LOCAL_INLINE void FTU_HWA_ClearPwmSyncMode(FTU_Type *pFtu) +{ + pFtu->MODE &= ~FTU_MODE_PWMSYNC_MASK; +} + +/** + * @brief Set the REINIT flag + * + * @param pFtu the base address of the FTU instance + */ +LOCAL_INLINE void FTU_HWA_SetReinitBySync(FTU_Type *pFtu) +{ + pFtu->SYNC |= FTU_SYNC_REINIT_MASK; +} + +/** + * @brief Clear the REINIT flag + * + * @param pFtu the base address of the FTU instance + */ +LOCAL_INLINE void FTU_HWA_ClearReinitBySync(FTU_Type *pFtu) +{ + pFtu->SYNC &= ~FTU_SYNC_REINIT_MASK; +} + +/** + * @brief Set the CNTMAX flag + * + * @param pFtu the base address of the FTU instance + */ +LOCAL_INLINE void FTU_HWA_EnableMaxLoadPoint(FTU_Type *pFtu) +{ + pFtu->SYNC |= FTU_SYNC_CNTMAX_MASK; +} + +/** + * @brief Clear the CNTMAX flag + * + * @param pFtu the base address of the FTU instance + */ +LOCAL_INLINE void FTU_HWA_DisableMaxLoadPoint(FTU_Type *pFtu) +{ + pFtu->SYNC &= ~FTU_SYNC_CNTMAX_MASK; +} + +/** + * @brief Set the CNTMIN flag + * + * @param pFtu the base address of the FTU instance + */ +LOCAL_INLINE void FTU_HWA_EnableMinLoadPoint(FTU_Type *pFtu) +{ + pFtu->SYNC |= FTU_SYNC_CNTMIN_MASK; +} + +/** + * @brief Clear the CNTMIN flag + * + * @param pFtu the base address of the FTU instance + */ +LOCAL_INLINE void FTU_HWA_DisableMinLoadPoint(FTU_Type *pFtu) +{ + pFtu->SYNC &= ~FTU_SYNC_CNTMIN_MASK; +} + +/** + * @brief Set the CHNSEL flag of a channel + * + * @param pFtu the base address of the FTU instance + * @param u32Channel channel index + */ +LOCAL_INLINE void FTU_HWA_EnableChannelMatchReload(FTU_Type *pFtu, uint32_t u32Channel) +{ + pFtu->PWMLOAD |= FTU_PWMLOAD_CHNSEL((uint32_t)1u << u32Channel); +} + +/** + * @brief Clear the CHNSEL flag of a channel + * + * @param pFtu the base address of the FTU instance + * @param u32Channel channel index + */ +LOCAL_INLINE void FTU_HWA_DisableChannelMatchReload(FTU_Type *pFtu, uint32_t u32Channel) +{ + pFtu->PWMLOAD &= ~FTU_PWMLOAD_CHNSEL((uint32_t)1u << u32Channel); +} + +/** + * @brief configure the frequency of the reload opportunities + * + * @param pFtu the base address of the FTU instance + * @param u8Freq the number of enabled reload opportunities that should happen until an + * enabled reload opportunity becomes a reload point + */ +LOCAL_INLINE void FTU_HWA_ConfigFreqOfReloadOp(FTU_Type *pFtu, uint8_t u8Freq) +{ + pFtu->CONF &= ~FTU_CONF_LDFQ_MASK; + pFtu->CONF |= FTU_CONF_LDFQ(u8Freq); +} + +/** + * @brief Selects the FTU behavior in Debug mode + * + * @param pFtu the base address of the FTU instance + * @param u32Mode debug mode + */ +LOCAL_INLINE void FTU_HWA_ConfigDebugMode(FTU_Type *pFtu, uint32_t u32Mode) +{ + pFtu->CONF &= ~FTU_CONF_DBG_MASK; + pFtu->CONF |= FTU_CONF_DBG(u32Mode); +} + +/** + * @brief Disable channel match trigger/interrupt when count-up/down in CPWM/QUAD mode + * + * @param pFtu the base address of the FTU instance + * @param eUpdownDisable up-down disable mode + */ +LOCAL_INLINE void FTU_HWA_ConfigUpDownDisable(FTU_Type *pFtu, FTU_UpDownDisableType eUpdownDisable) +{ + pFtu->SC &= ~FTU_SC_UPDOWN_DIS_MASK; + pFtu->SC |= FTU_SC_UPDOWN_DIS((uint32_t)eUpdownDisable); +} + +/** + * @brief Enable reload point interrupt + * + * @param pFtu the base address of the FTU instance + */ +LOCAL_INLINE void FTU_HWA_EnableReloadPointInterrupt(FTU_Type *pFtu) +{ + pFtu->SC |= FTU_SC_RIE_MASK; +} + +/** + * @brief Disable reload point interrupt + * + * @param pFtu the base address of the FTU instance + */ +LOCAL_INLINE void FTU_HWA_DisableReloadPointInterrupt(FTU_Type *pFtu) +{ + pFtu->SC &= ~((uint32_t)FTU_SC_RIE_MASK); +} + +/** + * @brief Enable software output control of channels + * + * @param pFtu the base address of the FTU instance + * @param u32Mask channel mask + */ +LOCAL_INLINE void FTU_HWA_EnalbeSWOControl(FTU_Type *pFtu, uint32_t u32Mask) +{ + pFtu->SWOCTRL |= FTU_SWOCTRL_CHNOC(u32Mask); +} + +/** + * @brief Disable software output control of channels + * + * @param pFtu the base address of the FTU instance + * @param u32Mask channel mask + */ +LOCAL_INLINE void FTU_HWA_DisalbeSWOControl(FTU_Type *pFtu, uint32_t u32Mask) +{ + pFtu->SWOCTRL &= ~FTU_SWOCTRL_CHNOC(u32Mask); +} + +/** + * @brief Set the software output control value + * + * @param pFtu the base address of the FTU instance + * @param u32Mask channel mask + */ +LOCAL_INLINE void FTU_HWA_SetSWOValue(FTU_Type *pFtu, uint32_t u32Mask) +{ + pFtu->SWOCTRL |= FTU_SWOCTRL_CHNOCV(u32Mask); +} + +/** + * @brief Clear the software output control value + * + * @param pFtu the base address of the FTU instance + * @param u32Mask channel mask + */ +LOCAL_INLINE void FTU_HWA_ClearSWOValue(FTU_Type *pFtu, uint32_t u32Mask) +{ + pFtu->SWOCTRL &= ~FTU_SWOCTRL_CHNOCV(u32Mask); +} + +/** + * @brief Configure the pair deadtime prescaler value + * + * @param pFtu the base address of the FTU instance + * @param u32Channel channel index + * @param ePrescaler prescaler value + */ +LOCAL_INLINE void FTU_HWA_ConfigPairDeadtimePrescaler(FTU_Type *pFtu, uint32_t u32Channel, FTU_DeadTimePrescalerType ePrescaler) +{ + uint32_t u32RegValue; + volatile uint32_t *pPairDeadtime = &pFtu->PAIRDEADTIME0; + u32Channel = u32Channel >> 1u; + u32RegValue = pPairDeadtime[(u32Channel << 1u)]; + u32RegValue &= ~(uint32_t)FTU_DEADTIME_DTPS_MASK; + u32RegValue |= FTU_DEADTIME_DTPS(ePrescaler); + *pPairDeadtime = u32RegValue; +} + +/** + * @brief Configure the deadtime value + * + * @param pFtu the base address of the FTU instance + * @param u32Channel channel index + * @param u32Value deadtime value + */ +LOCAL_INLINE void FTU_HWA_ConfigPairDeadtimeValue(FTU_Type *pFtu, uint32_t u32Channel, uint32_t u32Value) +{ + uint32_t u32RegValue; + volatile uint32_t *pPairDeadtime = &pFtu->PAIRDEADTIME0; + u32Channel = u32Channel >> 1u; + u32RegValue = pPairDeadtime[(u32Channel << 1u)]; + u32RegValue &= ~(uint32_t)FTU_DEADTIME_DTVAL_MASK; + u32RegValue &= ~(uint32_t)FTU_DEADTIME_DTVALEX_MASK; + u32RegValue |= FTU_DEADTIME_DTVAL(u32Value & 0x3Fu); + u32RegValue |= FTU_DEADTIME_DTVALEX(u32Value >> 6); + *pPairDeadtime = u32RegValue; +} + +/** + * @brief Configure the deadtime prescaler value + * + * @param pFtu the base address of the FTU instance + * @param ePrescaler prescaler value + */ +LOCAL_INLINE void FTU_HWA_ConfigDeadtimePrescaler(FTU_Type *pFtu, FTU_DeadTimePrescalerType ePrescaler) +{ + uint32_t u32RegValue = pFtu->DEADTIME; + u32RegValue &= ~(uint32_t)FTU_DEADTIME_DTPS_MASK; + u32RegValue |= FTU_DEADTIME_DTPS(ePrescaler); + pFtu->DEADTIME = u32RegValue; +} + +/** + * @brief Configure the deadtime value + * + * @param pFtu the base address of the FTU instance + * @param u32Value deadtime value + */ +LOCAL_INLINE void FTU_HWA_ConfigDeadtimeValue(FTU_Type *pFtu, uint32_t u32Value) +{ + uint32_t u32RegValue = pFtu->DEADTIME; + u32RegValue &= ~(uint32_t)FTU_DEADTIME_DTVAL_MASK; + u32RegValue &= ~(uint32_t)FTU_DEADTIME_DTVALEX_MASK; + u32RegValue |= FTU_DEADTIME_DTVAL(u32Value & 0x3Fu); + u32RegValue |= FTU_DEADTIME_DTVALEX(u32Value >> 6); + pFtu->DEADTIME = u32RegValue; +} + +/** + * @brief Get the counter value of the selected FTU module + * + * @param pFtu the base address of the FTU instance + */ +LOCAL_INLINE uint32_t FTU_HWA_GetCounterValue(FTU_Type *pFtu) +{ + return (uint32_t)pFtu->CNT; +} + +/** + * @brief Clear FTU counter + * + * @param pFtu the base address of the FTU instance + * @param u32RegValue CNT register value + */ +LOCAL_INLINE void FTU_HWA_ClearModuleCounter(FTU_Type *pFtu, uint32_t u32RegValue) +{ + pFtu->CNT = u32RegValue; +} + +/** + * @brief Configure FTU channel + * + * @param pFtu the base address of the FTU instance + * @param u8Channel channel number, range is 0-7 + * @param u32RegValue the value to write to CSC register + */ +LOCAL_INLINE void FTU_HWA_ConfigChannel(FTU_Type *pFtu, uint8_t u8Channel, uint32_t u32RegValue) +{ + pFtu->CONTROLS[u8Channel].CSCn = u32RegValue; +} + +/** + * @brief Get FTU channel value + * + * @param pFtu the base address of the FTU instance + * @param u8Channel channel number, range is 0-7 + * @return CVn register value + */ +LOCAL_INLINE uint32_t FTU_HWA_GetChannelValue(FTU_Type *pFtu, uint8_t u8Channel) +{ + return (pFtu->CONTROLS[u8Channel].CVn); +} + +/** + * @brief Set FTU channel value + * + * @param pFtu the base address of the FTU instance + * @param u8Channel channel number, range is 0-7 + * @param u32RegValue CVn register value + */ +LOCAL_INLINE void FTU_HWA_SetChannelValue(FTU_Type *pFtu, uint8_t u8Channel, uint32_t u32RegValue) +{ + pFtu->CONTROLS[u8Channel].CVn = u32RegValue; +} + +/** + * @brief Set FTU counter compare val + * + * @param pFtu the base address of the FTU instance + * @param u32RegValue MOD register value + */ +LOCAL_INLINE void FTU_HWA_SetModuleCompareValue(FTU_Type *pFtu, uint32_t u32RegValue) +{ + pFtu->MOD = u32RegValue & FTU_MOD_MASK; +} + +/** + * @brief Set FTU counter initial value + * + * @param pFtu the base address of the FTU instance + * @param u32RegValue CNTIN register value + */ +LOCAL_INLINE void FTU_HWA_SetCounterInitialValue(FTU_Type *pFtu, uint32_t u32RegValue) +{ + pFtu->CNTIN = u32RegValue & FTU_CNTIN_INIT_MASK; +} + +/** + * @brief Configure FTU mode + * + * @param pFtu the base address of the FTU instance + * @param u32RegValue MODE register value + */ +LOCAL_INLINE void FTU_HWA_ConfigModuleMode(FTU_Type *pFtu, uint32_t u32RegValue) +{ + pFtu->MODE = u32RegValue; +} + +/** + * @brief Configure FTU deadtime + * + * @param pFtu the base address of the FTU instance + * @param u32RegValue DEADTIME register value + */ +LOCAL_INLINE void FTU_HWA_ConfigDeadtime(FTU_Type *pFtu, uint32_t u32RegValue) +{ + pFtu->DEADTIME = u32RegValue; +} + +/** + * @brief Configure input capture filter + * + * @param pFtu the base address of the FTU instance + * @param u32Channel Channel of FTU instance + * @param u32FilterValue Filter value + */ +LOCAL_INLINE void FTU_HWA_ConfigInputCaptureFilter(FTU_Type *pFtu, uint32_t u32Channel, uint32_t u32FilterValue) +{ + pFtu->FILTER &= ~((uint32_t)0xFu << (u32Channel << 2)); + pFtu->FILTER |= u32FilterValue << (u32Channel << 2); +} + +/** + * @brief Enable FTU module fault + * + * @param pFtu the base address of the FTU instance + * @param u8InputMask Fault input mask, 0-3 bit indicate fault 0-3 + */ +LOCAL_INLINE void FTU_HWA_EnableModuleFault(FTU_Type *pFtu, uint8_t u8InputMask) +{ + pFtu->FLTCTRL |= ((uint32_t)u8InputMask & (uint32_t)0xFU); +} + +/** + * @brief get the fault input enable status + * + * @param pFtu the base address of the FTU instance + */ +LOCAL_INLINE uint32_t FTU_HWA_GetFaultEnable(FTU_Type *pFtu) +{ + uint32_t u32RegValue = pFtu->FLTCTRL; + return u32RegValue & (uint32_t)0xFU; +} + +/** + * @brief Disable FTU module fault + * + * @param pFtu the base address of the FTU instance + * @param u8Input Fault input number, 0-3 bit indicate fault 0-3 + */ +LOCAL_INLINE void FTU_HWA_DisableModuleFault(FTU_Type *pFtu, uint8_t u8Input) +{ + pFtu->FLTCTRL &= ~((uint32_t)u8Input & (uint32_t)0xFU); +} + +/** + * @brief Enable FTU module fault glitch filter + * + * @param pFtu the base address of the FTU instance + * @param u8Input Fault input number, 0-3 bit indicate fault 0-3 + */ +LOCAL_INLINE void FTU_HWA_EnableModuleFaultGlitchFilter(FTU_Type *pFtu, uint8_t u8Input) +{ + pFtu->FLTCTRL |= (((uint32_t)u8Input & (uint32_t)0xFU) << 4U); +} + +/** + * @brief Disable FTU module fault glitch filter + * + * @param pFtu the base address of the FTU instance + * @param u8Input Fault input number, 0-3 bit indicate fault 0-3 + */ +LOCAL_INLINE void FTU_HWA_DisableModuleFaultGlitchFilter(FTU_Type *pFtu, uint8_t u8Input) +{ + pFtu->FLTCTRL &= ~(((uint32_t)u8Input & (uint32_t)0xFU) << FTU_FLTCTRL_FLT0GFEN_SHIFT); +} + +/** + * @brief Set FTU module fault filter value + * + * @param pFtu the base address of the FTU instance + * @param u8Value FTU fault filter value + */ +LOCAL_INLINE void FTU_HWA_SetModuleFaultFilterValue(FTU_Type *pFtu, uint8_t u8Value) +{ + uint32_t u32TempRegValue = pFtu->FLTCTRL; + pFtu->FLTCTRL = (u32TempRegValue & ~(uint32_t)FTU_FLTCTRL_FFVAL_MASK) | FTU_FLTCTRL_FFVAL(u8Value); +} + +/** + * @brief Set FTU module fault disable channel output delay value0 + * + * @param pFtu the base address of the FTU instance + * @param u8Value FTU fault delay value0 + */ +LOCAL_INLINE void FTU_HWA_SetFaultDelay0(FTU_Type *pFtu, uint8_t u8Value) +{ + pFtu->FLTCTRL &= ~(uint32_t)FTU_FLTCTRL_FDLYV0_MASK; + pFtu->FLTCTRL |= FTU_FLTCTRL_FDLYV0(u8Value); +} + +/** + * @brief Set FTU module fault disable channel output delay value + * + * @param pFtu the base address of the FTU instance + * @param u8Value FTU fault delay value1 + */ +LOCAL_INLINE void FTU_HWA_SetFaultDelay1(FTU_Type *pFtu, uint8_t u8Value) +{ + pFtu->FLTPOL &= ~(uint32_t)FTU_FLTPOL_FDLYV1_MASK; + pFtu->FLTPOL |= FTU_FLTPOL_FDLYV1(u8Value); +} + +/** + * @brief Configure FTU module fault polarity + * + * @param pFtu the base address of the FTU instance + * @param u32FaultIndex index of the fault + * @param u8InputPol the polarity of the fault input + */ +LOCAL_INLINE void FTU_HWA_ConfigFaultPolarity(FTU_Type *pFtu, uint32_t u32FaultIndex, uint8_t u8InputPol) +{ + uint32_t u32RegValue = pFtu->FLTPOL; + u32RegValue &= ~(FTU_FLTPOL_FLT0POL_MASK << u32FaultIndex); + u32RegValue |= FTU_FLTPOL_FLT0POL(u8InputPol) << u32FaultIndex; + pFtu->FLTPOL = u32RegValue; +} + +/** + * @brief Set FTU module prescale + * + * @param pFtu the base address of the FTU instance + * @param ePs FTU clock prescaler enumeration + */ +LOCAL_INLINE void FTU_HWA_SetModulePrescale(FTU_Type *pFtu, FTU_PrescalerType ePs) +{ + uint32_t u32RegValue = pFtu->SC; + pFtu->SC = (u32RegValue & ~(uint32_t)FTU_SC_PS_MASK) | FTU_SC_PS(ePs); +} + +/** + * @brief Read FTU module overflow flag + * + * @param pFtu the base address of the FTU instance + * @return FTU overflow flag + */ +LOCAL_INLINE uint8_t FTU_HWA_ReadModuleOverflowFlag(FTU_Type *pFtu) +{ + return (uint8_t)((pFtu->SC & (uint32_t)FTU_SC_TOF_MASK) >> FTU_SC_TOF_SHIFT); +} + +/** + * @brief Read FTU module overflow interrupt enable + * + * @param pFtu the base address of the FTU instance + * @return FTU overflow interrupt enable + */ +LOCAL_INLINE uint8_t FTU_HWA_ReadModuleOverflowIntrEnable(FTU_Type *pFtu) +{ + return (uint8_t)((pFtu->SC & (uint32_t)FTU_SC_TOIE_MASK) >> FTU_SC_TOIE_SHIFT); +} + +/** + * @brief Read FTU module reload flag + * + * @param pFtu the base address of the FTU instance + * @return FTU reload flag + */ +LOCAL_INLINE uint8_t FTU_HWA_ReadModuleReloadFlag(FTU_Type *pFtu) +{ + return (uint8_t)((pFtu->SC & (uint32_t)FTU_SC_RF_MASK) >> FTU_SC_RF_SHIFT); +} + +/** + * @brief Read FTU module reload interrupt enable + * + * @param pFtu the base address of the FTU instance + * @return reload interrupt enable + */ +LOCAL_INLINE uint8_t FTU_HWA_ReadReloadIntrEnable(FTU_Type *pFtu) +{ + return (uint8_t)((pFtu->SC & (uint32_t)FTU_SC_RIE_MASK) >> FTU_SC_RIE_SHIFT); +} + +/** + * @brief Read FTU channel interrupt flag + * + * @param pFtu the base address of the FTU instance + * @param u8Channel FTU channel number, range is 0-7. + * @return FTU channel interrupt flag + */ +LOCAL_INLINE bool FTU_HWA_ReadChannelInterruptFlag(FTU_Type *pFtu, uint8_t u8Channel) +{ + return (0u != (pFtu->CONTROLS[u8Channel].CSCn & (uint32_t)FTU_CSC_CHF_MASK)); +} + +/** + * @brief Configure the channel output mode + * + * @param pFtu the base address of the FTU instance + * @param u8Channel FTU channel number, range is 0-7. + * @param eMode output mode of the selected channel. + */ +LOCAL_INLINE void FTU_HWA_ConfigTrigOutputMode(FTU_Type *pFtu, uint8_t u8Channel, FTU_TrigOutputModeType eMode) +{ + pFtu->CONTROLS[u8Channel].CSCn &= ~(uint32_t)FTU_CSC_TRIGMODE_MASK; + pFtu->CONTROLS[u8Channel].CSCn |= (uint32_t)FTU_CSC_TRIGMODE(eMode); +} + +/** + * @brief Select fault disable channel output delay value + * + * @param pFtu the base address of the FTU instance + * @param u8Channel FTU channel number, range is 0-7. + * @param eSelection Fault disable channel output delay value selection. + */ +LOCAL_INLINE void FTU_HWA_SelectFaultDelay(FTU_Type *pFtu, uint8_t u8Channel, FTU_FaultDisableDelayType eSelection) +{ + pFtu->CONTROLS[u8Channel].CSCn &= ~(uint32_t)FTU_CSC_FDLYSEL_MASK; + pFtu->CONTROLS[u8Channel].CSCn |= (uint32_t)FTU_CSC_FDLYSEL(eSelection); +} + +/** + * @brief Read FTU channel interrupt enable flag + * + * @param pFtu the base address of the FTU instance + * @param u8Channel FTU channel number, range is 0-7. + * @return FTU channel interrupt flag + */ +LOCAL_INLINE uint8_t FTU_HWA_ReadChannelInterruptEnableFlag(FTU_Type *pFtu, uint8_t u8Channel) +{ + return (uint8_t)((pFtu->CONTROLS[u8Channel].CSCn & (uint32_t)FTU_CSC_CHIE_MASK) >> FTU_CSC_CHIE_SHIFT); +} + +/** + * @brief Read FTU module fault(n) flag + * + * @param pFtu the base address of the FTU instance + * @return FTU fault flag + */ +LOCAL_INLINE uint32_t FTU_HWA_ReadModuleFaultFlag(FTU_Type *pFtu) +{ + return (uint32_t)(pFtu->FMS & (uint32_t)0xFU); +} + +/** + * @brief Read FTU module fault interrupt enable + * + * @param pFtu the base address of the FTU instance + * @return FTU fault interrupt enable + */ +LOCAL_INLINE uint8_t FTU_HWA_ReadFaultIntrEnable(FTU_Type *pFtu) +{ + return (uint8_t)((pFtu->MODE & (uint32_t)FTU_MODE_FAULTIE_MASK) >> FTU_MODE_FAULTIE_SHIFT); +} + +/** + * @brief Read FTU module fault detection flag + * + * @param pFtu the base address of the FTU instance + * @return FTU fault detection flag + */ +LOCAL_INLINE uint8_t FTU_HWA_ReadModuleFaultDetectionFlag(FTU_Type *pFtu) +{ + return (uint8_t)((pFtu->FMS & (uint32_t)FTU_FMS_FAULTF_MASK) >> FTU_FMS_FAULTF_SHIFT); +} + +/** + * @brief Enable FTU module channel(n) output + * + * @param pFtu the base address of the FTU instance + * @param u8ChannelMask 0-7 bit indicate 0-7 channel + */ +LOCAL_INLINE void FTU_HWA_EnableChannelsOutput(FTU_Type *pFtu, uint8_t u8ChannelMask) +{ + pFtu->SC |= (uint32_t)FTU_SC_CHNOUTEN(u8ChannelMask); +} + +/** + * @brief Get cpwm mode of the FTU module + * + * @param pFtu the base address of the FTU instance + * @return cpwm mode bit value of the FTU module + */ +LOCAL_INLINE uint8_t FTU_HWA_GetModuleCpwmMode(FTU_Type *pFtu) +{ + return (uint8_t)((pFtu->SC & (uint32_t)FTU_SC_CPWMS_MASK) >> FTU_SC_CPWMS_SHIFT); +} + +/** + * @brief Enable FTU module cpwm mode + * + * @param pFtu the base address of the FTU instance + */ +LOCAL_INLINE void FTU_HWA_EnableModuleCpwmMode(FTU_Type *pFtu) +{ + pFtu->SC |= (uint32_t)FTU_SC_CPWMS_MASK; +} + +/** + * @brief Disable FTU module cpwm mode + * + * @param pFtu the base address of the FTU instance + */ +LOCAL_INLINE void FTU_HWA_DisableModuleCpwmMode(FTU_Type *pFtu) +{ + pFtu->SC &= ~(uint32_t)FTU_SC_CPWMS_MASK; +} + +/** + * @brief Set FTU module filter prescale + * + * @param pFtu the base address of the FTU instance + * @param eFilterPs FTU clock filter prescaler enumeration + */ +LOCAL_INLINE void FTU_HWA_ConfigModuleFilterPrescale(FTU_Type *pFtu, FTU_FilterPrescalerType eFilterPs) +{ + pFtu->SC &= ~(uint32_t)FTU_SC_FLTPS_MASK; + pFtu->SC |= FTU_SC_FLTPS(eFilterPs); +} + +/** + * @brief Selects the external clock as the FTU function clock + * + * @param pFtu the base address of the FTU instance + * @param eTclk FTU external clock enumeration + */ +LOCAL_INLINE void FTU_HWA_ConfigExternalClkSrc(FTU_Type *pFtu, FTU_TclkSelType eTclk) +{ + pFtu->SC &= ~(uint32_t)FTU_SC_TCKSEL_MASK; + pFtu->SC |= FTU_SC_TCKSEL(eTclk); +} + +LOCAL_INLINE void FTU_HWA_ConfigChannelMode(FTU_Type *pFtu, uint8_t u8Channel, FTU_ChannelModeType eMode) +{ + pFtu->CONTROLS[u8Channel].CSCn &= ~(uint32_t)(FTU_CSC_MSB_MASK | FTU_CSC_MSA_MASK); + pFtu->CONTROLS[u8Channel].CSCn |= (eMode << FTU_CSC_MSA_SHIFT) & (uint32_t)(FTU_CSC_MSB_MASK | FTU_CSC_MSA_MASK); +} + +LOCAL_INLINE void FTU_HWA_ConfigChannelEdgeLevel(FTU_Type *pFtu, uint8_t u8Channel, FTU_ChannelEdgeLevelType eEdgeLevel) +{ + pFtu->CONTROLS[u8Channel].CSCn &= ~(uint32_t)(FTU_CSC_ELSB_MASK | FTU_CSC_ELSA_MASK); + pFtu->CONTROLS[u8Channel].CSCn |= (eEdgeLevel << FTU_CSC_ELSA_SHIFT) & (uint32_t)(FTU_CSC_ELSB_MASK | FTU_CSC_ELSA_MASK); +} + +LOCAL_INLINE uint8_t FTU_HWA_GetEdgeNumberCount(FTU_Type *pFtu, uint8_t u8Channel) +{ + return (uint8_t)((pFtu->CONTROLS[u8Channel].CSCn & FTU_CSC_ICM_ICEXP_NUM_ICM_ECNT_MASK) >> FTU_CSC_ICM_ICEXP_NUM_ICM_ECNT_SHIFT); +} + +LOCAL_INLINE void FTU_HWA_ConfigEdgeNumber(FTU_Type *pFtu, uint8_t u8Channel, uint8_t u8EdgeNumber) +{ + pFtu->CONTROLS[u8Channel].CSCn &= (uint32_t)~FTU_CSC_ICM_ICEXP_NUM_ICM_ECNT_MASK; + pFtu->CONTROLS[u8Channel].CSCn |= FTU_CSC_ICM_ICEXP_NUM_ICM_ECNT(u8EdgeNumber); +} + +/** + * @brief Re-start measurement when in single mode + * + * @param pFtu the base address of the FTU instance + * @param u8Channel FTU channel number, range is 0-7. + */ +LOCAL_INLINE void FTU_HWA_SingleMeasurement(FTU_Type *pFtu, uint8_t u8Channel) +{ + pFtu->CONTROLS[u8Channel].CSCn |= (uint32_t)FTU_CSC_ICM_SINGLE_MASK; +} +/** + * @brief Set the measurement channel to continuous mode + * + * @param pFtu the base address of the FTU instance + * @param u8Channel FTU channel number, range is 0-7. + */ +LOCAL_INLINE void FTU_HWA_EnableMeasureContinous(FTU_Type *pFtu, uint8_t u8Channel) +{ + pFtu->CONTROLS[u8Channel].CSCn |= (uint32_t)FTU_CSC_ICM_CONT_MASK; +} +/** + * @brief Set the measurement channel to single mode + * + * @param pFtu the base address of the FTU instance + * @param u8Channel FTU channel number, range is 0-7. + */ +LOCAL_INLINE void FTU_HWA_DisableMeasureContinous(FTU_Type *pFtu, uint8_t u8Channel) +{ + pFtu->CONTROLS[u8Channel].CSCn &= ~(uint32_t)FTU_CSC_ICM_CONT_MASK; +} +/** + * @brief Set the channel starts measuring after the first edge is detected + * + * @param pFtu the base address of the FTU instance + * @param u8Channel FTU channel number, range is 0-7. + */ +LOCAL_INLINE void FTU_HWA_EnableMeasureStartImmd(FTU_Type *pFtu, uint8_t u8Channel) +{ + pFtu->CONTROLS[u8Channel].CSCn |= (uint32_t)FTU_CSC_ICM_START_MASK; +} + +LOCAL_INLINE void FTU_HWA_ConfigInputCaptureMeasureMode(FTU_Type *pFtu, uint8_t u8Channel, FTU_MeasurementModeType eMode) +{ + pFtu->CONTROLS[u8Channel].CSCn &= ~(uint32_t)FTU_CSC_ICM_MODE_MASK; + pFtu->CONTROLS[u8Channel].CSCn |= FTU_CSC_ICM_MODE(eMode); +} + +/** + * @brief Set the measurement starts immediately after activating the channel + * + * @param pFtu the base address of the FTU instance + * @param u8Channel FTU channel number, range is 0-7. + */ +LOCAL_INLINE void FTU_HWA_DisableMeasureStartImmd(FTU_Type *pFtu, uint8_t u8Channel) +{ + pFtu->CONTROLS[u8Channel].CSCn &= ~(uint32_t)FTU_CSC_ICM_START_MASK; +} + +/** + * @brief Get channel measure mode + * + * @param pFtu the base address of the FTU instance + * @param u8Channel FTU channel + * @return measure mode + */ +LOCAL_INLINE FTU_MeasurementModeType FTU_HWA_GetMeasureMode(FTU_Type *pFtu, uint8_t u8Channel) +{ + return (FTU_MeasurementModeType)((pFtu->CONTROLS[u8Channel].CSCn & FTU_CSC_ICM_MODE_MASK) >> FTU_CSC_ICM_MODE_SHIFT); +} + +/** + * @brief Configure Edge-Aligned pwm mode channel to High-true pulses(clear output on match) + * + * @param pFtu the base address of the FTU instance + * @param u8Channel FTU channel number, range is 0-7. + */ +LOCAL_INLINE void FTU_HWA_SetChannelEpwmHighTrue(FTU_Type *pFtu, uint8_t u8Channel) +{ + pFtu->CONTROLS[u8Channel].CSCn &= ~(uint32_t)FTU_CSC_ELSA_MASK; + pFtu->CONTROLS[u8Channel].CSCn |= (uint32_t)(FTU_CSC_MSB_MASK | FTU_CSC_ELSB_MASK); +} + +/** + * @brief Configure Edge-Aligned pwm mode channel to Low-true pulses(set output on match) + * + * @param pFtu the base address of the FTU instance + * @param u8Channel FTU channel number, range is 0-7. + */ +LOCAL_INLINE void FTU_HWA_SetChannelEpwmLowTrue(FTU_Type *pFtu, uint8_t u8Channel) +{ + pFtu->CONTROLS[u8Channel].CSCn |= (uint32_t)(FTU_CSC_MSB_MASK | FTU_CSC_ELSA_MASK); +} + +/** + * @brief Configure pwm link mode channel + * + * @param pFtu the base address of the FTU instance + * @param u8Channel FTU channel number, range is 0-7. + */ +LOCAL_INLINE void FTU_HWA_ConfigChannelPwmLinkMode(FTU_Type *pFtu, uint8_t u8Channel) +{ + pFtu->CONTROLS[u8Channel].CSCn &= ~(uint32_t)(FTU_CSC_ELSA_MASK | FTU_CSC_MSB_MASK | FTU_CSC_MSA_MASK); + pFtu->CONTROLS[u8Channel].CSCn |= (uint32_t)FTU_CSC_ELSB_MASK; +} + +/** + * @brief Enable FTU channel interrupt + * + * @param pFtu the base address of the FTU instance + * @param u8Channel FTU channel number, range is 0-7. + */ +LOCAL_INLINE void FTU_HWA_EnableChannelInterrupt(FTU_Type *pFtu, uint8_t u8Channel) +{ + pFtu->CONTROLS[u8Channel].CSCn |= (uint32_t)FTU_CSC_CHIE_MASK; +} + +/** + * @brief Set MODE[FTUEN], this field define different free running counter and synchronization behavior. + * + * @param pFtu the base address of the FTU instance + */ +LOCAL_INLINE void FTU_HWA_SetModuleUpdateRegBySync(FTU_Type *pFtu) +{ + pFtu->MODE |= (uint32_t)FTU_MODE_FTUEN_MASK; +} + +/** + * @brief Clear MODE[FTUEN], this field define different free running counter and synchronization behavior. + * + * @param pFtu the base address of the FTU instance + */ +LOCAL_INLINE void FTU_HWA_ClearModuleUpdateRegBySync(FTU_Type *pFtu) +{ + pFtu->MODE &= ~(uint32_t)FTU_MODE_FTUEN_MASK; +} + +/** + * @brief Enable FTU module fault interrupt + * + * @param pFtu the base address of the FTU instance + */ +LOCAL_INLINE void FTU_HWA_EnableModuleFaultInterrupt(FTU_Type *pFtu) +{ + pFtu->MODE |= (uint32_t)FTU_MODE_FAULTIE_MASK; +} + + +/** + * @brief Enable FTU channel dma + * + * @param pFtu the base address of the FTU instance + * @param u8Channel FTU channel number, range is 0-7. + */ +LOCAL_INLINE void FTU_HWA_EnableChannelDma(FTU_Type *pFtu, uint8_t u8Channel) +{ + pFtu->CONTROLS[u8Channel].CSCn |= (uint32_t)FTU_CSC_DMA_MASK; +} + + +/** + * @brief Configure FTU module fault mode + * + * @param pFtu the base address of the FTU instance + * @param eMode Fault mode type + */ +LOCAL_INLINE void FTU_HWA_ConfigModuleFaultMode(FTU_Type *pFtu, FTU_FaultModeType eMode) +{ + pFtu->MODE &= ~(uint32_t)FTU_MODE_FAULTM_MASK; + pFtu->MODE |= FTU_MODE_FAULTM(eMode); +} + +/** + * @brief Enable synchronization hardware trigger 0 + * + * @param pFtu the base address of the FTU instance + */ +LOCAL_INLINE void FTU_HWA_EnableTrigger0Sync(FTU_Type *pFtu) +{ + pFtu->SYNC |= (uint32_t)FTU_SYNC_TRIG0_MASK; +} + +/** + * @brief Enable synchronization hardware trigger 1 + * + * @param pFtu the base address of the FTU instance + */ +LOCAL_INLINE void FTU_HWA_EnableTrigger1Sync(FTU_Type *pFtu) +{ + pFtu->SYNC |= (uint32_t)FTU_SYNC_TRIG1_MASK; +} + +/** + * @brief Enable synchronization hardware trigger 2 + * + * @param pFtu the base address of the FTU instance + */ +LOCAL_INLINE void FTU_HWA_EnableTrigger2Sync(FTU_Type *pFtu) +{ + pFtu->SYNC |= (uint32_t)FTU_SYNC_TRIG2_MASK; +} + +/** + * @brief Enable FTU module output mask synchronization + * + * @param pFtu the base address of the FTU instance + */ +LOCAL_INLINE void FTU_HWA_EnableOutputMaskBySync(FTU_Type *pFtu) +{ + pFtu->SYNC |= (uint32_t)FTU_SYNC_SYNCHOM_MASK; +} + +/** + * @brief Disable FTU module output mask synchronization + * + * @param pFtu the base address of the FTU instance + */ +LOCAL_INLINE void FTU_HWA_DisableOutputMaskBySync(FTU_Type *pFtu) +{ + pFtu->SYNC &= ~(uint32_t)FTU_SYNC_SYNCHOM_MASK; +} + +/** + * @brief Generate FTU software trigger + * + * @param pFtu the base address of the FTU instance + */ +LOCAL_INLINE void FTU_HWA_GenerateSwSync(FTU_Type *pFtu) +{ + pFtu->SYNC |= (uint32_t)FTU_SYNC_SWSYNC_MASK; +} + +/** + * @brief Configure FTU trigger mode + * + * @param pFtu the base address of the FTU instance + * @param eTrigMode Trigger mode type + */ +LOCAL_INLINE void FTU_HWA_ConfigTrigMode(FTU_Type *pFtu, FTU_TrigModeType eTrigMode) +{ + pFtu->SYNCONF &= ~(uint32_t)FTU_SYNCONF_HWTRIGMODE_MASK; + pFtu->SYNCONF |= (uint32_t)FTU_SYNCONF_HWTRIGMODE(eTrigMode); +} + +/** + * @brief Enable channel(n/n+1) deadtime functionality + * + * @param pFtu the base address of the FTU instance + * @param u8Channel channel number, range is 0-7 + */ +LOCAL_INLINE void FTU_HWA_EnableChannelDeadtime(FTU_Type *pFtu, uint8_t u8Channel) +{ + pFtu->CHCTRL |= FTU_CHCTRL_DEADTIME_CHANNEL(u8Channel); +} + +/** + * @brief Enable channel(n/n+1) complement functionality + * + * @param pFtu the base address of the FTU instance + * @param u8Channel channel number, range is 0-7 + */ +LOCAL_INLINE void FTU_HWA_EnableChannelComplement(FTU_Type *pFtu, uint8_t u8Channel) +{ + pFtu->CHCTRL |= FTU_CHCTRL_COMPLEMENT_CHANNEL(u8Channel); +} + +/** + * @brief Enable channel(n/n+1) synchronization functionality + * + * @param pFtu the base address of the FTU instance + * @param u8Channel channel number, range is 0-7 + */ +LOCAL_INLINE void FTU_HWA_EnableChannelSync(FTU_Type *pFtu, uint8_t u8Channel) +{ + pFtu->CHCTRL |= FTU_CHCTRL_SYNCEN_CHANNEL(u8Channel); +} + +/** + * @brief Enable channel(n/n+1) Phase Shift Mode functionality + * + * @param pFtu the base address of the FTU instance + * @param u8Channel channel number, range is 0-7 + */ +LOCAL_INLINE void FTU_HWA_EnableChannelPhase(FTU_Type *pFtu, uint8_t u8Channel) +{ + pFtu->CHCTRL |= FTU_CHCTRL_PHASE_CHANNEL(u8Channel); +} +/** + * @brief Disable channel(n/n+1) Phase Shift Mode functionality + * + * @param pFtu the base address of the FTU instance + * @param u8Channel channel number, range is 0-7 + */ +LOCAL_INLINE void FTU_HWA_DisableChannelPhase(FTU_Type *pFtu, uint8_t u8Channel) +{ + pFtu->CHCTRL &= ~FTU_CHCTRL_PHASE_CHANNEL(u8Channel); +} +/** + * @brief Enable channel(n/n+1) Enhanced Phase Shift Mode functionality + * + * @param pFtu the base address of the FTU instance + * @param u8Channel channel number, range is 0-7 + */ +LOCAL_INLINE void FTU_HWA_EnableChannelEnhancedPhase(FTU_Type *pFtu, uint8_t u8Channel) +{ + pFtu->CHCTRL |= FTU_CHCTRL_EPHASE_CHANNEL(u8Channel); +} +/** + * @brief Disable channel(n/n+1) Enhanced Phase Shift Mode functionality + * + * @param pFtu the base address of the FTU instance + * @param u8Channel channel number, range is 0-7 + */ +LOCAL_INLINE void FTU_HWA_DisableChannelEnhancedPhase(FTU_Type *pFtu, uint8_t u8Channel) +{ + pFtu->CHCTRL &= ~FTU_CHCTRL_EPHASE_CHANNEL(u8Channel); +} + +/** + * @brief Enable channel(n/n+1) fault functionality + * + * @param pFtu the base address of the FTU instance + * @param u8Channel channel number, range is 0-7 + */ +LOCAL_INLINE void FTU_HWA_EnableChannelFault(FTU_Type *pFtu, uint8_t u8Channel) +{ + pFtu->CHCTRL |= FTU_CHCTRL_FAULT_CHANNEL(u8Channel); +} + +/** + * @brief Enable channel trigger out + * + * @param pFtu the base address of the FTU instance + * @param u8ChannelMask FTU channel mask, bit 0-7 indicate channel 0-7 + */ +LOCAL_INLINE void FTU_HWA_EnableChannelTriggerOut(FTU_Type *pFtu, uint8_t u8ChannelMask) +{ + + uint32_t u32TempRegValue = FTU_TRIGCONF_CH7TRIG(((uint32_t)u8ChannelMask >> 7u) & 1u) | + FTU_TRIGCONF_CH6TRIG(((uint32_t)u8ChannelMask >> 6u) & 1u) | + FTU_TRIGCONF_CH5TRIG(((uint32_t)u8ChannelMask >> 5u) & 1u) | + FTU_TRIGCONF_CH4TRIG(((uint32_t)u8ChannelMask >> 4u) & 1u) | + FTU_TRIGCONF_CH3TRIG(((uint32_t)u8ChannelMask >> 3u) & 1u) | + FTU_TRIGCONF_CH2TRIG(((uint32_t)u8ChannelMask >> 2u) & 1u) | + FTU_TRIGCONF_CH1TRIG(((uint32_t)u8ChannelMask >> 1u) & 1u) | + FTU_TRIGCONF_CH0TRIG((uint32_t)u8ChannelMask & 1u); + pFtu->TRIGCONF |= u32TempRegValue; +} + +/** + * @brief Disable channel trigger out + * + * @param pFtu the base address of the FTU instance + * @param u8ChannelMask FTU channel mask, bit 0-7 indicate channel 0-7 + */ +LOCAL_INLINE void FTU_HWA_DisableChannelTriggerOut(FTU_Type *pFtu, uint8_t u8ChannelMask) +{ + uint32_t u32TempRegValue = FTU_TRIGCONF_CH7TRIG(((uint32_t)u8ChannelMask >> 7u) & 1u) | + FTU_TRIGCONF_CH6TRIG(((uint32_t)u8ChannelMask >> 6u) & 1u) | + FTU_TRIGCONF_CH5TRIG(((uint32_t)u8ChannelMask >> 5u) & 1u) | + FTU_TRIGCONF_CH4TRIG(((uint32_t)u8ChannelMask >> 4u) & 1u) | + FTU_TRIGCONF_CH3TRIG(((uint32_t)u8ChannelMask >> 3u) & 1u) | + FTU_TRIGCONF_CH2TRIG(((uint32_t)u8ChannelMask >> 2u) & 1u) | + FTU_TRIGCONF_CH1TRIG(((uint32_t)u8ChannelMask >> 1u) & 1u) | + FTU_TRIGCONF_CH0TRIG((uint32_t)u8ChannelMask & 1u); + pFtu->TRIGCONF &= ~u32TempRegValue; +} + +/** + * @brief clear the channel trigger flag + * + * @param pFtu the base address of the FTU instance + */ +LOCAL_INLINE void FTU_HWA_ClearChannelTriggerFlag(FTU_Type *pFtu) +{ + pFtu->TRIGCONF &= ~FTU_TRIGCONF_TRIGF_MASK; +} + +/** + * @brief Enable reload trigger + * + * @param pFtu the base address of the FTU instance + */ +LOCAL_INLINE void FTU_HWA_EnableReloadTrigger(FTU_Type *pFtu) +{ + pFtu->TRIGCONF |= (uint32_t)FTU_TRIGCONF_RELOADTRIGEN_MASK; +} + +/** + * @brief Set channel polarity + * + * @param pFtu the base address of the FTU instance + * @param u8Mask FTU channel mask, bit 0-7 indicate channel 0-7 + */ +LOCAL_INLINE void FTU_HWA_SetChannelPolarity(FTU_Type *pFtu, uint8_t u8Mask) +{ + pFtu->POL |= FTU_POL_POLN(u8Mask); +} + +/** + * @brief Set FTU module outmask + * + * @param pFtu the base address of the FTU instance + * @param u8Channel Bit of channel indicate channel number, range: 0~7 bit + */ +LOCAL_INLINE void FTU_HWA_ConfigModuleOutmask(FTU_Type *pFtu, uint8_t u8Channel) +{ + pFtu->OUTMASK &= ~(uint32_t)0xFFU; + pFtu->OUTMASK |= (uint32_t)u8Channel & (uint32_t)0xFFU; +} + +/** + * @brief Set channel filter value + * + * @param pFtu the base address of the FTU instance + * @param u8Channel channel number, range is 0-3 + * @param u8FilterVal FTU filter value + */ +LOCAL_INLINE void FTU_HWA_ConfigChannelFilterValue(FTU_Type *pFtu, uint8_t u8Channel, uint8_t u8FilterVal) +{ + pFtu->FILTER &= ~((uint32_t)0xFu << ((uint32_t)u8Channel << 2U)); + pFtu->FILTER |= ((uint32_t)u8FilterVal << ((uint32_t)u8Channel << 2U)); +} + +/** + * @brief Configure quadrature mode + * + * @param pFtu the base address of the FTU instance + * @param eMode FTU quadrature mode + */ +LOCAL_INLINE void FTU_HWA_ConfigQuadratureMode(FTU_Type *pFtu, FTU_QuadratureModeType eMode) +{ + pFtu->QDCTRL &= ~(uint32_t)FTU_QDCTRL_QUADMODE_MASK; + pFtu->QDCTRL |= (uint32_t)FTU_QDCTRL_QUADMODE(eMode); +} + +/** + * @brief Configure FTU Counter Direction In Quadrature Decoder Mode + * + * @param pFtu the base address of the FTU instance + * @param eDir the counting direction + */ +LOCAL_INLINE void FTU_HWA_ConfigQuadDirection(FTU_Type *pFtu, FTU_QuadratureDirectionType eDir) +{ + pFtu->QDCTRL &= ~(uint32_t)FTU_QDCTRL_QUADIR_MASK; + pFtu->QDCTRL |= (uint32_t)FTU_QDCTRL_QUADIR(eDir); +} + +/** + * @brief Configure Timer Overflow Direction In Quadrature Decoder Mode + * + * @param pFtu the base address of the FTU instance + * @param eDir Indicates if the TOF bit was set on the top or the bottom of counting + */ +LOCAL_INLINE void FTU_HWA_ConfigTimerOverflowDir(FTU_Type *pFtu, FTU_TimerOverflowDirectionType eDir) +{ + pFtu->QDCTRL &= ~(uint32_t)FTU_QDCTRL_TOFDIR_MASK; + pFtu->QDCTRL |= (uint32_t)FTU_QDCTRL_TOFDIR(eDir); +} + +/** + * @brief inverted polarity of phase B input signal + * + * @param pFtu the base address of the FTU instance + */ +LOCAL_INLINE void FTU_HWA_EnablePhbInv(FTU_Type *pFtu) +{ + pFtu->QDCTRL |= (uint32_t)FTU_QDCTRL_PHBPOL_MASK; +} + +/** + * @brief do not inverted polarity of phase B input signal + * + * @param pFtu the base address of the FTU instance + */ +LOCAL_INLINE void FTU_HWA_DisablePhbInv(FTU_Type *pFtu) +{ + pFtu->QDCTRL &= ~(uint32_t)FTU_QDCTRL_PHBPOL_MASK; +} + +/** + * @brief inverted polarity of phase A input signal + * + * @param pFtu the base address of the FTU instance + */ +LOCAL_INLINE void FTU_HWA_EnablePhaInv(FTU_Type *pFtu) +{ + pFtu->QDCTRL |= (uint32_t)FTU_QDCTRL_PHAPOL_MASK; +} + +/** + * @brief do not inverted polarity of phase B input signal + * + * @param pFtu the base address of the FTU instance + */ +LOCAL_INLINE void FTU_HWA_DisablePhaInv(FTU_Type *pFtu) +{ + pFtu->QDCTRL &= ~(uint32_t)FTU_QDCTRL_PHAPOL_MASK; +} + +/** + * @brief Enable phase A glitch filter + * + * @param pFtu the base address of the FTU instance + */ +LOCAL_INLINE void FTU_HWA_EnablePhaGlitchFilter(FTU_Type *pFtu) +{ + pFtu->QDCTRL |= (uint32_t)FTU_QDCTRL_PHAGFEN_MASK; +} + +/** + * @brief Disable phase A glitch filter + * + * @param pFtu the base address of the FTU instance + */ +LOCAL_INLINE void FTU_HWA_DisablePhaGlitchFilter(FTU_Type *pFtu) +{ + pFtu->QDCTRL &= ~(uint32_t)FTU_QDCTRL_PHAGFEN_MASK; +} + +/** + * @brief Enable phase B glitch filter + * + * @param pFtu the base address of the FTU instance + */ +LOCAL_INLINE void FTU_HWA_EnablePhbGlitchFilter(FTU_Type *pFtu) +{ + pFtu->QDCTRL |= (uint32_t)FTU_QDCTRL_PHBGFEN_MASK; +} + +/** + * @brief Disable phase B glitch filter + * + * @param pFtu the base address of the FTU instance + */ +LOCAL_INLINE void FTU_HWA_DisablePhbGlitchFilter(FTU_Type *pFtu) +{ + pFtu->QDCTRL &= ~(uint32_t)FTU_QDCTRL_PHBGFEN_MASK; +} + +/** + * @brief Enable FTU module quadrature mode + * + * @param pFtu the base address of the FTU instance + */ +LOCAL_INLINE void FTU_HWA_EnableQuadratureMode(FTU_Type *pFtu) +{ + pFtu->QDCTRL |= (uint32_t)FTU_QDCTRL_QUADEN_MASK; +} + +/** + * @brief Disable FTU module quadrature mode + * + * @param pFtu the base address of the FTU instance + */ +LOCAL_INLINE void FTU_HWA_DisableQuadratureMode(FTU_Type *pFtu) +{ + pFtu->QDCTRL &= ~(uint32_t)FTU_QDCTRL_QUADEN_MASK; +} + +/** + * @brief Configure FTU module debug mode + * + * @param pFtu the base address of the FTU instance + * @param eDbgMode debug mode enumeration + */ +LOCAL_INLINE void FTU_HWA_ConfigModuleDebugMode(FTU_Type *pFtu, FTU_DebugModeType eDbgMode) +{ + pFtu->CONF &= ~(uint32_t)FTU_CONF_DBG_MASK; + pFtu->CONF |= FTU_CONF_DBG(eDbgMode); +} + +/** + * @brief Set FTU module clock source + * + * @param pFtu the base address of the FTU instance + * @param eClkSrc FTU module clock source type + */ +LOCAL_INLINE void FTU_HWA_ConfigModuleClkSrc(FTU_Type *pFtu, FTU_ModuleClkSrcType eClkSrc) +{ + pFtu->SC &= ~(uint32_t)FTU_SC_CLKS_MASK; + pFtu->SC |= FTU_SC_CLKS(eClkSrc); +} + +/** + * @brief Clear FTU module overflow flag + * + * @param pFtu the base address of the FTU instance + */ +LOCAL_INLINE void FTU_HWA_ClearOverflowFlag(FTU_Type *pFtu) +{ + pFtu->SC &= ~(uint32_t)FTU_SC_TOF_MASK; +} + +/** + * @brief Clear FTU module reload flag + * + * @param pFtu the base address of the FTU instance + */ +LOCAL_INLINE void FTU_HWA_ClearReloadFlag(FTU_Type *pFtu) +{ + pFtu->SC &= ~(uint32_t)FTU_SC_RF_MASK; +} + +/** + * @brief Enable FTU module interrupt + * + * @param pFtu the base address of the FTU instance + */ +LOCAL_INLINE void FTU_HWA_EnableOverflowInterrupt(FTU_Type *pFtu) +{ + pFtu->SC |= (uint32_t)FTU_SC_TOIE_MASK; +} + +/** + * @brief Disable FTU module overflow interrupt + * + * @param pFtu the base address of the FTU instance + */ +LOCAL_INLINE void FTU_HWA_DisableOverflowInterrupt(FTU_Type *pFtu) +{ + pFtu->SC &= ~(uint32_t)FTU_SC_TOIE_MASK; +} + +/** + * @brief Clear FTU channel interrupt flag + * + * @param pFtu the base address of the FTU instance + * @param u8Channel FTU channel number, range is 0-7. + */ +LOCAL_INLINE void FTU_HWA_ClearChannelInterruptFlag(FTU_Type *pFtu, uint8_t u8Channel) +{ + pFtu->CONTROLS[u8Channel].CSCn &= ~(uint32_t)FTU_CSC_CHF_MASK; +} + +/** + * @brief Disable channel interrupt + * + * @param pFtu the base address of the FTU instance + * @param u8Channel FTU channel number, range is 0-7. + */ +LOCAL_INLINE void FTU_HWA_DisableChannelInterrupt(FTU_Type *pFtu, uint8_t u8Channel) +{ + pFtu->CONTROLS[u8Channel].CSCn &= ~(uint32_t)FTU_CSC_CHIE_MASK; +} + +/** + * @brief Disable write protection + * + * @param pFtu the base address of the FTU instance + */ +LOCAL_INLINE void FTU_HWA_DisableWriteProtection(FTU_Type *pFtu) +{ + pFtu->MODE |= (uint32_t)FTU_MODE_WPDIS_MASK; +} + +/** + * @brief Disable FTU module fault interrupt + * + * @param pFtu the base address of the FTU instance + */ +LOCAL_INLINE void FTU_HWA_DisableModuleFaultInterrupt(FTU_Type *pFtu) +{ + pFtu->MODE &= ~(uint32_t)FTU_MODE_FAULTIE_MASK; +} + +/** + * @brief Disable synchronization hardware trigger 0 + * + * @param pFtu the base address of the FTU instance + */ +LOCAL_INLINE void FTU_HWA_DisableTrigger0Sync(FTU_Type *pFtu) +{ + pFtu->SYNC &= ~(uint32_t)FTU_SYNC_TRIG0_MASK; +} + +/** + * @brief Disable synchronization hardware trigger 1 + * + * @param pFtu the base address of the FTU instance + */ +LOCAL_INLINE void FTU_HWA_DisableTrigger1Sync(FTU_Type *pFtu) +{ + pFtu->SYNC &= ~(uint32_t)FTU_SYNC_TRIG1_MASK; +} + +/** + * @brief Disable synchronization hardware trigger 2 + * + * @param pFtu the base address of the FTU instance + */ +LOCAL_INLINE void FTU_HWA_DisableTrigger2Sync(FTU_Type *pFtu) +{ + pFtu->SYNC &= ~(uint32_t)FTU_SYNC_TRIG2_MASK; +} + +/** + * @brief Disable generate FTU software trigger + * + * @param pFtu the base address of the FTU instance + */ +LOCAL_INLINE void FTU_HWA_DisableGenerateSwSync(FTU_Type *pFtu) +{ + pFtu->SYNC &= ~(uint32_t)FTU_SYNC_SWSYNC_MASK; +} + +/** + * @brief Disable reload trigger + * + * @param pFtu the base address of the FTU instance + */ +LOCAL_INLINE void FTU_HWA_DisableReloadTrigger(FTU_Type *pFtu) +{ + pFtu->TRIGCONF &= ~(uint32_t)FTU_TRIGCONF_RELOADTRIGEN_MASK; +} + +/** + * @brief Disable channel(n/n+1) deadtime functionality + * + * @param pFtu the base address of the FTU instance + * @param u8Channel channel number, range is 0-7 + */ +LOCAL_INLINE void FTU_HWA_DisableChannelDeadtime(FTU_Type *pFtu, uint8_t u8Channel) +{ + pFtu->CHCTRL &= ~FTU_CHCTRL_DEADTIME_CHANNEL(u8Channel); +} + +/** + * @brief Disable channel(n/n+1) complement functionality + * + * @param pFtu the base address of the FTU instance + * @param u8Channel channel number, range is 0-7 + */ +LOCAL_INLINE void FTU_HWA_DisableChannelComplement(FTU_Type *pFtu, uint8_t u8Channel) +{ + pFtu->CHCTRL &= ~FTU_CHCTRL_COMPLEMENT_CHANNEL(u8Channel); +} + +/** + * @brief Disable channel(n/n+1) synchronization functionality + * + * @param pFtu the base address of the FTU instance + * @param u8Channel channel number, range is 0-7 + */ +LOCAL_INLINE void FTU_HWA_DisableChannelSync(FTU_Type *pFtu, uint8_t u8Channel) +{ + pFtu->CHCTRL &= ~FTU_CHCTRL_SYNCEN_CHANNEL(u8Channel); +} + +/** + * @brief Disable channel(n/n+1) fault functionality + * + * @param pFtu the base address of the FTU instance + * @param u8Channel channel number, range is 0-7 + */ +LOCAL_INLINE void FTU_HWA_DisableChannelFault(FTU_Type *pFtu, uint8_t u8Channel) +{ + pFtu->CHCTRL &= ~FTU_CHCTRL_FAULT_CHANNEL(u8Channel); +} + +/** + * @brief Clear channel polarity + * + * @param pFtu the base address of the FTU instance + * @param u8Channel FTU channel, bit 0-7 indicate channel 0-7 + */ +LOCAL_INLINE void FTU_HWA_ClearChannelPolarity(FTU_Type *pFtu, uint8_t u8Channel) +{ + pFtu->POL &= ~FTU_POL_POLN(u8Channel); +} + +/** + * @brief Get channel polarity + * + * @param pFtu the base address of the FTU instance + * @param u8Channel FTU channel, bit 0-7 indicate channel 0-7 + * @return polarity of the channels + */ +LOCAL_INLINE uint32_t FTU_HWA_GetChannelPolarity(FTU_Type *pFtu, uint8_t u8Channel) +{ + return pFtu->POL & FTU_POL_POLN(u8Channel); +} + +/** + * @brief Clear FTU module fault flag + * + * @param pFtu the base address of the FTU instance + * @param u8Flag bit 0-3 indicate fault flag 0-3. + */ +LOCAL_INLINE void FTU_HWA_ClearModuleFaultFlag(FTU_Type *pFtu, uint8_t u8Flag) +{ + pFtu->FMS &= ~(uint32_t)((uint32_t)u8Flag & 0xFu); +} + +/** + * @brief Clear FTU global fault flag + * + * @param pFtu the base address of the FTU instance + */ +LOCAL_INLINE void FTU_HWA_ClearGlobalFaultFlag(FTU_Type *pFtu) +{ + pFtu->FMS &= ~(uint32_t)FTU_FMS_FAULTF_MASK; +} + +#endif /* #ifndef _HWA_FTU_H_ */ diff --git a/MODULES/HwA_Flagchip_FC7240/Inc/HwA_gpio.h b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_gpio.h new file mode 100644 index 0000000..ca7629e --- /dev/null +++ b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_gpio.h @@ -0,0 +1,245 @@ +/** + * @file HwA_gpio.h + * @author Flagchip + * @brief FC7xxx GPIO hardware access layer + * @version 0.1.0 + * @date 2023-02-13 + * + * @copyright Copyright (c) 2023 Flagchip Semiconductors Co., Ltd. + * + * @details + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2022-11-18 Flagchip071 N/A First version for FC7xxx + ******************************************************************************** */ + +#ifndef _HWA_GPIO_H_ +#define _HWA_GPIO_H_ + +#include "device_header.h" + +/** @brief GPIO initialization level */ +typedef enum +{ + GPIO_LOW = 0U, + GPIO_HIGH = 1U +} GPIO_PinLevelType; + + +/** + * @brief Set port data output, port output can set 1 or 0 + * + * @param pGpio Gpio instance + * @param u32Value Written value + */ +LOCAL_INLINE void GPIO_HWA_ConfigPortDataOutput(GPIO_Type *pGpio, uint32_t u32Value) +{ + pGpio->PDOR = u32Value; +} + +/** + * @brief Set pin data output, pin output can set 1 or 0 + * + * @param pGpio Gpio instance + * @param u32Pin Pin mask + * @param ePinLevel Pin level + */ +LOCAL_INLINE void GPIO_HWA_ConfigPinDataOutput(GPIO_Type *pGpio, uint32_t u32Pin, GPIO_PinLevelType ePinLevel) +{ + if (GPIO_HIGH == ePinLevel) + { + pGpio->PDOR |= GPIO_PDOR_PDO(u32Pin); + } + else + { + pGpio->PDOR &= ~GPIO_PDOR_PDO(u32Pin); + } +} + +/** + * @brief Set port output to 1 + * + * @param pGpio Gpio instance + * @param u32Value Written value + */ +LOCAL_INLINE void GPIO_HWA_SetPortOutput(GPIO_Type *pGpio, uint32_t u32Value) +{ + pGpio->PSOR |= u32Value; +} + +/** + * @brief Set port output to 0 + * + * @param pGpio Gpio instance + * @param u32Value Written value + */ +LOCAL_INLINE void GPIO_HWA_ClearPortOutput(GPIO_Type *pGpio, uint32_t u32Value) +{ + pGpio->PCOR |= u32Value; +} + +/** + * @brief Toggle port output + * + * @param pGpio Gpio instance + * @param u32Value Written value + */ +LOCAL_INLINE void GPIO_HWA_TogglePort(GPIO_Type *pGpio, uint32_t u32Value) +{ + pGpio->PTOR = u32Value; +} + +/** + * @brief Set port direction + * + * @param pGpio Gpio instance + * @param u32Value Written value + */ +LOCAL_INLINE void GPIO_HWA_SetPortDirection(GPIO_Type *pGpio, uint32_t u32Value) +{ + pGpio->PDDR = u32Value; +} + +/** + * @brief Set port input disable + * + * @param pGpio Gpio instance + * @param u32Value Written value + */ +LOCAL_INLINE void GPIO_HWA_SetPortInputDisable(GPIO_Type *pGpio, uint32_t u32Value) +{ + pGpio->PIDR = u32Value; +} + + +/** + * @brief Read port data output + * + * @param pGpio Gpio instance + * @return PDOR register value + */ +LOCAL_INLINE uint32_t GPIO_HWA_ReadPortDataOutput(GPIO_Type *pGpio) +{ + return pGpio->PDOR; +} + +/** + * @brief Read port data input, this register indicate data on pad. + * + * @param pGpio Gpio instance + * @return PDIR register value + */ +LOCAL_INLINE uint32_t GPIO_HWA_ReadPortDataInput(GPIO_Type *pGpio) +{ + return pGpio->PDIR; +} + + +/** + * @brief Set pin data output, pin output can set 1 or 0 + * + * @param pGpio Gpio instance + * @param u8Pin Pin number + */ +LOCAL_INLINE void GPIO_HWA_SetPinDataOutput(GPIO_Type *pGpio, uint8_t u8Pin) +{ + pGpio->PDOR |= (uint32_t)1 << u8Pin; +} + +/** + * @brief Set pin output to 1 + * + * @param pGpio Gpio instance + * @param u8Pin Pin number + */ +LOCAL_INLINE void GPIO_HWA_SetPinOutput(GPIO_Type *pGpio, uint8_t u8Pin) +{ + pGpio->PSOR |= (uint32_t)1 << u8Pin; +} + +/** + * @brief Set pin output to 0 + * + * @param pGpio Gpio instance + * @param u8Pin Pin number + */ +LOCAL_INLINE void GPIO_HWA_ClearPinOutput(GPIO_Type *pGpio, uint8_t u8Pin) +{ + pGpio->PCOR |= (uint32_t)1 << u8Pin; +} + +/** + * @brief Toggle pin + * + * @param pGpio Gpio instance + * @param u8Pin Pin number + */ +LOCAL_INLINE void GPIO_HWA_TogglePin(GPIO_Type *pGpio, uint8_t u8Pin) +{ + pGpio->PTOR |= (uint32_t)1 << u8Pin; +} + +/** + * @brief Set pin direction + * + * @param pGpio Gpio instance + * @param u8Pin Pin number + */ +LOCAL_INLINE void GPIO_HWA_SetPinDirection(GPIO_Type *pGpio, uint8_t u8Pin) +{ + pGpio->PDDR |= (uint32_t)1 << u8Pin; +} + +/** + * @brief Set pin input disable + * + * @param pGpio Gpio instance + * @param u8Pin Pin number + */ +LOCAL_INLINE void GPIO_HWA_SetPinInputDisable(GPIO_Type *pGpio, uint8_t u8Pin) +{ + pGpio->PIDR |= (uint32_t)1 << u8Pin; +} + + +/** + * @brief Clear pin data output + * + * @param pGpio Gpio instance + * @param u8Pin Pin number + */ +LOCAL_INLINE void GPIO_HWA_ClearPinDataOutput(GPIO_Type *pGpio, uint8_t u8Pin) +{ + pGpio->PDOR &= ~((uint32_t)1 << u8Pin); +} + +/** + * @brief Clear pin direction + * + * @param pGpio Gpio instance + * @param u8Pin Pin number + */ +LOCAL_INLINE void GPIO_HWA_ClearPinDirection(GPIO_Type *pGpio, uint8_t u8Pin) +{ + pGpio->PDDR &= ~((uint32_t)1 << u8Pin); +} + +/** + * @brief Clear pin input disable + * + * @param pGpio Gpio instance + * @param u8Pin Pin number + */ +LOCAL_INLINE void GPIO_HWA_ClearPinInputDisable(GPIO_Type *pGpio, uint8_t u8Pin) +{ + pGpio->PIDR &= ~((uint32_t)1 << u8Pin); +} + + + + +#endif /* #ifndef _HWA_GPIO_H_ */ diff --git a/MODULES/HwA_Flagchip_FC7240/Inc/HwA_intm.h b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_intm.h new file mode 100644 index 0000000..5016a93 --- /dev/null +++ b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_intm.h @@ -0,0 +1,179 @@ +/** + * @file HwA_intm.h + * @author Flagchip + * @brief FC7240 INTM HWA driver type definition and API + * @version 0.1.0 + * @date 2024-01-10 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-01-10 Flagchip084 N/A FC7240 release version + ******************************************************************************** */ + +#ifndef _HWA_INTM_H_ +#define _HWA_INTM_H_ + +#include "device_header.h" + +typedef struct +{ + __IO uint32_t IRQSELR; /* INTM Interrupt Request Select Register*/ + __IO uint32_t LATR; /* INTM Latency Register */ + __IO uint32_t TMR; /* INTM Timer Register */ + __I uint32_t SR; /* INTM Status Register */ +} INTM_MonitorType, *INTM_MonitorMemMapPtr; + +/** + * @brief Enable the INTM. + * @param pIntm INTM instance. INTM instance. + * @param bEnable Enable the ITNM. + */ +LOCAL_INLINE void INTM_HWA_Enable(INTM_Type *const pIntm, bool bEnable) +{ + if (bEnable) + { + pIntm->ER = INTM_ER_EN_MASK; + } + else + { + pIntm->ER = 0U; + } +} + +/** + * @brief Get the instance of interrupt monitor. + * @param pIntm INTM instance. + * @param u8IrqMonitorIndex Interrupt monitor index. + * @return Monitor Instance. + */ +LOCAL_INLINE INTM_MonitorType *INTM_HWA_GetIrqMonitor(INTM_Type *const pIntm, uint8_t u8IrqMonitorIndex) +{ + return (INTM_MonitorType *)((uint32_t) & (pIntm->IRQSELR0) + (uint32_t)u8IrqMonitorIndex * 0x10U); +} + +/** + * @brief Set the interrupt acknowledge. + * @param pIntm INTM instance. + * @param u16IrqNum Interrupt number to be monitored. + */ +LOCAL_INLINE void INTM_HWA_SetIACKR(INTM_Type *const pIntm, uint16_t u16IrqNum) +{ + pIntm->IACKR = u16IrqNum; +} + +/** + * @brief Set which interrupt to be monoterd. + * @param pIntm INTM instance. + * @param u16IrqNum Interrupt number to be monitored. + */ +LOCAL_INLINE void INTM_HWA_SetIRQReqNum(INTM_MonitorType *const pIrqMon, uint16_t u16IrqNum) +{ + pIrqMon->IRQSELR = u16IrqNum; +} + +/** + * @brief Enable reset when interrupt delays overtime. + * @param pIrqMon Interrupt monitor instance. + * @param bEnable Enable reset. + */ +LOCAL_INLINE void INTM_HWA_EnableReset(INTM_MonitorType *const pIrqMon, bool bEnable) +{ + pIrqMon->IRQSELR = (pIrqMon->IRQSELR & ~INTM_IRQSELR_RSTE_MASK) | INTM_IRQSELR_RSTE(bEnable); +} + +/** + * @brief Enable interrupt when monitored interrupt delays overtime. + * @param pIrqMon Interrupt monitor instance. + * @param bEnable Enabel the interrupt. + */ +LOCAL_INLINE void INTM_HWA_EnableInterrupt(INTM_MonitorType *const pIrqMon, bool bEnable) +{ + pIrqMon->IRQSELR = (pIrqMon->IRQSELR & ~INTM_IRQSELR_INTE_MASK) | INTM_IRQSELR_INTE(bEnable); +} + +/** + * @brief Enable inactive mode. + * @param pIrqMon Interrupt monitor instance. + * @param bEnable Enable inactive mode. + */ +LOCAL_INLINE void INTM_HWA_EnableInactiveMode(INTM_MonitorType *const pIrqMon, bool bEnable) +{ + pIrqMon->IRQSELR = (pIrqMon->IRQSELR & ~INTM_IRQSELR_IACTE_MASK) | INTM_IRQSELR_IACTE(bEnable); + __asm volatile( + "dmb \n" + "ldr r8, [%[IRQSELR]] \n"/* Must Read IRQSELR after set. */ + : : [IRQSELR] "r"(&pIrqMon->IRQSELR) : "r8", "memory" + ); +} + +/** + * @brief Start the inactive mode. + * @param pIrqMon Interrupt monitor instance. + */ +LOCAL_INLINE void INTM_HWA_StartInactiveMode(INTM_MonitorType *const pIrqMon) +{ + pIrqMon->IRQSELR |= INTM_IRQSELR_IACTST_MASK; + __asm volatile( + "dmb \n" + "ldr r8, [%[IRQSELR]] \n"/* Must Read IRQSELR after set. */ + : : [IRQSELR] "r"(&pIrqMon->IRQSELR) : "r8", "memory" + ); +} + +/** + * @brief Stop the inactive mode. + * @param pIrqMon Interrupt monitor instance. + * @param bEnable + */ +LOCAL_INLINE void INTM_HWA_StopInactiveMode(INTM_MonitorType *const pIrqMon) +{ + pIrqMon->IRQSELR &= ~INTM_IRQSELR_IACTST_MASK; +} + +/** + * @brief Set the timeout value of interrupt. + * @param pIrqMon Interrupt monitor instance. + * @param u32Latency the timeout value of interrupt monitor. + */ +LOCAL_INLINE void INTM_HWA_SetLatency(INTM_MonitorType *const pIrqMon, uint32_t u32Latency) +{ + pIrqMon->LATR = u32Latency; +} + +/** + * @brief Get the value of timer. + * @param pIrqMon Interrupt monitor instance. + * @return Timer value + */ +LOCAL_INLINE uint32_t INTM_HWA_GetTimerCounter(INTM_MonitorType *const pIrqMon) +{ + return pIrqMon->TMR; +} + +/** + * @brief Set the value of timer. + * @param pIrqMon Interrupt monitor instance. + * @param u32Value The value to be set. + */ +LOCAL_INLINE void INTM_HWA_SetTimerCounter(INTM_MonitorType *const pIrqMon, uint32_t u32Value) +{ + pIrqMon->TMR = u32Value; +} + +/** + * @brief Read interrupt status. + * @param pIrqMon Interrupt monitor instance. + * @return Interrupt status. + */ +LOCAL_INLINE bool INTM_HWA_ReadStatus(INTM_MonitorType *const pIrqMon) +{ + return (pIrqMon->SR & INTM_SR_MASK) == INTM_SR_MASK ? true : false; +} + +#endif /*#ifndef _HWA_INTM_H_*/ diff --git a/MODULES/HwA_Flagchip_FC7240/Inc/HwA_ism.h b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_ism.h new file mode 100644 index 0000000..38eef1a --- /dev/null +++ b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_ism.h @@ -0,0 +1,645 @@ +/** + * @file HwA_ism.h + * @author Flagchip084 + * @brief FC7xxx ISM hardware access layer + * @version 0.2.0 + * @date 2023-02-13 + * + * @copyright Copyright (c) 2023 Flagchip Semiconductors Co., Ltd. + * + * @details + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2022-11-18 Flagchip084 N/A First version for FC7xxx + * 0.2.0 2023-02-13 Flagchip084 N/A FC7xxx release version + ******************************************************************************** */ +#ifndef _HWA_ISM_H_ +#define _HWA_ISM_H_ + +#include "device_header.h" + +/** + * @addtogroup HwA_ism + * @{ + * + */ +/********* macros ************/ + +/********* Local typedef ************/ + +typedef struct +{ + __IO uint32_t FPC_STATUS; + __IO uint32_t FPC_CTRL; + __IO uint32_t FPC_CONFIG; + __IO uint32_t FPC_TIMER; +} FPC_Type, *FPC_MemMapPtr; + +typedef struct +{ + __IO uint32_t LAM_STATUS; + __IO uint32_t LAM_CTRL; + __IO uint32_t LAM_CONFIG; + __IO uint32_t LAM_CONTER; +} LAM_Type, *LAM_MemMapPtr; + +typedef enum +{ + ISM_FPC_DETECT_NO_FILTER = 0U, /*No filter mode. Copy input to SOUT directly, which is LAM input.*/ + ISM_FPC_DETECT_IMMI_FILTER = 1U, /*Immediate filter mode.*/ + ISM_FPC_DETECT_DELAY_MODE = 2U, /*Delay mode.*/ + ISM_FPC_DETECT_PRESCALER_MODE = 3U /*Prescaler mode.*/ +} ISM_FPC_EdgeDetectModeType; + +typedef enum +{ + ISM_FPC_DELAY_FIXED0 = 0U, /*Fixed delay mode.*/ + ISM_FPC_DELAY_FIXED1 = 1U, /*Fixed delay mode.*/ + ISM_FPC_DELAY_SMART_DELAY0 = 2U, /*Smart delay mode. The counter is decremented when a glitch happens.*/ + ISM_FPC_DELAY_SMART_DELAY1 = 3U /*Smart delay mode. The counter is reset when a glitch happens.*/ +} ISM_FPC_EdgeDelayModeType; + + +typedef enum +{ + ISM_LAM_EVT_WIN_NON_INVERT = 0U, /*Event window non-inverted.*/ + ISM_LAM_EVT_WIN_INVERT = 1U /*Event window inverted.*/ +} ISM_LAM_InvertEventWindowType; + +typedef enum +{ + ISM_LAM_NTR_CLEAR_NTR_GATE = 0U, /*Neither edge used to clear the event window counter. Neither edge used to gate event generation.*/ + ISM_LAM_POS_CLEAR_NTR_GATE = 1U, /*Positive edge used to clear the event window counter. Neither edge used to gate event generation.*/ + ISM_LAM_NEG_CLEAR_NTR_GATE = 2U, /*Negative edge used to clear the event window counter. Neither edge used to gate event generation.*/ + ISM_LAM_ETR_CLEAR_NTR_GATE = 3U, /*Either edge used to clear the event window counter. Neither edge used to gate event generation.*/ + ISM_LAM_NTR_CLEAR_POS_GATE = 4U, /*Neither edge used to clear the event window counter. Positive edge used to gate event generation.*/ + ISM_LAM_POS_CLEAR_POS_GATE = 5U, /*Positive edge used to clear the event window counter. Positive edge used to gate event generation.*/ + ISM_LAM_NEG_CLEAR_POS_GATE = 6U, /*Negative edge used to clear the event window counter. Positive edge used to gate event generation.*/ + ISM_LAM_ETR_CLEAR_POS_GATE = 7U, /*Either edge used to clear the event window counter. Positive edge used to gate event generation.*/ + ISM_LAM_NTR_CLEAR_NEG_GATE = 8U, /*Neither edge used to clear the event window counter. Negative edge used to gate event generation.*/ + ISM_LAM_POS_CLEAR_NEG_GATE = 9U, /*Positive edge used to clear the event window counter. Negative edge used to gate event generation.*/ + ISM_LAM_NEG_CLEAR_NEG_GATE = 10U, /*Negative edge used to clear the event window counter. Negative edge used to gate event generation.*/ + ISM_LAM_ETR_CLEAR_NEG_GATE = 11U, /*Either edge used to clear the event window counter. Negative edge used to gate event generation.*/ + ISM_LAM_NTR_CLEAR_ETR_GATE = 12U, /*Neither edge used to clear the event window counter. Either edge used to gate event generation.*/ + ISM_LAM_POS_CLEAR_ETR_GATE = 13U, /*Positive edge used to clear the event window counter. Either edge used to gate event generation.*/ + ISM_LAM_NEG_CLEAR_ETR_GATE = 14U, /*Negative edge used to clear the event window counter. Either edge used to gate event generation.*/ + ISM_LAM_ETR_CLEAR_ETR_GATE = 15U /*Either edge used to clear the event window counter. Either edge used to gate event generation.*/ +} ISM_LAM_EventWindowEdgeType; + +typedef enum +{ + ISM_LAM_EVT_WIN_SEL_REF = 0U, /*Event window generation is determined from the reference signal.*/ + ISM_LAM_EVT_WIN_SEL_MON = 1U /*Event window generation is determined from the monitor signal.*/ +} ISM_LAM_EventWindowSelectType; + +typedef enum +{ + ISM_LAM_RUN_FREE = 0U, /*Event window generation is free-running.*/ + ISM_LAM_RUN_GATED = 1U /*Event window generation is gated with the monitor or reference signal.*/ +} ISM_LAM_RunModeSelectType; + + +typedef enum +{ + ISM_LAM_SRC_FPC_MON = 0U, /* Monitor signal is sourced directly from FPC monitor channel.*/ + ISM_LAM_SRC_EXORD_FPC_REF = 1U /* Monitor signal is EXOR'd with FPC reference channel.*/ +} ISM_LAM_MonitorSourceType; + +typedef enum +{ + ISM_LAM_FPC_MON_NON_INVERT = 0U, /* Do not invert the monitor signal from FPC.*/ + ISM_LAM_FPC_MON_INVERT = 1U /* Invert the monitor signal from FPC.*/ +} ISM_LAM_InvertMonitorType; + +typedef enum +{ + ISM_LAM_FPC_REF_NON_INVERT = 0U, /* Do not invert the reference signal from FPC.*/ + ISM_LAM_FPC_REF_INVERT = 1U /* Invert the reference signal from FPC.*/ +} ISM_LAM_InvertReferenceType; + +/********* Local inline function ************/ + +/********* ISM Register interface ************/ + +/** + * @brief Get ISM ECM count + * + * @param pIsm ISM Instance + * @return ECM count + */ +LOCAL_INLINE uint8_t ISM_HWA_PARAM_ECMC(ISM_Type *const pIsm) +{ + return (uint8_t)((pIsm->PARAM & ISM_PARAM_ECMC_MASK) >> ISM_PARAM_ECMC_SHIFT); +} + +/** + * @brief Get ISM FPC count + * + * @param pIsm ISM Instance + * @return FPC count + */ +LOCAL_INLINE uint8_t ISM_HWA_PARAM_FPC(ISM_Type *const pIsm) +{ + return (uint8_t)((pIsm->PARAM & ISM_PARAM_FPC_MASK) >> ISM_PARAM_FPC_SHIFT); +} + +/** + * @brief Get ISM LAM count + * + * @param pIsm ISM Instance + * @return LAM count + */ +LOCAL_INLINE uint8_t ISM_HWA_PARAM_LAM(ISM_Type *const pIsm) +{ + return (uint8_t)((pIsm->PARAM & ISM_PARAM_LAM_MASK) >> ISM_PARAM_LAM_SHIFT); +} + +/** + * @brief Enable ISM + * + * @param pIsm ISM Instance + * @param bEnable EN value + */ +LOCAL_INLINE void ISM_HWA_Enable(ISM_Type *const pIsm, bool bEnable) +{ + pIsm->CTRL = (pIsm->CTRL & ~ISM_CTRL_EN_MASK) | ISM_CTRL_EN(bEnable); +} + +/** + * @brief Enable ISM Interrupt + * + * @param pIsm ISM Instance + * @param bEnable IEN value + */ +LOCAL_INLINE void ISM_HWA_InterruptEnable(ISM_Type *const pIsm, bool bEnable) +{ + pIsm->CTRL = (pIsm->CTRL & ~ISM_CTRL_IEN_MASK) | ISM_CTRL_IEN(bEnable); +} + +/** + * @brief Get ECS of ISM_E_STATUS register + * + * @param pIsm ISM Instance + * @return ECS value + */ +LOCAL_INLINE uint8_t ISM_HWA_GetEcs(ISM_Type *const pIsm) +{ + return (uint8_t)((pIsm->E_STATUS & ISM_E_STATUS_ECS_MASK) >> ISM_E_STATUS_ECS_SHIFT); +} + +/** + * @brief Clear ECS of ISM_E_STATUS register + * + * @param pIsm ISM Instance + * @param u32Channels ECM channels + */ +LOCAL_INLINE void ISM_HWA_ClearEcs(ISM_Type *const pIsm, uint32_t u32Channels) +{ + pIsm->E_STATUS = (u32Channels << ISM_E_STATUS_ECS_SHIFT) & ISM_E_STATUS_ECS_MASK; +} + +/** + * @brief Get ES of ISM_E_STATUS register + * + * @param pIsm ISM Instance + * @return ES value + */ +LOCAL_INLINE uint16_t ISM_HWA_GetEs(ISM_Type *const pIsm) +{ + return (uint16_t)((pIsm->E_STATUS & ISM_E_STATUS_ES_MASK) >> ISM_E_STATUS_ES_SHIFT); +} + +/** + * @brief Clear ES of ISM_E_STATUS register + * + * @param pIsm ISM Instance + * @param u32Channels ECM channels + */ +LOCAL_INLINE void ISM_HWA_ClearEs(ISM_Type *const pIsm, uint32_t u32Channels) +{ + pIsm->E_STATUS = (u32Channels << ISM_E_STATUS_ES_SHIFT) & ISM_E_STATUS_ES_MASK; +} + +/** + * @brief Enable ISM ECM channels system event + * + * @param pIsm ISM Instance + * @param u32Channels ECM Channels + * @param bEnable enable value + */ +LOCAL_INLINE void ISM_HWA_EnableEcmSystemEvent(ISM_Type *const pIsm, uint32_t u32Channels, bool bEnable) +{ + if (bEnable) + { + pIsm->E_CTRL = pIsm->E_CTRL | (u32Channels << ISM_E_CTRL_ECE_SHIFT); + } + else + { + pIsm->E_CTRL = pIsm->E_CTRL & ~(u32Channels << ISM_E_CTRL_ECE_SHIFT); + } +} + +/** + * @brief Get Enabled ISM ECM channels system event + * + * @param pIsm ISM Instance + * @return Enabled ECM event + */ +LOCAL_INLINE uint8_t ISM_HWA_GetEnabledEcmSystemEvent(ISM_Type *const pIsm) +{ + return (uint8_t)((pIsm->E_CTRL & ISM_E_CTRL_ECE_MASK) >> ISM_E_CTRL_ECE_SHIFT); +} + +/** + * @brief Enable ISM LAM channels system event + * + * @param pIsm ISM Instance + * @param u32Channels LAM Channels + * @param bEnable enable value + */ +LOCAL_INLINE void ISM_HWA_EnableLamSystemEvent(ISM_Type *const pIsm, uint32_t u32Channels, bool bEnable) +{ + if (bEnable) + { + pIsm->E_CTRL = pIsm->E_CTRL | (u32Channels << ISM_E_CTRL_EE_SHIFT); + } + else + { + pIsm->E_CTRL = pIsm->E_CTRL & ~(u32Channels << ISM_E_CTRL_EE_SHIFT); + } +} + +/** + * @brief Get Enabled ISM LAM channels system event + * + * @param pIsm ISM Instance + * @return Enabled LAM event + */ +LOCAL_INLINE uint16_t ISM_HWA_GetEnabledLamSystemEvent(ISM_Type *const pIsm) +{ + return (uint16_t)((pIsm->E_CTRL & ISM_E_CTRL_EE_MASK) >> ISM_E_CTRL_EE_SHIFT); +} + +/** + * @brief Set the EC_CTRL register + * + * @param pIsm ISM Instance + * @param u32Value register Value + */ +LOCAL_INLINE void ISM_HWA_SetEcCtrl(ISM_Type *const pIsm, uint32_t u32Value) +{ + pIsm->EC_CTRL = u32Value; +} + +/** + * @brief Set THRL and LAM channel of ECM0 + * + * @param pIsm ISM Instance + * @param u32Value THRL value + * @param u32LamChannel Lam channel + */ +LOCAL_INLINE void ISM_HWA_SetEcm0EcCtrl(ISM_Type *const pIsm, uint32_t u32Value, uint32_t u32LamChannel) +{ + uint32_t u32TempValue = pIsm->EC_CTRL; + + u32TempValue = (u32TempValue & ~ISM_EC_CTRL_SEL_0_MASK) | ISM_EC_CTRL_SEL_0(u32LamChannel); + u32TempValue = (u32TempValue & ~ISM_EC_CTRL_THRL_0_MASK) | ISM_EC_CTRL_THRL_0(u32Value); + pIsm->EC_CTRL = u32TempValue; +} + +/** + * @brief Set THRL and LAM channel of ECM1 + * + * @param pIsm ISM Instance + * @param u32Value THRL value + * @param u32LamChannel Lam channel + */ +LOCAL_INLINE void ISM_HWA_SetEcm1EcCtrl(ISM_Type *const pIsm, uint32_t u32Value, uint32_t u32LamChannel) +{ + uint32_t u32TempValue = pIsm->EC_CTRL; + + u32TempValue = (u32TempValue & ~ISM_EC_CTRL_SEL_1_MASK) | ISM_EC_CTRL_SEL_1(u32LamChannel); + u32TempValue = (u32TempValue & ~ISM_EC_CTRL_THRL_1_MASK) | ISM_EC_CTRL_THRL_1(u32Value); + pIsm->EC_CTRL = u32TempValue; +} + +/** + * @brief Set THRL and LAM channel of ECM2 + * + * @param pIsm ISM Instance + * @param u32Value THRL value + * @param u32LamChannel Lam channel + */ +LOCAL_INLINE void ISM_HWA_SetEcm2EcCtrl(ISM_Type *const pIsm, uint32_t u32Value, uint32_t u32LamChannel) +{ + uint32_t u32TempValue = pIsm->EC_CTRL; + + u32TempValue = (u32TempValue & ~ISM_EC_CTRL_SEL_2_MASK) | ISM_EC_CTRL_SEL_2(u32LamChannel); + u32TempValue = (u32TempValue & ~ISM_EC_CTRL_THRL_2_MASK) | ISM_EC_CTRL_THRL_2(u32Value); + pIsm->EC_CTRL = u32TempValue; +} + +/** + * @brief Set THRL and LAM channel of ECM3 + * + * @param pIsm ISM Instance + * @param u32Value THRL value + * @param u32LamChannel Lam channel + */ +LOCAL_INLINE void ISM_HWA_SetEcm3EcCtrl(ISM_Type *const pIsm, uint32_t u32Value, uint32_t u32LamChannel) +{ + uint32_t u32TempValue = pIsm->EC_CTRL; + + u32TempValue = (u32TempValue & ~ISM_EC_CTRL_SEL_3_MASK) | ISM_EC_CTRL_SEL_3(u32LamChannel); + u32TempValue = (u32TempValue & ~ISM_EC_CTRL_THRL_3_MASK) | ISM_EC_CTRL_THRL_3(u32Value); + pIsm->EC_CTRL = u32TempValue; +} + +/** + * @brief Get the RGD value of FPC_STATUS + * + * @param pFpc FPC Instance + * @return RGD value + */ +LOCAL_INLINE bool ISM_HWA_GetFpcRgd(FPC_Type *const pFpc) +{ + return (pFpc->FPC_STATUS & ISM_FPC_STATUS_RGD_MASK) == ISM_FPC_STATUS_RGD_MASK ? true : false; +} + +/** + * @brief Clear the RGD value of FPC_STATUS + * + * @param pFpc FPC Instance + */ +LOCAL_INLINE void ISM_HWA_ClearFpcRgd(FPC_Type *const pFpc) +{ + pFpc->FPC_STATUS = ISM_FPC_STATUS_RGD_MASK; +} + +/** + * @brief Get the FGD value of FPC_STATUS + * + * @param pFpc FPC Instance + * @return FGD value + */ +LOCAL_INLINE bool ISM_HWA_GetFpcFgd(FPC_Type *const pFpc) +{ + return (pFpc->FPC_STATUS & ISM_FPC_STATUS_FGD_MASK) == ISM_FPC_STATUS_FGD_MASK ? true : false; +} + +/** + * @brief Clear the FGD value of FPC_STATUS + * + * @param pFpc FPC Instance + */ +LOCAL_INLINE void ISM_HWA_ClearFpcFgd(FPC_Type *const pFpc) +{ + pFpc->FPC_STATUS = ISM_FPC_STATUS_FGD_MASK; +} + +/** + * @brief Set the EN of FPC_CTRL + * + * @param pFpc FPC Instance + * @param bEnable EN value + */ +LOCAL_INLINE void ISM_HWA_SetFpcCtrlEn(FPC_Type *const pFpc, bool bEnable) +{ + pFpc->FPC_CTRL = (pFpc->FPC_CTRL & ~ISM_FPC_CTRL_EN_MASK) | ISM_FPC_CTRL_EN(bEnable); +} + +/** + * @brief Set the IEN of FPC_CTRL + * + * @param pFpc FPC Instance + * @param bEnable IEN value + */ +LOCAL_INLINE void ISM_HWA_SetFpcCtrlIen(FPC_Type *const pFpc, bool bEnable) +{ + pFpc->FPC_CTRL = (pFpc->FPC_CTRL & ~ISM_FPC_CTRL_IEN_MASK) | ISM_FPC_CTRL_IEN(bEnable); +} + +/** + * @brief Get the IEN of FPC_CTRL + * + * @param pFpc FPC Instance + * @return Interrupt enable bit + */ +LOCAL_INLINE bool ISM_HWA_GetFpcCtrlIen(FPC_Type *const pFpc) +{ + return (pFpc->FPC_CTRL & ISM_FPC_CTRL_IEN_MASK) == ISM_FPC_CTRL_IEN_MASK ? true : false; +} + +/** + * @brief Set the FEG of FPC_CONFIG + * + * @param pFpc FPC Instance + * @param eMode FEG mode + */ +LOCAL_INLINE void ISM_HWA_SetFpcFallingDetectMode(FPC_Type *const pFpc, ISM_FPC_EdgeDetectModeType eMode) +{ + pFpc->FPC_CONFIG = (pFpc->FPC_CONFIG & ~ISM_FPC_CONFIG_FEG_MASK) | ISM_FPC_CONFIG_FEG(eMode); +} + +/** + * @brief Set the FED of FPC_CONFIG + * + * @param pFpc FPC Instance + * @param eMode FED mode + */ +LOCAL_INLINE void ISM_HWA_SetFpcFallingDelayMode(FPC_Type *const pFpc, ISM_FPC_EdgeDelayModeType eMode) +{ + pFpc->FPC_CONFIG = (pFpc->FPC_CONFIG & ~ISM_FPC_CONFIG_FED_MASK) | ISM_FPC_CONFIG_FED(eMode); +} + +/** + * @brief Set the REG of FPC_CONFIG + * + * @param pFpc FPC Instance + * @param eMode REG mode + */ +LOCAL_INLINE void ISM_HWA_SetFpcRisingDetectMode(FPC_Type *const pFpc, ISM_FPC_EdgeDetectModeType eMode) +{ + pFpc->FPC_CONFIG = (pFpc->FPC_CONFIG & ~ISM_FPC_CONFIG_REG_MASK) | ISM_FPC_CONFIG_REG(eMode); +} + +/** + * @brief Set the RED of FPC_CONFIG + * + * @param pFpc FPC Instance + * @param eMode RED mode + */ +LOCAL_INLINE void ISM_HWA_SetFpcRisingDelayMode(FPC_Type *const pFpc, ISM_FPC_EdgeDelayModeType eMode) +{ + pFpc->FPC_CONFIG = (pFpc->FPC_CONFIG & ~ISM_FPC_CONFIG_RED_MASK) | ISM_FPC_CONFIG_RED(eMode); +} + +/** + * @brief Set the CMP of FPC_CONFIG + * + * @param pFpc FPC Instance + * @param u32Value FPC threshold value that is compared with the 16-bit timer. + */ +LOCAL_INLINE void ISM_HWA_SetFpcConfigCmp(FPC_Type *const pFpc, uint32_t u32Value) +{ + pFpc->FPC_CONFIG = (pFpc->FPC_CONFIG & ~ISM_FPC_CONFIG_CMP_MASK) | ISM_FPC_CONFIG_CMP(u32Value); +} + +/** + * @brief Set the value of FPC_CONFIG + * + * @param pFpc FPC Instance + * @param u32Value Register value + */ +LOCAL_INLINE void ISM_HWA_SetFpcConfig(FPC_Type *const pFpc, uint32_t u32Value) +{ + pFpc->FPC_CONFIG = u32Value; +} + +/** + * @brief Get the TIM of FPC_TIMER + * + * @param pFpc FPC Instance + * @return TIM value + */ +LOCAL_INLINE uint16_t ISM_HWA_GetFpcTimer(FPC_Type *const pFpc) +{ + return (uint16_t)((pFpc->FPC_TIMER & ISM_FPC_TIMER_TIM_MASK) >> ISM_FPC_TIMER_TIM_SHIFT); +} + +/** + * @brief Clear the TIM of FPC_TIMER + * + * @param pFpc FPC Instance + */ +LOCAL_INLINE void ISM_HWA_ClearFpcTimer(FPC_Type *const pFpc) +{ + pFpc->FPC_TIMER = ISM_FPC_TIMER_TIM_MASK; +} + +/** + * @brief Get the COUNT of LAM_STATUS + * + * @param pLam LAM Instance + * @return COUNT value + */ +LOCAL_INLINE uint32_t ISM_HWA_GetLamStatusCounter(LAM_Type *const pLam) +{ + return (pLam->LAM_STATUS & ISM_LAM_STATUS_COUNT_MASK) >> ISM_LAM_STATUS_COUNT_SHIFT; +} + +/** + * @brief Clear the COUNT of LAM_STATUS + * + * @param pLam LAM Instance + */ +LOCAL_INLINE void ISM_HWA_ClearLamStatusCounter(LAM_Type *const pLam) +{ + pLam->LAM_STATUS = ISM_LAM_STATUS_COUNT_MASK; +} + +/** + * @brief Get the OVFL of LAM_STATUS + * + * @param pLam LAM Instance + * @return OVFL value + */ +LOCAL_INLINE bool ISM_HWA_GetLamStatusOvfl(LAM_Type *const pLam) +{ + return (pLam->LAM_STATUS & ISM_LAM_STATUS_OVFL_MASK) == ISM_LAM_STATUS_OVFL_MASK ? true : false; +} + +/** + * @brief Clear the OVFL of LAM_STATUS + * + * @param pLam LAM Instance + */ +LOCAL_INLINE void ISM_HWA_ClearLamStatusOvfl(LAM_Type *const pLam) +{ + pLam->LAM_STATUS = ISM_LAM_STATUS_OVFL_MASK; +} + +/** + * @brief Set the IEN of LAM_CTRL + * + * @param pLam LAM Instance + * @param bEnable IEN value, LAM Channel Overflow Interrupt Enable + */ +LOCAL_INLINE void ISM_HWA_SetLamCtrIen(LAM_Type *const pLam, bool bEnable) +{ + pLam->LAM_CTRL = (pLam->LAM_CTRL & ~ISM_LAM_CTRL_IEN_MASK) | ISM_LAM_CTRL_IEN(bEnable); +} + +/** + * @brief Get the IEN of LAM_CTRL + * + * @param pLam LAM Instance + * @return LAM Channel Overflow Interrupt Enable bit + */ +LOCAL_INLINE bool ISM_HWA_GetLamCtrIen(LAM_Type *const pLam) +{ + return (pLam->LAM_CTRL & ISM_LAM_CTRL_IEN_MASK) == ISM_LAM_CTRL_IEN_MASK ? true : false; +} + +/** + * @brief Set the EN of LAM_CTRL + * + * @param pLam LAM Instance + * @param bEnable EN value, LAM Channel Enable + */ +LOCAL_INLINE void ISM_HWA_SetLamCtrEn(LAM_Type *const pLam, bool bEnable) +{ + pLam->LAM_CTRL = (pLam->LAM_CTRL & ~ISM_LAM_CTRL_EN_MASK) | ISM_LAM_CTRL_EN(bEnable); +} + +/** + * @brief Set the value of LAM_CONFIG + * + * @param pLam LAM Instance + * @param u32Value Reigster value + */ +LOCAL_INLINE void ISM_HWA_SetLamConfig(LAM_Type *const pLam, uint32_t u32Value) +{ + pLam->LAM_CONFIG = u32Value; +} + +/** + * @brief Set the value of LAM_COUNTER + * + * @param pLam LAM Instance + * @param u32Value Reigster value + */ +LOCAL_INLINE void ISM_HWA_SetLamCounter(LAM_Type *const pLam, uint32_t u32Value) +{ + pLam->LAM_CONTER = u32Value; +} + +/** + * @brief Get the FPC instance. + * @param pIsm ISM Instance + * @param u8FpcIndex FPC index + * @return FPC Instance + */ +LOCAL_INLINE FPC_Type *ISM_HWA_GetFpc(ISM_Type *const pIsm, uint8_t u8FpcIndex) +{ + return (FPC_Type *)((uint32_t) & (pIsm->FPC_STATUS0) + (uint32_t)u8FpcIndex * 0x10U); +} + +/** + * @brief Get the LAM instance. + * @param pIsm ISM Instance + * @param u8FpcIndex LAM index + * @return LAM Instance + */ +LOCAL_INLINE LAM_Type *ISM_HWA_GetLam(ISM_Type *const pIsm, uint8_t u8LamIndex) +{ + return (LAM_Type *)((uint32_t) & (pIsm->LAM_STATUS0) + (uint32_t)u8LamIndex * 0x10U); +} + +/** @}*/ /* HwA_ism */ + +#endif /* #ifndef _HWA_ISM_H_ */ diff --git a/MODULES/HwA_Flagchip_FC7240/Inc/HwA_lu.h b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_lu.h new file mode 100644 index 0000000..f94599d --- /dev/null +++ b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_lu.h @@ -0,0 +1,248 @@ +/** + * @file HwA_lu.h + * @author Flagchip0103 + * @brief FC7xxx LU hardware access layer + * @version 0.1.0 + * @date 2023-12-19 + * + * @copyright Copyright (c) 2023 Flagchip Semiconductors Co., Ltd. + * + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2023-12-19 Flagchip0103 N/A First version for FC7240 + ******************************************************************************** */ + +#ifndef _HWA_LU_H_ +#define _HWA_LU_H_ + +#include "device_header.h" + +/********* Local typedef ************/ +/** @brief LU LG instance */ +typedef enum +{ + LU_LG_0 = 0U, + LU_LG_1, + LU_LG_2, + LU_LG_3 +} LU_LgType; + +/** @brief LU AOI mode */ +typedef enum +{ + LU_NO_BYPASS = 0U, + LU_AOI0_BYPASS, + LU_AOI1_BYPASS, + LU_AOI0_AOI1_BYPASS +} LU_BypassModeType; + +/** @brief LU FF mode */ +typedef enum +{ + LU_BYPASS_MODE0 = 0U, + LU_RS_MODE, + LU_TFF_MODE, + LU_DFF_MODE, + LU_JKFF_MODE, + LU_LATCH_MODE +} LU_ConfigModeType; + +/** @brief LU Input(n) type */ +typedef enum +{ + LU_INPUT_N_A = 0U, + LU_INPUT_N_B, + LU_INPUT_N_C, + LU_INPUT_N_D +} LU_InputNType; +/********* Local inline function ************/ +/** + * @brief Configure LU LG(n) AOI0 configuration + * + * @param pLu LU instance + * @param eLg LG instance + * @param u32RegValue AOI0 register value + */ +LOCAL_INLINE void LU_HWA_ConfigAOI0(LU_Type* pLu, LU_LgType eLg, uint32_t u32RegValue) +{ + pLu->LG[eLg].AOI_0 = u32RegValue; +} + +/** + * @brief Configure LU LG(n) AOI1 configuration + * + * @param pLu LU instance + * @param eLg LG instance + * @param u32RegValue AOI1 register value + */ +LOCAL_INLINE void LU_HWA_ConfigAOI1(LU_Type* pLu, LU_LgType eLg, uint32_t u32RegValue) +{ + pLu->LG[eLg].AOI_1 = u32RegValue; +} + +/** + * @brief Configure LU LG(n) contrl configuration + * + * @param pLu LU instance + * @param eLg LG instance + * @param u32RegValue CTRL register value + */ +LOCAL_INLINE void LU_HWA_ConfigCtrl(LU_Type* pLu, LU_LgType eLg, uint32_t u32RegValue) +{ + pLu->LG[eLg].CTRL = u32RegValue; +} + +/** + * @brief Configure LU LG(n) filter configuration + * + * @param pLu LU instance + * @param eLg LG instance + * @param u32RegValue FILT register value + */ +LOCAL_INLINE void LU_HWA_ConfigFilter(LU_Type* pLu, LU_LgType eLg, uint32_t u32RegValue) +{ + pLu->LG[eLg].FILT = u32RegValue; +} + +/** + * @brief Set LG bypass control + * + * @param pLu LU instance + * @param eLg LG instance + * @param eMode LG bypass control mode + */ +LOCAL_INLINE void LU_HWA_SetLgBypassControl(LU_Type* pLu, LU_LgType eLg, LU_BypassModeType eMode) +{ + uint32_t u32TempRegValue = pLu->LG[eLg].CTRL; + pLu->LG[eLg].CTRL = ((u32TempRegValue & ~(uint32_t)LU_CTRL_BYPASS_MASK) | LU_CTRL_BYPASS(eMode)); +} + +/** + * @brief Set LG Flip-Flop mode + * + * @param pLu LU instance + * @param eLg LG instance + * @param eMode Flip-Flop mode + */ +LOCAL_INLINE void LU_HWA_SetLgFlipFlopMode(LU_Type* pLu, LU_LgType eLg, LU_ConfigModeType eMode) +{ + uint32_t u32TempRegValue = pLu->LG[eLg].CTRL; + pLu->LG[eLg].CTRL = ((u32TempRegValue & ~(uint32_t)LU_CTRL_MOD_MASK) | LU_CTRL_MOD(eMode)); +} + +/** + * @brief Set LG inputs synchronous control + * + * @param pLu LU instance + * @param eLg LG instance + * @param u32Value LG input bit,0-3 bit indicate INPUT(n)A/INPUT(n)B/INPUT(n)C/INPUT(n)D + */ +LOCAL_INLINE void LU_HWA_SetLgInputsSyncCtrl(LU_Type* pLu, LU_LgType eLg, uint32_t u32Value) +{ + uint32_t u32TempRegValue = pLu->LG[eLg].CTRL; + pLu->LG[eLg].CTRL = ((u32TempRegValue & ~(uint32_t)LU_CTRL_SYNC_MASK) | LU_CTRL_SYNC(u32Value)); +} + +/** + * @brief Set LG output feedback override control + * + * @param pLu LU instance + * @param eLg LG instance + * @param eInput Feedback to LG input + */ +LOCAL_INLINE void LU_HWA_SetLgFeedbackOverrideCtrl(LU_Type* pLu, LU_LgType eLg, LU_InputNType eInput) +{ + uint32_t u32TempRegValue = pLu->LG[eLg].CTRL; + pLu->LG[eLg].CTRL = ((u32TempRegValue & ~(uint32_t)LU_CTRL_FB_OVRD_MASK) | LU_CTRL_FB_OVRD(eInput)); +} + +/** + * @brief Configure the output of flip-flop as "1" + * + * @param pLu LU instance + * @param eLg LG instance + */ +LOCAL_INLINE void LU_HWA_ConfigFlipFlopTo1(LU_Type* pLu, LU_LgType eLg) +{ + pLu->LG[eLg].CTRL |= (uint32_t)LU_CTRL_FF_INIT_MASK; +} + +/** + * @brief Generate enable pulse + * + * @param pLu LU instance + * @param eLg LG instance + */ +LOCAL_INLINE void LU_HWA_EnableControlFlipFlopInitOutput(LU_Type* pLu, LU_LgType eLg) +{ + pLu->LG[eLg].CTRL |= (uint32_t)LU_CTRL_INIT_EN_MASK; +} + +/** + * @brief Input filter sample count for AOI0 + * + * @param pLu LU instance + * @param eLg LG instance + * @param u32Value Sample count value + */ +LOCAL_INLINE void LU_HWA_SetAOI0InputFilterSampleCount(LU_Type* pLu, LU_LgType eLg, uint32_t u32Value) +{ + uint32_t u32TempRegValue = pLu->LG[eLg].FILT; + pLu->LG[eLg].FILT = ((u32TempRegValue & ~(uint32_t)LU_FILT_CNT0_MASK) | LU_FILT_CNT0(u32Value)); +} + +/** + * @brief Input filter sample period for AOI0 + * + * @param pLu LU instance + * @param eLg LG instance + * @param u32Value Sample period value + */ +LOCAL_INLINE void LU_HWA_SetAOI0InputFilterSamplePeriod(LU_Type* pLu, LU_LgType eLg, uint32_t u32Value) +{ + uint32_t u32TempRegValue = pLu->LG[eLg].FILT; + pLu->LG[eLg].FILT = ((u32TempRegValue & ~(uint32_t)LU_FILT_PRE0_MASK) | LU_FILT_PRE0(u32Value)); +} + +/** + * @brief Input filter sample count for AOI1 + * + * @param pLu LU instance + * @param eLg LG instance + * @param u32Value Sample count value + */ +LOCAL_INLINE void LU_HWA_SetAOI1InputFilterSampleCount(LU_Type* pLu, LU_LgType eLg, uint32_t u32Value) +{ + uint32_t u32TempRegValue = pLu->LG[eLg].FILT; + pLu->LG[eLg].FILT = ((u32TempRegValue & ~(uint32_t)LU_FILT_CNT1_MASK) | LU_FILT_CNT1(u32Value)); +} + +/** + * @brief Input filter sample period for AOI1 + * + * @param pLu LU instance + * @param eLg LG instance + * @param u32Value Sample period value + */ +LOCAL_INLINE void LU_HWA_SetAOI1InputFilterSamplePeriod(LU_Type* pLu, LU_LgType eLg, uint32_t u32Value) +{ + uint32_t u32TempRegValue = pLu->LG[eLg].FILT; + pLu->LG[eLg].FILT = ((u32TempRegValue & ~(uint32_t)LU_FILT_PRE1_MASK) | LU_FILT_PRE1(u32Value)); +} + +/** + * @brief Configure the output of flip-flop as "0" + * + * @param pLu LU instance + * @param eLg LG instance + */ +LOCAL_INLINE void LU_HWA_ConfigFlipFlopTo0(LU_Type* pLu, LU_LgType eLg) +{ + pLu->LG[eLg].CTRL &= ~(uint32_t)LU_CTRL_FF_INIT_MASK; +} + +#endif /* #ifndef _HWA_LU_H_ */ diff --git a/MODULES/HwA_Flagchip_FC7240/Inc/HwA_mam.h b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_mam.h new file mode 100644 index 0000000..4897dec --- /dev/null +++ b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_mam.h @@ -0,0 +1,126 @@ +/** + * @file HwA_mam.h + * @author Flagchip + * @brief Hardware access layer for MAM + * @version 0.2.0 + * @date 2023-02-08 + * + * @copyright Copyright (c) 2023 Flagchip Semiconductors Co., Ltd. + * + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2023-02-08 Flagchip054 N/A First version for FC7300 + ******************************************************************************** */ +#ifndef _HWA_MAM_H_ +#define _HWA_MAM_H_ +#include "device_header.h" + +/** + * @brief Set Mam module Matrix Configure register + * + * @param1 MAM base pointer + * + * @param2 u32Value Matrix Configure register value + */ +LOCAL_INLINE void Mam_HWA_SetMatrixCfg(MAM_Type *MAMInstance, uint32_t u32Value) +{ + MAMInstance->MAXCFG = u32Value; +} + +/** + * @brief Read Mam module Ctrl register + * + * @param MAM base pointer + * + * @return Matrix Configure register value + */ +LOCAL_INLINE uint32_t Mam_HWA_GetMatrixCfg(MAM_Type *MAMInstance) +{ + return (uint32_t)(MAMInstance->MAXCFG); +} + +/** + * @brief Set Mam module Wdgctr register + * + * @param1 MAM base pointer + * + * @param2 u32Value Wdgctr register value + */ +LOCAL_INLINE void Mam_HWA_Set_Wdgctr(MAM_Type *MAMInstance, uint32_t u32Value) +{ + MAMInstance->WDGCR = u32Value; +} + +/** + * @brief Read Mam module Wdgctr register + * + * @param MAM base pointer + * + * @return Wdgctr register value + */ +LOCAL_INLINE uint32 Mam_HWA_Get_Wdgctr(MAM_Type *MAMInstance) +{ + return MAMInstance->WDGCR; +} + +/** + * @brief Set Mam module ACR register + * + * @param1 MAM base pointer + * + * @param2 idx ACR register index + * + * @param3 u32Value ACR register value + */ +LOCAL_INLINE void Mam_HWA_Set_ACR(MAM_Type *MAMInstance, uint32_t idx, uint32_t u32Value) +{ + MAMInstance->ACR[idx] = u32Value; +} + +/** + * @brief Read Mam module ACR register + * + * @param1 MAM base pointer + * + * @param2 idx ACR register index + * + * @return ACR register value + */ +LOCAL_INLINE uint32_t Mam_HWA_Get_ACR(MAM_Type *MAMInstance, uint32_t idx) +{ + return MAMInstance->ACR[idx]; +} + +/** + * @brief Set Mam module ACLR register + * + * @param1 MAM base pointer + * + * @param2 idx ACLR register index + * + * @param3 u32Value ACLR register value + */ +LOCAL_INLINE void Mam_HWA_Set_ACLR(MAM_Type *MAMInstance, uint32_t idx, uint32_t u32Value) +{ + MAMInstance->ACLR[idx] = u32Value; +} + +/** + * @brief Read Mam module ACLR register + * + * @param1 MAM base pointer + * + * @param2 idx ACLR register index + * + * @return ACLR register value + */ +LOCAL_INLINE uint32_t Mam_HWA_Get_ACLR(MAM_Type *MAMInstance, uint32_t idx) +{ + return MAMInstance->ACLR[idx]; +} + +#endif diff --git a/MODULES/HwA_Flagchip_FC7240/Inc/HwA_mb.h b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_mb.h new file mode 100644 index 0000000..9cfb2cb --- /dev/null +++ b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_mb.h @@ -0,0 +1,408 @@ +/** + * @file HwA_mb.h + * @author Flagchip070 + * @brief FC7xxx Mailbox hardware access layer + * @version 0.1.0 + * @date 2022-11-15 + * + * @copyright Copyright (c) 2022 Flagchip Semiconductors Co., Ltd. + * + * @details + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2022-11-15 Flagchip070 N/A First version for FC7300 + ******************************************************************************** */ + +#ifndef _HWA_MAILBOX_H_ +#define _HWA_MAILBOX_H_ +#include "device_header.h" + +/** + * @brief The definition of mask all events + * + */ +#define MB_EVENT_NONE 0u +/** + * @brief The definition of receiving all events + * + */ +#define MB_EVENT_ALL 0xFFFFFFFFu +/** + * @brief The definition of receiving all request events + * + */ +#define MB_EVENT_ALL_REQ 0x0000FFFFu +/** + * @brief The definition of receiving all done events + * + */ +#define MB_EVENT_ALL_DONE 0xFFFF0000u +/** + * @brief The definition of request events on ch + * + */ +#define MB_EVENT_REQ(ch) (uint32_t)((uint32_t)1u << (ch)) +/** + * @brief The definition of done events on ch + * + */ +#define MB_EVENT_DONE(ch) (uint32_t)((uint32_t)1u << ((ch) + 16u)) +/** + * @brief The definition of issue to no core + * + */ +#define MB_CORE_MASK_CORE_NONE 0u +/** + * @brief The definition of issue to core 0 + * + */ +#define MB_CORE_MASK_CORE_0 1u +/** + * @brief The definition of issue to HSM + * + */ +#define MB_CORE_MASK_HSM 2u +/** + * @brief The definition of issue to all cores + * + */ +#define MB_CORE_MASK_ALL 0x3u +/** + * @brief The definition of issue to core + * + */ +#define MB_CORE_MASK(core) (uint32_t)(1ul << (core)) + +enum +{ + MB_CORE_INDEX_CORE_0 = 0, /*!< Core index of core 0 */ + MB_CORE_INDEX_HSM, /*!< Core index of HSM */ +}; + +/** + * @brief Configure receive events of mailbox interrupt channel + * + * @param u32CoreIndex the index of the core + * @param u32Mask configuration for receiving events + */ +LOCAL_INLINE void MB_HWA_ConfigFlagMask(uint32_t u32CoreIndex, uint32_t u32Mask) +{ + MB->INTR[u32CoreIndex].MB_INTn_CTRL &= ~MB_INTn_CTRL_FLG_MASK_LOCK_MASK; + MB->INTR[u32CoreIndex].MB_INTn_FLG_MASK = u32Mask; + MB->INTR[u32CoreIndex].MB_INTn_CTRL |= MB_INTn_CTRL_FLG_MASK_LOCK_MASK; +} + +/** + * @brief Enable receive events of mailbox interrupt channel + * + * @param u32CoreIndex the index of the core + * @param u32Mask indicates the events to be enabled + */ +LOCAL_INLINE void MB_HWA_EnableEvent(uint32_t u32CoreIndex, uint32_t u32Mask) +{ + MB->INTR[u32CoreIndex].MB_INTn_CTRL &= ~MB_INTn_CTRL_FLG_MASK_LOCK_MASK; + MB->INTR[u32CoreIndex].MB_INTn_FLG_MASK |= u32Mask; + MB->INTR[u32CoreIndex].MB_INTn_CTRL |= MB_INTn_CTRL_FLG_MASK_LOCK_MASK; +} + +/** + * @brief Disable receive events of mailbox interrupt channel + * + * @param u32CoreIndex the index of the core + * @param u32Mask indicates the events to be enabled + */ +LOCAL_INLINE void MB_HWA_DisableEvent(uint32_t u32CoreIndex, uint32_t u32Mask) +{ + MB->INTR[u32CoreIndex].MB_INTn_CTRL &= ~MB_INTn_CTRL_FLG_MASK_LOCK_MASK; + MB->INTR[u32CoreIndex].MB_INTn_FLG_MASK &= ~u32Mask; + MB->INTR[u32CoreIndex].MB_INTn_CTRL |= MB_INTn_CTRL_FLG_MASK_LOCK_MASK; +} + +/** + * @brief Configure the interrupt of mailbox interrupt channel + * + * @param u32CoreIndex the index of the core + * @param u32Mask configuration for interrupts + */ +LOCAL_INLINE void MB_HWA_ConfigIntrEnable(uint32_t u32CoreIndex, uint32_t u32Mask) +{ + MB->INTR[u32CoreIndex].MB_INTn_CTRL &= ~MB_INTn_CTRL_INTEN_LOCK_MASK; + MB->INTR[u32CoreIndex].MB_INTn_INTEN = u32Mask; + MB->INTR[u32CoreIndex].MB_INTn_CTRL |= MB_INTn_CTRL_INTEN_LOCK_MASK; +} + +/** + * @brief Enable the interrupt of mailbox interrupt channel + * + * @param u32CoreIndex the index of the core + * @param u32Mask indicates the interrupts to be enabled + */ +LOCAL_INLINE void MB_HWA_EnableIntr(uint32_t u32CoreIndex, uint32_t u32Mask) +{ + MB->INTR[u32CoreIndex].MB_INTn_CTRL &= ~MB_INTn_CTRL_INTEN_LOCK_MASK; + MB->INTR[u32CoreIndex].MB_INTn_INTEN |= u32Mask; + MB->INTR[u32CoreIndex].MB_INTn_CTRL |= MB_INTn_CTRL_INTEN_LOCK_MASK; +} + +/** + * @brief Disable the interrupt of mailbox interrupt channel + * + * @param u32CoreIndex the index of the core + * @param u32Mask indicates the interrupts to be disabled + */ +LOCAL_INLINE void MB_HWA_DisableIntr(uint32_t u32CoreIndex, uint32_t u32Mask) +{ + MB->INTR[u32CoreIndex].MB_INTn_CTRL &= ~MB_INTn_CTRL_INTEN_LOCK_MASK; + MB->INTR[u32CoreIndex].MB_INTn_INTEN &= ~u32Mask; + MB->INTR[u32CoreIndex].MB_INTn_CTRL |= MB_INTn_CTRL_INTEN_LOCK_MASK; +} + +/** + * @brief Clear the flag of mailbox interrupt channel + * + * @param u32CoreIndex the index of the core + * @param u32Mask indicates the flags to be cleared + */ +LOCAL_INLINE void MB_HWA_ClearFlag(uint32_t u32CoreIndex, uint32_t u32Mask) +{ + MB->INTR[u32CoreIndex].MB_INTn_CTRL &= ~MB_INTn_CTRL_FLG_LOCK_MASK; + MB->INTR[u32CoreIndex].MB_INTn_FLG |= u32Mask; + MB->INTR[u32CoreIndex].MB_INTn_CTRL |= MB_INTn_CTRL_FLG_LOCK_MASK; +} + +/** + * @brief Get the flag masks of mailbox interrupt channel + * + * @param u32CoreIndex the index of the core + * @param u32Mask the mask to get + * @return the flag masks of the mailbox interrupt channel + */ +LOCAL_INLINE uint32_t MB_HWA_GetFlagMask(uint32_t u32CoreIndex, uint32_t u32Mask) +{ + uint32_t u32RegValue = MB->INTR[u32CoreIndex].MB_INTn_FLG_MASK & u32Mask; + return u32RegValue; +} + +/** + * @brief Get the flags of mailbox interrupt channel + * + * @param u32CoreIndex the index of the core + * @param u32Mask the mask to get + * @return the flags of the mailbox interrupt channel + */ +LOCAL_INLINE uint32_t MB_HWA_GetFlag(uint32_t u32CoreIndex, uint32_t u32Mask) +{ + uint32_t u32RegValue = MB->INTR[u32CoreIndex].MB_INTn_FLG & u32Mask; + return u32RegValue; +} + +/** + * @brief Get the result of flag & inten of mailbox interrupt channel + * + * @param u32CoreIndex the index of the core + * @param u32Mask the mask to get + * @return the result of flag & inten of the mailbox interrupt channel + */ +LOCAL_INLINE uint32_t MB_HWA_GetFlagStat(uint32_t u32CoreIndex, uint32_t u32Mask) +{ + uint32_t u32RegValue = MB->INTR[u32CoreIndex].MB_INTn_FLG_STAT & u32Mask; + return u32RegValue; +} + +/** + * @brief Get the master ID of the currently obtained channel + * + * @param u32Channel the index of the channel + * @return the master ID + */ +LOCAL_INLINE uint32_t MB_HWA_GetMasterID(uint32_t u32Channel) +{ + uint32_t u32MasterId = MB->CHANNEL[u32Channel].MB_CCn_STAT; + u32MasterId = (u32MasterId & MB_CCn_STAT_CURRENT_LOCK_MASTER_ID_MASK) >> MB_CCn_STAT_CURRENT_LOCK_MASTER_ID_SHIFT; + return u32MasterId; +} + +/** + * @brief Get the security information of the currently obtained channel + * + * @param u32Channel the index of the channel + * @return the security information + */ +LOCAL_INLINE uint32_t MB_HWA_GetSecure(uint32_t u32Channel) +{ + uint32_t u32Secure = MB->CHANNEL[u32Channel].MB_CCn_STAT & MB_CCn_STAT_CURRENT_LOCK_MASTER_SEC_MASK; + return u32Secure; +} + +/** + * @brief Get the processing mode of the currently obtained channel + * + * @param u32Channel the index of the channel + * @return the processing mode + */ +LOCAL_INLINE uint32_t MB_HWA_GetSupervisor(uint32_t u32Channel) +{ + uint32_t u32Supervisor = MB->CHANNEL[u32Channel].MB_CCn_STAT & MB_CCn_STAT_CURRENT_LOCK_MASTER_SUPERVISOR_MASK; + return u32Supervisor; +} + +/** + * @brief Send data to the mailbox channel + * + * @param u32Channel the index of the channel + * @param pData the buffer to be written + */ +LOCAL_INLINE void MB_HWA_WriteData(uint32_t u32Channel, uint32_t *pData) +{ + MB->CHANNEL[u32Channel].MB_CCn_DATA0 = pData[0]; + MB->CHANNEL[u32Channel].MB_CCn_DATA1 = pData[1]; +} + +/** + * @brief Receive data from the mailbox channel + * + * @param u32Channel the index of the channel + * @param pData the buffer to receive data + */ +LOCAL_INLINE void MB_HWA_GetData(uint32_t u32Channel, uint32_t *pData) +{ + pData[0] = MB->CHANNEL[u32Channel].MB_CCn_DATA0; + pData[1] = MB->CHANNEL[u32Channel].MB_CCn_DATA1; +} + +/** + * @brief Get the automatically clear status of the mailbox channel + * + * @param u32Channel the index of the channel + * @param u32CoreIndex the index of the core + * @return automatically clear the channel lock enable bit + */ +LOCAL_INLINE uint32_t MB_HWA_GetAutoClear(uint32_t u32Channel, uint32_t u32CoreIndex) +{ + uint32_t u32SemaUnlock = MB->CHANNEL[u32Channel].MB_CCn_SEMA_UNLK; + u32SemaUnlock &= (uint32_t)1u << (u32CoreIndex + MB_CCn_SEMA_UNLK_AUTO_CLEAR_EN_SHIFT); + return u32SemaUnlock; +} + +/** + * @brief Release the mailbox channel + * + * @param u32Channel the index of the channel + */ +LOCAL_INLINE void MB_HWA_ReleaseChannel(uint32_t u32Channel) +{ + MB->CHANNEL[u32Channel].MB_CCn_DONE = MB_MASTER_DONE_CODE; +} + +/** + * @brief Software clears channel lock + * + * @param u32Channel the index of the channel + */ +LOCAL_INLINE void MB_HWA_UnlockChanne(uint32_t u32Channel) +{ + MB->CHANNEL[u32Channel].MB_CCn_CLR = MB_FORCE_UNLOCK_CODE; +} + +/** + * @brief Issue a done event + * + * @param u32Channel the index of the channel + * @param u32DoneMask the cores to issue + */ +LOCAL_INLINE void MB_HWA_SetDone(uint32_t u32Channel, uint32_t u32DoneMask) +{ + MB->CHANNEL[u32Channel].MB_CCn_DONE |= (u32DoneMask & MB_CCn_DONE_DONE_MASK); +} + +/** + * @brief Try to lock a channel + * + * @param u32Channel the index of the channel + * @return Channel Lock Acquisition + */ +LOCAL_INLINE uint32_t MB_HWA_LockChannel(uint32_t u32Channel) +{ + uint32_t u32RegValue = MB->CHANNEL[u32Channel].MB_CCn_SEMA; + return u32RegValue & MB_CCn_SEMA_LOCK_MASK; +} + +/** + * @brief Configure the master ID of the core that generates a done event + * + * @param u32Channel the index of the channel + * @param u32MasterId master ID + */ +LOCAL_INLINE void MB_HWA_ConfigDoneMasterId(uint32_t u32Channel, uint32_t u32MasterId) +{ + MB->CHANNEL[u32Channel].MB_CCn_DONE_MASK &= ~MB_CCn_DONE_MASK_DONE_MASTER_ID_MASK; + MB->CHANNEL[u32Channel].MB_CCn_DONE_MASK |= MB_CCn_DONE_MASK_DONE_MASTER_ID(u32MasterId); +} + +/** + * @brief Get the master ID of the core that generates a done event + * + * @param u32Channel the index of the channel + * @return the master ID + */ +LOCAL_INLINE uint32_t MB_HWA_GetDoneMasterId(uint32_t u32Channel) +{ + uint32_t u32MasterId = + (MB->CHANNEL[u32Channel].MB_CCn_DONE_MASK & MB_CCn_DONE_MASK_DONE_MASTER_ID_MASK) + >> MB_CCn_DONE_MASK_DONE_MASTER_ID_SHIFT; + return u32MasterId; + +} + +/** + * @brief Configure the mask of the done events + * + * @param u32Channel the index of the channel + * @param u32DoneMask the cores to issue + */ +LOCAL_INLINE void MB_HWA_ConfigDoneMask(uint32_t u32Channel, uint32_t u32DoneMask) +{ + MB->CHANNEL[u32Channel].MB_CCn_DONE_MASK &= ~MB_CCn_DONE_DONE_MASK; + MB->CHANNEL[u32Channel].MB_CCn_DONE_MASK |= (u32DoneMask << MB_CCn_DONE_DONE_SHIFT) & MB_CCn_DONE_DONE_MASK; +} + +/** + * @brief Get the mask of the done events + * + * @param u32Channel the index of the channel + * @return the mask of the done events + */ +LOCAL_INLINE uint32_t MB_HWA_GetDoneMask(uint32_t u32Channel) +{ + uint32_t u32Mask = MB->CHANNEL[u32Channel].MB_CCn_DONE_MASK & MB_CCn_DONE_DONE_MASK; + return u32Mask; +} + +/** + * @brief Configure the automatically clear of the lock enable bit + * + * @param u32Channel the index of the channel + * @param u32AutoUnlockMask the automatically clear of the lock enable bit + */ +LOCAL_INLINE void MB_HWA_ConfigAutoUnlock(uint32_t u32Channel, uint32_t u32AutoUnlockMask) +{ + MB->CHANNEL[u32Channel].MB_CCn_SEMA_UNLK = MB_CCn_SEMA_UNLK_AUTO_CLEAR_EN(u32AutoUnlockMask); +} + +/** + * @brief Issue request events + * + * @param u32Channel the index of the channel + * @param u32RequestMask the cores to issue + */ +LOCAL_INLINE void MB_HWA_ConfigRequest(uint32_t u32Channel, uint32_t u32RequestMask) +{ + MB->CHANNEL[u32Channel].MB_CCn_REQUEST = MB_CCn_REQUEST_REQ(u32RequestMask); +} + +#endif + diff --git a/MODULES/HwA_Flagchip_FC7240/Inc/HwA_mpu.h b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_mpu.h new file mode 100644 index 0000000..aeee8a1 --- /dev/null +++ b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_mpu.h @@ -0,0 +1,320 @@ +/** + * @file HwA_mpu.h + * @author Flagchip085 + * @brief FC7xxx MPU hardware access layer + * @version 0.1.0 + * @date 2024-01-12 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-01-12 Flagchip085 N/A First version for FC7240 + ******************************************************************************** */ +#ifndef _HWA_MPU_H_ +#define _HWA_MPU_H_ + +#include "device_header.h" + +/** + * @brief The MPU registers struct + * + */ +typedef struct { + __I uint32_t MPU_TYPE; /* TYPE, offset: 0x0 */ + __IO uint32_t MPU_CTRL; /* CTRL, offset: 0x4 */ + __IO uint32_t MPU_RNR; /* RNR, offset: 0x8 */ + __IO uint32_t MPU_RBAR; /* RBAR, offset: 0xC */ + __IO uint32_t MPU_RASR; /* RASR, offset: 0x10 */ +} CORTEX_MPU_Type, *PCORTEX_MPU_Type; + +/** mpu base Address */ +#define CORTEX_MPU_BASE (0xE000ED90U) +#define CORTEX_MPU ((CORTEX_MPU_Type *)CORTEX_MPU_BASE) + + +/** TYPE Bit Fields **/ +#define CORTEX_MPU_TYPE_IREGION_MASK 0xFF0000U + +#define CORTEX_MPU_TYPE_IREGION_SHIFT 16U + +#define CORTEX_MPU_TYPE_IREGION_WIDTH 8U + +#define CORTEX_MPU_TYPE_IREGION(x) (((uint32_t)(((uint32_t)(x))<MPU_TYPE; +} + +/** + * @brief disable fault exceptions + * + * + */ +LOCAL_INLINE void MPU_HWA_Fault_Disable(void) +{ + SCB->SHCSR &= ~((uint32_t)SCB_SHCSR_MEMFAULTENA_Msk); +} + +/** + * @brief enable fault exceptions + * + * + */ +LOCAL_INLINE void MPU_HWA_Fault_Enable(void) +{ + SCB->SHCSR |= (uint32_t)SCB_SHCSR_MEMFAULTENA_Msk; +} + +/** + * @brief set mpu control register + * + * @param u32RegValue the value write to register + * @return LOCAL_INLINE + */ +LOCAL_INLINE void MPU_HWA_Set_CR(uint32_t u32RegValue) +{ + CORTEX_MPU->MPU_CTRL = u32RegValue; +} + +/** + * @brief set mpu number register + * + * @param u32RegValue the value write to register + * @return LOCAL_INLINE + */ +LOCAL_INLINE void MPU_HWA_Set_NR(uint8_t u32RegValue) +{ + CORTEX_MPU->MPU_RNR = (MPU_REGION_MASK_U32 & u32RegValue); +} + +/** + * @brief set mpu base address register + * + * @param u32RegValue the value write to register + * @return LOCAL_INLINE + */ +LOCAL_INLINE void MPU_HWA_Set_BAR(uint32_t u32RegValue) +{ + CORTEX_MPU->MPU_RBAR = u32RegValue; +} + + +/** + * @brief set mpu attribute and size register + * + * @param u32RegValue the value write to registe + * @return LOCAL_INLINE + */ +LOCAL_INLINE void MPU_HWA_Set_ASR(uint32_t u32RegValue) +{ + CORTEX_MPU->MPU_RASR = u32RegValue; +} + + +#endif /* _HWA_MPU_H_ */ + diff --git a/MODULES/HwA_Flagchip_FC7240/Inc/HwA_msc.h b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_msc.h new file mode 100644 index 0000000..4498f9c --- /dev/null +++ b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_msc.h @@ -0,0 +1,841 @@ +/** + * @file HwA_msc.h + * @author Flagchip + * @brief FC7240 MSC HWA driver type definition and API + * @version 0.1.0 + * @date 2024-01-10 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-01-10 Flagchip084 N/A FC7240 release version + ******************************************************************************** */ + +#ifndef _HWA_MSC_H_ +#define _HWA_MSC_H_ + +#include "device_header.h" + +/** + * @addtogroup HwA_msc + * @{ + * + */ +/********* macros ************/ + +typedef enum +{ + MSC_RSV_SUCCESS = 0x0U, /*!< MSC receive status is successful. */ + MSC_RSV_PARITY_ERROR = 0x1U, /*!< MSC receive has parity error. */ + MSC_RSV_STOP_ERROR = 0x2U /*!< MSC receive has stop error. */ +} MSC_ReceiveStatusType; + +/********* Local typedef ************/ + +/********* Local inline function ************/ + +/********* xxx Register interface ************/ + +/** + * @brief Get the msc TCCTR register + * + * @param pMsc MSCInstance + * @param u32Value TCCTR register value + */ +LOCAL_INLINE void MSC_HWA_SetTcctr(MSC_Type *const pMsc, uint32_t u32Value) +{ + pMsc->TCCTR = u32Value; +} + +/** + * @brief Get the msc TCCTR register DTS bit + * + * @param pMsc MSCInstance + * @return DTS value + */ +LOCAL_INLINE bool MSC_HWA_GetDataNeedSend(MSC_Type *const pMsc) +{ + return (pMsc->TCCTR & MSC_TCCTR_DTS_MASK) == MSC_TCCTR_DTS_MASK ? true : false; +} + +/** + * @brief Set the msc TCCTR register DTS bit + * + * @param pMsc MSCInstance + */ +LOCAL_INLINE void MSC_HWA_SetDataNeedSend(MSC_Type *const pMsc) +{ + pMsc->ISCR = MSC_ISCR_SDTS_MASK; +} + +/** + * @brief Get the msc TCCTR register CTS bit + * + * @param pMsc MSCInstance + * @return CTS value + */ +LOCAL_INLINE bool MSC_HWA_GetCmdNeedSend(MSC_Type *const pMsc) +{ + return (pMsc->TCCTR & MSC_TCCTR_CTS_MASK) == MSC_TCCTR_CTS_MASK ? true : false; +} + +/** + * @brief Get the CFB value of TCSTR register + * + * @param pMsc MSCInstance + * @return CFB value + */ +LOCAL_INLINE bool MSC_HWA_GetCfb(MSC_Type *const pMsc) +{ + return (bool)(((pMsc->TCSTR & (uint32_t)MSC_TCSTR_CFB_MASK) != 0U) ? true : false); +} + +/** + * @brief Get the DFB value of TCSTR register + * + * @param pMsc MSCInstance + * @return DFB value + */ +LOCAL_INLINE bool MSC_HWA_GetDfb(MSC_Type *const pMsc) +{ + return ((pMsc->TCSTR & (uint32_t)MSC_TCSTR_DFB_MASK) != 0U) ? true : false; +} + +/** + * @brief Set the NP value of TCSTR register + * + * @param pMsc MSCInstance + */ +LOCAL_INLINE void MSC_HWA_SetNp(MSC_Type *const pMsc, uint8_t u8Np) +{ + pMsc->TCSTR = (pMsc->TCSTR & ~MSC_TCSTR_NP_MASK) | MSC_TCSTR_NP(u8Np); +} + +/** + * @brief Get the NP value of TCSTR register + * + * @param pMsc MSCInstance + * @return NP value + */ +LOCAL_INLINE uint32_t MSC_HWA_GetNp(MSC_Type *const pMsc) +{ + return ((pMsc->TCSTR & (uint32_t)MSC_TCSTR_NP_MASK)) >> MSC_TCSTR_NP_SHIFT; +} + +/** + * @brief Set the msc TCDAR register + * + * @param pMsc MSCInstance + * @param u32Value TCDAR value + */ +LOCAL_INLINE void MSC_HWA_SetTcdar(MSC_Type *const pMsc, uint32_t u32Value) +{ + pMsc->TCDAR = u32Value; +} + +/** + * @brief Set the TDH of TCDAR register + * + * @param pMsc MSCInstance + * @param u16Value TDH value + */ +LOCAL_INLINE void MSC_HWA_SetTcdarTdh(MSC_Type *const pMsc, uint16_t u16Value) +{ + pMsc->TCDAR = (pMsc->TCDAR & ~MSC_TCDAR_TDH_MASK) | MSC_TCDAR_TDH(u16Value); +} + +/** + * @brief Set the TDL of TCDAR register + * + * @param pMsc MSCInstance + * @param u16Value TDL value + */ +LOCAL_INLINE void MSC_HWA_SetTcdarTdl(MSC_Type *const pMsc, uint16_t u16Value) +{ + pMsc->TCDAR = (pMsc->TCDAR & ~MSC_TCDAR_TDL_MASK) | MSC_TCDAR_TDL(u16Value); +} + +/** + * @brief Set the TCCOR register + * + * @param pMsc MSCInstance + * @param u32Value TCCOR value + */ +LOCAL_INLINE void MSC_HWA_SetTccor(MSC_Type *const pMsc, uint32_t u32Value) +{ + pMsc->TCCOR = u32Value; +} + +/** + * @brief Set the TCH of TCCOR register + * + * @param pMsc MSCInstance + * @param u16Value TCH value + */ +LOCAL_INLINE void MSC_HWA_SetTccorTch(MSC_Type *const pMsc, uint16_t u16Value) +{ + pMsc->TCCOR = (pMsc->TCCOR & ~MSC_TCCOR_TCH_MASK) | MSC_TCCOR_TCH(u16Value); +} + +/** + * @brief Set the TCL of TCCOR register + * + * @param pMsc MSCInstance + * @param u16Value TCL value + */ +LOCAL_INLINE void MSC_HWA_SetTccorTcl(MSC_Type *const pMsc, uint16_t u16Value) +{ + pMsc->TCCOR = (pMsc->TCCOR & ~MSC_TCCOR_TCL_MASK) | MSC_TCCOR_TCL(u16Value); +} + +/** + * @brief Set the TCSLR register + * + * @param pMsc MSCInstance + * @param u32Value TCSLR value + */ +LOCAL_INLINE void MSC_HWA_SetTcslr(MSC_Type *const pMsc, uint32_t u32Value) +{ + pMsc->TCSLR = u32Value; +} + +/** + * @brief Set the TCSHR register + * + * @param pMsc MSCInstance + * @param u32Value TCSHR value + */ +LOCAL_INLINE void MSC_HWA_SetTcshr(MSC_Type *const pMsc, uint32_t u32Value) +{ + pMsc->TCSHR = u32Value; +} + +/** + * @brief Set the TCELR register + * + * @param pMsc MSCInstance + * @param u32Value TCELR value + */ +LOCAL_INLINE void MSC_HWA_SetTcelr(MSC_Type *const pMsc, uint32_t u32Value) +{ + pMsc->TCELR = u32Value; +} + +/** + * @brief Get the IOCR register value + * + * @param pMsc MSCInstance + * @return IOCR value + */ +LOCAL_INLINE uint32_t MSC_HWA_GetIocr(MSC_Type *const pMsc) +{ + return pMsc->IOCR; +} + +/** + * @brief Set the IOCR register + * + * @param pMsc MSCInstance + * @param u32Value IOCR value + */ +LOCAL_INLINE void MSC_HWA_SetIocr(MSC_Type *const pMsc, uint32_t u32Value) +{ + pMsc->IOCR = u32Value; +} + +/** + * @brief Set the ISCR register + * + * @param pMsc MSCInstance + * @param u32Value ISCR value + */ +LOCAL_INLINE void MSC_HWA_SetIscr(MSC_Type *const pMsc, uint32_t u32Value) +{ + pMsc->ISCR = u32Value; +} + +/** + * @brief Set the msc TCDIS + * + * @param pMsc MSCInstance + */ +LOCAL_INLINE void MSC_HWA_SetTcdis(MSC_Type *const pMsc) +{ + pMsc->ISCR = MSC_ISCR_SDIS_MASK; +} + +/** + * @brief Clear the msc TCDIS + * + * @param pMsc MSCInstance + */ +LOCAL_INLINE void MSC_HWA_ClearTcdis(MSC_Type *const pMsc) +{ + pMsc->ISCR = MSC_ISCR_CDIS_MASK; +} + +/** + * @brief Clear the msc CRFI + * + * @param pMsc MSCInstance + */ +LOCAL_INLINE void MSC_HWA_ClearCrfi(MSC_Type *const pMsc) +{ + pMsc->ISCR = MSC_ISCR_CRFI_MASK; +} + +/** + * @brief Clear the msc CTFI + * + * @param pMsc MSCInstance + */ +LOCAL_INLINE void MSC_HWA_ClearCtfi(MSC_Type *const pMsc) +{ + pMsc->ISCR = MSC_ISCR_CTFI_MASK; +} + +/** + * @brief Clear the msc CCFI + * + * @param pMsc MSCInstance + */ +LOCAL_INLINE void MSC_HWA_ClearCcfi(MSC_Type *const pMsc) +{ + pMsc->ISCR = MSC_ISCR_CCFI_MASK; +} + +/** + * @brief Clear the msc CDFI + * + * @param pMsc MSCInstance + */ +LOCAL_INLINE void MSC_HWA_ClearCdfi(MSC_Type *const pMsc) +{ + pMsc->ISCR = MSC_ISCR_CDFI_MASK; +} + +/** + * @brief Get the msc INSR register + * + * @param pMsc MSCInstance + * @return INSR register value + */ +LOCAL_INLINE uint32_t MSC_HWA_GetInsr(MSC_Type *const pMsc) +{ + return pMsc->INSR & (uint32_t)MSC_INSR_MASK; +} + +/** + * @brief Set the INCR register + * + * @param pMsc MSCInstance + * @param u32Value INCR value + */ +LOCAL_INLINE void MSC_HWA_SetIncr(MSC_Type *const pMsc, uint32_t u32Value) +{ + pMsc->INCR = u32Value; +} + +/** + * @brief Check the RFIE of INCR register + * + * @param pMsc MSCInstance + * @return RFIE enable + */ +LOCAL_INLINE bool MSC_HWA_GetRfieEnable(MSC_Type *const pMsc) +{ + return (pMsc->INCR & MSC_INCR_RFIE_MASK) != 0U ? true : false; +} + +/** + * @brief Set the RFIE of INCR register + * + * @param pMsc MSCInstance + * @param bEnable enable RFIE + */ +LOCAL_INLINE void MSC_HWA_SetRfieEnable(MSC_Type *const pMsc, bool bEnable) +{ + pMsc->INCR = (pMsc->INCR & ~MSC_INCR_RFIE_MASK) | MSC_INCR_RFIE(bEnable); +} + +/** + * @brief Check the TFIE of INCR register + * + * @param pMsc MSCInstance + * @return TFIE enable + */ +LOCAL_INLINE bool MSC_HWA_GetTfieEnable(MSC_Type *const pMsc) +{ + return (pMsc->INCR & MSC_INCR_TFIE_MASK) == MSC_INCR_TFIE_MASK ? true : false; +} + +/** + * @brief Set the TFIE of INCR register + * + * @param pMsc MSCInstance + * @param bEnable enable TFIE + */ +LOCAL_INLINE void MSC_HWA_SetTfieEnable(MSC_Type *const pMsc, bool bEnable) +{ + pMsc->INCR = (pMsc->INCR & ~MSC_INCR_TFIE_MASK) | MSC_INCR_TFIE(bEnable); +} + +/** + * @brief Check the CFIE of INCR register + * + * @param pMsc MSCInstance + * @return CFIE enable + */ +LOCAL_INLINE bool MSC_HWA_GetCfieEnable(MSC_Type *const pMsc) +{ + return (pMsc->INCR & MSC_INCR_CFIE_MASK) == MSC_INCR_CFIE_MASK ? true : false; +} + +/** + * @brief Set the CFIE of INCR register + * + * @param pMsc MSCInstance + * @param bEnable enable CFIE + */ +LOCAL_INLINE void MSC_HWA_SetCfieEnable(MSC_Type *const pMsc, bool bEnable) +{ + pMsc->INCR = (pMsc->INCR & ~MSC_INCR_CFIE_MASK) | MSC_INCR_CFIE(bEnable); +} + +/** + * @brief Check the DFIE of INCR register + * + * @param pMsc MSCInstance + * @return DFIE enable + */ +LOCAL_INLINE bool MSC_HWA_GetDfieEnable(MSC_Type *const pMsc) +{ + return (pMsc->INCR & MSC_INCR_DFIE_MASK) == MSC_INCR_DFIE_MASK ? true : false; +} + +/** + * @brief Set the DFIE of INCR register + * + * @param pMsc MSCInstance + * @param bEnable enable DFIE + */ +LOCAL_INLINE void MSC_HWA_SetDfieEnable(MSC_Type *const pMsc, bool bEnable) +{ + pMsc->INCR = (pMsc->INCR & ~MSC_INCR_DFIE_MASK) | MSC_INCR_DFIE(bEnable); +} + +/** + * @brief Check the TOIE of RTOR register + * + * @param pMsc MSCInstance + * @return TOIE enable + */ +LOCAL_INLINE bool MSC_HWA_GetToieEnable(MSC_Type *const pMsc) +{ + return (pMsc->RTOR & MSC_RTOR_TOIE_MASK) == MSC_RTOR_TOIE_MASK ? true : false; +} + +/** + * @brief Set the TOIE of RTOR register + * + * @param pMsc MSCInstance + * @param bEnable enable TOIE + */ +LOCAL_INLINE void MSC_HWA_SetToieEnable(MSC_Type *const pMsc, bool bEnable) +{ + pMsc->RTOR = (pMsc->RTOR & ~MSC_RTOR_TOIE_MASK) | MSC_RTOR_TOIE(bEnable); +} + +/** + * @brief Check the TOF of RTOR register + * + * @param pMsc MSCInstance + * @return TOIE enable + */ +LOCAL_INLINE bool MSC_HWA_GetTofEnable(MSC_Type *const pMsc) +{ + return (pMsc->RTOR & MSC_RTOR_TOF_MASK) == MSC_RTOR_TOF_MASK ? true : false; +} + +/** + * @brief Check the TOF of RTOR register + * + * @param pMsc MSCInstance + */ +LOCAL_INLINE void MSC_HWA_ClearTofEnable(MSC_Type *const pMsc) +{ + pMsc->RTOR = (pMsc->RTOR & (~(MSC_RTOR_TOFC_MASK | MSC_RTOR_TOFS_MASK))) | MSC_RTOR_TOFC_MASK; +} + +/** + * @brief Check the RX busy status of RCCSR register + * + * @param pMsc MSCInstance + * @return rx busy status + */ +LOCAL_INLINE bool MSC_HWA_GetRxBusy(MSC_Type *const pMsc) +{ + return (pMsc->RCCSR & MSC_RCCSR_RX_BUSY_MASK) == MSC_RCCSR_RX_BUSY_MASK ? true : false; +} + +/** + * @brief Get the msc RCCSR register + * + * @param pMsc MSCInstance + * @return RCCSR register value + */ +LOCAL_INLINE uint32_t MSC_HWA_GetRccsr(MSC_Type *const pMsc) +{ + return pMsc->RCCSR; +} + +/** + * @brief Set the RCCSR register + * + * @param pMsc MSCInstance + * @param u32Value RCCSR value + */ +LOCAL_INLINE void MSC_HWA_SetRccsr(MSC_Type *const pMsc, uint32_t u32Value) +{ + pMsc->RCCSR = u32Value; +} + +/** + * @brief Get the DATA of RDR0 register + * + * @param pMsc MSCInstance + * @return RDATA value + */ +LOCAL_INLINE uint8_t MSC_HWA_GetRdr0Data(MSC_Type *const pMsc) +{ + return (uint8_t)((pMsc->RDR0 & MSC_RDR0_RDATA_MASK) >> MSC_RDR0_RDATA_SHIFT); +} + +/** + * @brief Get the LAF of RDR0 register + * + * @param pMsc MSCInstance + * @return LAF value + */ +LOCAL_INLINE uint8_t MSC_HWA_GetRdr0Addr(MSC_Type *const pMsc) +{ + return (uint8_t)((pMsc->RDR0 & MSC_RDR0_LAF_MASK) >> MSC_RDR0_LAF_SHIFT); +} + +/** + * @brief Get the VLD of RDR0 register + * + * @param pMsc MSCInstance + * @return VLD value + */ +LOCAL_INLINE bool MSC_HWA_GetRdr0Vld(MSC_Type *const pMsc) +{ + return (pMsc->RDR0 & MSC_RDR0_VLD_MASK) == MSC_RDR0_VLD_MASK ? true : false; +} + +/** + * @brief Get the RERR of RDR0 register + * + * @param pMsc MSCInstance + * @return RERR value + */ +LOCAL_INLINE MSC_ReceiveStatusType MSC_HWA_GetRdr0Rerr(MSC_Type *const pMsc) +{ + uint32_t u32Tempvalue = (pMsc->RDR0 & MSC_RDR0_RERR_MASK) >> MSC_RDR0_RERR_SHIFT; + return (MSC_ReceiveStatusType)u32Tempvalue; +} + +/** + * @brief Clear the VLD of register + * + * @param pMsc MSCInstance + */ +LOCAL_INLINE void MSC_HWA_ClearRdr0Vld(MSC_Type *const pMsc) +{ + pMsc->RDR0 |= MSC_RDR0_CLR_MASK; +} + + +/** + * @brief Get the DATA of RDR1 register + * + * @param pMsc MSCInstance + * @return RDATA value + */ +LOCAL_INLINE uint8_t MSC_HWA_GetRdr1Data(MSC_Type *const pMsc) +{ + return (uint8_t)((pMsc->RDR1 & MSC_RDR1_RDATA_MASK) >> MSC_RDR1_RDATA_SHIFT); +} + +/** + * @brief Get the LAF of RDR1 register + * + * @param pMsc MSCInstance + * @return LAF value + */ +LOCAL_INLINE uint8_t MSC_HWA_GetRdr1Addr(MSC_Type *const pMsc) +{ + return (uint8_t)((pMsc->RDR1 & MSC_RDR1_LAF_MASK) >> MSC_RDR1_LAF_SHIFT); +} + +/** + * @brief Get the VLD of RDR1 register + * + * @param pMsc MSCInstance + * @return VLD value + */ +LOCAL_INLINE bool MSC_HWA_GetRdr1Vld(MSC_Type *const pMsc) +{ + return (pMsc->RDR1 & MSC_RDR1_VLD_MASK) == MSC_RDR1_VLD_MASK ? true : false; +} + +/** + * @brief Get the RERR of RDR1 register + * + * @param pMsc MSCInstance + * @return RERR value + */ +LOCAL_INLINE MSC_ReceiveStatusType MSC_HWA_GetRdr1Rerr(MSC_Type *const pMsc) +{ + uint32_t u32Tempvalue = (pMsc->RDR1 & MSC_RDR1_RERR_MASK) >> MSC_RDR1_RERR_SHIFT; + return (MSC_ReceiveStatusType)u32Tempvalue ; +} + +/** + * @brief Clear the VLD of register + * + * @param pMsc MSCInstance + */ +LOCAL_INLINE void MSC_HWA_ClearRdr1Vld(MSC_Type *const pMsc) +{ + pMsc->RDR1 |= MSC_RDR1_CLR_MASK; +} + + +/** + * @brief Get the DATA of RDR2 register + * + * @param pMsc MSCInstance + * @return RDATA value + */ +LOCAL_INLINE uint8_t MSC_HWA_GetRdr2Data(MSC_Type *const pMsc) +{ + return (uint8_t)((pMsc->RDR2 & MSC_RDR2_RDATA_MASK) >> MSC_RDR2_RDATA_SHIFT); +} + +/** + * @brief Get the LAF of RDR2 register + * + * @param pMsc MSCInstance + * @return LAF value + */ +LOCAL_INLINE uint8_t MSC_HWA_GetRdr2Addr(MSC_Type *const pMsc) +{ + return (uint8_t)((pMsc->RDR2 & MSC_RDR2_LAF_MASK) >> MSC_RDR2_LAF_SHIFT); +} + +/** + * @brief Get the VLD of RDR2 register + * + * @param pMsc MSCInstance + * @return VLD value + */ +LOCAL_INLINE bool MSC_HWA_GetRdr2Vld(MSC_Type *const pMsc) +{ + return (pMsc->RDR2 & MSC_RDR2_VLD_MASK) == MSC_RDR2_VLD_MASK ? true : false; +} + +/** + * @brief Get the RERR of RDR2 register + * + * @param pMsc MSCInstance + * @return RERR value + */ +LOCAL_INLINE MSC_ReceiveStatusType MSC_HWA_GetRdr2Rerr(MSC_Type *const pMsc) +{ + uint32_t u32Tempvalue = (pMsc->RDR2 & MSC_RDR2_RERR_MASK) >> MSC_RDR2_RERR_SHIFT; + return (MSC_ReceiveStatusType)u32Tempvalue; +} + +/** + * @brief Clear the VLD of register + * + * @param pMsc MSCInstance + */ +LOCAL_INLINE void MSC_HWA_ClearRdr2Vld(MSC_Type *const pMsc) +{ + pMsc->RDR2 |= MSC_RDR2_CLR_MASK; +} + + +/** + * @brief Get the DATA of RDR3 register + * + * @param pMsc MSCInstance + * @return RDATA value + */ +LOCAL_INLINE uint8_t MSC_HWA_GetRdr3Data(MSC_Type *const pMsc) +{ + return (uint8_t)(pMsc->RDR3 & MSC_RDR3_RDATA_MASK) >> MSC_RDR3_RDATA_SHIFT; +} + +/** + * @brief Get the LAF of RDR3 register + * + * @param pMsc MSCInstance + * @return LAF value + */ +LOCAL_INLINE uint8_t MSC_HWA_GetRdr3Addr(MSC_Type *const pMsc) +{ + return (uint8_t)((pMsc->RDR3 & MSC_RDR3_LAF_MASK) >> MSC_RDR3_LAF_SHIFT); +} + +/** + * @brief Get the VLD of RDR3 register + * + * @param pMsc MSCInstance + * @return VLD value + */ +LOCAL_INLINE bool MSC_HWA_GetRdr3Vld(MSC_Type *const pMsc) +{ + return (pMsc->RDR3 & MSC_RDR3_VLD_MASK) == MSC_RDR3_VLD_MASK ? true : false; +} + +/** + * @brief Get the RERR of RDR3 register + * + * @param pMsc MSCInstance + * @return RERR value + */ +LOCAL_INLINE MSC_ReceiveStatusType MSC_HWA_GetRdr3Rerr(MSC_Type *const pMsc) +{ + uint32_t u32Tempvalue = (pMsc->RDR3 & MSC_RDR3_RERR_MASK) >> MSC_RDR3_RERR_SHIFT; + return (MSC_ReceiveStatusType)u32Tempvalue; +} + +/** + * @brief Clear the VLD of register + * + * @param pMsc MSCInstance + */ +LOCAL_INLINE void MSC_HWA_ClearRdr3Vld(MSC_Type *const pMsc) +{ + pMsc->RDR3 |= MSC_RDR3_CLR_MASK; +} + +/** + * @brief Reset the msc + * + * @param pMsc MSCInstance + */ +LOCAL_INLINE void MSC_HWA_SetMsrRst(MSC_Type *const pMsc) +{ + pMsc->MSR |= MSC_MSR_RST_MASK; +} + +/** + * @brief Get the reset status + * + * @param pMsc MSCInstance + * @return reset status + */ +LOCAL_INLINE bool MSC_HWA_GetMsrRdone(MSC_Type *const pMsc) +{ + return (bool)(((pMsc->MSR & MSC_MSR_RDONE_MASK) != 0U) ? true : false); +} + +/** + * @brief clear reset status + * + * @param pMsc MSCInstance + */ +LOCAL_INLINE void MSC_HWA_ClearMsrDone(MSC_Type *const pMsc) +{ + pMsc->SRCR = MSC_SRCR_RCLR_MASK; +} + +/** + * @brief Get the msc RTOR register + * + * @param pMsc MSCInstance + * @return RTOR register value + */ +LOCAL_INLINE uint32_t MSC_HWA_GetRtor(MSC_Type *const pMsc) +{ + return pMsc->RTOR; +} + +/** + * @brief Set the msc RTOR register + * + * @param pMsc MSCInstance + * @param u32Value RTOR value + */ +LOCAL_INLINE void MSC_HWA_SetRtor(MSC_Type *const pMsc, uint32_t u32Value) +{ + pMsc->RTOR = u32Value; +} + +/** + * @brief Get the msc TCCTR1 register + * + * @param pMsc MSCInstance + * @return TCCTR1 register value + */ +LOCAL_INLINE uint32_t MSC_HWA_GetTcctr1(MSC_Type *const pMsc) +{ + return pMsc->TCCTR1; +} + +/** + * @brief Set the msc TCCTR1 register + * + * @param pMsc MSCInstance + * @param u32Value TCCTR1 value + */ +LOCAL_INLINE void MSC_HWA_SetTcctr1(MSC_Type *const pMsc, uint32_t u32Value) +{ + pMsc->TCCTR1 = u32Value; +} + +/** + * @brief Set the EN msc GCR register + * + * @param pMsc MSCInstance + * @param bEnable EN value + */ +LOCAL_INLINE void MSC_HWA_SetMscEnable(MSC_Type *const pMsc, bool bEnable) +{ + pMsc->GCR = (pMsc->GCR & ~MSC_GCR_EN_MASK) | MSC_GCR_EN(bEnable); +} + +/** + * @brief Set the WP_EN of msc GCR register + * + * @param pMsc MSCInstance + * @param bEnable WP_EN value + */ +LOCAL_INLINE void MSC_HWA_SetMscWriteProtection(MSC_Type *const pMsc, bool bEnable) +{ + pMsc->GCR = (pMsc->GCR & ~MSC_GCR_WP_EN_MASK) | MSC_GCR_WP_EN(bEnable); +} + +/** + * @brief Unlock the msc CCULR register + * + * @param pMsc MSCInstance + */ +LOCAL_INLINE void MSC_HWA_Unlock(MSC_Type *const pMsc) +{ + pMsc->CCULR = 0x10248888U; +} + + +/** @}*/ /* HwA_msc */ + +#endif /* #ifndef _HWA_MSC_H_ */ diff --git a/MODULES/HwA_Flagchip_FC7240/Inc/HwA_overlay.h b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_overlay.h new file mode 100644 index 0000000..1e181b5 --- /dev/null +++ b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_overlay.h @@ -0,0 +1,315 @@ +/** + * @file HwA_overlay.h + * @author Flagchip + * @brief FC4xxx Overlay hardware access layer + * @version 0.1.0 + * @date 2023-12-25 + * + * @copyright Copyright (c) 2022 Flagchip Semiconductors Co., Ltd. + * + */ + +/******************************************************************************** +* Revision History: +* +* Version Date Initials CR# Descriptions +* --------- ---------- ------------ ---------- --------------- +* 0.1.0 2023-12-29 Flagchip0038 N/A First version for FC7240 +********************************************************************************/ + +#ifndef _HWA_OVERLAY_H_ +#define _HWA_OVERLAY_H_ + +#include "device_header.h" + +/** + * @defgroup HwA_overlay + * @ingroup fc7xxx_hwa_overlay + * @{ + */ + + +/** Overlay Region Count */ +#define OVERLYA_REGION_CNT 3U + +/** FAR source address */ +#define OVERLAY_FAR_SRC 0x08000000U + +/** FAR max size */ +#define OVERLAY_FAR_SIZE_MAX 0x2000000U +/** FAR size align */ +#define OVERLAY_FAR_SIZE_ALIGN 0x10000U +/** FAR size max mask **/ +#define OVERLAY_FAR_SIZE_MASK 0xFFFFU + +/** + * @brief OVERlay Region size + * + */ +typedef enum +{ + OVERLAY_OVERLAYSIZE_1KB = 0x1, /**< OVERLAY_OVERLAYSIZE_1KB, remapping overlay region size to 1KB */ + OVERLAY_OVERLAYSIZE_2KB = 0x2, /**< OVERLAY_OVERLAYSIZE_2KB, remapping overlay region size to 2KB */ + OVERLAY_OVERLAYSIZE_4KB = 0x4, /**< OVERLAY_OVERLAYSIZE_4KB, remapping overlay region size to 4KB */ + OVERLAY_OVERLAYSIZE_8KB = 0x8, /**< OVERLAY_OVERLAYSIZE_8KB, remapping overlay region size to 8KB */ + OVERLAY_OVERLAYSIZE_16KB = 0x10, /**< OVERLAY_OVERLAYSIZE_16KB, remapping overlay region size to 16KB */ + OVERLAY_OVERLAYSIZE_32KB = 0x20, /**< OVERLAY_OVERLAYSIZE_32KB, remapping overlay region size to 32KB */ + OVERLAY_OVERLAYSIZE_64KB = 0x40 /**< OVERLAY_OVERLAYSIZE_64KB, remapping overlay region size to 64KB */ +}OVERLAY_OverlaySizeType; + +/** + * @brief FAR Size + * + */ +typedef enum +{ + OVERLAY_FARUINTSIZE_64KB = 0x10000, /**< OVERLAY_FARUINTSIZE_64KB, remapping far uint size to 64KB */ +}OVERLAY_FARSizeType; + +/** + * @brief enable overlay global switch + * + */ +LOCAL_INLINE void OVERLAY_HWA_OverlayEnable(void) +{ + AHB_OVERLAY->GLOBAL_EN |= AHB_OVERLAY_GLOBAL_EN_OVERLAY_EN_MASK; +} + +/** + * @brief disable overlay global switch + * + */ +LOCAL_INLINE void OVERLAY_HWA_OverlayDisable(void) +{ + AHB_OVERLAY->GLOBAL_EN &= ~((uint32_t)AHB_OVERLAY_GLOBAL_EN_OVERLAY_EN_MASK); +} + +/** + * @brief enable far global switch + * + */ +LOCAL_INLINE void OVERLAY_HWA_FAREnable(void) +{ + AHB_OVERLAY->GLOBAL_EN |= AHB_OVERLAY_GLOBAL_EN_FAR_EN_MASK; +} + +/** + * @brief disable far global switch + * + */ +LOCAL_INLINE void OVERLAY_HWA_FARDisable(void) +{ + AHB_OVERLAY->GLOBAL_EN &= ~((uint32_t)AHB_OVERLAY_GLOBAL_EN_FAR_EN_MASK); +} + +/** + * @brief enable overlay region 0 + * + */ +LOCAL_INLINE void OVERLAY_HWA_OverlayRegion0Enable(void) +{ + AHB_OVERLAY->REGION_0_EN |= AHB_OVERLAY_REGION_0_EN_REGION0_EN_MASK; +} + +/** + * @brief disable overlay region 0 + * + */ +LOCAL_INLINE void OVERLAY_HWA_OverlayRegion0Disable(void) +{ + AHB_OVERLAY->REGION_0_EN &= ~((uint32_t)AHB_OVERLAY_REGION_0_EN_REGION0_EN_MASK); +} + +/** + * @brief Set Overlay Region 0 Source + * + * @param u32Src Source address + */ +LOCAL_INLINE void OVERLAY_HWA_SetOverlayRegion0Src(uint32_t u32Src) +{ + AHB_OVERLAY->REGION_0_SRC = AHB_OVERLAY_REGION_0_SRC_REGION0_SRC(u32Src); +} + +/** + * @brief Set Overlay Region 0 Destination + * + * @param u32Dst Destination address + */ +LOCAL_INLINE void OVERLAY_HWA_SetOverlayRegion0Dst(uint32_t u32Dst) +{ + AHB_OVERLAY->REGION_0_DST = AHB_OVERLAY_REGION_0_DST_REGION0_DST(u32Dst); +} + +/** + * @brief Set Overlay Region 0 Size + * + * @param eSize size + */ +LOCAL_INLINE void OVERLAY_HWA_SetOverlayRegion0Size(OVERLAY_OverlaySizeType eSize) +{ + AHB_OVERLAY->REGION_0_SIZE = AHB_OVERLAY_REGION_0_SIZE_REGION0_SIZE((uint32_t)eSize); +} + + + +/** + * @brief enable overlay region 1 + * + */ +LOCAL_INLINE void OVERLAY_HWA_OverlayRegion1Enable(void) +{ + AHB_OVERLAY->REGION_1_EN |= AHB_OVERLAY_REGION_1_EN_REGION1_EN_MASK; +} + +/** + * @brief disable overlay region 1 + * + */ +LOCAL_INLINE void OVERLAY_HWA_OverlayRegion1Disable(void) +{ + AHB_OVERLAY->REGION_1_EN &= ~((uint32_t)AHB_OVERLAY_REGION_1_EN_REGION1_EN_MASK); +} + +/** + * @brief Set Overlay Region 1 Source + * + * @param u32Src Source address + */ +LOCAL_INLINE void OVERLAY_HWA_SetOverlayRegion1Src(uint32_t u32Src) +{ + AHB_OVERLAY->REGION_1_SRC = AHB_OVERLAY_REGION_1_SRC_REGION1_SRC(u32Src); +} + +/** + * @brief Set Overlay Region 1 Destination + * + * @param u32Dst Destination address + */ +LOCAL_INLINE void OVERLAY_HWA_SetOverlayRegion1Dst(uint32_t u32Dst) +{ + AHB_OVERLAY->REGION_1_DST = AHB_OVERLAY_REGION_1_DST_REGION1_DST(u32Dst); +} + +/** + * @brief Set Overlay Region 1 Size + * + * @param eSize size + */ +LOCAL_INLINE void OVERLAY_HWA_SetOverlayRegion1Size(OVERLAY_OverlaySizeType eSize) +{ + AHB_OVERLAY->REGION_1_SIZE = AHB_OVERLAY_REGION_1_SIZE_REGION1_SIZE((uint32_t)eSize); +} + + +/** + * @brief enable overlay region 2 + * + */ +LOCAL_INLINE void OVERLAY_HWA_OverlayRegion2Enable(void) +{ + AHB_OVERLAY->REGION_2_EN |= AHB_OVERLAY_REGION_2_EN_REGION2_EN_MASK; +} + +/** + * @brief disable overlay region 2 + * + */ +LOCAL_INLINE void OVERLAY_HWA_OverlayRegion2Disable(void) +{ + AHB_OVERLAY->REGION_2_EN &= ~((uint32_t)AHB_OVERLAY_REGION_2_EN_REGION2_EN_MASK); +} + +/** + * @brief Set Overlay Region 2 Source + * + * @param u32Src Source address + */ +LOCAL_INLINE void OVERLAY_HWA_SetOverlayRegion2Src(uint32_t u32Src) +{ + AHB_OVERLAY->REGION_2_SRC = AHB_OVERLAY_REGION_2_SRC_REGION2_SRC(u32Src); +} + +/** + * @brief Set Overlay Region 2 Destination + * + * @param u32Dst Destination address + */ +LOCAL_INLINE void OVERLAY_HWA_SetOverlayRegion2Dst(uint32_t u32Dst) +{ + AHB_OVERLAY->REGION_2_DST = AHB_OVERLAY_REGION_2_DST_REGION2_DST(u32Dst); +} + +/** + * @brief Set Overlay Region 2 Size + * + * @param eSize size + */ +LOCAL_INLINE void OVERLAY_HWA_SetOverlayRegion2Size(OVERLAY_OverlaySizeType eSize) +{ + AHB_OVERLAY->REGION_2_SIZE = AHB_OVERLAY_REGION_2_SIZE_REGION2_SIZE((uint32_t)eSize); +} + + + + +/** + * @brief Set Far Destination + * + * @param u32Dst Destination address, must pflash + */ +LOCAL_INLINE void OVERLAY_HWA_SetFarDst(uint32_t u32Dst) +{ + AHB_OVERLAY->FAR_DST = AHB_OVERLAY_FAR_DST_FAR_DST_ADDR(u32Dst); +} + +/** + * @brief Set Far Size + * + * @param u32Size size=(u32Size+1)*64KB + */ +LOCAL_INLINE void OVERLAY_HWA_SetFarSize(uint32_t u32Size) +{ + AHB_OVERLAY->FAR_SIZE = AHB_OVERLAY_FAR_SIZE_FAR_SIZE_VAL(u32Size); +} + + +/** + * @brief enable error interrupt + * + */ +LOCAL_INLINE void OVERLAY_HWA_ErrorInterruptEnable(void) +{ + AHB_OVERLAY->INTR_EN |= AHB_OVERLAY_INTR_EN_INTR_ENABLE_MASK; +} + +/** + * @brief disable error interrupt + * + */ +LOCAL_INLINE void OVERLAY_HWA_ErrorInterruptDisable(void) +{ + AHB_OVERLAY->INTR_EN &= ~((uint32_t)AHB_OVERLAY_INTR_EN_INTR_ENABLE_MASK); +} + +/** + * @brief get error flag + * + */ +LOCAL_INLINE uint32 OVERLAY_HWA_GetErrorFlag(void) +{ + return (AHB_OVERLAY->INTR_FLAG & AHB_OVERLAY_INTR_FLAG_MASK); +} + +/** + * @brief clear error flag + * + */ +LOCAL_INLINE uint32 OVERLAY_HWA_ClrErrorFlag(uint32_t u32ClrBits) +{ + return AHB_OVERLAY->INTR_CLR |= AHB_OVERLAY_INTR_FLAG_MASK & u32ClrBits; +} + + +/** @}*/ + +#endif /* _HWA_OVERLAY_H_ */ diff --git a/MODULES/HwA_Flagchip_FC7240/Inc/HwA_pcc.h b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_pcc.h new file mode 100644 index 0000000..980c653 --- /dev/null +++ b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_pcc.h @@ -0,0 +1,191 @@ +/** + * @file HwA_pcc.h + * @author Flagchip085 + * @brief FC7xxx PCC register API + * @version 0.1.0 + * @date 2024-01-12 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-01-12 Flagchip085 N/A First version for FC7240 + ******************************************************************************** */ +#ifndef HWA_INCLUDE_HWA_PCC_H_ +#define HWA_INCLUDE_HWA_PCC_H_ +#include "device_header.h" + +/** + * @defgroup HwA_pcc + * @ingroup HwA_pcc + * @{ + */ + +/** @brief Marco for PCCn Bit Field definition */ +#define PCC_CGC_MASK 0x800000U +#define PCC_CGC_SHIFT 23U +#define PCC_CGC_WIDTH 1U +#define PCC_CGC(x) (((uint32_t)(((uint32_t)(x))<>PCC_CGC_SHIFT) + +#define PCC_SEL_MASK 0x700000U +#define PCC_SEL_SHIFT 20U +#define PCC_SEL_WIDTH 3U +#define PCC_SEL(x) (((uint32_t)(((uint32_t)(x))<>PCC_SEL_SHIFT) + +#define PCC_DIV_MASK 0x7U +#define PCC_DIV_SHIFT 0U +#define PCC_DIV_WIDTH 3U +#define PCC_DIV(x) (((uint32_t)(((uint32_t)(x))<>PCC_DIV_SHIFT) + +#define PCC_SWR_MASK 0x10000u + +/** + * @brief defined the clock source for function clock,match with PCC_XXX[SEL] bit filed. + */ +typedef enum +{ + PCC_CLKGATE_SRC_OFF_OR_TCLK = 0U, + PCC_CLKGATE_SRC_FOSCDIV = 1U, + PCC_CLKGATE_SRC_SIRCDIV = 2U, + PCC_CLKGATE_SRC_FIRCDIV = 3U, + PCC_CLKGATE_SRC_RESERVE0 = 4U, + PCC_CLKGATE_SRC_PLL1DIV = 5U, + PCC_CLKGATE_SRC_PLL0DIV = 6U, + PCC_CLKGATE_SRC_RESERVE1 = 7U, + PCC_CLKGATE_UNINVOLVED = 8U +} PCC_ClkGateSrcType; + +/** + * @brief define the clock divider,match with PCC_XXX[DIV] bit filed. + */ +typedef enum +{ + PCC_CLK_DIV_BY1 = 0U, /*!< Divide by 1 (pass-through, no clock divide) */ + PCC_CLK_DIV_BY2 = 1U, /*!< Divide by 2 */ + PCC_CLK_DIV_BY3 = 2U, /*!< Divide by 3 */ + PCC_CLK_DIV_BY4 = 3U, /*!< Divide by 4 */ + PCC_CLK_DIV_BY5 = 4U, /*!< Divide by 5 */ + PCC_CLK_DIV_BY6 = 5U, /*!< Divide by 6 */ + PCC_CLK_DIV_BY7 = 6U, /*!< Divide by 7 */ + PCC_CLK_DIV_BY8 = 7U, /*!< Divide by 8 */ + PCC_CLK_UNINVOLVED = 8U /*!< Current peripheral dose not contain DIV configuration */ +} PCC_ClkDivType; + + +/** + * @brief Get PCC register value + * + * @param u32Offset the PCC register offset + * @return uint32_t PCC register value + */ +LOCAL_INLINE uint32_t PCC_HWA_GetRegister(uint32_t u32Offset) +{ + return *((uint32_t *)((uint32_t)PCC_BASE + u32Offset)); +} + +/** + * @brief Set PCC register value + * + * @param u32Offset the PCC register offset + * @param eValue value to set + */ +LOCAL_INLINE void PCC_HWA_SetRegister(uint32_t u32Offset,uint32_t eValue) +{ + *((uint32_t *)((uint32_t)PCC_BASE + u32Offset)) = eValue; +} + +/** + * @brief Get PCC clock gate control + * + * @param u32Offset the PCC register offset + * @return bool PCC clock enabled or disabled + */ +LOCAL_INLINE bool PCC_HWA_GetClockGateControl(uint32_t u32Offset) +{ + uint32_t u32Value = *((uint32_t *)((uint32_t)PCC_BASE + u32Offset)); + return (bool)PCC_GetCGC(u32Value); +} + +/** + * @brief Set PCC clock gate control + * + * @param u32Offset the PCC register offset + * @param eSrc PCC clock source + */ +LOCAL_INLINE void PCC_HWA_SetClockGateControl(uint32_t u32Offset,bool bEnable) +{ + uint32_t *pRegister = (uint32_t *)((uint32_t)PCC_BASE + u32Offset); + *pRegister = ((*pRegister) & (~PCC_CGC_MASK)) | PCC_CGC(bEnable); +} + +/** + * @brief Get PCC clock source + * + * @param u32Offset the PCC register offset + * @return PCC_ClkGateSrcType PCC clock source + */ +LOCAL_INLINE PCC_ClkGateSrcType PCC_HWA_GetClockSource(uint32_t u32Offset) +{ + uint32_t u32Value = *((uint32_t *)((uint32_t)PCC_BASE + u32Offset)); + return (PCC_ClkGateSrcType)PCC_GetSEL(u32Value); +} + +/** + * @brief Set PCC clock source + * + * @param u32Offset the PCC register offset + * @param eSrc PCC clock source + */ +LOCAL_INLINE void PCC_HWA_SetClockSource(uint32_t u32Offset,PCC_ClkGateSrcType eSrc) +{ + uint32_t *pRegister = (uint32_t *)((uint32_t)PCC_BASE + u32Offset); + *pRegister = ((*pRegister) & (~PCC_SEL_MASK)) | PCC_SEL(eSrc); +} + +/** + * @brief PCC peripheral software reset + * + * @param u32Offset the PCC register offset + */ +LOCAL_INLINE void PCC_HWA_SoftwareReset(uint32_t u32Offset) +{ + *((uint32_t *)((uint32_t)PCC_BASE + u32Offset)) |= (uint32_t)PCC_SWR_MASK; + *((uint32_t *)((uint32_t)PCC_BASE + u32Offset)) &= ~(uint32_t)PCC_SWR_MASK; +} + +/** + * @brief Get PCC divider + * + * @param u32Offset the PCC register offset + * @return PCC_ClkDivType PCC clock divider + */ +LOCAL_INLINE PCC_ClkDivType PCC_HWA_GetDivider(uint32_t u32Offset) +{ + uint32_t u32Value = *((uint32_t *)((uint32_t)PCC_BASE + u32Offset)); + return (PCC_ClkDivType)PCC_GetDIV(u32Value); +} + +/** + * @brief Set PCC register value + * + * @param u32Offset the PCC register offset + * @param eDivider PCC clock divider + */ +LOCAL_INLINE void PCC_HWA_SetDivider(uint32_t u32Offset,PCC_ClkDivType eDivider) +{ + uint32_t *pRegister = (uint32_t *)((uint32_t)PCC_BASE + u32Offset); + *pRegister = ((*pRegister) & (~PCC_DIV_MASK)) | PCC_DIV(eDivider); +} + + + +/** @}*/ + +#endif /* HWA_INCLUDE_HWA_PCC_H_ */ diff --git a/MODULES/HwA_Flagchip_FC7240/Inc/HwA_pmc.h b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_pmc.h new file mode 100644 index 0000000..67ad751 --- /dev/null +++ b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_pmc.h @@ -0,0 +1,92 @@ +/** + * @file HwA_pmc.h + * @author Flagchip0105 + * @brief FC7xxx PMC register API + * @version 0.1.0 + * @date 2024-01-08 + * + * @copyright Copyright (c) 2022 Flagchip Semiconductors Co., Ltd. + * + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-01-08 Flagchip0105 N/A First version for FC7240 + ******************************************************************************** */ +#ifndef HWA_INCLUDE_HWA_PMC_H_ +#define HWA_INCLUDE_HWA_PMC_H_ +#include "device_header.h" + +/** + * @defgroup HwA_pmc + * @ingroup fc7xxx_driver_pmc + * @{ + */ + +/** + * @brief get PMC LVCSR register + * + * @return uint32_t LVCSR register value + */ +LOCAL_INLINE uint32_t PMC_HWA_GetLVCSRRegister(void) +{ + return (uint32)(PMC->LVSCR); +} + +/** + * @brief set PMC LVCSR register. + * + * This function configures the PMC LVCSR registe. + * + * @param u32LvcsrValue Set PMC LVCSR register value. + */ +LOCAL_INLINE void PMC_HWA_SetLVCSRRegister(uint32_t u32LvcsrValue) +{ + PMC->LVSCR = u32LvcsrValue; +} + +/** + * @brief get PMC CONFIG register + * + * @return uint32_t CONFIG register value + */ +LOCAL_INLINE uint32_t PMC_HWA_GetConfigRegister(void) +{ + return (uint32)(PMC -> CONFIG); +} + +/** + * @brief set PMC CONFIG register. + * + * This function configures the PMC CONFIG registe. + * + * @param u32LVSCRValue Set PMC CONFIG register value. + */ +LOCAL_INLINE void PMC_HWA_SetConfigRegister(uint32_t u32LVSCRValue) +{ + PMC -> CONFIG = u32LVSCRValue; +} + +/** + * @brief Unlock control for V15_EXT_EN and V15_AUTOSW + * + */ +LOCAL_INLINE void PMC_HWA_UnlockConfigRegister(void) +{ + PMC->CONFIG &= ~(uint32_t)PMC_CONFIG_V15_LOCK_MASK; +} + +/** + * @brief lock control for V15_EXT_EN and V15_AUTOSW + * + */ +LOCAL_INLINE void PMC_HWA_LockConfigRegister(void) +{ + PMC->CONFIG |= (uint32_t)PMC_CONFIG_V15_LOCK_MASK; +} + +/** @}*/ + +#endif /* HWA_INCLUDE_HWA_PMC_H_ */ diff --git a/MODULES/HwA_Flagchip_FC7240/Inc/HwA_port.h b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_port.h new file mode 100644 index 0000000..54f7288 --- /dev/null +++ b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_port.h @@ -0,0 +1,2348 @@ +/** + * @file HwA_port.h + * @author Flagchip + * @brief FC7xxx PORT hardware access layer + * @version 0.1.0 + * @date 2023-02-13 + * + * @copyright Copyright (c) 2023 Flagchip Semiconductors Co., Ltd. + * + * @details + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2022-11-18 Flagchip071 N/A First version for FC7xxx + ******************************************************************************** */ + +#ifndef _HWA_PORT_H_ +#define _HWA_PORT_H_ + +#include "device_header.h" + +/********* Local typedef ************/ +/** @brief Port Mode Type */ +typedef uint32_t Port_PinModeType; + +/** @brief PORTA 0 Mode enumeration */ +typedef enum +{ +PORTA_0_ADC1_SE30 = 0U, +PORTA_0_GPIO = 1U, +PORTA_0_FTU2_CH1 = 2U, +PORTA_0_AONTIMER0_CLK1 = 3U, +PORTA_0_SENT0_RXD3 = 4U, +PORTA_0_TPU_CH1 = 5U, +PORTA_0_FCUART0_CTS = 6U, +PORTA_0_TRGSEL_OUT3 = 7U, +} PORT_A0MuxType; + +/** @brief PORTA 1 Mode enumeration */ +typedef enum +{ +PORTA_1_ADC1_SE29 = 0U, +PORTA_1_GPIO = 1U, +PORTA_1_FTU1_CH1 = 2U, +PORTA_1_AONTIMER0_CLK2 = 3U, +PORTA_1_SENT0_RXD2 = 4U, +PORTA_1_FTU1_QD_PHB = 5U, +PORTA_1_FCUART0_RTS = 6U, +PORTA_1_TRGSEL_OUT0 = 7U, +} PORT_A1MuxType; + +/** @brief PORTA 10 Mode enumeration */ +typedef enum +{ +PORTA_10_GPIO = 1U, +PORTA_10_FTU1_CH4 = 2U, +PORTA_10_AONTIMER0_CLK0 = 3U, +PORTA_10_TPU_CH30 = 4U, +PORTA_10_FCIIC0_SCL = 5U, +PORTA_10_JTAG_TDO = 7U, +} PORT_A10MuxType; + +/** @brief PORTA 11 Mode enumeration */ +typedef enum +{ +PORTA_11_GPIO = 1U, +PORTA_11_FTU1_CH5 = 2U, +PORTA_11_LP_WAKEUP2 = 3U, +PORTA_11_TPU_CH29 = 4U, +PORTA_11_FCSPI0_PCS0 = 5U, +PORTA_11_NMI_b = 7U, +} PORT_A11MuxType; + +/** @brief PORTA 12 Mode enumeration */ +typedef enum +{ +PORTA_12_GPIO = 1U, +PORTA_12_FTU1_CH6 = 2U, +PORTA_12_FLEXCAN1_RX = 3U, +PORTA_12_FCSPI0_SOUT = 5U, +PORTA_12_FTU1_QD_PHB = 6U, +PORTA_12_TPU_CH9 = 7U, +} PORT_A12MuxType; + +/** @brief PORTA 13 Mode enumeration */ +typedef enum +{ +PORTA_13_ADC0_SE20 = 0U, +PORTA_13_GPIO = 1U, +PORTA_13_FTU1_CH7 = 2U, +PORTA_13_FLEXCAN1_TX = 3U, +PORTA_13_CMP1_OUT = 4U, +PORTA_13_FCUART0_RX = 5U, +PORTA_13_FTU1_QD_PHA = 6U, +PORTA_13_TPU_CH8 = 7U, +} PORT_A13MuxType; + +/** @brief PORTA 14 Mode enumeration */ +typedef enum +{ +PORTA_14_ADC0_SE21 = 0U, +PORTA_14_GPIO = 1U, +PORTA_14_FTU_FLT17 = 2U, +PORTA_14_AONTIMER0_CLK1 = 3U, +PORTA_14_FCUART0_TX = 5U, +PORTA_14_TPU_CH7 = 6U, +} PORT_A14MuxType; + +/** @brief PORTA 15 Mode enumeration */ +typedef enum +{ +PORTA_15_ADC0_SE26 = 0U, +PORTA_15_GPIO = 1U, +PORTA_15_FTU1_CH2 = 2U, +PORTA_15_TRGSEL_OUT0 = 5U, +PORTA_15_FLEXCAN3_RX = 6U, +PORTA_15_TPU_CH5 = 7U, +} PORT_A15MuxType; + +/** @brief PORTA 16 Mode enumeration */ +typedef enum +{ +PORTA_16_ADC0_SE28 = 0U, +PORTA_16_GPIO = 1U, +PORTA_16_FTU1_CH3 = 2U, +PORTA_16_FCSPI1_PCS2 = 3U, +PORTA_16_FTU1_QD_PHA = 4U, +PORTA_16_SENT0_RXD1 = 5U, +PORTA_16_FLEXCAN3_TX = 6U, +PORTA_16_TPU_CH4 = 7U, +} PORT_A16MuxType; + +/** @brief PORTA 17 Mode enumeration */ +typedef enum +{ +PORTA_17_GPIO = 1U, +PORTA_17_FTU0_CH6 = 2U, +PORTA_17_FTU7_CH0 = 3U, +PORTA_17_FLEXCAN2_TX = 4U, +PORTA_17_FCSPI5_PCS0 = 5U, +PORTA_17_FTU_FLT15 = 6U, +PORTA_17_FCUART3_RX = 7U, +} PORT_A17MuxType; + +/** @brief PORTA 18 Mode enumeration */ +typedef enum +{ +PORTA_18_GPIO = 1U, +PORTA_18_FTU4_CH0 = 2U, +PORTA_18_FCUART1_TX = 3U, +PORTA_18_TPU_CH0 = 4U, +PORTA_18_TPU_TCRCLK = 5U, +PORTA_18_FCSPI4_PCS1 = 6U, +} PORT_A18MuxType; + +/** @brief PORTA 19 Mode enumeration */ +typedef enum +{ +PORTA_19_GPIO = 1U, +PORTA_19_FTU4_CH1 = 2U, +PORTA_19_FCUART1_RX = 3U, +PORTA_19_TPU_CH1 = 4U, +PORTA_19_FCSPI4_PCS2 = 6U, +} PORT_A19MuxType; + +/** @brief PORTA 2 Mode enumeration */ +typedef enum +{ +PORTA_2_GPIO = 1U, +PORTA_2_FTU3_CH0 = 2U, +PORTA_2_FCIIC0_SDA = 3U, +PORTA_2_TPU_CH1 = 4U, +PORTA_2_FCSPI5_SOUT = 5U, +PORTA_2_FCUART0_RX = 6U, +} PORT_A2MuxType; + +/** @brief PORTA 20 Mode enumeration */ +typedef enum +{ +PORTA_20_GPIO = 1U, +PORTA_20_FTU4_CH2 = 2U, +PORTA_20_FCUART3_RTS = 3U, +PORTA_20_TPU_CH2 = 4U, +PORTA_20_FLEXCAN2_RX = 5U, +PORTA_20_FCSPI4_PCS3 = 6U, +} PORT_A20MuxType; + +/** @brief PORTA 21 Mode enumeration */ +typedef enum +{ +PORTA_21_GPIO = 1U, +PORTA_21_FTU4_CH3 = 2U, +PORTA_21_FCUART3_CTS = 3U, +PORTA_21_TPU_CH3 = 4U, +PORTA_21_FLEXCAN2_TX = 5U, +} PORT_A21MuxType; + +/** @brief PORTA 23 Mode enumeration */ +typedef enum +{ +PORTA_23_GPIO = 1U, +PORTA_23_FTU4_CH6 = 2U, +PORTA_23_FCUART3_RX = 3U, +PORTA_23_TPU_CH25 = 4U, +PORTA_23_FCSPI4_SCK = 6U, +} PORT_A23MuxType; + +/** @brief PORTA 24 Mode enumeration */ +typedef enum +{ +PORTA_24_GPIO = 1U, +PORTA_24_FTU4_CH7 = 2U, +PORTA_24_FCUART3_TX = 3U, +PORTA_24_TPU_CH4 = 4U, +PORTA_24_FCSPI4_SIN = 6U, +} PORT_A24MuxType; + +/** @brief PORTA 25 Mode enumeration */ +typedef enum +{ +PORTA_25_ADC0_SE0 = 0U, +PORTA_25_GPIO = 1U, +PORTA_25_FTU5_CH0 = 2U, +PORTA_25_FCSPI2_PCS2 = 3U, +PORTA_25_FTU2_CH5 = 4U, +PORTA_25_FCUART2_RX = 5U, +PORTA_25_TPU_TCRCLK = 6U, +PORTA_25_TPU_CH0 = 7U, +} PORT_A25MuxType; + +/** @brief PORTA 26 Mode enumeration */ +typedef enum +{ +PORTA_26_ADC0_SE2 = 0U, +PORTA_26_GPIO = 1U, +PORTA_26_FTU5_CH1 = 2U, +PORTA_26_FTU2_CH4 = 4U, +PORTA_26_FCSPI1_PCS0 = 5U, +PORTA_26_TPU_CH1 = 7U, +} PORT_A26MuxType; + +/** @brief PORTA 27 Mode enumeration */ +typedef enum +{ +PORTA_27_ADC0_SE6 = 0U, +PORTA_27_GPIO = 1U, +PORTA_27_FTU5_CH2 = 2U, +PORTA_27_FLEXCAN0_TX = 3U, +PORTA_27_FCUART0_TX = 4U, +PORTA_27_FCSPI1_SOUT = 5U, +PORTA_27_TPU_CH2 = 7U, +} PORT_A27MuxType; + +/** @brief PORTA 28 Mode enumeration */ +typedef enum +{ +PORTA_28_ADC0_SE7 = 0U, +PORTA_28_GPIO = 1U, +PORTA_28_FTU5_CH3 = 2U, +PORTA_28_FLEXCAN0_RX = 3U, +PORTA_28_FCUART0_RX = 4U, +PORTA_28_FCSPI1_SCK = 5U, +PORTA_28_TPU_CH4 = 7U, +} PORT_A28MuxType; + +/** @brief PORTA 29 Mode enumeration */ +typedef enum +{ +PORTA_29_ADC0_SE9 = 0U, +PORTA_29_GPIO = 1U, +PORTA_29_FTU5_CH4 = 2U, +PORTA_29_FCUART2_TX = 3U, +PORTA_29_FCSPI1_SIN = 5U, +PORTA_29_TPU_CH6 = 7U, +} PORT_A29MuxType; + +/** @brief PORTA 3 Mode enumeration */ +typedef enum +{ +PORTA_3_GPIO = 1U, +PORTA_3_FTU3_CH1 = 2U, +PORTA_3_FCIIC0_SCL = 3U, +PORTA_3_TPU_CH2 = 4U, +PORTA_3_FCSPI5_SCK = 5U, +PORTA_3_FCUART0_TX = 6U, +} PORT_A3MuxType; + +/** @brief PORTA 30 Mode enumeration */ +typedef enum +{ +PORTA_30_GPIO = 1U, +PORTA_30_FTU5_CH5 = 2U, +PORTA_30_FCUART2_RX = 3U, +PORTA_30_TPU_CH7 = 7U, +} PORT_A30MuxType; + +/** @brief PORTA 31 Mode enumeration */ +typedef enum +{ +PORTA_31_ADC0_SE13_CMP0_IN3 = 0U, +PORTA_31_GPIO = 1U, +PORTA_31_FTU5_CH6 = 2U, +PORTA_31_FLEXCAN3_TX = 3U, +PORTA_31_TPU_CH8 = 6U, +PORTA_31_FCSPI0_PCS1 = 7U, +} PORT_A31MuxType; + +/** @brief PORTA 4 Mode enumeration */ +typedef enum +{ +PORTA_4_GPIO = 1U, +PORTA_4_FTU1_CH0 = 2U, +PORTA_4_TRGSEL_OUT7 = 3U, +PORTA_4_CMP0_OUT = 4U, +PORTA_4_LP_WAKEUP4 = 5U, +PORTA_4_JTAG_TMS_SWD_DIO = 7U, +} PORT_A4MuxType; + +/** @brief PORTA 6 Mode enumeration */ +typedef enum +{ +PORTA_6_ADC1_SE9 = 0U, +PORTA_6_GPIO = 1U, +PORTA_6_FTU_FLT13 = 2U, +PORTA_6_FCSPI1_PCS1 = 3U, +PORTA_6_FTU5_CH5 = 4U, +PORTA_6_TRGSEL_OUT4 = 5U, +PORTA_6_FCUART1_CTS = 6U, +PORTA_6_FTU4_CH7 = 7U, +} PORT_A6MuxType; + +/** @brief PORTA 7 Mode enumeration */ +typedef enum +{ +PORTA_7_GPIO = 1U, +PORTA_7_FTU_FLT12 = 2U, +PORTA_7_FTU3_CH1 = 3U, +PORTA_7_FTU5_CH3 = 4U, +PORTA_7_FCSPI1_SCK = 5U, +PORTA_7_FCUART1_RTS = 6U, +PORTA_7_MSC0_EN0 = 7U, +} PORT_A7MuxType; + +/** @brief PORTA 8 Mode enumeration */ +typedef enum +{ +PORTA_8_ADC1_SE3 = 0U, +PORTA_8_GPIO = 1U, +PORTA_8_FCUART2_RX = 2U, +PORTA_8_FTU1_CH0 = 3U, +PORTA_8_CMP0_OUT = 4U, +PORTA_8_FTU_FLT21 = 5U, +PORTA_8_FCUART0_RX = 6U, +PORTA_8_TPU_CH13 = 7U, +} PORT_A8MuxType; + +/** @brief PORTA 9 Mode enumeration */ +typedef enum +{ +PORTA_9_ADC1_SE7 = 0U, +PORTA_9_GPIO = 1U, +PORTA_9_FCUART2_TX = 2U, +PORTA_9_FTU4_CH4 = 3U, +PORTA_9_FTU_FLT20 = 5U, +PORTA_9_FCUART0_TX = 6U, +PORTA_9_TPU_CH12 = 7U, +} PORT_A9MuxType; + +/** @brief PORTB 0 Mode enumeration */ +typedef enum +{ +PORTB_0_ADC1_SE10 = 0U, +PORTB_0_GPIO = 1U, +PORTB_0_FCUART0_RX = 2U, +PORTB_0_FCSPI0_PCS0 = 3U, +PORTB_0_FTU1_CH5 = 4U, +PORTB_0_FLEXCAN0_RX = 5U, +PORTB_0_FTU4_CH6 = 6U, +PORTB_0_MSC0_SDI1 = 7U, +} PORT_B0MuxType; + +/** @brief PORTB 1 Mode enumeration */ +typedef enum +{ +PORTB_1_ADC1_SE11 = 0U, +PORTB_1_GPIO = 1U, +PORTB_1_FCUART0_TX = 2U, +PORTB_1_FCSPI0_SOUT = 3U, +PORTB_1_FTU_TCK0 = 4U, +PORTB_1_FLEXCAN0_TX = 5U, +PORTB_1_FTU4_CH5 = 6U, +PORTB_1_MSC0_EN1 = 7U, +} PORT_B1MuxType; + +/** @brief PORTB 10 Mode enumeration */ +typedef enum +{ +PORTB_10_GPIO = 1U, +PORTB_10_FTU3_CH2 = 2U, +PORTB_10_FLEXCAN0_TX = 3U, +PORTB_10_SENT0_RXD0 = 4U, +PORTB_10_TRGSEL_OUT2 = 5U, +PORTB_10_TPU_CH0 = 6U, +PORTB_10_TPU_TCRCLK = 7U, +} PORT_B10MuxType; + +/** @brief PORTB 11 Mode enumeration */ +typedef enum +{ +PORTB_11_V15_BASE_DRIVER = 0U, +PORTB_11_GPIO = 1U, +PORTB_11_FTU6_CH0 = 2U, +PORTB_11_FCUART2_TX = 3U, +PORTB_11_FLEXCAN0_TX = 4U, +} PORT_B11MuxType; + +/** @brief PORTB 12 Mode enumeration */ +typedef enum +{ +PORTB_12_GPIO = 1U, +PORTB_12_FTU0_CH0 = 2U, +PORTB_12_TPU_CH26 = 5U, +PORTB_12_FCSMU_PIN0 = 7U, +} PORT_B12MuxType; + +/** @brief PORTB 13 Mode enumeration */ +typedef enum +{ +PORTB_13_GPIO = 1U, +PORTB_13_FTU0_CH1 = 2U, +PORTB_13_FCUART6_CTS = 4U, +PORTB_13_TPU_CH25 = 5U, +PORTB_13_FCSMU_PIN1 = 7U, +} PORT_B13MuxType; + +/** @brief PORTB 14 Mode enumeration */ +typedef enum +{ +PORTB_14_ADC1_SE18 = 0U, +PORTB_14_GPIO = 1U, +PORTB_14_FTU0_CH2 = 2U, +PORTB_14_FCSPI1_SCK = 3U, +PORTB_14_TPU_CH5 = 4U, +PORTB_14_FTU5_CH4 = 6U, +PORTB_14_FLEXCAN2_RX = 7U, +} PORT_B14MuxType; + +/** @brief PORTB 15 Mode enumeration */ +typedef enum +{ +PORTB_15_ADC1_SE17 = 0U, +PORTB_15_GPIO = 1U, +PORTB_15_FTU0_CH3 = 2U, +PORTB_15_FCSPI1_SIN = 3U, +PORTB_15_TPU_CH6 = 4U, +PORTB_15_FTU5_CH5 = 6U, +PORTB_15_FLEXCAN2_TX = 7U, +} PORT_B15MuxType; + +/** @brief PORTB 16 Mode enumeration */ +typedef enum +{ +PORTB_16_ADC1_SE16 = 0U, +PORTB_16_GPIO = 1U, +PORTB_16_FTU0_CH4 = 2U, +PORTB_16_FCSPI1_SOUT = 3U, +PORTB_16_TPU_CH7 = 4U, +PORTB_16_FTU5_CH6 = 6U, +} PORT_B16MuxType; + +/** @brief PORTB 17 Mode enumeration */ +typedef enum +{ +PORTB_17_GPIO = 1U, +PORTB_17_FTU0_CH5 = 2U, +PORTB_17_FCSPI1_PCS3 = 3U, +PORTB_17_FLEXCAN2_RX = 4U, +PORTB_17_TRGSEL_OUT3 = 5U, +PORTB_17_FTU5_CH7 = 6U, +PORTB_17_FCUART3_TX = 7U, +} PORT_B17MuxType; + +/** @brief PORTB 18 Mode enumeration */ +typedef enum +{ +PORTB_18_GPIO = 1U, +PORTB_18_FTU5_CH7 = 2U, +PORTB_18_FLEXCAN3_RX = 3U, +PORTB_18_FCSPI4_PCS2 = 4U, +PORTB_18_FCSPI1_PCS1 = 5U, +PORTB_18_TPU_CH9 = 6U, +} PORT_B18MuxType; + +/** @brief PORTB 19 Mode enumeration */ +typedef enum +{ +PORTB_19_CMP0_IN4 = 0U, +PORTB_19_GPIO = 1U, +PORTB_19_FTU6_CH2 = 2U, +PORTB_19_FCUART4_RX = 3U, +PORTB_19_FLEXCAN3_TX = 4U, +PORTB_19_TPU_CH5 = 6U, +} PORT_B19MuxType; + +/** @brief PORTB 20 Mode enumeration */ +typedef enum +{ +PORTB_20_ADC0_SE14 = 0U, +PORTB_20_GPIO = 1U, +PORTB_20_FTU2_CH5 = 2U, +PORTB_20_FCUART1_TX = 3U, +PORTB_20_FTU6_CH2 = 4U, +PORTB_20_TPU_CH10 = 6U, +PORTB_20_SCG_CLKOUT = 7U, +} PORT_B20MuxType; + +/** @brief PORTB 21 Mode enumeration */ +typedef enum +{ +PORTB_21_ADC0_SE15 = 0U, +PORTB_21_GPIO = 1U, +PORTB_21_FTU2_CH4 = 2U, +PORTB_21_FCUART1_RX = 3U, +PORTB_21_FTU6_CH3 = 4U, +PORTB_21_TPU_CH11 = 6U, +} PORT_B21MuxType; + +/** @brief PORTB 22 Mode enumeration */ +typedef enum +{ +PORTB_22_GPIO = 1U, +PORTB_22_FTU_FLT8 = 2U, +PORTB_22_FLEXCAN2_TX = 3U, +PORTB_22_TPU_CH12 = 4U, +PORTB_22_FTU6_CH6 = 5U, +PORTB_22_MSC0_EN0 = 6U, +PORTB_22_FCSPI3_PCS1 = 7U, +} PORT_B22MuxType; + +/** @brief PORTB 23 Mode enumeration */ +typedef enum +{ +PORTB_23_CMP1_IN6 = 0U, +PORTB_23_GPIO = 1U, +PORTB_23_FTU_FLT9 = 2U, +PORTB_23_FCUART1_RX = 3U, +PORTB_23_FTU4_CH7 = 4U, +PORTB_23_FTU7_CH7 = 5U, +PORTB_23_TPU_CH13 = 6U, +PORTB_23_MSC0_FCLP = 7U, +} PORT_B23MuxType; + +/** @brief PORTB 24 Mode enumeration */ +typedef enum +{ +PORTB_24_CMP0_IN5 = 0U, +PORTB_24_GPIO = 1U, +PORTB_24_FTU6_CH3 = 2U, +PORTB_24_FCUART4_TX = 3U, +PORTB_24_FLEXCAN3_RX = 4U, +PORTB_24_TPU_CH6 = 6U, +} PORT_B24MuxType; + +/** @brief PORTB 25 Mode enumeration */ +typedef enum +{ +PORTB_25_GPIO = 1U, +PORTB_25_FTU1_CH2 = 2U, +PORTB_25_FTU1_QD_PHB = 3U, +PORTB_25_FCSPI2_PCS0 = 4U, +PORTB_25_FTU6_CH7 = 5U, +PORTB_25_FCUART3_TX = 6U, +} PORT_B25MuxType; + +/** @brief PORTB 26 Mode enumeration */ +typedef enum +{ +PORTB_26_CMP0_IN6 = 0U, +PORTB_26_GPIO = 1U, +PORTB_26_FTU6_CH4 = 2U, +PORTB_26_FCSPI3_SCK = 3U, +PORTB_26_FCUART3_TX = 4U, +PORTB_26_TPU_CH7 = 6U, +} PORT_B26MuxType; + +/** @brief PORTB 27 Mode enumeration */ +typedef enum +{ +PORTB_27_GPIO = 1U, +PORTB_27_FTU7_CH5 = 2U, +PORTB_27_FTU2_CH2 = 3U, +PORTB_27_FCSPI2_SOUT = 4U, +PORTB_27_FCUART5_RTS = 5U, +PORTB_27_TPU_CH14 = 6U, +} PORT_B27MuxType; + +/** @brief PORTB 28 Mode enumeration */ +typedef enum +{ +PORTB_28_GPIO = 1U, +PORTB_28_FTU7_CH4 = 2U, +PORTB_28_FTU2_CH1 = 3U, +PORTB_28_FCSPI2_SIN = 4U, +PORTB_28_FCUART5_CTS = 5U, +PORTB_28_TPU_CH15 = 6U, +} PORT_B28MuxType; + +/** @brief PORTB 29 Mode enumeration */ +typedef enum +{ +PORTB_29_GPIO = 1U, +PORTB_29_FTU1_CH0 = 2U, +PORTB_29_FCUART5_TX = 3U, +PORTB_29_FCSPI2_SCK = 4U, +PORTB_29_FTU1_QD_PHB = 5U, +PORTB_29_FCUART7_RTS = 6U, +PORTB_29_TPU_CH16 = 7U, +} PORT_B29MuxType; + +/** @brief PORTB 3 Mode enumeration */ +typedef enum +{ +PORTB_3_GPIO = 1U, +PORTB_3_FTU1_CH1 = 2U, +PORTB_3_FCSPI0_SIN = 3U, +PORTB_3_FTU1_QD_PHA = 4U, +PORTB_3_FTU7_CH3 = 5U, +PORTB_3_TPU_CH10 = 6U, +PORTB_3_FCUART5_RX = 7U, +} PORT_B3MuxType; + +/** @brief PORTB 30 Mode enumeration */ +typedef enum +{ +PORTB_30_CMP0_IN7 = 0U, +PORTB_30_GPIO = 1U, +PORTB_30_FTU6_CH5 = 2U, +PORTB_30_FCSPI3_SIN = 3U, +PORTB_30_FCUART3_RX = 4U, +PORTB_30_TPU_CH8 = 6U, +} PORT_B30MuxType; + +/** @brief PORTB 31 Mode enumeration */ +typedef enum +{ +PORTB_31_CMP1_IN0 = 0U, +PORTB_31_GPIO = 1U, +PORTB_31_FTU7_CH7 = 2U, +PORTB_31_FCSPI3_SOUT = 3U, +PORTB_31_FCUART5_TX = 4U, +PORTB_31_TPU_CH9 = 5U, +} PORT_B31MuxType; + +/** @brief PORTB 4 Mode enumeration */ +typedef enum +{ +PORTB_4_GPIO = 1U, +PORTB_4_FTU0_CH4 = 2U, +PORTB_4_FCIIC1_SDA = 3U, +PORTB_4_FCSPI4_SOUT = 4U, +PORTB_4_FTU7_CH6 = 5U, +PORTB_4_ETM_TRACE_D6 = 6U, +PORTB_4_TRGSEL_OUT4 = 7U, +} PORT_B4MuxType; + +/** @brief PORTB 5 Mode enumeration */ +typedef enum +{ +PORTB_5_GPIO = 1U, +PORTB_5_FTU0_CH5 = 2U, +PORTB_5_FCIIC1_SCL = 3U, +PORTB_5_FCSPI4_PCS0 = 4U, +PORTB_5_SCG_CLKOUT = 5U, +PORTB_5_ETM_TRACE_D5 = 6U, +PORTB_5_TRGSEL_OUT5 = 7U, +} PORT_B5MuxType; + +/** @brief PORTB 6 Mode enumeration */ +typedef enum +{ +PORTB_6_XTAL = 0U, +PORTB_6_GPIO = 1U, +PORTB_6_FCIIC0_SDA = 2U, +} PORT_B6MuxType; + +/** @brief PORTB 7 Mode enumeration */ +typedef enum +{ +PORTB_7_EXTAL = 0U, +PORTB_7_GPIO = 1U, +PORTB_7_FCIIC0_SCL = 2U, +} PORT_B7MuxType; + +/** @brief PORTB 8 Mode enumeration */ +typedef enum +{ +PORTB_8_ADC1_SE28 = 0U, +PORTB_8_GPIO = 1U, +PORTB_8_FTU3_CH0 = 2U, +PORTB_8_FLEXCAN0_RX = 3U, +PORTB_8_SENT0_RXD1 = 4U, +PORTB_8_TPU_CH0 = 5U, +PORTB_8_FCUART1_CTS = 6U, +} PORT_B8MuxType; + +/** @brief PORTB 9 Mode enumeration */ +typedef enum +{ +PORTB_9_ADC1_SE25 = 0U, +PORTB_9_GPIO = 1U, +PORTB_9_FTU3_CH1 = 2U, +PORTB_9_FTU1_CH6 = 3U, +PORTB_9_TRGSEL_OUT1 = 5U, +PORTB_9_TPU_CH29 = 6U, +PORTB_9_FCSPI5_PCS0 = 7U, +} PORT_B9MuxType; + +/** @brief PORTC 0 Mode enumeration */ +typedef enum +{ +PORTC_0_GPIO = 1U, +PORTC_0_FTU0_CH0 = 2U, +PORTC_0_FLEXCAN2_RX = 3U, +PORTC_0_TPU_CH15 = 4U, +PORTC_0_FlexCore_TCLK = 5U, +PORTC_0_FTU1_CH6 = 6U, +PORTC_0_FCSPI3_PCS2 = 7U, +} PORT_C0MuxType; + +/** @brief PORTC 1 Mode enumeration */ +typedef enum +{ +PORTC_1_GPIO = 1U, +PORTC_1_FTU0_CH1 = 2U, +PORTC_1_TPU_CH16 = 3U, +PORTC_1_FCSPI2_SOUT = 4U, +PORTC_1_FlexCore_TDI = 5U, +PORTC_1_FTU1_CH7 = 6U, +PORTC_1_FCUART3_TX = 7U, +} PORT_C1MuxType; + +/** @brief PORTC 10 Mode enumeration */ +typedef enum +{ +PORTC_10_ADC1_SE12 = 0U, +PORTC_10_GPIO = 1U, +PORTC_10_FTU3_CH4 = 2U, +PORTC_10_FTU0_CH5 = 3U, +PORTC_10_FCUART6_RX = 4U, +PORTC_10_FTU7_CH1 = 6U, +PORTC_10_TPU_CH8 = 7U, +} PORT_C10MuxType; + +/** @brief PORTC 11 Mode enumeration */ +typedef enum +{ +PORTC_11_ADC1_SE13 = 0U, +PORTC_11_GPIO = 1U, +PORTC_11_FTU3_CH5 = 2U, +PORTC_11_FTU4_CH2 = 3U, +PORTC_11_FCUART6_TX = 4U, +PORTC_11_FCSPI1_PCS0 = 5U, +PORTC_11_FTU7_CH2 = 6U, +PORTC_11_TPU_CH9 = 7U, +} PORT_C11MuxType; + +/** @brief PORTC 12 Mode enumeration */ +typedef enum +{ +PORTC_12_ADC1_SE14 = 0U, +PORTC_12_GPIO = 1U, +PORTC_12_FTU3_CH6 = 2U, +PORTC_12_FTU2_CH6 = 3U, +PORTC_12_FCUART2_CTS = 4U, +PORTC_12_TRGSEL_OUT5 = 5U, +PORTC_12_FCUART7_RX = 6U, +PORTC_12_MSC0_SOP = 7U, +} PORT_C12MuxType; + +/** @brief PORTC 13 Mode enumeration */ +typedef enum +{ +PORTC_13_ADC1_SE15 = 0U, +PORTC_13_GPIO = 1U, +PORTC_13_FTU3_CH7 = 2U, +PORTC_13_FTU2_CH7 = 3U, +PORTC_13_FCUART2_RTS = 4U, +PORTC_13_TRGSEL_OUT6 = 5U, +PORTC_13_FCUART7_TX = 6U, +PORTC_13_MSC0_FCLP = 7U, +} PORT_C13MuxType; + +/** @brief PORTC 14 Mode enumeration */ +typedef enum +{ +PORTC_14_CMP1_IN7 = 0U, +PORTC_14_GPIO = 1U, +PORTC_14_FTU1_CH2 = 2U, +PORTC_14_TPU_CH11 = 3U, +PORTC_14_FCSPI2_PCS0 = 4U, +PORTC_14_FTU1_QD_PHA = 5U, +PORTC_14_TRGSEL_OUT6 = 6U, +} PORT_C14MuxType; + +/** @brief PORTC 15 Mode enumeration */ +typedef enum +{ +PORTC_15_CMP1_IN5 = 0U, +PORTC_15_GPIO = 1U, +PORTC_15_FTU1_CH3 = 2U, +PORTC_15_TPU_CH12 = 3U, +PORTC_15_FCSPI2_SCK = 4U, +PORTC_15_FTU6_CH1 = 5U, +PORTC_15_TRGSEL_OUT7 = 6U, +PORTC_15_FCUART5_TX = 7U, +} PORT_C15MuxType; + +/** @brief PORTC 16 Mode enumeration */ +typedef enum +{ +PORTC_16_CMP1_IN4 = 0U, +PORTC_16_GPIO = 1U, +PORTC_16_FTU_FLT7 = 2U, +PORTC_16_FTU4_CH0 = 3U, +PORTC_16_FCSPI2_SIN = 4U, +PORTC_16_FTU7_CH4 = 5U, +PORTC_16_TPU_CH13 = 6U, +PORTC_16_FCUART5_RX = 7U, +} PORT_C16MuxType; + +/** @brief PORTC 17 Mode enumeration */ +typedef enum +{ +PORTC_17_DEBUGMUX_P1 = 0U, +PORTC_17_GPIO = 1U, +PORTC_17_FTU_FLT6 = 2U, +PORTC_17_FTU4_CH1 = 3U, +PORTC_17_FCSPI2_PCS3 = 4U, +PORTC_17_FTU6_CH2 = 5U, +PORTC_17_TPU_CH14 = 6U, +PORTC_17_FCUART4_TX = 7U, +} PORT_C17MuxType; + +/** @brief PORTC 18 Mode enumeration */ +typedef enum +{ +PORTC_18_CMP1_IN1 = 0U, +PORTC_18_GPIO = 1U, +PORTC_18_FTU7_CH6 = 2U, +PORTC_18_FCSPI3_PCS0 = 3U, +PORTC_18_FCUART5_RX = 4U, +PORTC_18_TPU_CH10 = 5U, +} PORT_C18MuxType; + +/** @brief PORTC 19 Mode enumeration */ +typedef enum +{ +PORTC_19_GPIO = 1U, +PORTC_19_FTU7_CH3 = 2U, +PORTC_19_FCSPI2_PCS1 = 4U, +PORTC_19_TPU_CH17 = 5U, +PORTC_19_FCUART3_RX = 6U, +} PORT_C19MuxType; + +/** @brief PORTC 2 Mode enumeration */ +typedef enum +{ +PORTC_2_DEBUGMUX_P2 = 0U, +PORTC_2_GPIO = 1U, +PORTC_2_FTU0_CH2 = 2U, +PORTC_2_FLEXCAN0_RX = 3U, +PORTC_2_FCUART0_RX = 4U, +PORTC_2_FTU5_CH4 = 5U, +PORTC_2_ETM_TRACE_CLKOUT = 6U, +PORTC_2_FCSPI0_PCS2 = 7U, +} PORT_C2MuxType; + +/** @brief PORTC 20 Mode enumeration */ +typedef enum +{ +PORTC_20_GPIO = 1U, +PORTC_20_FTU7_CH2 = 2U, +PORTC_20_FCSPI2_SCK = 4U, +PORTC_20_FCUART3_RTS = 5U, +PORTC_20_TPU_CH12 = 6U, +PORTC_20_MSC0_FCLP = 7U, +} PORT_C20MuxType; + +/** @brief PORTC 21 Mode enumeration */ +typedef enum +{ +PORTC_21_GPIO = 1U, +PORTC_21_FTU7_CH1 = 2U, +PORTC_21_FCSPI2_SIN = 4U, +PORTC_21_FCUART3_CTS = 5U, +PORTC_21_TPU_CH13 = 6U, +PORTC_21_MSC0_SOP = 7U, +} PORT_C21MuxType; + +/** @brief PORTC 22 Mode enumeration */ +typedef enum +{ +PORTC_22_GPIO = 1U, +PORTC_22_FTU6_CH4 = 2U, +PORTC_22_FCSPI0_SCK = 3U, +PORTC_22_FCUART5_RX = 4U, +PORTC_22_FTU7_CH6 = 5U, +PORTC_22_TPU_CH18 = 6U, +PORTC_22_MSC0_EN2 = 7U, +} PORT_C22MuxType; + +/** @brief PORTC 23 Mode enumeration */ +typedef enum +{ +PORTC_23_GPIO = 1U, +PORTC_23_FTU7_CH0 = 2U, +PORTC_23_FCUART6_TX = 3U, +PORTC_23_FCSPI2_SOUT = 4U, +PORTC_23_TPU_CH14 = 6U, +PORTC_23_MSC0_EN3 = 7U, +} PORT_C23MuxType; + +/** @brief PORTC 24 Mode enumeration */ +typedef enum +{ +PORTC_24_GPIO = 1U, +PORTC_24_FTU4_CH3 = 2U, +PORTC_24_FCUART6_RX = 3U, +PORTC_24_FCSPI2_PCS0 = 4U, +PORTC_24_TPU_CH15 = 6U, +PORTC_24_MSC0_SDI2 = 7U, +} PORT_C24MuxType; + +/** @brief PORTC 25 Mode enumeration */ +typedef enum +{ +PORTC_25_ADC1_SE20 = 0U, +PORTC_25_GPIO = 1U, +PORTC_25_FTU4_CH1 = 2U, +PORTC_25_FCUART5_RTS = 3U, +PORTC_25_FCUART6_TX = 4U, +PORTC_25_FTU0_CH6 = 5U, +PORTC_25_SENT0_RXD0 = 6U, +PORTC_25_FCSPI4_SCK = 7U, +} PORT_C25MuxType; + +/** @brief PORTC 26 Mode enumeration */ +typedef enum +{ +PORTC_26_ADC1_SE21 = 0U, +PORTC_26_GPIO = 1U, +PORTC_26_FTU4_CH0 = 2U, +PORTC_26_FCUART5_CTS = 3U, +PORTC_26_FCUART6_RX = 4U, +PORTC_26_FTU1_CH4 = 5U, +PORTC_26_SENT0_RXD1 = 6U, +PORTC_26_FCSPI4_PCS0 = 7U, +} PORT_C26MuxType; + +/** @brief PORTC 27 Mode enumeration */ +typedef enum +{ +PORTC_27_GPIO = 1U, +PORTC_27_FTU4_CH4 = 2U, +PORTC_27_FTU3_CH3 = 3U, +PORTC_27_FCSPI4_SOUT = 4U, +PORTC_27_TPU_CH19 = 6U, +PORTC_27_MSC0_EN0 = 7U, +} PORT_C27MuxType; + +/** @brief PORTC 28 Mode enumeration */ +typedef enum +{ +PORTC_28_GPIO = 1U, +PORTC_28_FTU4_CH7 = 2U, +PORTC_28_FLEXCAN3_TX = 3U, +PORTC_28_FTU3_CH2 = 4U, +PORTC_28_TPU_CH20 = 6U, +PORTC_28_MSC0_SDI0 = 7U, +} PORT_C28MuxType; + +/** @brief PORTC 29 Mode enumeration */ +typedef enum +{ +PORTC_29_GPIO = 1U, +PORTC_29_FTU5_CH2 = 2U, +PORTC_29_FLEXCAN3_RX = 3U, +PORTC_29_FCSPI4_SIN = 4U, +PORTC_29_TPU_CH21 = 6U, +} PORT_C29MuxType; + +/** @brief PORTC 3 Mode enumeration */ +typedef enum +{ +PORTC_3_GPIO = 1U, +PORTC_3_FTU0_CH3 = 2U, +PORTC_3_FLEXCAN0_TX = 3U, +PORTC_3_FCUART0_TX = 4U, +PORTC_3_FTU5_CH2 = 5U, +PORTC_3_ETM_TRACE_D7 = 6U, +PORTC_3_FCSPI0_SOUT = 7U, +} PORT_C3MuxType; + +/** @brief PORTC 30 Mode enumeration */ +typedef enum +{ +PORTC_30_GPIO = 1U, +PORTC_30_FTU5_CH4 = 2U, +PORTC_30_FTU3_CH0 = 3U, +PORTC_30_FCSPI4_PCS0 = 4U, +PORTC_30_TPU_CH22 = 6U, +} PORT_C30MuxType; + +/** @brief PORTC 31 Mode enumeration */ +typedef enum +{ +PORTC_31_GPIO = 1U, +PORTC_31_FTU5_CH6 = 2U, +PORTC_31_FTU3_CH4 = 3U, +PORTC_31_FCIIC1_SDA = 4U, +PORTC_31_FLEXCAN1_RX = 5U, +PORTC_31_TPU_CH23 = 6U, +} PORT_C31MuxType; + +/** @brief PORTC 4 Mode enumeration */ +typedef enum +{ +PORTC_4_GPIO = 1U, +PORTC_4_JTAG_TCLK_SWD_CLK = 7U, +} PORT_C4MuxType; + +/** @brief PORTC 5 Mode enumeration */ +typedef enum +{ +PORTC_5_GPIO = 1U, +PORTC_5_FTU2_CH0 = 2U, +PORTC_5_RTC_CLKOUT = 3U, +PORTC_5_CMP1_OUT = 4U, +PORTC_5_FCIIC0_SDA = 5U, +PORTC_5_FTU2_QD_PHB = 6U, +PORTC_5_JTAG_TDI = 7U, +} PORT_C5MuxType; + +/** @brief PORTC 6 Mode enumeration */ +typedef enum +{ +PORTC_6_ADC0_SE29 = 0U, +PORTC_6_GPIO = 1U, +PORTC_6_FCUART1_RX = 2U, +PORTC_6_FLEXCAN1_RX = 3U, +PORTC_6_FTU3_CH2 = 4U, +PORTC_6_SENT0_RXD0 = 5U, +PORTC_6_TPU_CH3 = 6U, +} PORT_C6MuxType; + +/** @brief PORTC 7 Mode enumeration */ +typedef enum +{ +PORTC_7_ADC0_SE30 = 0U, +PORTC_7_GPIO = 1U, +PORTC_7_FCUART1_TX = 2U, +PORTC_7_FLEXCAN1_TX = 3U, +PORTC_7_FTU3_CH3 = 4U, +PORTC_7_TPU_CH2 = 6U, +} PORT_C7MuxType; + +/** @brief PORTC 8 Mode enumeration */ +typedef enum +{ +PORTC_8_GPIO = 1U, +PORTC_8_FCUART1_RX = 2U, +PORTC_8_FTU_FLT11 = 3U, +PORTC_8_FTU5_CH1 = 4U, +PORTC_8_FCSPI1_SIN = 5U, +PORTC_8_FCUART0_CTS = 6U, +PORTC_8_MSC0_EN1 = 7U, +} PORT_C8MuxType; + +/** @brief PORTC 9 Mode enumeration */ +typedef enum +{ +PORTC_9_GPIO = 1U, +PORTC_9_FCUART1_TX = 2U, +PORTC_9_FTU_FLT10 = 3U, +PORTC_9_FTU5_CH0 = 4U, +PORTC_9_FCSPI1_SOUT = 5U, +PORTC_9_FCUART0_RTS = 6U, +PORTC_9_FCUART5_TX = 7U, +} PORT_C9MuxType; + +/** @brief PORTD 0 Mode enumeration */ +typedef enum +{ +PORTD_0_ADC1_SE1 = 0U, +PORTD_0_GPIO = 1U, +PORTD_0_FTU0_CH2 = 2U, +PORTD_0_FTU2_CH0 = 3U, +PORTD_0_FCSPI1_SCK = 4U, +PORTD_0_TPU_CH28 = 5U, +PORTD_0_ETM_TRACE_D0 = 6U, +PORTD_0_TRGSEL_OUT1 = 7U, +} PORT_D0MuxType; + +/** @brief PORTD 1 Mode enumeration */ +typedef enum +{ +PORTD_1_ADC1_SE5 = 0U, +PORTD_1_GPIO = 1U, +PORTD_1_FTU0_CH3 = 2U, +PORTD_1_FTU2_CH1 = 3U, +PORTD_1_FCSPI1_SIN = 4U, +PORTD_1_TPU_CH29 = 5U, +PORTD_1_TRGSEL_OUT2 = 7U, +} PORT_D1MuxType; + +/** @brief PORTD 10 Mode enumeration */ +typedef enum +{ +PORTD_10_GPIO = 1U, +PORTD_10_FTU2_CH0 = 2U, +PORTD_10_FTU2_QD_PHB = 3U, +PORTD_10_SCG_CLKOUT = 4U, +PORTD_10_FlexCore_TMS = 5U, +PORTD_10_ETM_TRACE_D3 = 6U, +PORTD_10_FCSPI3_PCS3 = 7U, +} PORT_D10MuxType; + +/** @brief PORTD 11 Mode enumeration */ +typedef enum +{ +PORTD_11_GPIO = 1U, +PORTD_11_FTU2_CH1 = 2U, +PORTD_11_FTU2_QD_PHA = 3U, +PORTD_11_FCSPI4_PCS1 = 4U, +PORTD_11_FCUART2_CTS = 5U, +PORTD_11_ETM_TRACE_D2 = 6U, +PORTD_11_FCSPI3_PCS0 = 7U, +} PORT_D11MuxType; + +/** @brief PORTD 12 Mode enumeration */ +typedef enum +{ +PORTD_12_GPIO = 1U, +PORTD_12_FTU2_CH2 = 2U, +PORTD_12_FCUART4_RX = 3U, +PORTD_12_FTU6_CH7 = 4U, +PORTD_12_FCUART2_RTS = 5U, +PORTD_12_ETM_TRACE_D1 = 6U, +PORTD_12_FCSPI3_SOUT = 7U, +} PORT_D12MuxType; + +/** @brief PORTD 13 Mode enumeration */ +typedef enum +{ +PORTD_13_GPIO = 1U, +PORTD_13_FTU6_CH3 = 2U, +PORTD_13_FCUART1_TX = 3U, +PORTD_13_TPU_CH11 = 4U, +PORTD_13_FCUART7_CTS = 6U, +PORTD_13_MSC0_SOP = 7U, +} PORT_D13MuxType; + +/** @brief PORTD 15 Mode enumeration */ +typedef enum +{ +PORTD_15_ADC0_SE11_CMP0_IN1 = 0U, +PORTD_15_GPIO = 1U, +PORTD_15_FTU0_CH0 = 2U, +PORTD_15_FCUART2_RTS = 3U, +PORTD_15_TPU_CH18 = 4U, +PORTD_15_ETM_TRACE_D3 = 6U, +PORTD_15_FCSPI0_SCK = 7U, +} PORT_D15MuxType; + +/** @brief PORTD 16 Mode enumeration */ +typedef enum +{ +PORTD_16_ADC0_SE10_CMP0_IN0 = 0U, +PORTD_16_GPIO = 1U, +PORTD_16_FTU0_CH1 = 2U, +PORTD_16_TPU_CH19 = 4U, +PORTD_16_ETM_TRACE_D2 = 6U, +PORTD_16_FCSPI0_SIN = 7U, +} PORT_D16MuxType; + +/** @brief PORTD 17 Mode enumeration */ +typedef enum +{ +PORTD_17_ADC0_SE8 = 0U, +PORTD_17_GPIO = 1U, +PORTD_17_FTU6_CH1 = 2U, +PORTD_17_FCUART7_RX = 3U, +PORTD_17_FTU_FLT3 = 4U, +PORTD_17_FCSPI4_PCS0 = 6U, +PORTD_17_TPU_CH5 = 7U, +} PORT_D17MuxType; + +/** @brief PORTD 18 Mode enumeration */ +typedef enum +{ +PORTD_18_GPIO = 1U, +PORTD_18_FTU5_CH7 = 2U, +PORTD_18_FTU3_CH5 = 3U, +PORTD_18_FCSPI4_SCK = 4U, +PORTD_18_TPU_CH24 = 6U, +} PORT_D18MuxType; + +/** @brief PORTD 19 Mode enumeration */ +typedef enum +{ +PORTD_19_GPIO = 1U, +PORTD_19_FTU6_CH0 = 2U, +PORTD_19_FCSPI1_PCS2 = 3U, +PORTD_19_FCIIC1_SCL = 4U, +PORTD_19_FLEXCAN1_TX = 5U, +PORTD_19_SENT0_RXD2 = 6U, +} PORT_D19MuxType; + +/** @brief PORTD 2 Mode enumeration */ +typedef enum +{ +PORTD_2_GPIO = 1U, +PORTD_2_FTU3_CH4 = 2U, +PORTD_2_FTU6_CH5 = 3U, +PORTD_2_FCUART6_RX = 4U, +PORTD_2_FCSPI5_PCS2 = 5U, +PORTD_2_FTU1_CH1 = 6U, +PORTD_2_ISP_EN_B = 7U, +} PORT_D2MuxType; + +/** @brief PORTD 20 Mode enumeration */ +typedef enum +{ +PORTD_20_GPIO = 1U, +PORTD_20_FTU6_CH2 = 2U, +PORTD_20_FCUART5_RX = 3U, +PORTD_20_TPU_CH16 = 4U, +PORTD_20_SENT0_RXD2 = 6U, +PORTD_20_FCSPI4_SIN = 7U, +} PORT_D20MuxType; + +/** @brief PORTD 21 Mode enumeration */ +typedef enum +{ +PORTD_21_ADC1_SE22 = 0U, +PORTD_21_GPIO = 1U, +PORTD_21_FTU6_CH3 = 2U, +PORTD_21_FCUART5_TX = 3U, +PORTD_21_TPU_CH17 = 4U, +PORTD_21_SENT0_RXD3 = 6U, +PORTD_21_FCSPI4_SOUT = 7U, +} PORT_D21MuxType; + +/** @brief PORTD 22 Mode enumeration */ +typedef enum +{ +PORTD_22_ADC1_SE19 = 0U, +PORTD_22_GPIO = 1U, +PORTD_22_FTU6_CH1 = 2U, +PORTD_22_FTU0_CH1 = 3U, +PORTD_22_TPU_TCRCLK = 4U, +PORTD_22_FCSPI5_PCS3 = 5U, +PORTD_22_FLEXCAN1_RX = 6U, +} PORT_D22MuxType; + +/** @brief PORTD 23 Mode enumeration */ +typedef enum +{ +PORTD_23_GPIO = 1U, +PORTD_23_FTU6_CH5 = 2U, +PORTD_23_FLEXCAN3_TX = 4U, +PORTD_23_TPU_CH27 = 5U, +PORTD_23_FTU1_CH0 = 6U, +} PORT_D23MuxType; + +/** @brief PORTD 24 Mode enumeration */ +typedef enum +{ +PORTD_24_GPIO = 1U, +PORTD_24_FTU3_CH3 = 2U, +PORTD_24_TPU_CH28 = 3U, +PORTD_24_FCUART6_RTS = 4U, +PORTD_24_FCSPI5_PCS1 = 5U, +PORTD_24_FLEXCAN1_TX = 6U, +} PORT_D24MuxType; + +/** @brief PORTD 25 Mode enumeration */ +typedef enum +{ +PORTD_25_ADC1_SE24 = 0U, +PORTD_25_GPIO = 1U, +PORTD_25_FTU6_CH6 = 2U, +PORTD_25_FTU0_CH0 = 3U, +PORTD_25_FCUART4_RTS = 4U, +PORTD_25_TPU_CH18 = 6U, +PORTD_25_FCSPI5_SCK = 7U, +} PORT_D25MuxType; + +/** @brief PORTD 26 Mode enumeration */ +typedef enum +{ +PORTD_26_ADC1_SE26 = 0U, +PORTD_26_GPIO = 1U, +PORTD_26_FTU6_CH7 = 2U, +PORTD_26_FTU3_CH7 = 3U, +PORTD_26_FCUART4_CTS = 4U, +PORTD_26_SENT0_RXD3 = 5U, +PORTD_26_TPU_CH19 = 6U, +PORTD_26_FCSPI5_SIN = 7U, +} PORT_D26MuxType; + +/** @brief PORTD 27 Mode enumeration */ +typedef enum +{ +PORTD_27_ADC1_SE27 = 0U, +PORTD_27_GPIO = 1U, +PORTD_27_FTU7_CH0 = 2U, +PORTD_27_FCUART6_TX = 3U, +PORTD_27_FLEXCAN3_RX = 4U, +PORTD_27_TPU_CH30 = 6U, +} PORT_D27MuxType; + +/** @brief PORTD 28 Mode enumeration */ +typedef enum +{ +PORTD_28_GPIO = 1U, +PORTD_28_FTU7_CH1 = 2U, +PORTD_28_FCUART6_RX = 3U, +PORTD_28_TPU_CH31 = 6U, +PORTD_28_FCSPI5_PCS1 = 7U, +} PORT_D28MuxType; + +/** @brief PORTD 29 Mode enumeration */ +typedef enum +{ +PORTD_29_GPIO = 1U, +PORTD_29_FTU7_CH2 = 2U, +PORTD_29_FCUART7_RX = 3U, +PORTD_29_TPU_CH14 = 6U, +} PORT_D29MuxType; + +/** @brief PORTD 3 Mode enumeration */ +typedef enum +{ +PORTD_3_GPIO = 1U, +PORTD_3_FTU3_CH5 = 2U, +PORTD_3_FCSPI1_PCS0 = 3U, +PORTD_3_FCSPI5_PCS0 = 5U, +PORTD_3_FTU1_CH2 = 6U, +PORTD_3_TPU_CH3 = 7U, +} PORT_D3MuxType; + +/** @brief PORTD 30 Mode enumeration */ +typedef enum +{ +PORTD_30_ADC1_SE31 = 0U, +PORTD_30_GPIO = 1U, +PORTD_30_FTU7_CH3 = 2U, +PORTD_30_FCUART7_TX = 3U, +PORTD_30_TPU_CH15 = 6U, +} PORT_D30MuxType; + +/** @brief PORTD 31 Mode enumeration */ +typedef enum +{ +PORTD_31_ADC0_SE31 = 0U, +PORTD_31_GPIO = 1U, +PORTD_31_FTU7_CH4 = 2U, +PORTD_31_AONTIMER0_CLK0 = 3U, +PORTD_31_SENT0_RXD2 = 4U, +PORTD_31_FCUART7_RX = 5U, +PORTD_31_TPU_CH20 = 6U, +PORTD_31_FCSPI5_PCS2 = 7U, +} PORT_D31MuxType; + +/** @brief PORTD 4 Mode enumeration */ +typedef enum +{ +PORTD_4_ADC1_SE23 = 0U, +PORTD_4_GPIO = 1U, +PORTD_4_FTU_FLT16 = 2U, +PORTD_4_FTU6_CH4 = 3U, +PORTD_4_FCUART6_TX = 4U, +PORTD_4_FCSPI5_SIN = 5U, +PORTD_4_FTU1_CH3 = 6U, +PORTD_4_TPU_CH4 = 7U, +} PORT_D4MuxType; + +/** @brief PORTD 5 Mode enumeration */ +typedef enum +{ +PORTD_5_GPIO = 1U, +PORTD_5_FTU2_CH3 = 2U, +PORTD_5_FCUART4_TX = 3U, +PORTD_5_FTU_FLT5 = 4U, +PORTD_5_FTU7_CH5 = 5U, +PORTD_5_TPU_CH20 = 6U, +PORTD_5_FCSPI3_SIN = 7U, +} PORT_D5MuxType; + +/** @brief PORTD 6 Mode enumeration */ +typedef enum +{ +PORTD_6_GPIO = 1U, +PORTD_6_FCUART2_RX = 2U, +PORTD_6_FLEXCAN3_RX = 3U, +PORTD_6_FTU_FLT4 = 4U, +PORTD_6_FTU2_CH4 = 5U, +PORTD_6_TPU_CH21 = 6U, +PORTD_6_FCSPI3_SCK = 7U, +} PORT_D6MuxType; + +/** @brief PORTD 7 Mode enumeration */ +typedef enum +{ +PORTD_7_GPIO = 1U, +PORTD_7_FCUART2_TX = 2U, +PORTD_7_FLEXCAN3_TX = 3U, +PORTD_7_FCSPI4_SIN = 4U, +PORTD_7_FTU2_CH5 = 5U, +PORTD_7_ETM_TRACE_D0 = 6U, +} PORT_D7MuxType; + +/** @brief PORTD 8 Mode enumeration */ +typedef enum +{ +PORTD_8_CMP1_IN3 = 0U, +PORTD_8_GPIO = 1U, +PORTD_8_FCIIC1_SDA = 2U, +PORTD_8_FTU4_CH2 = 3U, +PORTD_8_FCSPI2_PCS2 = 4U, +PORTD_8_FlexCore_TRST = 5U, +PORTD_8_FTU1_CH4 = 6U, +PORTD_8_FCUART4_RX = 7U, +} PORT_D8MuxType; + +/** @brief PORTD 9 Mode enumeration */ +typedef enum +{ +PORTD_9_CMP1_IN2 = 0U, +PORTD_9_GPIO = 1U, +PORTD_9_FCIIC1_SCL = 2U, +PORTD_9_FTU4_CH3 = 3U, +PORTD_9_FCSPI2_PCS1 = 4U, +PORTD_9_FlexCore_TDO = 5U, +PORTD_9_FTU1_CH5 = 6U, +PORTD_9_FCUART3_RX = 7U, +} PORT_D9MuxType; + +/** @brief PORTE 0 Mode enumeration */ +typedef enum +{ +PORTE_0_ADC0_SE16 = 0U, +PORTE_0_GPIO = 1U, +PORTE_0_FCUART0_CTS = 2U, +PORTE_0_FTU_TCK1 = 3U, +PORTE_0_FCIIC1_SDA = 4U, +PORTE_0_FCSPI0_SCK = 5U, +PORTE_0_FTU_FLT19 = 6U, +PORTE_0_TPU_CH11 = 7U, +} PORT_E0MuxType; + +/** @brief PORTE 1 Mode enumeration */ +typedef enum +{ +PORTE_1_ADC0_SE17 = 0U, +PORTE_1_GPIO = 1U, +PORTE_1_FCUART0_RTS = 2U, +PORTE_1_FCIIC1_SCL = 4U, +PORTE_1_FCSPI0_SIN = 5U, +PORTE_1_FTU_FLT18 = 6U, +PORTE_1_TPU_CH10 = 7U, +} PORT_E1MuxType; + +/** @brief PORTE 10 Mode enumeration */ +typedef enum +{ +PORTE_10_ADC1_SE0 = 0U, +PORTE_10_GPIO = 1U, +PORTE_10_FTU2_CH4 = 2U, +PORTE_10_FCSPI2_PCS1 = 3U, +PORTE_10_TPU_CH26 = 4U, +PORTE_10_FCUART2_TX = 5U, +PORTE_10_SCG_CLKOUT = 6U, +PORTE_10_TRGSEL_OUT4 = 7U, +} PORT_E10MuxType; + +/** @brief PORTE 11 Mode enumeration */ +typedef enum +{ +PORTE_11_ADC1_SE4 = 0U, +PORTE_11_GPIO = 1U, +PORTE_11_FTU2_CH5 = 2U, +PORTE_11_FCSPI2_PCS0 = 3U, +PORTE_11_TPU_CH27 = 5U, +PORTE_11_TRGSEL_OUT5 = 7U, +} PORT_E11MuxType; + +/** @brief PORTE 12 Mode enumeration */ +typedef enum +{ +PORTE_12_ADC0_SE3 = 0U, +PORTE_12_GPIO = 1U, +PORTE_12_FTU6_CH0 = 2U, +PORTE_12_FCUART7_TX = 3U, +PORTE_12_FTU_FLT2 = 4U, +PORTE_12_FCSPI4_SOUT = 6U, +PORTE_12_TPU_CH3 = 7U, +} PORT_E12MuxType; + +/** @brief PORTE 13 Mode enumeration */ +typedef enum +{ +PORTE_13_ADC0_SE5 = 0U, +PORTE_13_GPIO = 1U, +PORTE_13_FTU4_CH5 = 2U, +PORTE_13_FCSPI2_SOUT = 3U, +PORTE_13_TPU_CH24 = 4U, +PORTE_13_FTU3_CH3 = 5U, +} PORT_E13MuxType; + +/** @brief PORTE 14 Mode enumeration */ +typedef enum +{ +PORTE_14_OSC32K_XTAL = 0U, +PORTE_14_GPIO = 1U, +PORTE_14_FTU2_CH7 = 2U, +PORTE_14_FTU2_QD_PHA = 3U, +PORTE_14_FTU_FLT0 = 4U, +PORTE_14_FLEXCAN0_RX = 5U, +PORTE_14_TPU_TCRCLK = 6U, +} PORT_E14MuxType; + +/** @brief PORTE 15 Mode enumeration */ +typedef enum +{ +PORTE_15_ADC1_SE2 = 0U, +PORTE_15_GPIO = 1U, +PORTE_15_FTU2_CH6 = 2U, +PORTE_15_FCSPI2_SCK = 3U, +PORTE_15_TPU_CH30 = 4U, +PORTE_15_FCUART1_CTS = 6U, +PORTE_15_TRGSEL_OUT6 = 7U, +} PORT_E15MuxType; + +/** @brief PORTE 16 Mode enumeration */ +typedef enum +{ +PORTE_16_ADC1_SE6 = 0U, +PORTE_16_GPIO = 1U, +PORTE_16_FTU2_CH7 = 2U, +PORTE_16_FCSPI2_SIN = 3U, +PORTE_16_TPU_CH31 = 4U, +PORTE_16_FCUART1_RTS = 6U, +PORTE_16_TRGSEL_OUT7 = 7U, +} PORT_E16MuxType; + +/** @brief PORTE 17 Mode enumeration */ +typedef enum +{ +PORTE_17_GPIO = 1U, +PORTE_17_FTU7_CH5 = 2U, +PORTE_17_SENT0_RXD0 = 4U, +PORTE_17_TPU_CH21 = 6U, +PORTE_17_FCSPI5_SOUT = 7U, +} PORT_E17MuxType; + +/** @brief PORTE 18 Mode enumeration */ +typedef enum +{ +PORTE_18_ADC0_SE27 = 0U, +PORTE_18_GPIO = 1U, +PORTE_18_FTU7_CH6 = 2U, +PORTE_18_FTU6_CH7 = 3U, +PORTE_18_SENT0_RXD1 = 4U, +PORTE_18_FCUART7_TX = 5U, +PORTE_18_TPU_CH22 = 6U, +PORTE_18_FCSPI5_PCS3 = 7U, +} PORT_E18MuxType; + +/** @brief PORTE 19 Mode enumeration */ +typedef enum +{ +PORTE_19_ADC0_SE23 = 0U, +PORTE_19_GPIO = 1U, +PORTE_19_SCG_CLKOUT = 2U, +PORTE_19_FCIIC0_SCL = 3U, +PORTE_19_RTC_CLKOUT = 4U, +PORTE_19_FLEXCAN2_RX = 5U, +PORTE_19_TPU_CH31 = 6U, +} PORT_E19MuxType; + +/** @brief PORTE 2 Mode enumeration */ +typedef enum +{ +PORTE_2_ADC0_SE24 = 0U, +PORTE_2_GPIO = 1U, +PORTE_2_FTU6_CH6 = 2U, +PORTE_2_AONTIMER0_CLK2 = 3U, +PORTE_2_FTU3_CH6 = 4U, +PORTE_2_SENT0_RXD3 = 5U, +PORTE_2_FCUART1_CTS = 6U, +PORTE_2_FTU1_CH7 = 7U, +} PORT_E2MuxType; + +/** @brief PORTE 20 Mode enumeration */ +typedef enum +{ +PORTE_20_ADC0_SE22 = 0U, +PORTE_20_GPIO = 1U, +PORTE_20_FTU4_CH0 = 2U, +PORTE_20_FCIIC0_SDA = 3U, +PORTE_20_FTU1_CH3 = 4U, +PORTE_20_FCSPI0_PCS0 = 5U, +} PORT_E20MuxType; + +/** @brief PORTE 21 Mode enumeration */ +typedef enum +{ +PORTE_21_GPIO = 1U, +PORTE_21_FTU4_CH1 = 2U, +PORTE_21_AONTIMER0_CLK2 = 3U, +PORTE_21_FLEXCAN0_TX = 4U, +PORTE_21_FCUART0_RTS = 5U, +} PORT_E21MuxType; + +/** @brief PORTE 22 Mode enumeration */ +typedef enum +{ +PORTE_22_GPIO = 1U, +PORTE_22_FTU4_CH2 = 2U, +PORTE_22_LP_WAKEUP0 = 3U, +PORTE_22_FLEXCAN0_RX = 4U, +PORTE_22_FCUART0_CTS = 5U, +} PORT_E22MuxType; + +/** @brief PORTE 23 Mode enumeration */ +typedef enum +{ +PORTE_23_ADC0_SE19 = 0U, +PORTE_23_GPIO = 1U, +PORTE_23_FTU4_CH3 = 2U, +PORTE_23_FCUART0_TX = 3U, +PORTE_23_TPU_CH26 = 4U, +PORTE_23_FCSPI0_PCS3 = 5U, +PORTE_23_LP_WAKEUP1 = 6U, +} PORT_E23MuxType; + +/** @brief PORTE 24 Mode enumeration */ +typedef enum +{ +PORTE_24_ADC0_SE18 = 0U, +PORTE_24_GPIO = 1U, +PORTE_24_FTU4_CH4 = 2U, +PORTE_24_FLEXCAN2_TX = 3U, +PORTE_24_TPU_CH27 = 4U, +PORTE_24_FCSPI0_PCS2 = 5U, +} PORT_E24MuxType; + +/** @brief PORTE 25 Mode enumeration */ +typedef enum +{ +PORTE_25_DEBUGMUX_P0 = 0U, +PORTE_25_GPIO = 1U, +PORTE_25_FTU4_CH5 = 2U, +PORTE_25_FCUART0_RX = 3U, +PORTE_25_TPU_CH28 = 4U, +PORTE_25_FCSPI0_PCS1 = 5U, +} PORT_E25MuxType; + +/** @brief PORTE 26 Mode enumeration */ +typedef enum +{ +PORTE_26_GPIO = 1U, +PORTE_26_FTU4_CH6 = 2U, +PORTE_26_LP_WAKEUP3 = 3U, +PORTE_26_FTU1_CH2 = 4U, +PORTE_26_FCUART1_TX = 5U, +PORTE_26_TPU_CH23 = 6U, +} PORT_E26MuxType; + +/** @brief PORTE 27 Mode enumeration */ +typedef enum +{ +PORTE_27_GPIO = 1U, +PORTE_27_FTU4_CH7 = 2U, +PORTE_27_FLEXCAN2_RX = 3U, +PORTE_27_FTU1_CH0 = 4U, +PORTE_27_FCUART1_RX = 5U, +PORTE_27_TPU_CH24 = 6U, +} PORT_E27MuxType; + +/** @brief PORTE 29 Mode enumeration */ +typedef enum +{ +PORTE_29_GPIO = 1U, +PORTE_29_FTU2_CH0 = 2U, +PORTE_29_RTC_CLKOUT = 3U, +PORTE_29_FTU1_CH1 = 4U, +PORTE_29_FLEXCAN2_TX = 5U, +PORTE_29_FTU2_QD_PHA = 6U, +PORTE_29_TPU_CH25 = 7U, +} PORT_E29MuxType; + +/** @brief PORTE 3 Mode enumeration */ +typedef enum +{ +PORTE_3_OSC32K_EXTAL = 0U, +PORTE_3_GPIO = 1U, +PORTE_3_FTU2_CH6 = 2U, +PORTE_3_FCUART2_RX = 3U, +PORTE_3_FTU_FLT1 = 4U, +PORTE_3_FTU2_QD_PHB = 5U, +PORTE_3_FTU_TCK0 = 6U, +} PORT_E3MuxType; + +/** @brief PORTE 4 Mode enumeration */ +typedef enum +{ +PORTE_4_ADC0_SE4 = 0U, +PORTE_4_GPIO = 1U, +PORTE_4_FTU6_CH0 = 2U, +PORTE_4_FTU2_QD_PHB = 3U, +PORTE_4_FCSPI1_PCS0 = 4U, +PORTE_4_FTU2_CH2 = 5U, +PORTE_4_ETM_TRACE_D1 = 6U, +PORTE_4_TPU_CH22 = 7U, +} PORT_E4MuxType; + +/** @brief PORTE 5 Mode enumeration */ +typedef enum +{ +PORTE_5_ADC0_SE1 = 0U, +PORTE_5_GPIO = 1U, +PORTE_5_FTU_TCK2 = 2U, +PORTE_5_FTU2_QD_PHA = 3U, +PORTE_5_FCSPI1_SOUT = 4U, +PORTE_5_FTU2_CH3 = 5U, +PORTE_5_TPU_CH23 = 6U, +} PORT_E5MuxType; + +/** @brief PORTE 6 Mode enumeration */ +typedef enum +{ +PORTE_6_ADC0_SE25 = 0U, +PORTE_6_GPIO = 1U, +PORTE_6_FTU7_CH7 = 2U, +PORTE_6_FTU6_CH3 = 3U, +PORTE_6_FTU3_CH7 = 4U, +PORTE_6_SENT0_RXD2 = 5U, +PORTE_6_FCUART1_RTS = 6U, +PORTE_6_TPU_CH6 = 7U, +} PORT_E6MuxType; + +/** @brief PORTE 7 Mode enumeration */ +typedef enum +{ +PORTE_7_ADC1_SE8 = 0U, +PORTE_7_GPIO = 1U, +PORTE_7_FTU0_CH7 = 2U, +PORTE_7_FTU_FLT14 = 3U, +PORTE_7_FTU5_CH6 = 4U, +PORTE_7_TRGSEL_OUT3 = 5U, +PORTE_7_SENT0_RXD3 = 6U, +PORTE_7_MSC0_SDI3 = 7U, +} PORT_E7MuxType; + +/** @brief PORTE 8 Mode enumeration */ +typedef enum +{ +PORTE_8_GPIO = 1U, +PORTE_8_FTU0_CH6 = 2U, +PORTE_8_FCSPI4_SCK = 4U, +PORTE_8_FTU7_CH7 = 5U, +PORTE_8_ETM_TRACE_D4 = 6U, +PORTE_8_FCSPI0_PCS3 = 7U, +} PORT_E8MuxType; + +/** @brief PORTE 9 Mode enumeration */ +typedef enum +{ +PORTE_9_ADC0_SE12_CMP0_IN2 = 0U, +PORTE_9_GPIO = 1U, +PORTE_9_FTU0_CH7 = 2U, +PORTE_9_FCUART2_CTS = 3U, +PORTE_9_TPU_CH17 = 4U, +PORTE_9_ETM_TRACE_CLKOUT = 6U, +PORTE_9_FCSPI0_PCS0 = 7U, +} PORT_E9MuxType; + + +/** @brief Port Pin Mux structure */ +typedef union +{ + PORT_A0MuxType ePortA0Mode; + PORT_A1MuxType ePortA1Mode; + PORT_A2MuxType ePortA2Mode; + PORT_A3MuxType ePortA3Mode; + PORT_A4MuxType ePortA4Mode; + PORT_A6MuxType ePortA6Mode; + PORT_A7MuxType ePortA7Mode; + PORT_A8MuxType ePortA8Mode; + PORT_A9MuxType ePortA9Mode; + PORT_A10MuxType ePortA10Mode; + PORT_A11MuxType ePortA11Mode; + PORT_A12MuxType ePortA12Mode; + PORT_A13MuxType ePortA13Mode; + PORT_A14MuxType ePortA14Mode; + PORT_A15MuxType ePortA15Mode; + PORT_A16MuxType ePortA16Mode; + PORT_A17MuxType ePortA17Mode; + PORT_A18MuxType ePortA18Mode; + PORT_A19MuxType ePortA19Mode; + PORT_A20MuxType ePortA20Mode; + PORT_A21MuxType ePortA21Mode; + PORT_A23MuxType ePortA23Mode; + PORT_A24MuxType ePortA24Mode; + PORT_A25MuxType ePortA25Mode; + PORT_A26MuxType ePortA26Mode; + PORT_A27MuxType ePortA27Mode; + PORT_A28MuxType ePortA28Mode; + PORT_A29MuxType ePortA29Mode; + PORT_A30MuxType ePortA30Mode; + PORT_A31MuxType ePortA31Mode; + PORT_B0MuxType ePortB0Mode; + PORT_B1MuxType ePortB1Mode; + PORT_B3MuxType ePortB3Mode; + PORT_B4MuxType ePortB4Mode; + PORT_B5MuxType ePortB5Mode; + PORT_B6MuxType ePortB6Mode; + PORT_B7MuxType ePortB7Mode; + PORT_B8MuxType ePortB8Mode; + PORT_B9MuxType ePortB9Mode; + PORT_B10MuxType ePortB10Mode; + PORT_B11MuxType ePortB11Mode; + PORT_B12MuxType ePortB12Mode; + PORT_B13MuxType ePortB13Mode; + PORT_B14MuxType ePortB14Mode; + PORT_B15MuxType ePortB15Mode; + PORT_B16MuxType ePortB16Mode; + PORT_B17MuxType ePortB17Mode; + PORT_B18MuxType ePortB18Mode; + PORT_B19MuxType ePortB19Mode; + PORT_B20MuxType ePortB20Mode; + PORT_B21MuxType ePortB21Mode; + PORT_B22MuxType ePortB22Mode; + PORT_B23MuxType ePortB23Mode; + PORT_B24MuxType ePortB24Mode; + PORT_B25MuxType ePortB25Mode; + PORT_B26MuxType ePortB26Mode; + PORT_B27MuxType ePortB27Mode; + PORT_B28MuxType ePortB28Mode; + PORT_B29MuxType ePortB29Mode; + PORT_B30MuxType ePortB30Mode; + PORT_B31MuxType ePortB31Mode; + PORT_C0MuxType ePortC0Mode; + PORT_C1MuxType ePortC1Mode; + PORT_C2MuxType ePortC2Mode; + PORT_C3MuxType ePortC3Mode; + PORT_C4MuxType ePortC4Mode; + PORT_C5MuxType ePortC5Mode; + PORT_C6MuxType ePortC6Mode; + PORT_C7MuxType ePortC7Mode; + PORT_C8MuxType ePortC8Mode; + PORT_C9MuxType ePortC9Mode; + PORT_C10MuxType ePortC10Mode; + PORT_C11MuxType ePortC11Mode; + PORT_C12MuxType ePortC12Mode; + PORT_C13MuxType ePortC13Mode; + PORT_C14MuxType ePortC14Mode; + PORT_C15MuxType ePortC15Mode; + PORT_C16MuxType ePortC16Mode; + PORT_C17MuxType ePortC17Mode; + PORT_C18MuxType ePortC18Mode; + PORT_C19MuxType ePortC19Mode; + PORT_C20MuxType ePortC20Mode; + PORT_C21MuxType ePortC21Mode; + PORT_C22MuxType ePortC22Mode; + PORT_C23MuxType ePortC23Mode; + PORT_C24MuxType ePortC24Mode; + PORT_C25MuxType ePortC25Mode; + PORT_C26MuxType ePortC26Mode; + PORT_C27MuxType ePortC27Mode; + PORT_C28MuxType ePortC28Mode; + PORT_C29MuxType ePortC29Mode; + PORT_C30MuxType ePortC30Mode; + PORT_C31MuxType ePortC31Mode; + PORT_D0MuxType ePortD0Mode; + PORT_D1MuxType ePortD1Mode; + PORT_D2MuxType ePortD2Mode; + PORT_D3MuxType ePortD3Mode; + PORT_D4MuxType ePortD4Mode; + PORT_D5MuxType ePortD5Mode; + PORT_D6MuxType ePortD6Mode; + PORT_D7MuxType ePortD7Mode; + PORT_D8MuxType ePortD8Mode; + PORT_D9MuxType ePortD9Mode; + PORT_D10MuxType ePortD10Mode; + PORT_D11MuxType ePortD11Mode; + PORT_D12MuxType ePortD12Mode; + PORT_D13MuxType ePortD13Mode; + PORT_D15MuxType ePortD15Mode; + PORT_D16MuxType ePortD16Mode; + PORT_D17MuxType ePortD17Mode; + PORT_D18MuxType ePortD18Mode; + PORT_D19MuxType ePortD19Mode; + PORT_D20MuxType ePortD20Mode; + PORT_D21MuxType ePortD21Mode; + PORT_D22MuxType ePortD22Mode; + PORT_D23MuxType ePortD23Mode; + PORT_D24MuxType ePortD24Mode; + PORT_D25MuxType ePortD25Mode; + PORT_D26MuxType ePortD26Mode; + PORT_D27MuxType ePortD27Mode; + PORT_D28MuxType ePortD28Mode; + PORT_D29MuxType ePortD29Mode; + PORT_D30MuxType ePortD30Mode; + PORT_D31MuxType ePortD31Mode; + PORT_E0MuxType ePortE0Mode; + PORT_E1MuxType ePortE1Mode; + PORT_E2MuxType ePortE2Mode; + PORT_E3MuxType ePortE3Mode; + PORT_E4MuxType ePortE4Mode; + PORT_E5MuxType ePortE5Mode; + PORT_E6MuxType ePortE6Mode; + PORT_E7MuxType ePortE7Mode; + PORT_E8MuxType ePortE8Mode; + PORT_E9MuxType ePortE9Mode; + PORT_E10MuxType ePortE10Mode; + PORT_E11MuxType ePortE11Mode; + PORT_E12MuxType ePortE12Mode; + PORT_E13MuxType ePortE13Mode; + PORT_E14MuxType ePortE14Mode; + PORT_E15MuxType ePortE15Mode; + PORT_E16MuxType ePortE16Mode; + PORT_E17MuxType ePortE17Mode; + PORT_E18MuxType ePortE18Mode; + PORT_E19MuxType ePortE19Mode; + PORT_E20MuxType ePortE20Mode; + PORT_E21MuxType ePortE21Mode; + PORT_E22MuxType ePortE22Mode; + PORT_E23MuxType ePortE23Mode; + PORT_E24MuxType ePortE24Mode; + PORT_E25MuxType ePortE25Mode; + PORT_E26MuxType ePortE26Mode; + PORT_E27MuxType ePortE27Mode; + PORT_E29MuxType ePortE29Mode; + Port_PinModeType u32PortPinMode; +} Port_PinMuxType; + +/** @brief Port interrupt configuration */ +typedef enum +{ + PORT_IRQ_DISABLE = 0U, + PORT_IRQ_LOGIC_0 = 8U, + PORT_IRQ_RISING = 9U, + PORT_IRQ_FALLING = 10U, + PORT_IRQ_BOTH_EDGE = 11U, + PORT_IRQ_LOGIC_1 = 12U +} PORT_IntConfigType; + +/** @brief Port DMA request configuration */ +typedef enum +{ + PORT_DMA_REQ_DISABLE = 0U, + PORT_DMA_REQ_RISING = 1U, + PORT_DMA_REQ_FALLING = 2U, + PORT_DMA_REQ_BOTH_EDGE = 3U, +} PORT_DMAReqType; + +/** @brief Port digital filter clock source */ +typedef enum +{ + PORT_FILTER_BUS_CLK = 0U, + PORT_FILTER_AON32K_CLK, +} PORT_DigitalFilterClkSrcType; + +/** @brief Port pull status */ +typedef enum +{ + PORT_PULL_DOWN = 0U, + PORT_PULL_UP +} PORT_PullStatusType; + +/********* Local inline function ************/ +/** + * @brief Configure pin + * + * @param pPort Port instance + * @param u8Pin Pin number + * @param u32PcrReg Pin PCR register value + */ +LOCAL_INLINE void PORT_HWA_ConfigPin(PORT_Type *pPort, uint8_t u8Pin, uint32_t u32PcrReg) +{ + pPort->PCR[u8Pin] = u32PcrReg; +} + +/** + * @brief Configure Pin Domain Write Protection + * + * @param pPort Port instance + * @param u8Pin Pin number + * @param u32DwpValue Bit field value:Domain Write Protection + */ +LOCAL_INLINE void PORT_HWA_SelPinRegWrtPermit(PORT_Type *pPort, uint8_t u8Pin, uint32_t u32DwpValue) +{ + uint32_t u32TempRegVal = (uint32_t)(pPort->PCR[u8Pin]); + pPort->PCR[u8Pin] = (u32TempRegVal & (~ (uint32_t)PORT_PCR_DWP_MASK)) | PORT_PCR_DWP(u32DwpValue); +} + +/** + * @brief Configure Pin Domain Write Protection Lock + * + * @param pPort Port instance + * @param u8Pin Pin number + * @param bEnable Enable or Disable DWP Lock + */ +LOCAL_INLINE void PORT_HWA_ConfigPinDwpLock(PORT_Type *pPort, uint8_t u8Pin, bool bEnable) +{ + uint32_t u32TempRegVal = (uint32_t)(pPort->PCR[u8Pin]); + pPort->PCR[u8Pin] = (u32TempRegVal & (~ (uint32_t)PORT_PCR_DWPLK_MASK)) | PORT_PCR_DWPLK(bEnable); +} + +/** + * @brief Configure Pin Emergency Stop + * + * @param pPort Port instance + * @param u8Pin Pin number + * @param bEnable Enable or Disable Emergency Stop of this Pin + */ +LOCAL_INLINE void PORT_HWA_CfgPinEmgcyStop(PORT_Type *pPort, uint8_t u8Pin, bool bEnable) +{ + uint32_t u32TempRegVal = (uint32_t)(pPort->PCR[u8Pin]); + pPort->PCR[u8Pin] = (u32TempRegVal & (~ (uint32_t)PORT_PCR_ESTOP_MASK)) | PORT_PCR_ESTOP(bEnable); +} + +/** + * @brief Configure Global Domain Write Protection Lock + * + * @param pPort Port instance + * @param u8Pin Pin number + * @param bEnable Enable or Disable Global DWP Lock + */ +LOCAL_INLINE void PORT_HWA_CfgGlobalDwpLock(PORT_Type *pPort, bool bEnable) +{ + uint32_t u32TempRegVal = (uint32_t)(pPort->GLDWP); + pPort->GLDWP = (u32TempRegVal & (~ (uint32_t)PORT_GLDWP_DWPLK_MASK)) | PORT_GLDWP_DWPLK(bEnable); +} + +/** + * @brief Configure Global Domain Write Protection + * + * @param pPort Port instance + * @param u8Pin Pin number + * @param u32GlbDwpValue Bit field value:Global Domain Write Protection + */ +LOCAL_INLINE void PORT_HWA_CfgGlobalRegWrtPermit(PORT_Type *pPort, uint8_t u8Pin, uint32_t u32GlbDwpValue) +{ + uint32_t u32TempRegVal = (uint32_t)(pPort->PCR[u8Pin]); + pPort->GLDWP = (u32TempRegVal & (~ (uint32_t)PORT_GLDWP_DWP_MASK)) | PORT_GLDWP_DWP(u32GlbDwpValue); +} + +/** + * @brief Read pin interrupt flag + * + * @param pPort Port instance + * @param u8Pin Pin number + * @return interrupt flag value + */ +LOCAL_INLINE bool PORT_HWA_ReadPinInterruptFlag(PORT_Type *pPort, uint8_t u8Pin) +{ + return (bool)(pPort->PCR[u8Pin] & (uint32_t)PORT_PCR_ISF_MASK); +} + + +/** + * @brief Set pin multiplexing + * + * @param pPort Port instance + * @param u8Pin Pin number + * @param Port_PinMuxType Pin MXU configuration value + */ +LOCAL_INLINE void PORT_HWA_SetPinMux(PORT_Type *pPort, uint8_t u8Pin, Port_PinMuxType u32PinMux) +{ + uint32_t u32TempRegVal = (uint32_t)(pPort->PCR[u8Pin]); + pPort->PCR[u8Pin] = ((u32TempRegVal & ~(uint32_t)PORT_PCR_MUX_MASK) | PORT_PCR_MUX(u32PinMux.u32PortPinMode)); +} + +/** + * @brief Set pin interrupt mode + * + * @param pPort Port instance + * @param u8Pin Pin number + * @param u32PinIrqc Pin IRQC configuration value + */ +LOCAL_INLINE void PORT_HWA_SetPinInterruptMode(PORT_Type *pPort, uint8_t u8Pin, PORT_IntConfigType u32PinIrqc) +{ + uint32_t u32TempRegVal = (uint32_t)(pPort->PCR[u8Pin]); + pPort->PCR[u8Pin] = ((u32TempRegVal & ~(uint32_t)PORT_PCR_IRQC_MASK) | PORT_PCR_IRQC(u32PinIrqc)); +} + +/** + * @brief Set pin DMA request mode + * + * @param pPort Port instance + * @param u8Pin Pin number + * @param u32DMAReqMode Pin DMA request mode + */ +LOCAL_INLINE void PORT_HWA_SetPinDMAReqMode(PORT_Type *pPort, uint8_t u8Pin, PORT_DMAReqType u32DMAReqMode) +{ + uint32_t u32TempRegVal = (uint32_t)(pPort->PCR[u8Pin]); + pPort->PCR[u8Pin] = ((u32TempRegVal & ~(uint32_t)PORT_PCR_IRQC_MASK) | PORT_PCR_IRQC(u32DMAReqMode)); +} + +/** + * @brief Set pin pull enable + * + * @param pPort Port instance + * @param u8Pin Pin number + * @param u8PeValue Pin PE configuration value(1/0) + */ +LOCAL_INLINE void PORT_HWA_SetPinPullEnable(PORT_Type *pPort, uint8_t u8Pin, bool bPullEnable) +{ + if (bPullEnable) + { + pPort->PCR[u8Pin] |= (uint32_t)PORT_PCR_PE_MASK; + } + else + { + pPort->PCR[u8Pin] &= ~(uint32_t)PORT_PCR_PE_MASK; + } +} + +/** + * @brief Set pin pull mode + * + * @param pPort Port instance + * @param u8Pin Pin number + * @param u8PsValue Pin PS configuration value(1/0) + */ +LOCAL_INLINE void PORT_HWA_SetPinPullMode(PORT_Type *pPort, uint8_t u8Pin, PORT_PullStatusType u8PullSelect) +{ + uint32_t u32TempRegVal = (uint32_t)(pPort->PCR[u8Pin]); + pPort->PCR[u8Pin] = ((u32TempRegVal & ~(uint32_t)PORT_PCR_PS_MASK) | PORT_PCR_PS(u8PullSelect)); +} + +/** + * @brief Set pin drive strength 0 + * + * @param pPort Port instance + * @param u8Pin Pin number + * @note only hs PAD use this bit + */ +LOCAL_INLINE void PORT_HWA_EnablePinDriveStrength0(PORT_Type *pPort, uint8_t u8Pin) +{ + pPort->PCR[u8Pin] |= (uint32_t)PORT_PCR_DSE0_MASK; +} + +/** + * @brief Set pin drive strength 1 + * + * @param pPort Port instance + * @param u8Pin Pin number + * @note only UHS PAD use this bit + */ +LOCAL_INLINE void PORT_HWA_EnablePinDriveStrength1(PORT_Type *pPort, uint8_t u8Pin) +{ + pPort->PCR[u8Pin] |= (uint32_t)(PORT_PCR_DSE1_MASK | PORT_PCR_DSE0_MASK); +} + +/** + * @brief Set pin passive filter enable + * + * @param pPort Port instance + * @param u8Pin Pin number + * @param u8PfeValue Pin PFE configuration value(1/0) + */ +LOCAL_INLINE void PORT_HWA_SetPinPassiveFilterEnable(PORT_Type *pPort, uint8_t u8Pin, bool bPfEable) +{ + if (bPfEable) + { + pPort->PCR[u8Pin] |= (uint32_t)PORT_PCR_PFE_MASK; + } + else + { + pPort->PCR[u8Pin] &= ~(uint32_t)PORT_PCR_PFE_MASK; + } +} + +/** + * @brief Configure port digital filter + * + * @param pPort Port instance + * @param u32RegValue Enable bit,0-31 bit indicate pin 0-31 + */ +LOCAL_INLINE void PORT_HWA_ConfigDigitalFilter(PORT_Type *pPort, uint32_t u32RegValue) +{ + pPort->DFER = u32RegValue; +} + +/** + * @brief Set port digital filter enable + * + * @param pPort Port instance + * @param u8RegBit DFER register bit + */ +LOCAL_INLINE void PORT_HWA_SetDigitalFilterEnable(PORT_Type *pPort, uint8_t u8RegBit) +{ + pPort->DFER |= (uint32_t)1 << u8RegBit; +} + +/** + * @brief Set port digital filter clock source + * + * @param pPort Port instance + * @param eClkSrc Digital filter clock source + */ +LOCAL_INLINE void PORT_HWA_SetDigitalFilterClkSrc(PORT_Type *pPort, PORT_DigitalFilterClkSrcType eClkSrc) +{ + pPort->DFCR |= PORT_DFCR_CS(eClkSrc); +} + +/** + * @brief Configure digital filter width + * @param pPort Port instance + * @param u32FilterWidth Digital filter length value,range:0-31 + */ +LOCAL_INLINE void PORT_HWA_ConfigDigitalFilterWidth(PORT_Type *pPort, uint32_t u32FilterWidth) +{ + pPort->DFWR = PORT_DFWR_FILT(u32FilterWidth); +} + +/** + * @brief Clear pin interrupt mode + * + * @param pPort Port instance + * @param u8Pin Pin number + */ +LOCAL_INLINE void PORT_HWA_ClearPinInterruptMode(PORT_Type *pPort, uint8_t u8Pin) +{ + pPort->PCR[u8Pin] &= ~(uint32_t)PORT_PCR_IRQC_MASK; +} + +/** + * @brief Clear pin interrupt flag + * + * @param pPort Port instance + * @param u8Pin Pin number + */ +LOCAL_INLINE void PORT_HWA_ClearPinInterruptFlag(PORT_Type *pPort, uint8_t u8Pin) +{ + pPort->PCR[u8Pin] |= (uint32_t)PORT_PCR_ISF_MASK; +} + +/** + * @brief CLear port digital filter enable + * + * @param pPort Port instance + */ +LOCAL_INLINE void PORT_HWA_ClearDigitalFilterEnable(PORT_Type *pPort) +{ + pPort->DFER = (uint32_t)0U; +} + +/** + * @brief Clear port digital filter enable for specific pin + * + * @param pPort Port instance + * @param u8RegBit DFER register bit + */ +LOCAL_INLINE void PORT_HWA_ClearDigitalFilterPin(PORT_Type *pPort, uint8_t u8RegBit) +{ + pPort->DFER &= (uint32_t)~((uint32_t)1 << u8RegBit); +} + +/** + * @brief Clear port digital filter clock source + * + * @param pPort Port instance + */ +LOCAL_INLINE void PORT_HWA_ClearDigitalFilterClkSrc(PORT_Type *pPort) +{ + pPort->DFCR &= ~(uint32_t)PORT_DFCR_CS_MASK; +} + +/** + * @brief Clear port digital filter width + * + * @param pPort Port instance + */ +LOCAL_INLINE void PORT_HWA_ClearDigitalFilterWidth(PORT_Type *pPort) +{ + pPort->DFWR &= ~(uint32_t)PORT_DFWR_FILT_MASK; +} + +/** + * @brief Write Global Pin Control Low Register( Write Regvalue to bits[15:0] of PCR0 ~ 15 ) + * + * @param pPort Port instance + * @param u32Pin Port pin number + * @param u32LowPcrRegValue Register value in bits[15:0] of PCR0 ~ 15 + */ +LOCAL_INLINE void PORT_HWA_WriteGPCLR(PORT_Type *pPort,uint32_t u32Pin,uint32_t u32LowPcrRegValue) +{ + pPort->GPCLR = PORT_GPCLR_GPWE(u32Pin) | PORT_GPCLR_GPWD(u32LowPcrRegValue); +} + +/** + * @brief Write Global Pin Control High Register( Write Regvalue to bits[15:0] of PCR16 ~ 31 ) + * + * @param pPort Port instance + * @param u32Pin Port pin number + * @param u32LowPcrRegValue Register value in bits[15:0] of PCR16 ~ 31 + */ +LOCAL_INLINE void PORT_HWA_WriteGPCHR(PORT_Type *pPort,uint32_t u32Pin,uint32_t u32LowPcrRegValue) +{ + pPort->GPCHR = (u32Pin & PORT_GPCHR_GPWE_MASK) | PORT_GPCHR_GPWD(u32LowPcrRegValue); +} + +/** + * @brief Write Global Interrupt Control Low Register( Write Regvalue to bits[31:16] of PCR0 ~ 15 ) + * + * @param pPort Port instance + * @param u32Pin Port pin number + * @param u32HighPcrRegValue Register value in bits[31:16] of PCR0 ~ 15 + */ +LOCAL_INLINE void PORT_HWA_WriteGICLR(PORT_Type *pPort,uint32_t u32Pin,uint32_t u32HighPcrRegValue) +{ + pPort->GICLR = (u32HighPcrRegValue & PORT_GICLR_GIWD_MASK) | PORT_GICLR_GIWE(u32Pin); +} + +/** + * @brief Write Global Interrupt Control High Register( Write Regvalue to bits[31:16] of PCR16 ~ 31 ) + * + * @param pPort Port instance + * @param u32Pin Port pin number + * @param u32HighPcrRegValue Register value in bits[31:16] of PCR16 ~ 31 + */ +LOCAL_INLINE void PORT_HWA_WriteGICHR(PORT_Type *pPort,uint32_t u32Pin,uint32_t u32HighPcrRegValue) +{ + pPort->GICHR = (u32HighPcrRegValue & PORT_GICHR_GIWD_MASK) & PORT_GICHR_GIWE(u32Pin); +} + + +#endif /* #ifndef _HWA_PORT_H_ */ diff --git a/MODULES/HwA_Flagchip_FC7240/Inc/HwA_ptimer.h b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_ptimer.h new file mode 100644 index 0000000..3e7dbfc --- /dev/null +++ b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_ptimer.h @@ -0,0 +1,701 @@ +/** + * @file HwA_ptimer.h + * @author Flagchip0126 + * @brief Hardware access layer for PTIMER + * @version 0.1.0 + * @date 2024-01-15 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-01-15 Flagchip0126 N/A First version for FC7240 + ******************************************************************************** */ + +#ifndef _HWA_PTIMER_H_ +#define _HWA_PTIMER_H_ + +#include "device_header.h" + +/** + * @defgroup HwA_ptimer + * @ingroup fc4xxx_driver_ptimer + * @{ + */ + +/** + * @brief Ptimer value load mode + * + * Some Ptimer registers are buffered and will only take effect after called + * PTIMER_LoadValue() function, and this option selects when the buffered configurations + * will tack effect after PTIMER_LoadValue() is called. + * + */ +typedef enum +{ + PTIMER_LOAD_VAL_IMMEDIATELY = 0U, + /*!< Loaded immediately after load operation. */ + PTIMER_LOAD_VAL_AT_MODULO_COUNTER = 1U, + /*!< Loaded when counter hits the max count after load operation. */ + PTIMER_LOAD_VAL_AT_NEXT_TRIGGER = 2U, + /*!< Loaded when detecting an input trigger after load operation. */ + PTIMER_LOAD_VAL_AT_MODULO_COUNTER_OR_NEXT_TRIGGER = 3U + /*!< Loaded when counter hits the max count or detecting an input trigger after load operation. */ +} PTIMER_LoadValueModeType; + +/** + * @brief Ptimer clock pre-divider factor + * + * The Ptimer clock source is from core clock and the divider is a multiplication of + * PTIMER_ClockPreDividerType and PTIMER_ClockPreDivMultiplyFactorType, and thus: + * Freq = Core_Freq / (PTIMER_ClockPreDividerType * PTIMER_ClockPreDivMultiplyFactorType) + * + */ +typedef enum +{ + PTIMER_PRE_DIVIDE_BY_1 = 0U, + PTIMER_PRE_DIVIDE_BY_2 = 1U, + PTIMER_PRE_DIVIDE_BY_4 = 2U, + PTIMER_PRE_DIVIDE_BY_8 = 3U, + PTIMER_PRE_DIVIDE_BY_16 = 4U, + PTIMER_PRE_DIVIDE_BY_32 = 5U, + PTIMER_PRE_DIVIDE_BY_64 = 6U, + PTIMER_PRE_DIVIDE_BY_128 = 7U +} PTIMER_ClockPreDividerType; + +/** + * @brief Ptimer clock divider multiplication factor + * + * The Ptimer clock source is from core clock and the divider is a multiplication of + * PTIMER_ClockPreDividerType and PTIMER_ClockPreDivMultiplyFactorType, and thus: + * Freq = Core_Freq / (PTIMER_ClockPreDividerType * PTIMER_ClockPreDivMultiplyFactorType) + * + */ +typedef enum +{ + PTIMER_PRE_DIVIDER_MULTIPLY_BY_1 = 0U, + PTIMER_PRE_DIVIDER_MULTIPLY_BY_10 = 1U, + PTIMER_PRE_DIVIDER_MULTIPLY_BY_20 = 2U, + PTIMER_PRE_DIVIDER_MULTIPLY_BY_40 = 3U +} PTIMER_ClockPreDivMultiplyFactorType; + +/** + * @brief Ptimer trigger source + * + */ +typedef enum +{ + PTIMER_TRGSRC_TRGSEL = 0x00U, /*!< Ptimer trigger source from TrgSel */ + PTIMER_TRGSRC_SW = 0x0FU /*!< Ptimer trigger source from software trigger*/ +} PTIMER_TrgSrcType; + +/** + * @brief Get the STATUS_CTRL register value + * + * @param pPtimer the base address of the Ptimer instance + */ +LOCAL_INLINE uint32_t PTIMER_HWA_GetStatusCtrl(const PTIMER_Type *const pPtimer) +{ + return pPtimer->STATUS_CTRL; +} + +/** + * @brief Set the STATUS_CTRL register value + * + * @param pPtimer the base address of the Ptimer instance + * @param u32CfgValue the register value to set + */ +LOCAL_INLINE void PTIMER_HWA_SetStatusCtrl(PTIMER_Type *const pPtimer, uint32_t u32CfgValue) +{ + pPtimer->STATUS_CTRL = u32CfgValue; +} + +/** + * @brief Get the load mode of the Ptimer instance + * + * @param pPtimer the base address of the Ptimer instance + * @return PTIMER_LoadValueModeType the load mode of the Ptimer instance + */ +LOCAL_INLINE PTIMER_LoadValueModeType PTIMER_HWA_GetLoadMode(const PTIMER_Type *const pPtimer) +{ + uint32_t u32TmpVal = (pPtimer->STATUS_CTRL & PTIMER_STATUS_CTRL_LDMODE_MASK) >> PTIMER_STATUS_CTRL_LDMODE_SHIFT; + return (PTIMER_LoadValueModeType)u32TmpVal; +} + +/** + * @brief Set the load mode of the Ptimer instance + * + * @param pPtimer the base address of the Ptimer instance + * @param eLoadMode the load mode of the Ptimer instance + */ +LOCAL_INLINE void PTIMER_HWA_SetLoadMode(PTIMER_Type *const pPtimer, PTIMER_LoadValueModeType eLoadMode) +{ + pPtimer->STATUS_CTRL = (pPtimer->STATUS_CTRL & ~PTIMER_STATUS_CTRL_LDMODE_MASK) | PTIMER_STATUS_CTRL_LDMODE(eLoadMode); +} + +/** + * @brief Get whether sequence error interrupt is enabled + * + * @param pPtimer the base address of the Ptimer instance + * @return true sequence error interrupt is enabled + * @return false sequence error interrupt is disabled + */ +LOCAL_INLINE bool PTIMER_HWA_GetSeqErrIntEnableFlag(const PTIMER_Type *const pPtimer) +{ + uint32_t u32TmpVal = (pPtimer->STATUS_CTRL & PTIMER_STATUS_CTRL_SERR_INTEN_MASK) >> PTIMER_STATUS_CTRL_SERR_INTEN_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Set whether to enable sequence error interrupt + * + * @param pPtimer the base address of the Ptimer instance + * @param bEnable whether to enable sequence error interrupt + */ +LOCAL_INLINE void PTIMER_HWA_SetSeqErrIntEnableFlag(PTIMER_Type *const pPtimer, bool bEnable) +{ + pPtimer->STATUS_CTRL = (pPtimer->STATUS_CTRL & ~PTIMER_STATUS_CTRL_SERR_INTEN_MASK) | PTIMER_STATUS_CTRL_SERR_INTEN( + bEnable ? 1U : 0U); +} + +/** + * @brief Generate software trigger signal for Ptimer instance + * + * @param pPtimer the base address of the Ptimer instance + */ +LOCAL_INLINE void PTIMER_HWA_GenerateSwTrigger(PTIMER_Type *const pPtimer) +{ + pPtimer->STATUS_CTRL |= PTIMER_STATUS_CTRL_SWTRG_MASK; +} + +/** + * @brief Get whether DMA is enabled for the Ptimer insstance + * + * @param pPtimer the base address of the Ptimer instance + * @return true DMA is enabled + * @return false DMA is disabled + */ +LOCAL_INLINE bool PTIMER_HWA_GetDMAEnableFlag(const PTIMER_Type *const pPtimer) +{ + uint32_t u32TmpVal = (pPtimer->STATUS_CTRL & PTIMER_STATUS_CTRL_DMAEN_MASK) >> PTIMER_STATUS_CTRL_DMAEN_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Set whether to enable Ptimer DMA + * + * @param pPtimer the base address of the Ptimer instance + * @param bEnable whether to enable DMA for the Ptimer instance + */ +LOCAL_INLINE void PTIMER_HWA_SetDMAEnableFlag(PTIMER_Type *const pPtimer, bool bEnable) +{ + pPtimer->STATUS_CTRL = (pPtimer->STATUS_CTRL & ~PTIMER_STATUS_CTRL_DMAEN_MASK) | PTIMER_STATUS_CTRL_DMAEN(bEnable ? 1U : 0U); +} + +/** + * @brief Get the predivider value of the Ptimer instance + * + * @param pPtimer the base address of the Ptimer instance + * @return PTIMER_ClockPreDividerType the predivider of the Ptimer instance + */ +LOCAL_INLINE PTIMER_ClockPreDividerType PTIMER_HWA_GetDivPrescaler(const PTIMER_Type *const pPtimer) +{ + uint32_t u32TmpVal = (pPtimer->STATUS_CTRL & PTIMER_STATUS_CTRL_PRESCALER_MASK) >> PTIMER_STATUS_CTRL_PRESCALER_SHIFT; + return (PTIMER_ClockPreDividerType)u32TmpVal; +} + +/** + * @brief Set the predivider value of the Ptimer instance + * + * @param pPtimer the base address of the Ptimer instance + * @param eDivPrescaler the predivider of the Ptimer instance + */ +LOCAL_INLINE void PTIMER_HWA_SetDivPrescaler(PTIMER_Type *const pPtimer, PTIMER_ClockPreDividerType eDivPrescaler) +{ + pPtimer->STATUS_CTRL = (pPtimer->STATUS_CTRL & ~PTIMER_STATUS_CTRL_PRESCALER_MASK) | PTIMER_STATUS_CTRL_PRESCALER( + eDivPrescaler); +} + +/** + * @brief Get the trigger source of the Ptimer instance + * + * @param pPtimer the base address of the Ptimer instance + * @return PTIMER_TRGSRC_TRGSEL the trigger source is from TrgSel + * @return PTIMER_TRGSRC_SW the trigger source is from software + */ +LOCAL_INLINE PTIMER_TrgSrcType PTIMER_HWA_GetTriggerSource(const PTIMER_Type *const pPtimer) +{ + uint32_t u32TmpVal = (pPtimer->STATUS_CTRL & PTIMER_STATUS_CTRL_TRGSEL_MASK) >> PTIMER_STATUS_CTRL_TRGSEL_SHIFT; + return (PTIMER_TrgSrcType)u32TmpVal; +} + +/** + * @brief Set the trigger source of the Ptimer instance + * + * @param pPtimer the base address of the Ptimer instance + * @param eTriggerSource the trigger source of the Ptimer instance + */ +LOCAL_INLINE void PTIMER_HWA_SetTriggerSource(PTIMER_Type *const pPtimer, PTIMER_TrgSrcType eTriggerSource) +{ + pPtimer->STATUS_CTRL = (pPtimer->STATUS_CTRL & ~PTIMER_STATUS_CTRL_TRGSEL_MASK) | PTIMER_STATUS_CTRL_TRGSEL( + eTriggerSource); +} + +/** + * @brief Get whether the Ptimer instance is enabled + * + * @param pPtimer the base address of the Ptimer instance + * @return true the Ptimer instance is enabled + * @return false the Ptimer instance is disabled + */ +LOCAL_INLINE bool PTIMER_HWA_GetEnableFlag(const PTIMER_Type *const pPtimer) +{ + uint32_t u32TmpVal = (pPtimer->STATUS_CTRL & PTIMER_STATUS_CTRL_ENABLE_MASK) >> PTIMER_STATUS_CTRL_ENABLE_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Enable the Ptimer instance + * + * @param pPtimer the base address of the Ptimer instance + */ +LOCAL_INLINE void PTIMER_HWA_Enable(PTIMER_Type *const pPtimer) +{ + pPtimer->STATUS_CTRL |= PTIMER_STATUS_CTRL_ENABLE_MASK; +} + +/** + * @brief Disable the Ptimer instance + * + * @param pPtimer the base address of the Ptimer instance + */ +LOCAL_INLINE void PTIMER_HWA_Disable(PTIMER_Type *const pPtimer) +{ + pPtimer->STATUS_CTRL &= ~PTIMER_STATUS_CTRL_ENABLE_MASK; +} + +/** + * @brief Get the delay interrupt flag of the Ptimer instance + * + * @param pPtimer the base address of the Ptimer instance + * @return true the delay interrupt flag of the Ptimer instance is generated + * @return false the delay interrupt flag of the Ptimer instance is not generated + */ +LOCAL_INLINE bool PTIMER_HWA_GetInterruptFlag(const PTIMER_Type *const pPtimer) +{ + uint32_t u32TmpVal = (pPtimer->STATUS_CTRL & PTIMER_STATUS_CTRL_INTFLAG_MASK) >> PTIMER_STATUS_CTRL_INTFLAG_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Clear the delay interrupt flag of the Ptimer instance + * + * @param pPtimer the base address of the Ptimer instance + */ +LOCAL_INLINE void PTIMER_HWA_ClearInterruptFlag(PTIMER_Type *const pPtimer) +{ + pPtimer->STATUS_CTRL &= ~PTIMER_STATUS_CTRL_INTFLAG_MASK; +} + +/** + * @brief Get whether delay interrupt is enabled for the Ptimer instance + * + * @param pPtimer the base address of the Ptimer instance + */ +LOCAL_INLINE bool PTIMER_HWA_GetInterruptEnableFlag(const PTIMER_Type *const pPtimer) +{ + uint32_t u32TmpVal = (pPtimer->STATUS_CTRL & PTIMER_STATUS_CTRL_INTEN_MASK) >> PTIMER_STATUS_CTRL_INTEN_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Set whether to enable delay interrupt for the Ptimer instance + * + * @param pPtimer the base address of the Ptimer instance + * @param bEnable whether to enable delay interrupt for the Ptimer instance + */ +LOCAL_INLINE void PTIMER_HWA_SetInterruptEnableFlag(PTIMER_Type *const pPtimer, bool bEnable) +{ + pPtimer->STATUS_CTRL = (pPtimer->STATUS_CTRL & ~PTIMER_STATUS_CTRL_INTEN_MASK) | PTIMER_STATUS_CTRL_INTEN(bEnable ? 1U : 0U); +} + +/** + * @brief Get the multiply factor of the predivider of the Ptimer instance + * + * @param pPtimer the base address of the Ptimer instance + * @return PTIMER_ClockPreDivMultiplyFactorType the multiply factor of the Ptimer instance + */ +LOCAL_INLINE PTIMER_ClockPreDivMultiplyFactorType PTIMER_HWA_GetDivMultiply(const PTIMER_Type *const pPtimer) +{ + uint32_t u32TmpVal = (pPtimer->STATUS_CTRL & PTIMER_STATUS_CTRL_MULT_MASK) >> PTIMER_STATUS_CTRL_MULT_SHIFT; + return (PTIMER_ClockPreDivMultiplyFactorType)u32TmpVal; +} + +/** + * @brief Set the multiply factor of the predivider of the Ptimer instance + * + * @param pPtimer the base address of the Ptimer instance + * @param eMultFactor the multiply factor of the Ptimer instance + */ +LOCAL_INLINE void PTIMER_HWA_SetDivMultiply(PTIMER_Type *const pPtimer, + PTIMER_ClockPreDivMultiplyFactorType eMultFactor) +{ + pPtimer->STATUS_CTRL = (pPtimer->STATUS_CTRL & ~PTIMER_STATUS_CTRL_MULT_MASK) | PTIMER_STATUS_CTRL_MULT(eMultFactor); +} + +/** + * @brief Get whether continuous mode is enabled for the Ptimer instance + * + * @param pPtimer the base address of the Ptimer instance + * @return true continuous mode is enabled for the Ptimer instance + * @return false continuous mode is disabled for the Ptimer instance + */ +LOCAL_INLINE bool PTIMER_HWA_GetContinuoiusModeFlag(const PTIMER_Type *const pPtimer) +{ + uint32_t u32TmpVal = (pPtimer->STATUS_CTRL & PTIMER_STATUS_CTRL_CONT_MASK) >> PTIMER_STATUS_CTRL_CONT_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Set whether to enable continuous mode for the Ptimer instance + * + * @param pPtimer the base address of the Ptimer instance + * @param bEnable whether to enable continuous mode for the Ptimer instance + */ +LOCAL_INLINE void PTIMER_HWA_SetContinuoiusModeFlag(PTIMER_Type *const pPtimer, bool bEnable) +{ + pPtimer->STATUS_CTRL = (pPtimer->STATUS_CTRL & ~PTIMER_STATUS_CTRL_CONT_MASK) | PTIMER_STATUS_CTRL_CONT(bEnable ? 1U : 0U); +} + +/** + * @brief Get the config value loading status + * + * @param pPtimer the base address of the Ptimer instance + * @return true the config values are in loading status + * @return false the config values are loaded + */ +LOCAL_INLINE bool PTIMER_HWA_GetValueLoadStatus(const PTIMER_Type *const pPtimer) +{ + uint32_t u32TmpVal = (pPtimer->STATUS_CTRL & PTIMER_STATUS_CTRL_LDOK_MASK) >> PTIMER_STATUS_CTRL_LDOK_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Load the buffered values into register + * + * @note Some Ptimer registers are buffered and will only take effect after called + * this function + * + * @param pPtimer the base address of the Ptimer instance + */ +LOCAL_INLINE void PTIMER_HWA_LoadValue(PTIMER_Type *const pPtimer) +{ + pPtimer->STATUS_CTRL |= PTIMER_STATUS_CTRL_LDOK_MASK; +} + +/** + * @brief Get the Ptimer max counter period + * When the Ptimer counter reaches the period, it will return to zero + * + * @param pPtimer the base address of the Ptimer instance + * @return uint16_t the Ptimer max count + */ +LOCAL_INLINE uint16_t PTIMER_HWA_GetMaxCount(const PTIMER_Type *const pPtimer) +{ + uint32_t u32TmpVal = (pPtimer->MAX_CNT & PTIMER_MAX_CNT_MAX_CNT_MASK) >> PTIMER_MAX_CNT_MAX_CNT_SHIFT; + return (uint16_t)u32TmpVal; +} + +/** + * @brief Set the Ptimer max counter period + * When the Ptimer counter reaches the period, it will return to zero + * + * @note the period parameter is buffered and will take effect only after called PTIMER_LoadValue() + * function. + * + * @param pPtimer the base address of the Ptimer instance + * @param u16MaxCnt the Ptimer max count + */ +LOCAL_INLINE void PTIMER_HWA_SetMaxCount(PTIMER_Type *const pPtimer, uint16_t u16MaxCnt) +{ + pPtimer->MAX_CNT = PTIMER_MAX_CNT_MAX_CNT(u16MaxCnt); +} + +/** + * @brief Get the Ptimer current count value + * + * @param pPtimer the base address of the Ptimer instance + * @return uint16_t the Ptimer current count value + */ +LOCAL_INLINE uint16_t PTIMER_HWA_GetCounterValue(const PTIMER_Type *const pPtimer) +{ + uint32_t u32TmpVal = (pPtimer->CNT & PTIMER_CNT_CNT_MASK) >> PTIMER_CNT_CNT_SHIFT; + return (uint16_t)u32TmpVal; +} + +/** + * @brief Get the ptimer interrupt period + * + * @param pPtimer the base address of the Ptimer instance + * @return uint16_t the Ptimer interrupt period + */ +LOCAL_INLINE uint16_t PTIMER_HWA_GetInterruptDelay(const PTIMER_Type *const pPtimer) +{ + uint32_t u32TmpVal = (pPtimer->INT_DLY & PTIMER_INT_DLY_INT_DLY_MASK) >> PTIMER_INT_DLY_INT_DLY_SHIFT; + return (uint16_t)u32TmpVal; +} + +/** + * @brief Set the ptimer interrupt period + * + * @param pPtimer the base address of the Ptimer instance + * @param u16InterruptDelay the Ptimer interrupt period + */ +LOCAL_INLINE void PTIMER_HWA_SetInterruptDelay(PTIMER_Type *const pPtimer, uint16_t u16InterruptDelay) +{ + pPtimer->INT_DLY = PTIMER_INT_DLY_INT_DLY(u16InterruptDelay); +} + +/** + * @brief Get whether back to back trigger is enbaled for the Ptimer channel + * + * @param pPtimer the base address of the Ptimer instance + * @param u8Channel the Ptimer channel + * @return true back to back trigger is enbaled for the Ptimer channel + * @return false back to back trigger is disabled for the Ptimer channel + */ +LOCAL_INLINE bool PTIMER_HWA_GetChannelBackToBackFlag(const PTIMER_Type *const pPtimer, uint8_t u8Channel) +{ + uint8_t u8PtimerChannelIdx = u8Channel / 8U; + uint8_t u8PtimerCtrlIdx = u8Channel % 8U; + uint32_t u32TmpVal = (pPtimer->CH[u8PtimerChannelIdx].CTRL & PTIMER_CTRL_CH_BTB(1UL << u8PtimerCtrlIdx)) >> + (PTIMER_CTRL_CH_BTB_SHIFT + u8PtimerCtrlIdx); + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get whether pre-trigger output is enbaled for the Ptimer channel + * + * @param pPtimer the base address of the Ptimer instance + * @param u8Channel the Ptimer channel + * @return true pre-trigger output is enbaled for the Ptimer channel + * @return false pre-trigger output is disabled for the Ptimer channel + */ +LOCAL_INLINE bool PTIMER_HWA_GetChannelPretriggerOutputFlag(const PTIMER_Type *const pPtimer, uint8_t u8Channel) +{ + uint8_t u8PtimerChannelIdx = u8Channel / 8U; + uint8_t u8PtimerCtrlIdx = u8Channel % 8U; + uint32_t u32TmpVal = (pPtimer->CH[u8PtimerChannelIdx].CTRL & PTIMER_CTRL_CH_PTOS(1UL << u8PtimerCtrlIdx)) >> + (PTIMER_CTRL_CH_PTOS_SHIFT + u8PtimerCtrlIdx); + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get whether pre-trigger is enbaled for the Ptimer channel + * + * @param pPtimer the base address of the Ptimer instance + * @param u8Channel the Ptimer channel + * @return true pre-trigger is enbaled for the Ptimer channel + * @return false pre-trigger is disabled for the Ptimer channel + */ +LOCAL_INLINE bool PTIMER_HWA_GetChannelPretriggerEnableFlag(const PTIMER_Type *const pPtimer, uint8_t u8Channel) +{ + uint8_t u8PtimerChannelIdx = u8Channel / 8U; + uint8_t u8PtimerCtrlIdx = u8Channel % 8U; + uint32_t u32TmpVal = (pPtimer->CH[u8PtimerChannelIdx].CTRL & PTIMER_CTRL_CH_PTEN(1UL << u8PtimerCtrlIdx)) >> + (PTIMER_CTRL_CH_PTEN_SHIFT + u8PtimerCtrlIdx); + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Set the Ptimer channel control flags + * + * @param pPtimer the base address of the Ptimer instance + * @param u8Channel the Ptimer channel + * @param bEnablePretrigger whether to enable pre-trigger + * @param bEnablePretriggerOutput whether to enable pre-trigger output + * @param bEnableBackToBack whether to enable back to back trigger + */ +LOCAL_INLINE void PTIMER_HWA_SetChannelControl(PTIMER_Type *const pPtimer, uint8_t u8Channel, bool bEnablePretrigger, + bool bEnablePretriggerOutput, bool bEnableBackToBack) +{ + uint8_t u8PtimerChannelIdx = u8Channel / 8U; + uint8_t u8PtimerCtrlIdx = u8Channel % 8U; + uint32_t u32CtrlMask = PTIMER_CTRL_CH_PTEN(1UL << u8PtimerCtrlIdx) | + PTIMER_CTRL_CH_PTOS(1UL << u8PtimerCtrlIdx) | + PTIMER_CTRL_CH_BTB(1UL << u8PtimerCtrlIdx); + pPtimer->CH[u8PtimerChannelIdx].CTRL = (pPtimer->CH[u8PtimerChannelIdx].CTRL & ~u32CtrlMask) | + PTIMER_CTRL_CH_PTEN((bEnablePretrigger ? 1UL : 0UL) << u8PtimerCtrlIdx) | + PTIMER_CTRL_CH_PTOS((bEnablePretriggerOutput ? 1UL : 0UL) << u8PtimerCtrlIdx) | + PTIMER_CTRL_CH_BTB((bEnableBackToBack ? 1UL : 0UL) << u8PtimerCtrlIdx); +} + +/** + * @brief Get whether the Ptimer counter matches the channel counter + * + * @param pPtimer the base address of the Ptimer instance + * @param u8Channel the Ptimer channel + * @return true the Ptimer counter matches the channel counter + * @return false the Ptimer counter has not reached the channel counter + */ +LOCAL_INLINE bool PTIMER_HWA_GetChannelCounterFlag(const PTIMER_Type *const pPtimer, uint8_t u8Channel) +{ + uint8_t u8PtimerChannelIdx = u8Channel / 8U; + uint8_t u8PtimerStatusIdx = u8Channel % 8U; + uint32_t u32TmpVal = (pPtimer->CH[u8PtimerChannelIdx].STATUS & PTIMER_STATUS_CH_CHN_FLAG(1UL << u8PtimerStatusIdx)) >> + (PTIMER_STATUS_CH_CHN_FLAG_SHIFT + u8PtimerStatusIdx); + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Clear the Ptimer channel counter match flag + * + * @param pPtimer the base address of the Ptimer instance + * @param u8Channel the Ptimer channel + */ +LOCAL_INLINE void PTIMER_HWA_ClearChannelCounterFlag(PTIMER_Type *const pPtimer, uint8_t u8Channel) +{ + uint8_t u8PtimerChannelIdx = u8Channel / 8U; + uint8_t u8PtimerStatusIdx = u8Channel % 8U; + pPtimer->CH[u8PtimerChannelIdx].STATUS &= ~PTIMER_STATUS_CH_CHN_FLAG(1UL << u8PtimerStatusIdx); +} + +/** + * @brief Get the sequence error status of the Ptimer instance + * + * @param pPtimer the base address of the Ptimer instance + * @param u8Channel the channel related to the sequence error + * @return true the selected channel has sequence error + * @return false the selected channel does not have sequence error + */ +LOCAL_INLINE bool PTIMER_HWA_GetChannelSequenceErrorFlag(const PTIMER_Type *const pPtimer, uint8_t u8Channel) +{ + uint8_t u8PtimerChannelIdx = u8Channel / 8U; + uint8_t u8PtimerStatusIdx = u8Channel % 8U; + uint32_t u32TmpVal = (pPtimer->CH[u8PtimerChannelIdx].STATUS & PTIMER_STATUS_CH_SERR_FLAG(1UL << u8PtimerStatusIdx)) >> + (PTIMER_STATUS_CH_SERR_FLAG_SHIFT + u8PtimerStatusIdx); + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Clear the sequence error flag of the selected Ptimer channel + * + * @param pPtimer the base address of the Ptimer instance + * @param u8Channel the Ptimer channel to clear the sequence error flag + */ +LOCAL_INLINE void PTIMER_HWA_ClearChannelSequenceErrorFlag(PTIMER_Type *const pPtimer, uint8_t u8Channel) +{ + uint8_t u8PtimerChannelIdx = u8Channel / 8U; + uint8_t u8PtimerStatusIdx = u8Channel % 8U; + pPtimer->CH[u8PtimerChannelIdx].STATUS &= ~PTIMER_STATUS_CH_SERR_FLAG(1UL << u8PtimerStatusIdx); +} + +/** + * @brief Get the channel delay value + * + * @param pPtimer the base address of the Ptimer instance + * @param u8Channel the Ptimer channel + * @return uint16_t the channel delay value + */ +LOCAL_INLINE uint16_t PTIMER_HWA_GetChannelDelay(const PTIMER_Type *const pPtimer, uint8_t u8Channel) +{ + uint8_t u8PtimerChannelIdx = u8Channel / PTIMER_CH_DLY_CNT; + uint8_t u8PtimerDelayIdx = u8Channel % PTIMER_CH_DLY_CNT; + uint32_t u32TmpVal = (pPtimer->CH[u8PtimerChannelIdx].DLY[u8PtimerDelayIdx] & PTIMER_DLY_CH_CHNDLY_MASK) >> + PTIMER_DLY_CH_CHNDLY_SHIFT; + return (uint16_t)u32TmpVal; +} + +/** + * @brief Set the channel delay value + * + * @param pPtimer the base address of the Ptimer instance + * @param u8Channel the Ptimer channel + * @param u16Delay the channel delay value + */ +LOCAL_INLINE void PTIMER_HWA_SetChannelDelay(PTIMER_Type *const pPtimer, uint8_t u8Channel, uint16_t u16Delay) +{ + uint8_t u8PtimerChannelIdx = u8Channel / PTIMER_CH_DLY_CNT; + uint8_t u8PtimerDelayIdx = u8Channel % PTIMER_CH_DLY_CNT; + pPtimer->CH[u8PtimerChannelIdx].DLY[u8PtimerDelayIdx] = PTIMER_DLY_CH_CHNDLY(u16Delay); +} + +/** + * @brief Get whether pulse-out is enabled + * + * @param pPtimer the base address of the Ptimer instance + * @return true pulse-out is enabled + * @return false pulse-out is disabled + */ +LOCAL_INLINE bool PTIMER_HWA_GetPulseOutEnableFlag(const PTIMER_Type *const pPtimer) +{ + uint32_t u32TmpVal = (pPtimer->POEN & PTIMER_POEN_POEN_MASK) >> PTIMER_POEN_POEN_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Enable pulse-out for the Ptimer instance + * + * @param pPtimer the base address of the Ptimer instance + */ +LOCAL_INLINE void PTIMER_HWA_EnablePulseOut(PTIMER_Type *const pPtimer) +{ + pPtimer->POEN |= PTIMER_POEN_POEN_MASK; +} + +/** + * @brief Disable pulse-out for the Ptimer instance + * + * @param pPtimer the base address of the Ptimer instance + */ +LOCAL_INLINE void PTIMER_HWA_DisablePulseOut(PTIMER_Type *const pPtimer) +{ + pPtimer->POEN &= ~PTIMER_POEN_POEN_MASK; +} + +/** + * @brief Get the delay high value for the pulse-out function + * When the Ptimer counter reach the delay high value, the pulse output goes high + * + * @param pPtimer the base address of the Ptimer instance + */ +LOCAL_INLINE uint16_t PTIMER_HWA_GetPulseOutDelayHigh(const PTIMER_Type *const pPtimer) +{ + uint32_t u32TmpVal = (pPtimer->PODLY & PTIMER_PODLY_DLY1_MASK) >> PTIMER_PODLY_DLY1_SHIFT; + return (uint16_t)u32TmpVal; +} + +/** + * @brief Get the delay low value for the pulse-out function + * When the Ptimer counter reach the delay low value, the pulse output goes low + * + * @param pPtimer the base address of the Ptimer instance + */ +LOCAL_INLINE uint16_t PTIMER_HWA_GetPulseOutDelayLow(const PTIMER_Type *const pPtimer) +{ + uint32_t u32TmpVal = (pPtimer->PODLY & PTIMER_PODLY_DLY2_MASK) >> PTIMER_PODLY_DLY2_SHIFT; + return (uint16_t)u32TmpVal; +} + +/** + * @brief Set the pulse out delay value + * When the Ptimer counter reach the delay high value, the pulse output goes high + * When the Ptimer counter reach the delay low value, the pulse output goes low + * The delay high value can be either greater or less than the delay low value + * + * @param pPtimer the base address of the Ptimer instance + * @param u16DelayHigh the delay high value + * @param u16DelayLow the delay low value + */ +LOCAL_INLINE void PTIMER_HWA_SetPulseOutDelay(PTIMER_Type *const pPtimer, uint16_t u16DelayHigh, uint16_t u16DelayLow) +{ + pPtimer->PODLY = PTIMER_PODLY_DLY1(u16DelayHigh) | PTIMER_PODLY_DLY2(u16DelayLow); +} + +/** @}*/ + +#endif /* _HWA_PTIMER_H_ */ diff --git a/MODULES/HwA_Flagchip_FC7240/Inc/HwA_rgm.h b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_rgm.h new file mode 100644 index 0000000..22ccab7 --- /dev/null +++ b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_rgm.h @@ -0,0 +1,427 @@ +/** + * @file HwA_rgm.h + * @author Flagchip + * @brief FC7xxx RGM hardware access layer + * @version 0.1.0 + * @date 2024-01-12 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + * @details + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-01-12 Flagchip119 N/A First version for FC7240 + ******************************************************************************** */ + +#ifndef _HWA_RGM_H_ +#define _HWA_RGM_H_ + +#include "device_header.h" +/********* Local typedef ************/ +/** @brief Rgm reset event */ +typedef enum +{ + RGM_WAKEUP = 0x00000001U, + RGM_LVD = 0x00000002U, + RGM_CLKERR1 = 0x00000004U, + RGM_CLKERR0 = 0x00000008U, + RGM_FSCMU = 0x00000010U, + RGM_HSMWDOG = 0x00000020U, + RGM_PIN = 0x00000040U, + RGM_POR = 0x00000080U, + RGM_JTAG = 0x00000100U, + RGM_SYSAP = 0x00000800U, + RGM_WDOG1 = 0x00001000U, + RGM_SACKERR = 0x00002000U, + RGM_CMU = 0x00004000U, + RGM_LBIST = 0x00008000U, + RGM_FSMERR = 0x20000000U, + RGM_PINRSTTOUT = 0x40000000U, + RGM_SYSRSTTOUT = 0x80000000U +} RGM_ResetEventType; + +/** @brief Rgm reset interrupt delay cycles type. */ +typedef enum +{ + RGM_8_CLOCK_CYCLES = 0x00U, + RGM_32_CLOCK_CYCLES = 0x01U, + RGM_128_CLOCK_CYCLES = 0x02U, + RGM_512_CLOCK_CYCLES = 0x03U +} RGM_ResetDelayType; + +/** @brief Rgm reset interrupt event manger */ +typedef enum +{ + RGM_INT_CLKERR0 = 0x0008U, + RGM_INT_FCSMU = 0x0010U, + RGM_INT_WDG = 0x0020U, + RGM_INT_PIN = 0x0040U, + RGM_INT_JTAG = 0x0100U, + RGM_INT_CPULOC = 0x0200U, + RGM_INT_SW = 0x0400U, + RGM_INT_SYSAP = 0x0800U, + RGM_INT_WDOG1 = 0x1000U, + RGM_INT_SACKERR = 0x2000U, + RGM_INT_CMU = 0x4000U +} RGM_ResetIntMangerType; + +/** @brief Select the Rgm CORE Write protection */ +typedef enum +{ + RGM_WPB_ALL = 0x00U, + RGM_WPB_CPU0 = 0x01U, + RGM_WPB_NOCORE = 0x04U +} RGM_WriteprotectionBitType; + +/** @brief Rgm CPU0,1,2 related interrupt event manger */ +typedef enum +{ + RGM_CPU_INT_LOCKUP = 0x01U, + RGM_CPU_INT_SYSRST = 0x02U, + RGM_CPU_INT_WDOG = 0x04U, + RGM_CPU_INT_INTM = 0x08U, + RGM_CPU_INT_SWRST = 0x10U +} RGM_CPUIntMangerType; + +/** @brief Rgm CPU0,1,2 software reset status */ +typedef enum +{ + RGM_CPU_OUT_RST_UNDER = 0x00U, + RGM_CPU_OUT_RST_OUT = 0x01U +} RGM_CPUOutResetType; + +/** @brief Rgm CPU0,1,2 reset event */ +typedef enum +{ + RGM_CPU_WAKEUP = 0x00000001U, + RGM_CPU_LVD = 0x00000002U, + RGM_CPU_CLKERR1 = 0x00000004U, + RGM_CPU_CLKERR0 = 0x00000008U, + RGM_CPU_FSCMU = 0x00000010U, + RGM_CPU_HSMWDOG = 0x00000020U, + RGM_CPU_PIN = 0x00000040U, + RGM_CPU_POR = 0x00000080U, + RGM_CPU_JTAG = 0x00000100U, + RGM_CPU_SYSAP = 0x00000800U, + RGM_CPU_WDOG1 = 0x00001000U, + RGM_CPU_SACKERR = 0x00002000U, + RGM_CPU_CMU = 0x00004000U, + RGM_CPU_LBIST = 0x00008000U, + RGM_CPU_LOCKUP = 0x00010000U, + RGM_CPU_SYSRST = 0x00020000U, + RGM_CPU_WDOG = 0x00040000U, + RGM_CPU_INTM = 0x00080000U, + RGM_CPU_SWRST = 0x00100000U, + RGM_CPU_FSMERR = 0x20000000U, + RGM_CPU_PINRSTTOUT = 0x40000000U, + RGM_CPU_SYSRSTTOUT = 0x80000000U +} RGM_CPUResetEventType; + +/** @brief Rgm CPU1,2 system reset enable flag */ +typedef enum +{ + RGM_CPU_EN_LOCKUP = 0x00010000U, + RGM_CPU_EN_SYSRST = 0x00020000U, + RGM_CPU_EN_WDOG = 0x00040000U, + RGM_CPU_EN_INTM = 0x00080000U, + RGM_CPU_EN_SWRST = 0x00100000U, +} RGM_CPUSystemRstMangerType; +/********* Local inline function ************/ +/** + * @brief Read last reset flag + * + * @return Last reset flag + */ +LOCAL_INLINE uint32_t RGM_HWA_ReadLastResetFlag(void) +{ + return (uint32_t)RGM->SRS; +} + +/** + * @brief Read all reset flag before POR,SSRS register is reset on POR only + * + * @return All reset flag before POR + */ +LOCAL_INLINE uint32_t RGM_HWA_ReadAllResetFlagBeforePOR(void) +{ + return (uint32_t)RGM->SSRS; +} + +/** + * @brief Read reset pin filter register + * + * @return Reset pin filter register + */ +LOCAL_INLINE uint32_t RGM_HWA_ReadResetPinFilterEnable(void) +{ + return (uint32_t)RGM->RSTFLT; +} + +/** + * @brief This api can clear reset flag of SSRS register which indicate all reset sources since the last POR or LVD that have not been cleared by software. + * + * @param eReset Reset flag + */ +LOCAL_INLINE void RGM_HWA_ClearResetFlagAfterPOR(RGM_ResetEventType eReset) +{ + RGM->SSRS = (uint32_t)(eReset); +} + +/** + * @brief This api can clear all reset flag of SSRS register which indicate all reset sources since the last POR or LVD that have not been cleared by software. + * + */ +LOCAL_INLINE void RGM_HWA_ClearAllResetFlagAfterPOR(void) +{ + RGM->SSRS = (uint32_t)0xE000F9FFU; +} + +/** + * @brief Set reset pin filter bus clock filter width + * + * @param u8Value Bus clock filter width value + */ +LOCAL_INLINE void RGM_HWA_SetBusClockFilterWidth(uint8_t u8Value) +{ + uint32_t u32RegValue = RGM->RSTFLT; + RGM->RSTFLT = (u32RegValue & ~(uint32_t)RGM_RSTFLT_RSTFLT_BUSW_MASK) | RGM_RSTFLT_RSTFLT_BUSW(u8Value); +} + +/** + * @brief Enable reset pin filter bus clock + * + */ +LOCAL_INLINE void RGM_HWA_EnableBusClockFilter(void) +{ + RGM->RSTFLT |= (uint32_t)RGM_RSTFLT_RSTFLT_BUS_MASK; +} + +/** + * @brief Enable reset pin filter AON32K clock + * + */ +LOCAL_INLINE void RGM_HWA_EnableAon32kClockFilter(void) +{ + RGM->RSTFLT |= (uint32_t)RGM_RSTFLT_RSTFLT_AON_MASK; +} + +/** + * @brief Enable reset pin filter AON32K low power clock + * + */ +LOCAL_INLINE void RGM_HWA_EnableAon32kLPClockFilter(void) +{ + RGM->RSTFLT |= (uint32_t)RGM_RSTFLT_RSTFLT_AON_LP_MASK; +} + +/** + * @brief Clear reset pin filter bus clock filter width + * + */ +LOCAL_INLINE void RGM_HWA_ClearBusClockFilterWidth(void) +{ + RGM->RSTFLT &= ~(uint32_t)RGM_RSTFLT_RSTFLT_BUSW_MASK; +} + +/** + * @brief Disable reset pin filter bus clock + * + */ +LOCAL_INLINE void RGM_HWA_DisableBusClockFilter(void) +{ + RGM->RSTFLT &= ~(uint32_t)RGM_RSTFLT_RSTFLT_BUS_MASK; +} + +/** + * @brief Disable reset pin filter AON32K clock + * + */ +LOCAL_INLINE void RGM_HWA_DisableAon32kClockFilter(void) +{ + RGM->RSTFLT &= ~(uint32_t)RGM_RSTFLT_RSTFLT_AON_MASK; +} + +/** + * @brief Disable reset pin filter AON32K low power clock + * + */ +LOCAL_INLINE void RGM_HWA_DisableAon32kLPClockFilter(void) +{ + RGM->RSTFLT &= ~(uint32_t)RGM_RSTFLT_RSTFLT_AON_LP_MASK; +} + +/** + * @brief Set Reset delay + * + * @param eDelay Reset delay type + */ +LOCAL_INLINE void RGM_HWA_SetResetDelay(RGM_ResetDelayType eDelay) +{ + uint32_t u32RegValue = RGM->SRIE; + RGM->SRIE = (u32RegValue & ~(uint32_t)RGM_SRIE_DELAY_MASK) | RGM_SRIE_DELAY(eDelay); +} + +/** + * @brief Clear Reset delay + */ +LOCAL_INLINE void RGM_HWA_ClearResetDelay(void) +{ + RGM->SRIE &= ~(uint32_t)RGM_SRIE_DELAY_MASK; +} + +/** + * @brief Enable global reset interrupt + * + */ +LOCAL_INLINE void RGM_HWA_EnableGlobalResetInterrupt(void) +{ + RGM->SRIE |= (uint32_t)RGM_SRIE_GLOBAL_RIE_MASK; +} + +/** + * @brief Enable reset interrupt + * + * @param eResetInterrupt Reset interrupt type + */ +LOCAL_INLINE void RGM_HWA_EnableResetInterrupt(RGM_ResetIntMangerType eResetInterrupt) +{ + RGM->SRIE |= (uint32_t)((uint32_t)eResetInterrupt & (RGM_SRIE_CLKERR0_RIE_MASK | RGM_SRIE_WDG_RIE_MASK | + RGM_SRIE_PIN_RIE_MASK | RGM_SRIE_JTAG_RIE_MASK | RGM_SRIE_CPULOC_RIE_MASK | RGM_SRIE_SW_RIE_MASK | + RGM_SRIE_SYSAP_RIE_MASK | RGM_SRIE_WDOG1_RIE_MASK | RGM_SRIE_SACKERR_RIE_MASK)); +} + +/** + * @brief Disable reset interrupt + * + * @param eResetInterrupt Reset interrupt type + */ +LOCAL_INLINE void RGM_HWA_DisableResetInterrupt(RGM_ResetIntMangerType eResetInterrupt) +{ + RGM->SRIE &= ~(uint32_t)((uint32_t)eResetInterrupt & (RGM_SRIE_CLKERR0_RIE_MASK | RGM_SRIE_WDG_RIE_MASK | + RGM_SRIE_PIN_RIE_MASK | RGM_SRIE_JTAG_RIE_MASK | RGM_SRIE_CPULOC_RIE_MASK | RGM_SRIE_SW_RIE_MASK | + RGM_SRIE_SYSAP_RIE_MASK | RGM_SRIE_WDOG1_RIE_MASK | RGM_SRIE_SACKERR_RIE_MASK)); +} + +/** + * @brief Get enabling status of system reset + * + * @return Interrupt enabling status of system reset + */ +LOCAL_INLINE uint32_t RGM_HWA_GetResetInterrupt(void) +{ + return (uint32_t)(RGM->SRIE & (RGM_SRIE_CLKERR0_RIE_MASK | RGM_SRIE_WDG_RIE_MASK | + RGM_SRIE_PIN_RIE_MASK | RGM_SRIE_GLOBAL_RIE_MASK | RGM_SRIE_JTAG_RIE_MASK | RGM_SRIE_CPULOC_RIE_MASK | + RGM_SRIE_SW_RIE_MASK | RGM_SRIE_SYSAP_RIE_MASK | RGM_SRIE_WDOG1_RIE_MASK | RGM_SRIE_SACKERR_RIE_MASK)); +} + +/** + * @brief Perform system reset. + * + */ +LOCAL_INLINE void CM7_HWA_SystemReset(void) +{ + uint32 u32Temp; + u32Temp = SCB->AIRCR; + u32Temp &= ~(uint32)(SCB_AIRCR_VECTKEY_Msk); + u32Temp |= (uint32)((((uint32_t)(((uint32_t)(0x5FAU))<AIRCR = u32Temp; +} + +/** + * @brief Enable CPU0 interrupt + * + * @param eCPU0ResetInterrupt CPU0 related interrupt type + */ +LOCAL_INLINE void RGM_HWA_EnableCPU0InterruptFlag(RGM_CPUIntMangerType eCPU0ResetInterrupt) +{ + RGM->C0_CFG |= (uint32_t)((uint32_t)eCPU0ResetInterrupt & (RGM_C0_CFG_C0_SWRST_IE_MASK | RGM_C0_CFG_C0_INTM_IE_MASK | RGM_C0_CFG_C0_WDOG_IE_MASK | + RGM_C0_CFG_C0_SYSRST_IE_MASK | RGM_C0_CFG_C0_LOCKUP_IE_MASK)); +} + +/** + * @brief Disable CPU0 interrupt + * + * @param eCPU0ResetInterrupt CPU0 related interrupt type + */ +LOCAL_INLINE void RGM_HWA_DisableCPU0InterruptFlag(RGM_CPUIntMangerType eCPU0ResetInterrupt) +{ + RGM->C0_CFG &= ~(uint32_t)((uint32_t)eCPU0ResetInterrupt & (RGM_C0_CFG_C0_SWRST_IE_MASK | RGM_C0_CFG_C0_INTM_IE_MASK | RGM_C0_CFG_C0_WDOG_IE_MASK | + RGM_C0_CFG_C0_SYSRST_IE_MASK | RGM_C0_CFG_C0_LOCKUP_IE_MASK)); +} + +/** + * @brief Get enabling status of CPU0 core related reset + * + * @return Interrupt enabling status of CPU0 core related reset + */ +LOCAL_INLINE uint32_t RGM_HWA_GetCPU0ResetInterrupt(void) +{ + return (uint32_t)(RGM->C0_CFG & (RGM_C0_CFG_C0_SWRST_IE_MASK | RGM_C0_CFG_C0_INTM_IE_MASK | RGM_C0_CFG_C0_WDOG_IE_MASK | + RGM_C0_CFG_C0_SYSRST_IE_MASK | RGM_C0_CFG_C0_LOCKUP_IE_MASK)); +} + +/** + * @brief Get the CPU0 exit reset flag + * + * @return RGM_CPU_OUT_RST_UNDER CPU0 is under reset + * @return RGM_CPU_OUT_RST_OUT CPU0 is out of reset + */ +LOCAL_INLINE RGM_CPUOutResetType RGM_HWA_GetCPU0OutResetFlag(void) +{ + uint8_t u8TmpVal = (uint8_t)(RGM->C0_RST & RGM_C0_RST_C0_OUT_OF_RST_MASK) >> RGM_C0_RST_C0_OUT_OF_RST_SHIFT; + return (RGM_CPUOutResetType)u8TmpVal; +} + +/** + * @brief Issue a CPU0 software reset. + * + */ +LOCAL_INLINE void RGM_HWA_CPU0SWReset(void) +{ + RGM->C0_RST |= (uint32_t)RGM_C0_RST_C0_SWRST_MASK; +} + +/** + * @brief Read CPU0 last reset flag + * + * @return CPU0 last reset flag + */ +LOCAL_INLINE uint32_t RGM_HWA_ReadCPU0LastResetFlag(void) +{ + return (uint32_t)RGM->C0_SRS; +} + +/** + * @brief Read CPU0 all reset flag before POR,SSRS register is reset on POR only + * + * @return CPU0 all reset flag before POR + */ +LOCAL_INLINE uint32_t RGM_HWA_ReadCPU0AllResetFlagBeforePOR(void) +{ + return (uint32_t)RGM->C0_SSRS; +} + +/** + * @brief This api can clear reset flag of RGM_C0_SSRS register which indicate all reset sources since the last POR or LVD that have not been cleared by software. + * + * @param eReset Reset flag + */ +LOCAL_INLINE void RGM_HWA_ClearC0ResetFlagAfterPOR(RGM_CPUResetEventType eReset) +{ + RGM->C0_SSRS = (uint32_t)(eReset); +} + +/** + * @brief This api can clear all reset flag of SSRGM_C0_SSRSRS register which indicate all reset sources since the last POR or LVD that have not been cleared by software. + * + */ +LOCAL_INLINE void RGM_HWA_ClearC0AllResetFlagAfterPOR(void) +{ + RGM->C0_SSRS = (uint32_t)0xE01FF9FFU; +} +#endif /* #ifndef _HWA_RGM_H_ */ diff --git a/MODULES/HwA_Flagchip_FC7240/Inc/HwA_rtc.h b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_rtc.h new file mode 100644 index 0000000..576f811 --- /dev/null +++ b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_rtc.h @@ -0,0 +1,276 @@ +/** + * @file HwA_rtc.h + * @author Flagchip + * @brief FC7xxx rtc hardware access layer + * @version 0.1.0 + * @date 2024-01-10 + * + * @copyright Copyright (c) 2023 Flagchip Semiconductors Co., Ltd. + * + * @details + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-01-10 Flagchip0076 N/A First version for FC7240 + ******************************************************************************** */ + +#ifndef HWA_INCLUDE_HWA_RTC_H_ +#define HWA_INCLUDE_HWA_RTC_H_ + + +#include "device_header.h" + +/** + * @addtogroup HwA_RTC + * @{ + * + */ + +/********* Local typedef ************/ + +/** + * @brief in the second interrupt mode, this type indicates the interrupt frequency. + * in the clkout mode , this type indicates the clkout frequency . + * + * */ +typedef enum +{ + RTC_FREQ_1HZ = 0, /*!< Set the RTC Seconds interrupt and the RTC_CLKOUT prescale output frequency to 1Hz */ + RTC_FREQ_2HZ, /*!< Set the RTC Seconds interrupt and the RTC_CLKOUT prescale output frequency to 2Hz */ + RTC_FREQ_4HZ, /*!< Set the RTC Seconds interrupt and the RTC_CLKOUT prescale output frequency to 4Hz */ + RTC_FREQ_8HZ, /*!< Set the RTC Seconds interrupt and the RTC_CLKOUT prescale output frequency to 8Hz */ + RTC_FREQ_16HZ, /*!< Set the RTC Seconds interrupt and the RTC_CLKOUT prescale output frequency to 16Hz */ + RTC_FREQ_32hZ, /*!< Set the RTC Seconds interrupt and the RTC_CLKOUT prescale output frequency to 32Hz */ + RTC_FREQ_64HZ, /*!< Set the RTC Seconds interrupt and the RTC_CLKOUT prescale output frequency to 64Hz */ + RTC_FREQ_128HZ /*!< Set the RTC Seconds interrupt and the RTC_CLKOUT prescale output frequency to 128Hz */ +} RTC_ClkoutSecIntFreqType; +/********* Local inline function ************/ + +/** + * @brief Read second value + * + * @return Second value + */ +LOCAL_INLINE uint32_t RTC_HWA_ReadSecondValue(void) +{ + return (uint32_t)RTC->SR; +} + +/** + * @brief Read RTC SR overflow flag + * + * @return true means Overflow flag is 1 ;false means Overflow flag is 0. + */ +LOCAL_INLINE bool RTC_HWA_GetOverflowFlag(void) +{ + return (bool)(((RTC->STR & (uint32_t)RTC_STR_TOF_MASK)!=0u)? true:false); +} + +/** + * @brief Read RTC IER overflow enable bit + * + * @return true means enable Overflow Interrupt ;false means disable Overflow Interrupt + */ +LOCAL_INLINE bool RTC_HWA_GetOverflowEnable(void) +{ + return (bool)(((RTC->IER & (uint32_t)RTC_IER_TOIE_MASK)!=0u) ? true:false); +} + +/** + * @brief Read RTC alarm flag + * + * @return true means alarm flag is 1 ;false means alarm flag is 0. + */ +LOCAL_INLINE bool RTC_HWA_GetAlarmFlag(void) +{ + return (bool)(((RTC->STR & (uint32_t)RTC_STR_TAF_MASK)!=0u)?true:false); +} + +/** + * @brief Read RTC alarm Enable + * + * @return true means enable alarm Interrupt ;false means disable alarm Interrupt + */ +LOCAL_INLINE bool RTC_HWA_GetAlarmEnable(void) +{ + return (bool)(((RTC->IER & (uint32_t)RTC_IER_TAIE_MASK)!=0u)?true:false); +} + +/** + * @brief Read RTC second interrupt Enable + * + * @return true means enable second Interrupt ;false means disable second Interrupt + */ +LOCAL_INLINE bool RTC_HWA_GetSecondEnable(void) +{ + return (bool)(((RTC->IER & (uint32_t)RTC_IER_TSIE_MASK)!=0u)?true:false); +} + +/** + * @brief Set RTC prescaler register + * + * @param u16Value PR register value + */ +LOCAL_INLINE void RTC_HWA_SetPrescalerCounterValue(uint16_t u16Value) +{ + RTC->PR = (uint32_t)u16Value; +} + +/** + * @brief Set RTC seconds register + * + * @param u32Value SR register value + */ +LOCAL_INLINE void RTC_HWA_SetSecondCounterValue(uint32_t u32Value) +{ + RTC->SR = u32Value; +} + +/** + * @brief Set RTC alarm value + * + * @param u32Value TAR register value + */ +LOCAL_INLINE void RTC_HWA_SetAlarmCounterValue(uint32_t u32Value) +{ + RTC->AR = u32Value; +} + +/** + * @brief Set RTC interrupt value + * + * @param u32Value IER register value + */ +LOCAL_INLINE void RTC_HWA_SetInterruptValue(uint32_t u32Value) +{ + RTC->IER = u32Value; +} + +/** + * @brief Configure control register + * + * @param u32Value Control value + */ +LOCAL_INLINE void RTC_HWA_ConfigControl(uint32_t u32Value) +{ + RTC->CR = u32Value; +} + +/** + * @brief Enable RTC time counter + * + */ +LOCAL_INLINE void RTC_HWA_EnableRtcCounter(void) +{ + RTC->STR |= (uint32_t)RTC_STR_TCE_MASK; +} + +/** + * @brief Set RTC_CLKOUT is from the 32.768 khz clock + * + */ +LOCAL_INLINE void RTC_HWA_SetClkoutFreqStable(void) +{ + RTC->CR |= (uint32_t)RTC_CR_CKPS_MASK; +} + +/** + * @brief Enable alarm interrupt + * + */ +LOCAL_INLINE void RTC_HWA_EnableAlarmInterrupt(void) +{ + RTC->IER |= (uint32_t)RTC_IER_TAIE_MASK; +} + +/** + * @brief Enable second interrupt + * + */ +LOCAL_INLINE void RTC_HWA_EnableSecondInterrupt(void) +{ + RTC->IER |= (uint32_t)RTC_IER_TSIE_MASK; +} + +/** + * @brief Enable overflow interrupt + * + */ +LOCAL_INLINE void RTC_HWA_EnableOverflowInterrupt(void) +{ + RTC->IER |= (uint32_t)RTC_IER_TOIE_MASK; +} + +/** + * @brief Unlock lock/status/control/compensation register + * + */ +LOCAL_INLINE void RTC_HWA_UnlockStatusControlCompensationReg(void) +{ + RTC->LR |= (uint32_t)(RTC_LR_LRL_MASK | RTC_LR_STRL_MASK | RTC_LR_CRL_MASK | RTC_LR_CPL_MASK); +} + +/** + * @brief Set second interrupt and RTC_CLKOUT frequency + * + * @param eFreq Frequency value + */ +LOCAL_INLINE void RTC_HWA_SetSecondAndClkoutFreq(RTC_ClkoutSecIntFreqType eFreq) +{ + uint32_t u32RegValue = RTC->IER; + RTC->IER &= ~(uint32_t)RTC_IER_TSIE_MASK; + RTC->IER = (u32RegValue & ~(uint32_t)RTC_IER_TSIC_MASK) | RTC_IER_TSIC(eFreq); +} + +/** + * @brief Disable RTC time counter + * + */ +LOCAL_INLINE void RTC_HWA_DisableRtcCounter(void) +{ + RTC->STR &= ~(uint32_t)RTC_STR_TCE_MASK; +} + +/** + * @brief Set RTC_CLKOUT is from the prescaler output clock selected by IER[TSIC] + * + */ +LOCAL_INLINE void RTC_HWA_SetClkoutFromSelectFreq(void) +{ + RTC->CR &= ~(uint32_t)RTC_CR_CKPS_MASK; +} + +/** + * @brief Disable alarm interrupt + * + */ +LOCAL_INLINE void RTC_HWA_DisableAlarmInterrupt(void) +{ + RTC->IER &= ~(uint32_t)RTC_IER_TAIE_MASK; +} + +/** + * @brief Disable second interrupt + * + */ +LOCAL_INLINE void RTC_HWA_DisableSecondInterrupt(void) +{ + RTC->IER &= ~(uint32_t)RTC_IER_TSIE_MASK; +} + +/** + * @brief Disable overflow interrupt + * + */ +LOCAL_INLINE void RTC_HWA_DisableOverflowInterrupt(void) +{ + RTC->IER &= ~(uint32_t)RTC_IER_TOIE_MASK; +} + + + +/** @}*/ /* HwA_RTC */ +#endif /* HWA_INCLUDE_HWA_RTC_H_ */ diff --git a/MODULES/HwA_Flagchip_FC7240/Inc/HwA_scg.h b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_scg.h new file mode 100644 index 0000000..efd3664 --- /dev/null +++ b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_scg.h @@ -0,0 +1,917 @@ +/** + * @file HwA_SCG.h + * @author Flagchip + * @brief FC7xxx SCG hardware access layer + * @version 0.1.0 + * @date 2023-01-12 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + * @details + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-01-12 Flagchip085 N/A First version for FC7240 + ******************************************************************************** */ +#ifndef _HWA_SCG_H_ +#define _HWA_SCG_H_ + +#include "device_header.h" + +/** + * @addtogroup HwA_SCG + * @{ + * + */ +/********* macros ************/ +#define UNKNOWN_CLOCK 0xFFFFFFFFU + +#define SCG_CORE_CLOCK_SYMBOL CORE +#define SCG_BUS_CLOCK_SYMBOL BUS +#define SCG_SLOW_CLOCK_SYMBOL SLOW +#define SCG_SIRC_CLOCK_SYMBOL SIRC +#define SCG_SIRC32K_CLOCK_SYMBOL SIRC32K +#define SCG_FIRC_CLOCK_SYMBOL FIRC +#define SCG_FOSC_CLOCK_SYMBOL FOSC +#define SCG_SOSC_CLOCK_SYMBOL SOSC +#define SCG_PLL0_CLOCK_SYMBOL PLL0 +#define SCG_PLL1_CLOCK_SYMBOL PLL1 + +/* PLL related */ +#define SCG_PLLCSR_LK_MASK 0x800000u +#define SCG_PLLCSR_EN_MASK 0x1u +#define SCG_PLLCSR_CMRE_MASK 0x20000u +#define SCG_PLLCSR_CMRE_SHIFT 17u +#define SCG_PLLCSR_CMRE(x) (((uint32_t)(((uint32_t)(x))<_pll_##CSR = val +#define SCG_HWA_SetPllCsr(pll, val) _SCG_HWA_SetPllCsr(pll, val) + +#define _SCG_HWA_UnlockPllCsr(_pll_) SCG->_pll_##CSR &= ~(uint32_t)SCG_PLLCSR_LK_MASK +#define SCG_HWA_UnlockPllCsr(pll) _SCG_HWA_UnlockPllCsr(pll) + +#define _SCG_HWA_LockPllCsr(_pll_) SCG->_pll_##CSR |= (uint32_t)SCG_PLLCSR_LK_MASK +#define SCG_HWA_LockPllCsr(pll) _SCG_HWA_LockPllCsr(pll) + +#define _SCG_HWA_EnablePllClockMonitor(_pll_) SCG->_pll_##CSR |= (uint32_t)SCG_PLLCSR_CM_MASK +#define SCG_HWA_EnablePllClockMonitor(pll) _SCG_HWA_EnablePllClockMonitor(pll) + +#define _SCG_HWA_EnablePllClockMonitorReset(_pll_) SCG->_pll_##CSR |= (uint32_t)SCG_PLLCSR_CMRE_MASK +#define SCG_HWA_EnablePllClockMonitorReset(pll) _SCG_HWA_EnablePllClockMonitorReset(pll) + +#define _SCG_HWA_SetPllCfg(_pll_, val) SCG->_pll_##CFG = val +#define SCG_HWA_SetPllCfg(pll, val) _SCG_HWA_SetPllCfg(pll, val) + +#define _SCG_HWA_SetPllDiv(_pll_, val) SCG->_pll_##DIV = val +#define SCG_HWA_SetPllDiv(pll, val) _SCG_HWA_SetPllDiv(pll, val) + +#define _SCG_HWA_EnablePll(_pll_) SCG->_pll_##CSR |= (uint32_t)(SCG_PLLCSR_EN_MASK) +#define SCG_HWA_EnablePll(pll) _SCG_HWA_EnablePll(pll) + + + +#define _SCG_HWA_GetPllMult(_pll_) (uint32_t)(((uint32_t)(SCG->_pll_##CFG) & SCG_PLLCFG_MULT_MASK) >> SCG_PLLCFG_MULT_SHIFT) +#define SCG_HWA_GetPllMult(pll) _SCG_HWA_GetPllMult(pll) + +#define _SCG_HWA_GetPllPrediv(_pll_) (uint32_t)(((uint32_t)(SCG->_pll_##CFG) & SCG_PLLCFG_PREDIV_MASK) >> SCG_PLLCFG_PREDIV_SHIFT) +#define SCG_HWA_GetPllPrediv(pll) _SCG_HWA_GetPllPrediv(pll) + +#define _SCG_HWA_GetPllPstdiv(_pll_) (uint32_t)(((uint32_t)(SCG->_pll_##CFG) & SCG_PLLCFG_PSTDIV_MASK) >> SCG_PLLCFG_PSTDIV_SHIFT) +#define SCG_HWA_GetPllPstdiv(pll) _SCG_HWA_GetPllPstdiv(pll) + +#define _SCG_HWA_GetPllSrc(_pll_) (uint32_t)(((uint32_t)(SCG->_pll_##CFG) & SCG_PLLCFG_SOURCE_MASK) >> SCG_PLLCFG_SOURCE_SHIFT) +#define SCG_HWA_GetPllSrc(pll) _SCG_HWA_GetPllSrc(pll) + +/* Clock valid and div related */ +#define _SCG_HWA_GetClockVliad(_clock_) (bool)((((uint32_t)SCG->_clock_##CSR & (uint32_t)SCG_##_clock_##CSR_VLD_MASK) != 0U) ? true : false) +#define SCG_HWA_GetClockVliad(_clock_) _SCG_HWA_GetClockVliad(_clock_) + +#define _SCG_HWA_GetClockDiv(_clock_) (uint32_t)SCG->_clock_##DIV +#define SCG_HWA_GetClockDiv(_clock_) _SCG_HWA_GetClockDiv(_clock_) + +#define SCG_CLOCKDIV_DIVL_ACK_MASK 0x40000000u +#define SCG_CLOCKDIV_DIVM_ACK_MASK 0x20000000u +#define SCG_CLOCKDIV_DIVH_ACK_MASK 0x10000000u +#define SCG_CLOCKDIV_DIVL_ACK_SHIFT 30u +#define SCG_CLOCKDIV_DIVM_ACK_SHIFT 29u +#define SCG_CLOCKDIV_DIVH_ACK_SHIFT 28u + +#define SCG_CLOCKDIV_DIVL_EN_MASK 0x4000000u +#define SCG_CLOCKDIV_DIVM_EN_MASK 0x2000000u +#define SCG_CLOCKDIV_DIVH_EN_MASK 0x1000000u +#define SCG_CLOCKDIV_DIVL_EN_SHIFT 26u +#define SCG_CLOCKDIV_DIVM_EN_SHIFT 25u +#define SCG_CLOCKDIV_DIVH_EN_SHIFT 24u + +#define SCG_CLOCKDIV_EN2ACK_SHIFT 4u + +#define SCG_CLOCKDIV_DIVL_VAL_MASK 0x70000u +#define SCG_CLOCKDIV_DIVM_VAL_MASK 0x700u +#define SCG_CLOCKDIV_DIVH_VAL_MASK 0x7u +#define SCG_CLOCKDIV_DIVL_VAL_SHIFT 16u +#define SCG_CLOCKDIV_DIVM_VAL_SHIFT 8u +#define SCG_CLOCKDIV_DIVH_VAL_SHIFT 0u + +#define SCG_CHECK_DIVL_ACK(reg_val) ((reg_val & SCG_CLOCKDIV_DIVL_ACK_MASK) >> SCG_CLOCKDIV_DIVL_ACK_SHIFT) +#define SCG_CHECK_DIVM_ACK(reg_val) ((reg_val & SCG_CLOCKDIV_DIVM_ACK_MASK) >> SCG_CLOCKDIV_DIVM_ACK_SHIFT) +#define SCG_CHECK_DIVH_ACK(reg_val) ((reg_val & SCG_CLOCKDIV_DIVH_ACK_MASK) >> SCG_CLOCKDIV_DIVH_ACK_SHIFT) +#define SCG_CHECK_DIVL_EN(reg_val) ((reg_val & SCG_CLOCKDIV_DIVL_EN_MASK) >> SCG_CLOCKDIV_DIVL_EN_SHIFT) +#define SCG_CHECK_DIVM_EN(reg_val) ((reg_val & SCG_CLOCKDIV_DIVM_EN_MASK) >> SCG_CLOCKDIV_DIVM_EN_SHIFT) +#define SCG_CHECK_DIVH_EN(reg_val) ((reg_val & SCG_CLOCKDIV_DIVH_EN_MASK) >> SCG_CLOCKDIV_DIVH_EN_SHIFT) +#define SCG_GET_DIVL_VAL(reg_val) ((0U == ((reg_val & SCG_CLOCKDIV_DIVL_VAL_MASK) >> SCG_CLOCKDIV_DIVL_VAL_SHIFT)) ? 1U : ((reg_val & SCG_CLOCKDIV_DIVL_VAL_MASK) >> SCG_CLOCKDIV_DIVL_VAL_SHIFT)) +#define SCG_GET_DIVM_VAL(reg_val) ((0U == ((reg_val & SCG_CLOCKDIV_DIVM_VAL_MASK) >> SCG_CLOCKDIV_DIVM_VAL_SHIFT)) ? 1U : ((reg_val & SCG_CLOCKDIV_DIVM_VAL_MASK) >> SCG_CLOCKDIV_DIVM_VAL_SHIFT)) +#define SCG_GET_DIVH_VAL(reg_val) ((0U == ((reg_val & SCG_CLOCKDIV_DIVH_VAL_MASK) >> SCG_CLOCKDIV_DIVH_VAL_SHIFT)) ? 1U : ((reg_val & SCG_CLOCKDIV_DIVH_VAL_MASK) >> SCG_CLOCKDIV_DIVH_VAL_SHIFT)) +#define SCG_CALCULATE_DIVL_FREQ(clk_freq, reg_val) (((1U == SCG_CHECK_DIVL_EN(reg_val)) && (clk_freq != UNKNOWN_CLOCK)) ? (uint32_t)clk_freq >> (uint8_t)(SCG_GET_DIVL_VAL(reg_val) - 1U) : (uint32_t)UNKNOWN_CLOCK) +#define SCG_CALCULATE_DIVM_FREQ(clk_freq, reg_val) (((1U == SCG_CHECK_DIVM_EN(reg_val)) && (clk_freq != UNKNOWN_CLOCK)) ? (uint32_t)clk_freq >> (uint8_t)(SCG_GET_DIVM_VAL(reg_val) - 1U) : (uint32_t)UNKNOWN_CLOCK) +#define SCG_CALCULATE_DIVH_FREQ(clk_freq, reg_val) (((1U == SCG_CHECK_DIVH_EN(reg_val)) && (clk_freq != UNKNOWN_CLOCK)) ? (uint32_t)clk_freq >> (uint8_t)(SCG_GET_DIVH_VAL(reg_val) - 1U) : (uint32_t)UNKNOWN_CLOCK) + + +typedef enum +{ + SCG_CLOCK_DIV_H = 0x01000000U, /* DIVH clock enable bit [24] */ + SCG_CLOCK_DIV_M = 0x02000000U, /* DIVM clock enable bit [25] */ + SCG_CLOCK_DIV_L = 0x04000000U, /* DIVL clock enable bit [26] */ + SCG_CLOCK_DIV_ALL = 0x07000000U, /* DIVH DIVM DIVL clock enable bit [26:24] */ +}SCG_DivEnableType; + +/********* Local inline function ************/ + +/** + * @brief Get clock out configure register CLKOUTSEL value + */ +LOCAL_INLINE uint8_t SCG_HWA_GetClkOutSel(void) +{ + return (uint8_t)(((uint32_t)SCG->CLKOUTCFG & SCG_CLKOUTCFG_CLKOUTSEL_MASK) >> SCG_CLKOUTCFG_CLKOUTSEL_SHIFT); +} + +/** + * @brief Get clock out configure register value + */ +LOCAL_INLINE uint32_t SCG_HWA_GetClkOutCfg(void) +{ + return SCG->CLKOUTCFG; +} + +/** + * @brief Unlock SOSC CSR register + * + */ +LOCAL_INLINE void SCG_HWA_UnlockSoscCsrReg(void) +{ + SCG->SOSCCSR &= ~(uint32_t)(SCG_SOSCCSR_LK_MASK); +} + +/** + * @brief Lock SOSC CSR register + * + */ +LOCAL_INLINE void SCG_HWA_LockSoscCsrReg(void) +{ + SCG->SOSCCSR |= (uint32_t)(SCG_SOSCCSR_LK_MASK); +} + +/** + * @brief Enable SOSC clock monitor + * + */ +LOCAL_INLINE void SCG_HWA_EnableSoscClockMonitor(void) +{ + SCG->SOSCCSR |= (uint32_t)(SCG_SOSCCSR_CM_MASK); +} + +/** + * @brief Enable SOSC clock monitor Reset + * + */ +LOCAL_INLINE void SCG_HWA_EnableSoscClockMonitorReset(void) +{ + SCG->SOSCCSR |= (uint32_t)(SCG_SOSCCSR_CMRE_MASK); +} + +/** + * @brief Set SOSC enable + */ +LOCAL_INLINE void SCG_HWA_EnableSosc(void) +{ + SCG->SOSCCSR |= (uint32_t)SCG_SOSCCSR_EN_MASK; +} + +/** + * @brief Diable SOSC + */ +LOCAL_INLINE void SCG_HWA_DisableSosc(void) +{ + SCG->SOSCCSR &= ~(uint32_t)SCG_SOSCCSR_EN_MASK; +} + +/** + * @brief Set recommend value to SOSCCFG register + * + */ +LOCAL_INLINE void SCG_HWA_SetSoscRecommendCfg(void) +{ + SCG->SOSCCFG = (uint32_t)(SCG_SOSCCFG_EOCV(64U) | SCG_SOSCCFG_GM_SEL(3U) | SCG_SOSCCFG_CURPRG_SF(3U) | SCG_SOSCCFG_CURPRG_COMP(3U)); +} + +/** + * @brief Set SOSC CSR register value + * + * @param u32CsrValue configured register value + */ +LOCAL_INLINE void SCG_HWA_SetSoscCsr(uint32_t u32CsrValue) +{ + SCG->SOSCCSR = u32CsrValue; +} + +/** + * @brief Get SOSC CSR register value + * + */ +LOCAL_INLINE uint32_t SCG_HWA_GetSoscCsr(void) +{ + return (uint32_t)SCG->SOSCCSR; +} + +/********* Fosc Register interface ************/ +/** + * @brief Enable FOSC + */ +LOCAL_INLINE void SCG_HWA_EnableFosc(void) +{ + SCG->FOSCCSR |= (uint32_t)SCG_FOSCCSR_EN_MASK; +} + +/** + * @brief Disable FOSC + */ +LOCAL_INLINE void SCG_HWA_DisableFosc(void) +{ + SCG->FOSCCSR &= ~SCG_FOSCCSR_EN_MASK; +} + +/** + * @brief Set FOSCCFG register value + * + * @param u32CfgValue configured register value + */ +LOCAL_INLINE void SCG_HWA_SetFoscCfg(uint32_t u32CfgValue) +{ + SCG->FOSCCFG = u32CfgValue; +} + +/** + * @brief Set FOSCCSR register value + * + * @param u32CsrValue configured register value + */ +LOCAL_INLINE void SCG_HWA_SetFoscCsr(uint32_t u32CsrValue) +{ + SCG->FOSCCSR = u32CsrValue; +} + +/** + * @brief Get FOSCCSR register value + * + */ +LOCAL_INLINE uint32_t SCG_HWA_GetFoscCsr(void) +{ + return (uint32_t)SCG->FOSCCSR; +} + +/** + * @brief Unlock FOSC CSR register + * + */ +LOCAL_INLINE void SCG_HWA_UnlockFoscCsrReg(void) +{ + SCG->FOSCCSR &= ~(uint32_t)(SCG_FOSCCSR_LK_MASK); +} + +/** + * @brief lock FOSC CSR register + * + */ +LOCAL_INLINE void SCG_HWA_LockFoscCsrReg(void) +{ + SCG->FOSCCSR |= (uint32_t)(SCG_FOSCCSR_LK_MASK); +} + +/** + * @brief Enable FOSC clock monitor + * + */ +LOCAL_INLINE void SCG_HWA_EnableFoscClockMonitor(void) +{ + SCG->FOSCCSR |= (uint32_t)(SCG_FOSCCSR_CM_MASK); +} + +/** + * @brief Enable FOSC clock monitor Reset + * + */ +LOCAL_INLINE void SCG_HWA_EnableFoscClockMonitorReset(void) +{ + SCG->FOSCCSR |= (uint32_t)(SCG_FOSCCSR_CMRE_MASK); +} + +/** + * @brief enable FOSCDIV as user manual request sequence + * @param DivEn the or value of SCG_DivEnableType + */ +LOCAL_INLINE void SCG_HWA_EnableFoscDiv(SCG_DivEnableType DivEn) +{ + SCG->FOSCDIV |= (uint32_t)DivEn; +} + +/** + * @brief Disable FOSCDIV as user manual request sequence + * @param DivEn the or value of SCG_DivEnableType + */ +LOCAL_INLINE void SCG_HWA_DiableFoscDiv(SCG_DivEnableType DivEn) +{ + SCG->FOSCDIV &= ~(uint32_t)DivEn; +} + +/** + * @brief Get the acknowledgment of DIV clocks enabled by SCG_HWA_EnableFoscDiv + * @param DivEn the or value of SCG_DivEnableType + * @return bool true : The enabled DIV clocks are acknowledged + * false : The enabled DIV clocks are not acknowledged + */ +LOCAL_INLINE bool SCG_HWA_GetFoscDivAck(SCG_DivEnableType DivEn) +{ + return (bool)((SCG->FOSCDIV & (DivEn << SCG_CLOCKDIV_EN2ACK_SHIFT)) == (DivEn << SCG_CLOCKDIV_EN2ACK_SHIFT)); +} + +/** + * @brief Set FOSCDIV register value + * + * @param u32DivValue configured register value + */ +LOCAL_INLINE void SCG_HWA_SetFoscDiv(uint32_t u32DivValue) +{ + SCG->FOSCDIV = u32DivValue; +} + +/** + * @brief Set Low Power Wakeup WDOG Register + * + * @param u8MSBVal Most Significant value, if OSC is 40M + * and FOSC not valid after 1.8ms wakeup, + * the chip will reset and RGM register will + * report clock error reset reason. + */ +LOCAL_INLINE void SCG_HWA_SetWKPWDG(uint8_t u8MSBVal) +{ + SCG->WKPWDG = SCG_WKPWDG_MSB(u8MSBVal) | SCG_WKPWDG_EN_MASK; +} + + + +/********* Sirc Register interface ************/ +/** + * @brief Set SIRCCSR register value + * + * @param u32CsrValue configured register value + */ +LOCAL_INLINE void SCG_HWA_SetSircCsr(uint32_t u32CsrValue) +{ + SCG->SIRCCSR = u32CsrValue; +} + +/** + * @brief Get SIRCCSR register value + * + */ +LOCAL_INLINE uint32_t SCG_HWA_GetSircCsr(void) +{ + return (uint32_t)SCG->SIRCCSR; +} + +/** + * @brief Unlock SIRC CSR register + * + */ +LOCAL_INLINE void SCG_HWA_UnlockSircCsrReg(void) +{ + SCG->SIRCCSR &= ~(uint32_t)SCG_SIRCCSR_LK_MASK; +} + +/** + * @brief Lock SIRC CSR register + * + */ +LOCAL_INLINE void SCG_HWA_LockSircCsrReg(void) +{ + SCG->SIRCCSR |= (uint32_t)SCG_SIRCCSR_LK_MASK; +} + +/** + * @brief Enable SIRC clock monitor + * + */ +LOCAL_INLINE void SCG_HWA_EnableSircClockMonitor(void) +{ + SCG->SIRCCSR |= (uint32_t)(SCG_SIRCCSR_CM_MASK); +} + +/** + * @brief Set SIRCDIV register value + * + * @param u32DivValue configured register value + */ +LOCAL_INLINE void SCG_HWA_SetSircDiv(uint32_t u32DivValue) +{ + SCG->SIRCDIV = u32DivValue; +} + +/** + * @brief enable SIRCDIV as user manual request sequence + * @param DivEn the or value of SCG_DivEnableType + */ +LOCAL_INLINE void SCG_HWA_EnableSircDiv(SCG_DivEnableType DivEn) +{ + SCG->SIRCDIV |= (uint32_t)DivEn; +} + +/** + * @brief Disable SIRCDIV as user manual request sequence + * @param DivEn the or value of SCG_DivEnableType + */ +LOCAL_INLINE void SCG_HWA_DiableSircDiv(SCG_DivEnableType DivEn) +{ + SCG->SIRCDIV &= ~(uint32_t)DivEn; +} + +/** + * @brief Get the acknowledgment of DIV clocks enabled by SCG_HWA_EnableSircDiv + * @param DivEn the or value of SCG_DivEnableType + * @return bool true : The enabled DIV clocks are acknowledged + * false : The enabled DIV clocks are not acknowledged + */ +LOCAL_INLINE bool SCG_HWA_GetSircDivAck(SCG_DivEnableType DivEn) +{ + return (bool)((SCG->SIRCDIV & (DivEn << SCG_CLOCKDIV_EN2ACK_SHIFT)) == (DivEn << SCG_CLOCKDIV_EN2ACK_SHIFT)); +} + +/** + * @brief Set SIRCTCFG register value for SIRC Trim configure. + * + * @param u32TcfgValue configured register value + */ +LOCAL_INLINE void SCG_HWA_SetSircTcfg(uint32_t u32TcfgValue) +{ + SCG->SIRCTCFG = u32TcfgValue; +} + +/********* Sirc32k Register interface ************/ +/** + * @brief Enable SIRC32KCSR register + * + */ +LOCAL_INLINE void SCG_HWA_EnableSirc32kCsr(void) +{ + SCG->SIRC32KCSR |= (uint32_t)SCG_SIRC32KCSR_EN_MASK; +} + +/** + * @brief Disable SIRC32KCSR register + * + */ +LOCAL_INLINE void SCG_HWA_DisableSirc32kCsr(void) +{ + SCG->SIRC32KCSR &= ~(uint32_t)SCG_SIRC32KCSR_EN_MASK; +} + +/** + * @brief Unlock SIRC32K CSR register + */ +LOCAL_INLINE void SCG_HWA_UnlockSirc32kCsrReg(void) +{ + SCG->SIRC32KCSR &= ~(uint32_t)(SCG_SIRC32KCSR_LK_MASK); +} + +/** + * @brief Lock SIRC32K CSR register + */ +LOCAL_INLINE void SCG_HWA_LockSirc32kCsrReg(void) +{ + SCG->SIRC32KCSR |= (uint32_t)(SCG_SIRC32KCSR_LK_MASK); +} + +/********* Firc Register interface ************/ +/** + * @brief Get FIRC CSR register value. + */ +LOCAL_INLINE uint32_t SCG_HWA_GetFircCsr(void) +{ + return (uint32_t)SCG->FIRCCSR; +} + +/** + * @brief Enable FIRC. + */ +LOCAL_INLINE void SCG_HWA_EnableFirc(void) +{ + SCG->FIRCCSR |= (uint32_t)SCG_FIRCCSR_EN_MASK; +} + +/** + * @brief Unlock FIRC CSR register + */ +LOCAL_INLINE void SCG_HWA_UnlockFircCsrReg(void) +{ + SCG->FIRCCSR &= ~(uint32_t)(SCG_FIRCCSR_LK_MASK); +} + +/** + * @brief Lock FIRC CSR register + */ +LOCAL_INLINE void SCG_HWA_LockFircCsrReg(void) +{ + SCG->FIRCCSR |= (uint32_t)(SCG_FIRCCSR_LK_MASK); +} + +/** + * @brief Enable FIRC clock monitor + * + */ +LOCAL_INLINE void SCG_HWA_EnableFircClockMonitor(void) +{ + SCG->FIRCCSR |= (uint32_t)(SCG_FIRCCSR_CM_MASK); +} + +/** + * @brief Disable FIRC. + */ +LOCAL_INLINE void SCG_HWA_DisableFirc(void) +{ + SCG->FIRCCSR &= ~(uint32_t)SCG_FIRCCSR_EN_MASK; +} + +/** + * @brief Set FIRCCSR register value + * + * @param u32CsrValue configured register value + */ +LOCAL_INLINE void SCG_HWA_SetFircCsr(uint32_t u32CsrValue) +{ + SCG->FIRCCSR = u32CsrValue; +} + +/** + * @brief Set FIRCCFG register value + * + * @param u32CfgValue configured register value + */ +LOCAL_INLINE void SCG_HWA_SetFircCfg(uint32_t u32CfgValue) +{ + SCG->FIRCCFG = u32CfgValue; +} + +/** + * @brief Set FOSCDIV register value + * + * @param u32DivValue configured register value + */ +LOCAL_INLINE void SCG_HWA_SetFircDiv(uint32_t u32DivValue) +{ + SCG->FIRCDIV = u32DivValue; +} + +/** + * @brief enable FIRCDIV as user manual request sequence + * @param DivEn the or value of SCG_DivEnableType + */ +LOCAL_INLINE void SCG_HWA_EnableFircDiv(SCG_DivEnableType DivEn) +{ + SCG->FIRCDIV |= (uint32_t)DivEn; +} + +/** + * @brief Disable FIRCDIV as user manual request sequence + * @param DivEn the or value of SCG_DivEnableType + */ +LOCAL_INLINE void SCG_HWA_DiableFircDiv(SCG_DivEnableType DivEn) +{ + SCG->FIRCDIV &= ~(uint32_t)DivEn; +} + +/** + * @brief Get the acknowledgment of DIV clocks enabled by SCG_HWA_EnableFircDiv + * @param DivEn the or value of SCG_DivEnableType + * @return bool true : The enabled DIV clocks are acknowledged + * false : The enabled DIV clocks are not acknowledged + */ +LOCAL_INLINE bool SCG_HWA_GetFircDivAck(SCG_DivEnableType DivEn) +{ + return (bool)((SCG->FIRCDIV & (DivEn << SCG_CLOCKDIV_EN2ACK_SHIFT)) == (DivEn << SCG_CLOCKDIV_EN2ACK_SHIFT)); +} + +/** + * @brief Set FIRCTCFG register value for FIRC clock trim configure. + * + * @param u32TcfgValue configured register value. + */ +LOCAL_INLINE void SCG_HWA_SetFircTcfg(uint32_t u32TcfgValue) +{ + SCG->FIRCTCFG = u32TcfgValue; +} + + +/********* PLL0 clock Register interface ************/ +/** + * @brief enable PLL0DIV as user manual request sequence + * @param DivEn the or value of SCG_DivEnableType + */ +LOCAL_INLINE void SCG_HWA_EnablePll0Div(SCG_DivEnableType DivEn) +{ + SCG->PLL0DIV |= (uint32_t)DivEn; +} + +/** + * @brief Disable FOSCDIV as user manual request sequence + * @param DivEn the or value of SCG_DivEnableType + */ +LOCAL_INLINE void SCG_HWA_DiablePll0Div(SCG_DivEnableType DivEn) +{ + SCG->PLL0DIV &= ~(uint32_t)DivEn; +} + +/** + * @brief Get the acknowledgment of DIV clocks enabled by SCG_HWA_EnablePll0Div + * @param DivEn the or value of SCG_DivEnableType + * @return bool true : The enabled DIV clocks are acknowledged + * false : The enabled DIV clocks are not acknowledged + */ +LOCAL_INLINE bool SCG_HWA_GetPll0DivAck(SCG_DivEnableType DivEn) +{ + return (bool)((SCG->PLL0DIV & (DivEn << SCG_CLOCKDIV_EN2ACK_SHIFT)) == (DivEn << SCG_CLOCKDIV_EN2ACK_SHIFT)); +} + + +/********* PLL1 clock Register interface ************/ +/** + * @brief enable PLL0DIV as user manual request sequence + * @param DivEn the or value of SCG_DivEnableType + */ +LOCAL_INLINE void SCG_HWA_EnablePll1Div(SCG_DivEnableType DivEn) +{ + SCG->PLL1DIV |= (uint32_t)DivEn; +} + +/** + * @brief Disable FOSCDIV as user manual request sequence + * @param DivEn the or value of SCG_DivEnableType + */ +LOCAL_INLINE void SCG_HWA_DiablePll1Div(SCG_DivEnableType DivEn) +{ + SCG->PLL1DIV &= ~(uint32_t)DivEn; +} + +/** + * @brief Get the acknowledgment of DIV clocks enabled by SCG_HWA_EnablePll1Div + * @param DivEn the or value of SCG_DivEnableType + * @return bool true : The enabled DIV clocks are acknowledged + * false : The enabled DIV clocks are not acknowledged + */ +LOCAL_INLINE bool SCG_HWA_GetPll1DivAck(SCG_DivEnableType DivEn) +{ + return (bool)((SCG->PLL1DIV & (DivEn << SCG_CLOCKDIV_EN2ACK_SHIFT)) == (DivEn << SCG_CLOCKDIV_EN2ACK_SHIFT)); +} + +/********* System clock Register interface ************/ +/** + * @brief Get system clock CCR register value + * + * @return system clock CCR register value + */ +LOCAL_INLINE uint32_t SCG_HWA_GetCCR(void) +{ + return SCG->CCR; +} + +/** + * @brief Set system clock CCR register value + * + * @param u32CcrValue configured register value + */ +LOCAL_INLINE void SCG_HWA_SetCCR(uint32_t u32CcrValue) +{ + SCG->CCR = u32CcrValue; +} + +/** + * @brief Set system clock + * + * @param u8SystemCLock System clock value + */ +LOCAL_INLINE void SCG_HWA_SetSystemClock(uint8_t u8SystemCLock) +{ + SCG->CCR = ((SCG->CCR & ~(uint32_t)SCG_CCR_SCS_MASK) | SCG_CCR_SCS(u8SystemCLock)); +} + +/** + * @brief Get system clock source. used to calculate system clock frequency at startup. + * used to check if the target clock soure successfully switched. + * @return uint8_t. system clock source. + */ +LOCAL_INLINE uint8_t SCG_HWA_GetSysClkSrc(void) +{ + return (uint8_t)(((uint32_t)(SCG->CSR) & (uint32_t)SCG_CSR_SCS_MASK) >> SCG_CSR_SCS_SHIFT); +} + +/** + * @brief Get system clock valid status, use this status to check system clock update finished or not. + * @return bool. true as updated; false as not updated. + */ +LOCAL_INLINE bool SCG_HWA_GetSysClkUPRD(void) +{ + return (bool)((((uint32_t)SCG->CSR & (uint32_t)SCG_CSR_CCR_UPRD_MASK) != 0U) ? true : false); +} + +/** + * @brief Get system clock Divcore. used to calculate core clock frequency at startup. + * @return uint8_t. system clock Divcore. + */ +LOCAL_INLINE uint8_t SCG_HWA_GetSysClkDivCore(void) +{ + return (uint8_t)(((uint32_t)(SCG->CSR) & SCG_CSR_DIVCORE_MASK) >> SCG_CSR_DIVCORE_SHIFT); +} + +/** + * @brief Get system clock Divbus. used to calculate bus clock frequency at startup. + * @return uint8_t. system clock Divbus. + */ +LOCAL_INLINE uint8_t SCG_HWA_GetSysClkDivBus(void) +{ + return (uint8_t)(((uint32_t)(SCG->CSR) & SCG_CSR_DIVBUS_MASK) >> SCG_CSR_DIVBUS_SHIFT); +} + +/** + * @brief Get system clock Divslow. used to calculate slow clock frequency at startup. + * @return uint8_t. system clock Divslow. + */ +LOCAL_INLINE uint8_t SCG_HWA_GetSysClkDivSlow(void) +{ + return (uint8_t)(((uint32_t)(SCG->CSR) & SCG_CSR_DIVSLOW_MASK) >> SCG_CSR_DIVSLOW_SHIFT); +} + +/********* Clkout Register interface ************/ +/** + * @brief Select clock out source + * + * @param u8ClkOutSel Clock out select + */ +LOCAL_INLINE void SCG_HWA_SetClkOutSel(uint8_t u8ClkOutSel) +{ + SCG->CLKOUTCFG = ((SCG->CLKOUTCFG & ~(uint32_t)SCG_CLKOUTCFG_CLKOUTSEL_MASK) | SCG_CLKOUTCFG_CLKOUTSEL(u8ClkOutSel)); +} + +/** + * @brief Set Nvm clock source + * + * @param u32NvmClkMask Nvm clock source mask + */ +LOCAL_INLINE void SCG_HWA_SetNvmClk(uint32_t u32NvmClkMask) +{ + SCG->CLKOUTCFG &= ~(uint32_t)(SCG_CLKOUTCFG_NVMCLK_FIRC_MASK | SCG_CLKOUTCFG_NVMCLK_SIRC_MASK); + SCG->CLKOUTCFG |= u32NvmClkMask; +} + +/** + * @brief Set CMU4 clock source + * + * @param u32Cmu4ClkMask CMU4 clock source mask + */ +LOCAL_INLINE void SCG_HWA_SetCmu4Clk(uint32_t u32Cmu4ClkMask) +{ + SCG->CLKOUTCFG &= ~(uint32_t)(SCG_CLKOUTCFG_CMU4CLK_FOSC_MASK | SCG_CLKOUTCFG_CMU4CLK_SIRC_MASK); + SCG->CLKOUTCFG |= u32Cmu4ClkMask; +} + +/********* CRC Register interface ************/ +/** + * @brief Generate SCG register CRC value + */ +LOCAL_INLINE void SCG_HWA_GenCrcVal(void) +{ + SCG->CRCCSR |= (uint32_t)SCG_CRCCSR_GEN_MASK; +} + +/** + * @brief Enable SCG register CRC check + */ +LOCAL_INLINE void SCG_HWA_EnableCrcCheck(void) +{ + SCG->CRCCSR |= (uint32_t)SCG_CRCCSR_CHKEN_MASK; +} + +/** + * @brief Disable SCG register CRC check + */ +LOCAL_INLINE void SCG_HWA_DisableCrcCheck(void) +{ + SCG->CRCCSR &= ~(uint32_t)SCG_CRCCSR_CHKEN_MASK; +} + +/** + * @brief Enable SCG register CRC error output + */ +LOCAL_INLINE void SCG_HWA_EnableCrcErrorOutput(void) +{ + SCG->CRCCSR |= (uint32_t)SCG_CRCCSR_EOEN_MASK; +} + +/** + * @brief Disable SCG register CRC error output + */ +LOCAL_INLINE void SCG_HWA_DisableCrcErrorOutput(void) +{ + SCG->CRCCSR &= ~(uint32_t)SCG_CRCCSR_EOEN_MASK; +} + +/** + * @brief Get CRC busy status + */ +LOCAL_INLINE bool SCG_HWA_GetCrcBusyStatus(void) +{ + return (0U != (SCG->CRCCSR & (uint32_t)SCG_CRCCSR_BUSY_MASK)); +} + +/** + * @brief Get CRC error status + */ +LOCAL_INLINE bool SCG_HWA_GetCrcErrorStatus(void) +{ + return (0U != (SCG->CRCCSR & (uint32_t)SCG_CRCCSR_ERR_MASK)); +} + +/** + * @brief Clear CRC error flag + */ +LOCAL_INLINE void SCG_HWA_ClearCrcErrorFlag(void) +{ + SCG->CRCCSR |= (uint32_t)SCG_CRCCSR_ERR_MASK; +} + +/** + * @brief Get CRC result + */ +LOCAL_INLINE uint32_t SCG_HWA_GetCrcResult(void) +{ + return SCG->CRCRES; +} + +/** + * @brief Enable SCG register CRC trigger mode + */ +LOCAL_INLINE void SCG_HWA_EnableCrcTriggerMode(void) +{ + SCG->CRCCSR |= (uint32_t)SCG_CRCCSR_TRGEN_MASK; +} + +/** + * @brief Disable SCG register CRC trigger mode + */ +LOCAL_INLINE void SCG_HWA_DisableCrcTriggerMode(void) +{ + SCG->CRCCSR &= ~(uint32_t)SCG_CRCCSR_TRGEN_MASK; +} + +/** @}*/ /* HwA_SCG */ + +#endif /* #ifndef _HWA_SCG_H_ */ diff --git a/MODULES/HwA_Flagchip_FC7240/Inc/HwA_scm.h b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_scm.h new file mode 100644 index 0000000..40e5e72 --- /dev/null +++ b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_scm.h @@ -0,0 +1,2388 @@ +/** + * @file HwA_scm.h + * @author Flagchip085 + * @brief Hardware access layer for SCM + * @version 0.1.0 + * @date 2024-01-12 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-01-12 Flagchip085 N/A First version for FC7240 + ******************************************************************************** */ + +#ifndef _HWA_SCM_H_ +#define _HWA_SCM_H_ +#include "device_header.h" + +/********* Local typedef ************/ + +/** + * @brief WPB cpu type + * + */ +typedef enum +{ + SCM_WP_CPU_ALL = 0U, /*!< All CPUs are allowed to write this peripheral */ + SCM_WP_CPU_0 = 1U, /*!< Only CPU0 is allowed to control this peripheral */ + SCM_WP_CPU_NONE /*!< No CPU is allowed to control this peripheral */ +} SCM_WPB_CpuType; + +/** + * @brief ECC Enable mode Control type + * + */ +typedef enum +{ + SCM_ECC_WRITE_EN_READ_DIS = 2U, /*!< ECC Generate Enable During Write, ECC Check Disable During Read */ + SCM_ECC_WRITE_EN_READ_EN = 3U /*!< ECC Generate Enable During Write, ECC Check Enable During Read */ +} SCM_EccEnModeType; + +/** + * @brief MAMECCEN0 MAM ECC Enable group 0 type + * + */ +typedef enum +{ + SCM_MAM0_S0_ECC = 0U, /*!< MAM0 S0 ROM Array ECC Enable Control */ + SCM_MAM0_S1_ECC = 1U, /*!< MAM0 S1 PFlash Slave ECC Enable Control */ + SCM_MAM0_S2_ECC = 3U, /*!< MAM0 S2 DFlash Slave ECC Enable Control */ + SCM_MAM0_S3_ECC = 4U, /*!< MAM0 S3 SRAM0 Slave ECC Enable Control */ + SCM_MAM0_S4_ECC = 5U, /*!< MAM0 S4 SRAM1 Slave ECC Enable Control */ + SCM_MAM0_S5_ECC = 7U, /*!< MAM0 S5 TCM Slave ECC Enable Control */ + SCM_MAM0_S6_ECC = 8U, /*!< MAM0 S6 AFCB0 Slave ECC Enable Control */ + SCM_MAM0_S7_ECC = 9U, /*!< MAM0 S7 AFCB1 Slave ECC Enable Control */ + SCM_MAM0_S8_ECC = 10U, /*!< MAM0 S8 GPIO Slave ECC Enable Control */ + SCM_SRAM0_ECC = 11U, /*!< SRAM0 Array ECC Enable Control */ + SCM_SRAM1_ECC = 12U /*!< SRAM1 Array ECC Enable Control */ +} SCM_MAMEccCtrlGrp0Type; + +/** + * @brief MAMECCEN1 MAM ECC Enable group 1 type + * + */ +typedef enum +{ + SCM_HSM_ECC = 0U, /*!< HSM Master ECC Enable Control */ + SCM_DMA0_ECC = 2U, /*!< DMA0 Master ECC Enable Control */ + SCM_DMA0_CFG_ECC = 4U, /*!< DMA0 CFG Memory ECC Enable Control */ + SCM_HSM_DRAM_ECC = 5U, /*!< HSM DRAM Memory ECC Enable Control */ + SCM_HSM_IRAM_ECC = 6U /*!< HSM IRAM Memory ECC Enable Control */ +} SCM_MAMEccCtrlGrp1Type; + +/** + * @brief CPU0 ECC Enable Register type + * + */ +typedef enum +{ + SCM_CPUXECCEN_CPUX_AHBM_ECC = 0U, /*!< SCM_CPUXECCEN_CPUX_AHBM_ECC peripheral */ + SCM_CPUXECCEN_CPUX_AHBP_ECC = 1U, /*!< SCM_CPUXECCEN_CPUX_AHBP_ECC peripheral */ + SCM_CPUXECCEN_CPUX_AHBS_ECC = 2U, /*!< SCM_CPUXECCEN_CPUX_AHBS_ECC peripheral */ + SCM_CPUXECCEN_CPUX_DTCM0_ECC = 3U, /*!< SCM_CPUXECCEN_CPUX_DTCM0_ECC peripheral */ + SCM_CPUXECCEN_CPUX_DTCM1_ECC = 4U, /*!< SCM_CPUXECCEN_CPUX_DTCM1_ECC peripheral */ + SCM_CPUXECCEN_CPUX_ITCM_ECC = 5U /*!< SCM_CPUXECCEN_CPUX_ITCM_ECC peripheral */ +} SCM_CPUEccCtrlType; + +/** + * @brief FCSPI monitor type + * + */ +typedef enum +{ + SCM_MON_FCSPI0 = 0U, /*!< Monitor FCSPI0's transmit interface */ + SCM_MON_FCSPI1, /*!< Monitor FCSPI1's transmit interface */ + SCM_MON_FCSPI2, /*!< Monitor FCSPI2's transmit interface */ + SCM_MON_FCSPI3, /*!< Monitor FCSPI3's transmit interface */ + SCM_MON_FCSPI4, /*!< Monitor FCSPI4's transmit interface */ + SCM_MON_FCSPI5 /*!< Monitor FCSPI5's transmit interface */ +} SCM_FCSPIxType; + +/** + * @brief FCUART monitor type + * + */ +typedef enum +{ + SCM_MON_FCUART0 = 0U, /*!< Monitor FCUART0's transmit interface */ + SCM_MON_FCUART1, /*!< Monitor FCUART1's transmit interface */ + SCM_MON_FCUART2, /*!< Monitor FCUART2's transmit interface */ + SCM_MON_FCUART3, /*!< Monitor FCUART3's transmit interface */ + SCM_MON_FCUART4, /*!< Monitor FCUART4's transmit interface */ + SCM_MON_FCUART5, /*!< Monitor FCUART5's transmit interface */ + SCM_MON_FCUART6, /*!< Monitor FCUART6's transmit interface */ + SCM_MON_FCUART7 /*!< Monitor FCUART7's transmit interface */ +} SCM_MON_FCUARTxType; + +/** + * @brief PTIMER Loop Mode Select type + * + */ +typedef enum +{ + SCM_LM_PTMR0CH0_PTMR1CH0 = 0U,/*!< PTIMER0 CH0 loop, PTIMER1 CH0 loop */ + SCM_LM_PTMR1CH0_CH1 = 1U,/*!< PTIMER1 CH0 and CH1 in loop mode */ + SCM_LM_PTMR0CH0_CH1 = 2U,/*!< PTIMER0 CH0 and CH1 in loop mode */ + SCM_LM_PTMR0CH0CH1_PTMR1CH0CH1 = 3U,/*!< PTIMER1 CH0 and CH1 in loop mode, PTIMER0 CH0 and CH1 in loop mode */ + SCM_LM_PTMR0_PTMR1_CH0 = 4U /*!< PTIMER0 CH0 and PTIMER1 CH0 in loop mode */ +} SCM_PTimerLMSelType; + +/** + * @brief ADC Trigger Source type + * + */ +typedef enum +{ + SCM_ADC_TRIGGER_SRC_PTIMER = 0U, /*!< ADC Trigger Source PTIMER output */ + SCM_ADC_TRIGGER_SRC_TRGSEL = 1U /*!< ADC Trigger Source TRGSEL output */ +} SCM_AdcTriggerSrcType; + +/** + * @brief ADC PreTrigger Source type + * + */ +typedef enum +{ + SCM_ADC_PRETRIGGER_PTIMER = 0U, /*!< ADC Pre-trigger PTIMER */ + SCM_ADC_PRETRIGGER_SCMSOFTWARE = 2U /*!< ADC Pre-trigger SCM software */ +} SCM_AdcPreTriggerSrcType; + +/** + * @brief ADC SCM software Pre-trigger Sources type + * + */ +typedef enum +{ + SCM_SOFTWARE_PRETRIGGER_DISABLED = 0U, /*!< SCM Software pre-trigger disabled */ + SCM_SOFTWARE_PRETRIGGER_0 = 4U, /*!< SCM Software pre-trigger 0 */ + SCM_SOFTWARE_PRETRIGGER_1 = 5U, /*!< SCM Software pre-trigger 1 */ + SCM_SOFTWARE_PRETRIGGER_2 = 6U, /*!< SCM Software pre-trigger 2 */ + SCM_SOFTWARE_PRETRIGGER_3 = 7U /*!< SCM Software pre-trigger 3 */ +} SCM_SoftwarePreTriggerType; + +/** + * @brief FTUx output source selection type + * + */ +typedef enum +{ + SCM_FTU_OUTPUT_STD = 0U, /*!< FTUx CHx output will direct route to corresponding pad(standard) */ + SCM_FTU_OUT_COMBINE /*!< FTUx pad output is equal to FTUx CHx output & FTUx CH1 output(combine) */ +} SCM_FTU_OutputSelType; + +/** + * @brief FTU2 CH1 input selection type + * + */ +typedef enum +{ + SCM_FTU_INPUT_STD = 0U, /*!< FTU2_CH1 input */ + SCM_FTU_INPUT_OR /*!< OR of FTU2_CH0,FTU2_CH1,and FTU1_CH1 */ +} SCM_FTU2_CH1_InputSelType; + +/** + * @brief FTUx CH0 input selection type + * + */ +typedef enum +{ + SCM_FTU_CH0_INPUT_STD = 0U, /*!< FTU2_CH0 input */ + SCM_FTU_CH0_INPUT_CMP0, /*!< CMP0 output */ + SCM_FTU_CH0_INPUT_CMP1 /*!< CMP1 output */ +} SCM_FTUx_CH0_InputSelType; + +/** + * @brief FTU Global Time Base Control type + * + */ +typedef enum +{ + SCM_FTU0_GTBC = 0x01U, /*!< FTU0 Global Time Base Control Select */ + SCM_FTU1_GTBC = 0x02U, /*!< FTU1 Global Time Base Control Select */ + SCM_FTU2_GTBC = 0x04U, /*!< FTU2 Global Time Base Control Select */ + SCM_FTU3_GTBC = 0x08U, /*!< FTU3 Global Time Base Control Select */ + SCM_FTU4_GTBC = 0x10U, /*!< FTU4 Global Time Base Control Select */ + SCM_FTU5_GTBC = 0x20U, /*!< FTU5 Global Time Base Control Select */ + SCM_FTU6_GTBC = 0x40U, /*!< FTU6 Global Time Base Control Select */ + SCM_FTU7_GTBC = 0x80U, /*!< FTU7 Global Time Base Control Select */ +} SCM_FTUGTBCtrlType; + +/** + * @brief FTU SYNC Control type + * + */ +typedef enum +{ + SCM_FTU0_SYNC = SCM_FTU_SYNC_FTU0SYNC_MASK, /*!< FTU0 Sync Control */ + SCM_FTU1_SYNC = SCM_FTU_SYNC_FTU1SYNC_MASK, /*!< FTU1 Sync Control */ + SCM_FTU2_SYNC = SCM_FTU_SYNC_FTU2SYNC_MASK, /*!< FTU2 Sync Control */ + SCM_FTU3_SYNC = SCM_FTU_SYNC_FTU3SYNC_MASK, /*!< FTU3 Sync Control */ + SCM_FTU4_SYNC = SCM_FTU_SYNC_FTU4SYNC_MASK, /*!< FTU4 Sync Control */ + SCM_FTU5_SYNC = SCM_FTU_SYNC_FTU5SYNC_MASK, /*!< FTU5 Sync Control */ + SCM_FTU6_SYNC = SCM_FTU_SYNC_FTU6SYNC_MASK, /*!< FTU6 Sync Control */ + SCM_FTU7_SYNC = SCM_FTU_SYNC_FTU7SYNC_MASK, /*!< FTU7 Sync Control */ +} SCM_FTUSyncCtrlType; + +/** + * @brief Trace clock selection + * + */ +typedef enum +{ + SCM_TRACE_CORE_CLK = 0U, /*!< Select platform fclk to trace clock */ + SCM_TRACE_PLL1DIVH_CLK = 1U /*!< Select SCG PLL1 platform clock to trace clock */ +} SCM_TraceClkSrcType; + +/** + * @brief Software trigger to TRGSEL0/TRGSEL1 + * + */ +typedef enum +{ + SCM_SW_TRIG_0 = 1U, /*!< Generate software trigger0 to (TRGSEL0 & TRGSEL4) */ + SCM_SW_TRIG_1 = 2U, /*!< Generate software trigger1 to (TRGSEL0 & TRGSEL4) */ + SCM_SW_TRIG_2 = 4U, /*!< Generate software trigger2 to (TRGSEL0 & TRGSEL4) */ + SCM_SW_TRIG_3 = 8U, /*!< Generate software trigger3 to (TRGSEL0 & TRGSEL4) */ + SCM_SW_TRIG_4 = 1U, /*!< Generate software trigger4 to (TRGSEL1 & TRGSEL5) */ + SCM_SW_TRIG_5 = 2U, /*!< Generate software trigger5 to (TRGSEL1 & TRGSEL5) */ + SCM_SW_TRIG_6 = 4U, /*!< Generate software trigger6 to (TRGSEL1 & TRGSEL5) */ + SCM_SW_TRIG_7 = 8U /*!< Generate software trigger7 to (TRGSEL1 & TRGSEL5) */ +} SCM_SwTrigxType; + +/** + * @brief Software trigger to TRGSEL0/TRGSEL1 + * + */ +typedef enum +{ + SCM_CCM0_STATUS_CPU_STOP_SYS_SLAVE = SCM_CCM0_STATUS_CPU0_STOP_SYS_SLAVE_MASK, /*!< CCM0 FCG Stop Sys Slave Ack */ + SCM_CCM0_STATUS_CPU_STOP_MASTER = SCM_CCM0_STATUS_CPU0_STOP_MASTER_MASK, /*!< CCM0 FCG Stop Master Ack */ + SCM_CCM0_STATUS_CPU_STOP_SLOW_SLAVE = SCM_CCM0_STATUS_CPU0_STOP_SLOW_SLAVE_MASK,/*!< CCM0 FCG Stop Slow Slave Ack */ + SCM_CCM0_STATUS_CPU_STOP_BUS_SLAVE = SCM_CCM0_STATUS_CPU0_STOP_BUS_SLAVE_MASK, /*!< CCM0 FCG Stop Bus Slave Ack */ + SCM_CCM0_STATUS_CPU_DEEPSLEEPING = SCM_CCM0_STATUS_CPU0_DEEPSLEEPING_MASK, /*!< CPU0 Sleepdeep */ + SCM_CCM0_STATUS_CPU_SLEEPING = SCM_CCM0_STATUS_CPU0_SLEEPING_MASK /*!< CPU0 Sleeping */ +} SCM_CCMxStatusType; + +/** + * @brief SDDF channel clock output selection + * + */ +typedef enum +{ + SCM_SDDF0_RESERVE = 0U, /*!< Reserved */ + SCM_SDDF0_CLKO0, /*!< SDDF0 CLKO0 */ + SCM_SDDF0_CLKO1, /*!< SDDF0 CLKO1 */ + SCM_SDDF0_CLKO2 /*!< SDDF0 CLKO2 */ +} SCM_SDDF_ClkOutSelType; + +/** + * @brief SDDF channel clock input selection + * + */ +typedef enum +{ + SCM_SDDF0_CLK0_IND = 0U, /*!< SDDF0 CLK0_IND */ + SCM_SDDF0_CLK1_IND, /*!< SDDF0 CLK1_IND */ + SCM_SDDF0_CLK2_IND, /*!< SDDF0 CLK2_IND */ + SCM_SDDF0_CLK3_IND /*!< SDDF0 CLK3_IND */ +} SCM_SDDF_ClkInSelType; + +/** + * @brief FLEXCAN routing selection + * + */ +typedef enum +{ + SCM_FLEXCAN_9_9_OR_8_8 = 0U, /*!< FLEXCAN 9 Rx/Tx pad from/to FLEXCAN 9 Rx/Tx pad or + FLEXCAN 8 Rx/Tx pad from/to FLEXCAN 8 Rx/Tx pad */ + SCM_FLEXCAN_9_1_OR_8_0, /*!< FLEXCAN 9 Rx/Tx pad from/to FLEXCAN 1 Rx/Tx pad or + FLEXCAN 8 Rx/Tx pad from/to FLEXCAN 0 Rx/Tx pad */ + SCM_FLEXCAN_9_3_OR_8_2, /*!< FLEXCAN 9 Rx/Tx pad from/to FLEXCAN 3 Rx/Tx pad or + FLEXCAN 8 Rx/Tx pad from/to FLEXCAN 2 Rx/Tx pad */ + SCM_FLEXCAN_9_5_OR_8_4 /*!< FLEXCAN 9 Rx/Tx pad from/to FLEXCAN 5 Rx/Tx pad or + FLEXCAN 8 Rx/Tx pad from/to FLEXCAN 4 Rx/Tx pad */ +} SCM_FlexCanRouterType; + +/** + * @brief MSC routing selection + * + */ +typedef enum +{ + SCM_MSC_FTU0_TO_MSC = 0U, /*!< Select FTU0 ch do out[7:0] to MSCx ALTIN[31:24]/[23:16]/[15:8]/[7:0] */ + SCM_MSC_FTU1_TO_MSC, /*!< Select FTU1 ch do out[7:0] to MSCx ALTIN[31:24]/[23:16]/[15:8]/[7:0] */ + SCM_MSC_FTU2_TO_MSC, /*!< Select FTU2 ch do out[7:0] to MSCx ALTIN[31:24]/[23:16]/[15:8]/[7:0] */ + SCM_MSC_FTU3_TO_MSC, /*!< Select FTU3 ch do out[7:0] to MSCx ALTIN[31:24]/[23:16]/[15:8]/[7:0] */ + SCM_MSC_FTU4_TO_MSC, /*!< Select FTU4 ch do out[7:0] to MSCx ALTIN[31:24]/[23:16]/[15:8]/[7:0] */ + SCM_MSC_FTU5_TO_MSC, /*!< Select FTU5 ch do out[7:0] to MSCx ALTIN[31:24]/[23:16]/[15:8]/[7:0] */ + SCM_MSC_FTU6_TO_MSC, /*!< Select FTU6 ch do out[7:0] to MSCx ALTIN[31:24]/[23:16]/[15:8]/[7:0] */ + SCM_MSC_FTU7_TO_MSC /*!< Select FTU7 ch do out[7:0] to MSCx ALTIN[31:24]/[23:16]/[15:8]/[7:0] */ +} SCM_MSCAltInSelType; + +/** + * @brief ISM routing selection + * + */ +typedef enum +{ + SCM_ISM_FTU0_TO_TRGSEL3 = 0U, /*!< Select FTU0 ch do out[7:0] to TRGSEL3 source [89:82]/[81:74] */ + SCM_ISM_FTU1_TO_TRGSEL3, /*!< Select FTU1 ch do out[7:0] to TRGSEL3 source [89:82]/[81:74] */ + SCM_ISM_FTU2_TO_TRGSEL3, /*!< Select FTU2 ch do out[7:0] to TRGSEL3 source [89:82]/[81:74] */ + SCM_ISM_FTU3_TO_TRGSEL3, /*!< Select FTU3 ch do out[7:0] to TRGSEL3 source [89:82]/[81:74] */ + SCM_ISM_FTU4_TO_TRGSEL3, /*!< Select FTU4 ch do out[7:0] to TRGSEL3 source [89:82]/[81:74] */ + SCM_ISM_FTU5_TO_TRGSEL3, /*!< Select FTU5 ch do out[7:0] to TRGSEL3 source [89:82]/[81:74] */ + SCM_ISM_FTU6_TO_TRGSEL3, /*!< Select FTU6 ch do out[7:0] to TRGSEL3 source [89:82]/[81:74] */ + SCM_ISM_FTU7_TO_TRGSEL3 /*!< Select FTU7 ch do out[7:0] to TRGSEL3 source [89:82]/[81:74] */ +} SCM_ISMRouterType; + +/** + * @brief Matrix status register 0 type + * + */ +typedef enum +{ + SCM_MATRIX_STATUS0_MAM0_S5_M = SCM_MATRIX_STATUS0_MAM0_S5_M_MASK, /*!< MAM0_S5 slave ECC multi bit data error */ + SCM_MATRIX_STATUS0_MAM0_S5_AT = SCM_MATRIX_STATUS0_MAM0_S5_AT_MASK, /*!< MAM0_S5 slave ECC attribute error */ + SCM_MATRIX_STATUS0_MAM0_S5_D = SCM_MATRIX_STATUS0_MAM0_S5_D_MASK, /*!< MAM0_S5 slave ECC single bit data error */ + SCM_MATRIX_STATUS0_MAM0_S5_A = SCM_MATRIX_STATUS0_MAM0_S5_A_MASK, /*!< MAM0_S5 slave ECC address error */ + SCM_MATRIX_STATUS0_MAM0_S4_M = SCM_MATRIX_STATUS0_MAM0_S4_M_MASK, /*!< MAM0_S4 slave ECC multi bit data error */ + SCM_MATRIX_STATUS0_MAM0_S4_AT = SCM_MATRIX_STATUS0_MAM0_S4_AT_MASK, /*!< MAM0_S4 slave ECC attribute error */ + SCM_MATRIX_STATUS0_MAM0_S4_D = SCM_MATRIX_STATUS0_MAM0_S4_D_MASK, /*!< MAM0_S4 slave ECC single bit data error */ + SCM_MATRIX_STATUS0_MAM0_S4_A = SCM_MATRIX_STATUS0_MAM0_S4_A_MASK, /*!< MAM0_S4 slave ECC address error */ + SCM_MATRIX_STATUS0_MAM0_S3_M = SCM_MATRIX_STATUS0_MAM0_S3_M_MASK, /*!< MAM0_S3 slave ECC multi bit data error */ + SCM_MATRIX_STATUS0_MAM0_S3_AT = SCM_MATRIX_STATUS0_MAM0_S3_AT_MASK, /*!< MAM0_S3 slave ECC attribute error */ + SCM_MATRIX_STATUS0_MAM0_S3_D = SCM_MATRIX_STATUS0_MAM0_S3_D_MASK, /*!< MAM0_S3 slave ECC single bit data error*/ + SCM_MATRIX_STATUS0_MAM0_S3_A = SCM_MATRIX_STATUS0_MAM0_S3_A_MASK, /*!< MAM0_S3 slave ECC address error */ + SCM_MATRIX_STATUS0_MAM0_S2_M = SCM_MATRIX_STATUS0_MAM0_S2_M_MASK, /*!< MAM0_S2 slave ECC multi bit data error*/ + SCM_MATRIX_STATUS0_MAM0_S2_AT = SCM_MATRIX_STATUS0_MAM0_S2_AT_MASK, /*!< MAM0_S2 slave ECC attribute error */ + SCM_MATRIX_STATUS0_MAM0_S2_D = SCM_MATRIX_STATUS0_MAM0_S2_D_MASK, /*!< MAM0_S2 slave ECC single bit data error*/ + SCM_MATRIX_STATUS0_MAM0_S2_A = SCM_MATRIX_STATUS0_MAM0_S2_A_MASK, /*!< MAM0_S2 slave ECC address error */ + SCM_MATRIX_STATUS0_MAM0_S1_M = SCM_MATRIX_STATUS0_MAM0_S1_M_MASK, /*!< MAM0_S1 slave ECC multi bit data error */ + SCM_MATRIX_STATUS0_MAM0_S1_AT = SCM_MATRIX_STATUS0_MAM0_S1_AT_MASK, /*!< MAM0_S1 slave ECC attribute error */ + SCM_MATRIX_STATUS0_MAM0_S1_D = SCM_MATRIX_STATUS0_MAM0_S1_D_MASK, /*!< MAM0_S1 slave ECC single bit data error */ + SCM_MATRIX_STATUS0_MAM0_S1_A = SCM_MATRIX_STATUS0_MAM0_S1_A_MASK, /*!< MAM0_S1 slave ECC address error */ + SCM_MATRIX_STATUS0_ROM_M = SCM_MATRIX_STATUS0_ROM_M_MASK, /*!< ROM array ECC multi bit data error */ + SCM_MATRIX_STATUS0_ROM_D = SCM_MATRIX_STATUS0_ROM_D_MASK, /*!< ROM array ECC single bit data error */ + SCM_MATRIX_STATUS0_ROM_A = SCM_MATRIX_STATUS0_ROM_A_MASK /*!< ROM array ECC address error */ +} SCM_MatrixStatus0Type; + +/** + * @brief Matrix status register 1 type + * + */ +typedef enum +{ + SCM_MATRIX_STATUS1_DMA0_M = SCM_MATRIX_STATUS1_DMA0_M_MASK, /*!< DMA0 master ECC multi bit data error */ + SCM_MATRIX_STATUS1_DMA0_D = SCM_MATRIX_STATUS1_DMA0_D_MASK, /*!< DMA0 master ECC single bit data error */ + SCM_MATRIX_STATUS1_DMA0_A = SCM_MATRIX_STATUS1_DMA0_A_MASK, /*!< DMA0 master ECC address error */ + SCM_MATRIX_STATUS1_HSM_M = SCM_MATRIX_STATUS1_HSM_M_MASK, /*!< HSM master ECC multi bit data error */ + SCM_MATRIX_STATUS1_HSM_D = SCM_MATRIX_STATUS1_HSM_D_MASK, /*!< HSM master ECC single bit data error */ + SCM_MATRIX_STATUS1_HSM_A = SCM_MATRIX_STATUS1_HSM_A_MASK, /*!< HSM master ECC address error */ + SCM_MATRIX_STATUS1_MAM0_S5_DS_M = SCM_MATRIX_STATUS1_MAM0_S5_DS_M_MASK, /*!< MAM0_S5 downsize ECC multi bit data error */ + SCM_MATRIX_STATUS1_MAM0_S5_DS_D = SCM_MATRIX_STATUS1_MAM0_S5_DS_D_MASK, /*!< MAM0_S5 downsize ECC single bit data error */ + SCM_MATRIX_STATUS1_MAM0_S5_DS_A = SCM_MATRIX_STATUS1_MAM0_S5_DS_A_MASK, /*!< MAM0_S5 downsize ECC address error */ + SCM_MATRIX_STATUS1_MAM0_S8_M = SCM_MATRIX_STATUS1_MAM0_S8_M_MASK, /*!< MAM0_S8 slave ECC multi bit data error */ + SCM_MATRIX_STATUS1_MAM0_S8_AT = SCM_MATRIX_STATUS1_MAM0_S8_AT_MASK, /*!< MAM0_S8 slave ECC attribute error */ + SCM_MATRIX_STATUS1_MAM0_S8_D = SCM_MATRIX_STATUS1_MAM0_S8_D_MASK, /*!< MAM0_S8 slave ECC single bit data error */ + SCM_MATRIX_STATUS1_MAM0_S8_A = SCM_MATRIX_STATUS1_MAM0_S8_A_MASK, /*!< MAM0_S8 slave ECC address error */ + SCM_MATRIX_STATUS1_MAM0_S7_M = SCM_MATRIX_STATUS1_MAM0_S7_M_MASK, /*!< MAM0_S7 slave ECC multi bit data error */ + SCM_MATRIX_STATUS1_MAM0_S7_AT = SCM_MATRIX_STATUS1_MAM0_S7_AT_MASK, /*!< MAM0_S7 slave ECC attribute error */ + SCM_MATRIX_STATUS1_MAM0_S7_D = SCM_MATRIX_STATUS1_MAM0_S7_D_MASK, /*!< MAM0_S7 slave ECC single bit data error */ + SCM_MATRIX_STATUS1_MAM0_S7_A = SCM_MATRIX_STATUS1_MAM0_S7_A_MASK, /*!< MAM0_S7 slave ECC address error */ + SCM_MATRIX_STATUS1_MAM0_S6_M = SCM_MATRIX_STATUS1_MAM0_S6_M_MASK, /*!< MAM0_S6 slave ECC multi bit data error */ + SCM_MATRIX_STATUS1_MAM0_S6_AT = SCM_MATRIX_STATUS1_MAM0_S6_AT_MASK, /*!< MAM0_S6 slave ECC attribute error */ + SCM_MATRIX_STATUS1_MAM0_S6_D = SCM_MATRIX_STATUS1_MAM0_S6_D_MASK, /*!< MAM0_S6 slave ECC single bit data error*/ + SCM_MATRIX_STATUS1_MAM0_S6_A = SCM_MATRIX_STATUS1_MAM0_S6_A_MASK, /*!< MAM0_S6 slave ECC address error */ +} SCM_MatrixStatus1Type; + +/** + * @brief Matrix status register 2 type + * + */ +typedef enum +{ + SCM_MATRIX_STATUS2_C0_OVERLAY = SCM_MATRIX_STATUS2_C0_OVERLAY_MASK, /*!< CPU0 AHB Overlay error */ + SCM_MATRIX_STATUS2_C0_LOCKSTEP = SCM_MATRIX_STATUS2_C0_LOCKSTEP_MASK, /*!< CPU0 Lockstep error */ + SCM_MATRIX_STATUS2_C0_DTCM1_A = SCM_MATRIX_STATUS2_C0_DTCM1_A_MASK, /*!< CPU0 DTCM1 ECC Address error */ + SCM_MATRIX_STATUS2_C0_DTCM1_M = SCM_MATRIX_STATUS2_C0_DTCM1_M_MASK, /*!< CPU0 DTCM1 ECC Multi Bit Data error */ + SCM_MATRIX_STATUS2_C0_DTCM1_S = SCM_MATRIX_STATUS2_C0_DTCM1_S_MASK, /*!< CPU0 DTCM1 ECC Single Bit Data error */ + SCM_MATRIX_STATUS2_C0_DTCM0_A = SCM_MATRIX_STATUS2_C0_DTCM0_A_MASK, /*!< CPU0 DTCM0 ECC Address error */ + SCM_MATRIX_STATUS2_C0_DTCM0_M = SCM_MATRIX_STATUS2_C0_DTCM0_M_MASK, /*!< CPU0 DTCM0 ECC Multi Bit Data error */ + SCM_MATRIX_STATUS2_C0_DTCM0_S = SCM_MATRIX_STATUS2_C0_DTCM0_S_MASK, /*!< CPU0 DTCM0 ECC Single Bit Data error */ + SCM_MATRIX_STATUS2_C0_ITCM_A = SCM_MATRIX_STATUS2_C0_ITCM_A_MASK, /*!< CPU0 ITCM ECC Address error */ + SCM_MATRIX_STATUS2_C0_ITCM_M = SCM_MATRIX_STATUS2_C0_ITCM_M_MASK, /*!< CPU0 ITCM ECC Multi Bit Data error */ + SCM_MATRIX_STATUS2_C0_ITCM_S = SCM_MATRIX_STATUS2_C0_ITCM_S_MASK, /*!< CPU0 ITCM ECC Single Bit Data error */ + SCM_MATRIX_STATUS2_C0_DCACHE = SCM_MATRIX_STATUS2_C0_DCACHE_MASK, /*!< CPU0 DCache Array error */ + SCM_MATRIX_STATUS2_C0_ICACHE = SCM_MATRIX_STATUS2_C0_ICACHE_MASK, /*!< CPU0 ICache Array error */ + SCM_MATRIX_STATUS2_C0_DTCM1_DEC = SCM_MATRIX_STATUS2_C0_DTCM1_DEC_MASK, /*!< CPU0 DTCM1 decode monitor error */ + SCM_MATRIX_STATUS2_C0_DTCM0_DEC = SCM_MATRIX_STATUS2_C0_DTCM0_DEC_MASK, /*!< CPU0 DTCM0 decode monitor error */ + SCM_MATRIX_STATUS2_C0_ITCM_DEC = SCM_MATRIX_STATUS2_C0_ITCM_DEC_MASK, /*!< CPU0 ITCM decode monitor error */ + SCM_MATRIX_STATUS2_C0_AHBP_F2S = SCM_MATRIX_STATUS2_C0_AHBP_F2S_MASK, /*!< CPU0 AHBP fast to slow monitor error */ + SCM_MATRIX_STATUS2_C0_AHBM_M = SCM_MATRIX_STATUS2_C0_AHBM_M_MASK, /*!< CPU0 AHBM master ECC multi bit data error */ + SCM_MATRIX_STATUS2_C0_AHBM_D = SCM_MATRIX_STATUS2_C0_AHBM_D_MASK, /*!< CPU0 AHBM master ECC single bit data error */ + SCM_MATRIX_STATUS2_C0_AHBM_A = SCM_MATRIX_STATUS2_C0_AHBM_A_MASK, /*!< CPU0 AHBM master ECC address error */ + SCM_MATRIX_STATUS2_C0_AHBS_M = SCM_MATRIX_STATUS2_C0_AHBS_M_MASK, /*!< CPU0 AHBS master ECC multi bit data error */ + SCM_MATRIX_STATUS2_C0_AHBS_D = SCM_MATRIX_STATUS2_C0_AHBS_D_MASK, /*!< CPU0 AHBS master ECC single bit data error */ + SCM_MATRIX_STATUS2_C0_AHBS_A = SCM_MATRIX_STATUS2_C0_AHBS_A_MASK, /*!< CPU0 AHBS master ECC address error */ + SCM_MATRIX_STATUS2_C0_AHBP_M = SCM_MATRIX_STATUS2_C0_AHBP_M_MASK, /*!< CPU0 AHBP master ECC multi bit data error */ + SCM_MATRIX_STATUS2_C0_AHBP_D = SCM_MATRIX_STATUS2_C0_AHBP_D_MASK, /*!< CPU0 AHBP master ECC single bit data error */ + SCM_MATRIX_STATUS2_C0_AHBP_A = SCM_MATRIX_STATUS2_C0_AHBP_A_MASK, /*!< CPU0 AHBP master ECC address error */ +} SCM_MatrixStatus2Type; + +/** + * @brief Matrix status register 5 type + * + */ +typedef enum +{ + + SCM_MATRIX_STATUS5_DMA0_CFG_M = SCM_MATRIX_STATUS5_DMA0_CFG_M_MASK, /*!< DMA0_CFG ECC Multi Bit Data Error */ + SCM_MATRIX_STATUS5_DMA0_LOCKSTEP = SCM_MATRIX_STATUS5_DMA0_LOCKSTEP_MASK,/*!< DMA0 Lockstep Error */ + SCM_MATRIX_STATUS5_DMA0_CFG_S = SCM_MATRIX_STATUS5_DMA0_CFG_S_MASK, /*!< DMA0_CFG ECC Single Bit Data Error */ + SCM_MATRIX_STATUS5_DMA0_CFG_A = SCM_MATRIX_STATUS5_DMA0_CFG_A_MASK, /*!< DMA0_CFG ECC Address Error */ + SCM_MATRIX_STATUS5_EDC_HI = SCM_MATRIX_STATUS5_EDC_HI_MASK, /*!< Flash Control OCM EDC FCCU Alarm High Error */ + SCM_MATRIX_STATUS5_LINE_SBC = SCM_MATRIX_STATUS5_LINE_SBC_MASK, /*!< FCCU Alarm Linebuffer Self ECC Single Bit Error */ + SCM_MATRIX_STATUS5_LINE_MULTI = SCM_MATRIX_STATUS5_LINE_MULTI_MASK, /*!< FCCU Alarm Linebuffer Self ECC Multi Bit Error */ + SCM_MATRIX_STATUS5_ENC = SCM_MATRIX_STATUS5_ENC_MASK, /*!< FLASH Control OCM ENC FCCU Alarm Error */ + SCM_MATRIX_STATUS5_EDC = SCM_MATRIX_STATUS5_EDC_MASK, /*!< Flash Control OCM EDC FCCU Alarm Error */ + SCM_MATRIX_STATUS5_P2_D_M = SCM_MATRIX_STATUS5_P2_D_M_MASK, /*!< Flash Control Port 2 Data Multi Error */ + SCM_MATRIX_STATUS5_P1_D_M = SCM_MATRIX_STATUS5_P1_D_M_MASK, /*!< Flash Control Port 1 Data Multi Error */ + SCM_MATRIX_STATUS5_P0_D_M = SCM_MATRIX_STATUS5_P0_D_M_MASK, /*!< Flash Control Port 0 Data Multi Error */ + SCM_MATRIX_STATUS5_P2_C_M = SCM_MATRIX_STATUS5_P2_C_M_MASK, /*!< Flash Control Port 2 Code Multi Error */ + SCM_MATRIX_STATUS5_P1_C_M = SCM_MATRIX_STATUS5_P1_C_M_MASK, /*!< Flash Control Port 1 Code Multi Error */ + SCM_MATRIX_STATUS5_P0_C_M = SCM_MATRIX_STATUS5_P0_C_M_MASK, /*!< Flash Control Port 0 Code Multi Error */ + SCM_MATRIX_STATUS5_P2_D_S = SCM_MATRIX_STATUS5_P2_D_S_MASK, /*!< Flash Control Port 2 Data Single Error */ + SCM_MATRIX_STATUS5_P1_D_S = SCM_MATRIX_STATUS5_P1_D_S_MASK, /*!< Flash Control Port 1 Data Single Error */ + SCM_MATRIX_STATUS5_P0_D_S = SCM_MATRIX_STATUS5_P0_D_S_MASK, /*!< Flash Control Port 0 Data Single Error */ + SCM_MATRIX_STATUS5_P2_C_S = SCM_MATRIX_STATUS5_P2_C_S_MASK, /*!< Flash Control Port 2 Code Single Error */ + SCM_MATRIX_STATUS5_P1_C_S = SCM_MATRIX_STATUS5_P1_C_S_MASK, /*!< Flash Control Port 1 Code Single Error */ + SCM_MATRIX_STATUS5_P0_C_S = SCM_MATRIX_STATUS5_P0_C_S_MASK /*!< Flash Control Port 0 Code Single Error */ +} SCM_MatrixStatus5Type; + +/** + * @brief Matrix status register 6 type + * + */ +typedef enum +{ + SCM_MATRIX_STATUS6_STALL_ERR = SCM_MATRIX_STATUS6_STALL_ERR_MASK, /*!< MAM Stall Error */ + SCM_MATRIX_STATUS6_MAM0_S8_DS = SCM_MATRIX_STATUS6_MAM0_S8_DS_MASK, /*!< MAM0_S8 Downsize Monitor Error */ + SCM_MATRIX_STATUS6_MAM0_S5_DS = SCM_MATRIX_STATUS6_MAM0_S5_DS_MASK, /*!< MAM0_S5 Downsize Monitor Error */ + SCM_MATRIX_STATUS6_MAM0_S5_S2F = SCM_MATRIX_STATUS6_MAM0_S5_S2F_MASK, /*!< MAM0_S5 Slow to Fast Gasket Monitor Error */ + SCM_MATRIX_STATUS6_SRAM1_DEC = SCM_MATRIX_STATUS6_SRAM1_DEC_MASK, /*!< SARM1 Decode Monitor Error */ + SCM_MATRIX_STATUS6_SRAM0_DEC = SCM_MATRIX_STATUS6_SRAM0_DEC_MASK, /*!< SARM0 Decode Monitor Error */ + SCM_MATRIX_STATUS6_AFCB1_MON = SCM_MATRIX_STATUS6_AFCB1_MON_MASK, /*!< AFCB0 Monitor Error */ + SCM_MATRIX_STATUS6_AFCB0_MON = SCM_MATRIX_STATUS6_AFCB0_MON_MASK, /*!< AFCB1 Monitor Error */ + SCM_MATRIX_STATUS6_STCU_ST = SCM_MATRIX_STATUS6_STCU_ST_MASK, /*!< STCU Self Test Monitor Error */ + SCM_MATRIX_STATUS6_DCM_SCAN = SCM_MATRIX_STATUS6_DCM_SCAN_MASK, /*!< FCM Scan ECC Error */ + SCM_MATRIX_STATUS6_NON_USER = SCM_MATRIX_STATUS6_NON_USER_MASK, /*!< STCU Nonuser Error */ + SCM_MATRIX_STATUS6_SCM_CRC = SCM_MATRIX_STATUS6_SCM_CRC_MASK, /*!< SCM CRC Error */ + SCM_MATRIX_STATUS6_SCG_CRC = SCM_MATRIX_STATUS6_SCG_CRC_MASK, /*!< SCG CRC Error */ + SCM_MATRIX_STATUS6_SRAM1_CTRL_MON = SCM_MATRIX_STATUS6_SRAM1_CTRL_MON_MASK, /*!< SRAM1 Control Monitor Error */ + SCM_MATRIX_STATUS6_SRAM0_CTRL_MON = SCM_MATRIX_STATUS6_SRAM0_CTRL_MON_MASK, /*!< SRAM0 Control Monitor Error */ + SCM_MATRIX_STATUS6_SRAM1_M = SCM_MATRIX_STATUS6_SRAM1_M_MASK, /*!< SRAM1 Multi Bit Data Error */ + SCM_MATRIX_STATUS6_SRAM1_EDC = SCM_MATRIX_STATUS6_SRAM1_EDC_MASK, /*!< SRAM1 EDC Error */ + SCM_MATRIX_STATUS6_SRAM1_A = SCM_MATRIX_STATUS6_SRAM1_A_MASK, /*!< SRAM1 Address Error */ + SCM_MATRIX_STATUS6_SRAM1_S = SCM_MATRIX_STATUS6_SRAM1_S_MASK, /*!< SRAM1 Single Bit Data Error */ + SCM_MATRIX_STATUS6_SAM0_M = SCM_MATRIX_STATUS6_SAM0_M_MASK, /*!< SRAM0 Multi Bit Data Error */ + SCM_MATRIX_STATUS6_SRAM0_EDC = SCM_MATRIX_STATUS6_SRAM0_EDC_MASK, /*!< SRAM0 EDC Error */ + SCM_MATRIX_STATUS6_SRAM0_A = SCM_MATRIX_STATUS6_SRAM0_A_MASK, /*!< SRAM0 Address Error */ + SCM_MATRIX_STATUS6_SRAM0_S = SCM_MATRIX_STATUS6_SRAM0_S_MASK /*!< SRAM0 Single Bit Data Error */ +} SCM_MatrixStatus6Type; + +/** + * @brief Matrix status register 7 type + * + */ +typedef enum +{ + SCM_MATRIX_STATUS7_HSM_IRAM_M = SCM_MATRIX_STATUS7_HSM_IRAM_M_MASK, /*!< HSM IRAM Multi Bit Data Error */ + SCM_MATRIX_STATUS7_HSM_IRAM_S = SCM_MATRIX_STATUS7_HSM_IRAM_S_MASK, /*!< HSM IRAM Single Bit Data Error */ + SCM_MATRIX_STATUS7_HSM_DRAM_M = SCM_MATRIX_STATUS7_HSM_DRAM_M_MASK, /*!< HSM DRAM Multi Bit Data Error*/ + SCM_MATRIX_STATUS7_HSM_DRAM_S = SCM_MATRIX_STATUS7_HSM_DRAM_S_MASK, /*!< HSM DRAM Single Bit Data Error */ + SCM_MATRIX_STATUS7_HSM_WDOG = SCM_MATRIX_STATUS7_HSM_WDOG_MASK, /*!< HSM WDOG Request */ + SCM_MATRIX_STATUS7_MAM0_ERR = SCM_MATRIX_STATUS7_MAM0_ERR_MASK, /*!< MAM0 Timeout Error*/ + SCM_MATRIX_STATUS7_FOSC_ERR = SCM_MATRIX_STATUS7_FOSC_ERR_MASK, /*!< FOSC Loss of Clock Error*/ + SCM_MATRIX_STATUS7_PLL1_ERR = SCM_MATRIX_STATUS7_PLL1_ERR_MASK, /*!< PLL1 Loss of Clock Error*/ + SCM_MATRIX_STATUS7_PLL0_ERR = SCM_MATRIX_STATUS7_PLL0_ERR_MASK /*!< PLL0 Loss of Clock Error */ +} SCM_MatrixStatus7Type; + +/** + * @brief Matrix ID status type + * + */ +typedef enum +{ + SCM_MATRIX_ID_STATUS0_MAM0_S3_ID = 0U, /*!< MAM0_S3 Slave ECC Error with Which Master Access */ + SCM_MATRIX_ID_STATUS0_MAM0_S4_ID = 1U, /*!< MAM0_S4 Slave ECC Error with Which Master Access */ + SCM_MATRIX_ID_STATUS0_MAM0_S5_ID = 3U, /*!< MAM0_S5 Slave ECC Error with Which Master Access */ + SCM_MATRIX_ID_STATUS0_SRAM0_ID = 4U, /*!< SARM0 ECC error with which master access */ + SCM_MATRIX_ID_STATUS0_SRAM1_ID = 5U /*!< SARM1 ECC Error with Which Master Access */ +} SCM_MatrixIDStatusType; + +/** + * @brief Matrix ID status master type + * + */ +typedef enum +{ + SCM_MATRIX_ID_STATUS0_MASTER_CPU0 = 0x0U, /*!< SARM2 ECC error with CPU0 access */ + SCM_MATRIX_ID_STATUS0_MASTER_HSM = 0x8U, /*!< SARM1 ECC error with HSM access */ + SCM_MATRIX_ID_STATUS0_MASTER_DMA0 = 0xAU, /*!< SARM0 ECC error with DMA0 access */ +} SCM_MatrixIDStatusMasterType; + +/** + * @brief SCM SYSAP control Status2 Register Selection typ + * + */ +typedef enum +{ + SCM_SYSAP_STATUS2_SEL_UID0 = 0U, /*!< Select UID0 */ + SCM_SYSAP_STATUS2_SEL_UID1 = 1U, /*!< Select UID1 */ + SCM_SYSAP_STATUS2_SEL_UID2 = 2U, /*!< Select UID2 */ + SCM_SYSAP_STATUS2_SEL_UID3 = 3U, /*!< Select UID3 */ + SCM_SYSAP_STATUS2_SEL_NVRVERSION = 4U /*!< Select NVR version */ +} SCM_SysAPStatus2SelType; + +/** + * @brief Mass erase type + * + */ +typedef enum +{ + SCM_SECTORERASE_AS_MASSERASE = 0U, /*!< Use sector erase for mass erase */ + SCM_CHIPERASE_AS_MASSERASE /*!< Use chip erase for mass erase */ +} SCM_SysApMassEraseType; + +/** + * @brief Cpu Type of forcing to halt + * + */ +typedef enum +{ + SCM_DEBUG_CPU0 = 1U, /*!< Force CPU0 to halt */ +} SCM_SysApCpuDebugReqType; + +/** + * @brief Subsystem status type + * + */ +typedef enum +{ + SCM_SUBSYS_STATUS_CHIP_IS_FT = SCM_SUBSYS_STATUS_CHIP_IS_FT_MASK, /*!< SEC dc lifecycle ft */ + SCM_SUBSYS_STATUS_CHIP_IS_VIRGIN = SCM_SUBSYS_STATUS_CHIP_IS_VIRGIN_MASK, /*!< SEC dc lifecycle virgin */ + SCM_SUBSYS_STATUS_TPU_CLK_EN = SCM_SUBSYS_STATUS_TPU_CLK_EN_MASK, /*!< TPU Clock Enable */ + SCM_SUBSYS_STATUS_HSM_RST = SCM_SUBSYS_STATUS_HSM_RST_MASK, /*!< Subsystem reset state */ + SCM_SUBSYS_STATUS_HSM_SYS_ERR_INT = SCM_SUBSYS_STATUS_HSM_SYS_ERR_INT_MASK, /*!< Subsystem error interrupt */ + SCM_SUBSYS_STATUS_WDG_RST = SCM_SUBSYS_STATUS_WDG_RST_MASK, /*!< Subsystem WDG generated reset flag */ + SCM_SUBSYS_STATUS_INIT_DONE = SCM_SUBSYS_STATUS_INIT_DONE_MASK, /*!< Subsystem Initial done flag */ + SCM_SUBSYS_STATUS_ISP_TOGGLE = SCM_SUBSYS_STATUS_ISP_TOGGLE_MASK, /*!< Subsystem ISP PIN toggle flag */ + SCM_SUBSYS_STATUS_SUBSYS_SLEEP = SCM_SUBSYS_STATUS_HSM_SLEEP_MASK, /*!< Subsystem sleep state */ + SCM_SUBSYS_STATUS_STOP_ACK = SCM_SUBSYS_STATUS_STOP_ACK_MASK /*!< Subsystem stop mode ack */ +} SCM_SUBSYSStatusType; + +/** + * @brief Master halt request type + * + */ +typedef enum +{ + SCM_MASTER_HALT_REQ_HSM_REQ = 0U, /*!< HSM Halt Request */ + SCM_MASTER_HALT_REQ_DMA0_REQ = 2U, /*!< DMA0 Halt Request */ +} SCM_HaltReqType; + +/** + * @brief Master halt request type + * + */ +typedef enum +{ + SCM_MASTER_HALT_REQ_NOT_HALTED = 0U, /*!< Not Halted state */ + SCM_MASTER_HALT_REQ_HALTED_STATE = 1U, /*!< Halted state */ +} SCM_HaltReqAckType; + + +/********* Local inline function ************/ +/** + * @brief Get UIDL data(Unique identification for the chip. Loaded from NVR) + * + * @return return value + */ +LOCAL_INLINE uint32_t SCM_HWA_GetData_UIDL(void) +{ + return SCM->UIDL; +} + +/** + * @brief Get UIDML data(Unique identification for the chip. Loaded from NVR) + * + * @return return value + */ +LOCAL_INLINE uint32_t SCM_HWA_GetData_UIDML(void) +{ + return SCM->UIDML; +} + +/** + * @brief Get UIDMH data(Unique identification for the chip. Loaded from NVR) + * + * @return return value + */ +LOCAL_INLINE uint32_t SCM_HWA_GetData_UIDMH(void) +{ + return SCM->UIDMH; +} + +/** + * @brief Get UIDH data(Unique identification for the chip. Loaded from NVR) + * + * @return return value + */ +LOCAL_INLINE uint32_t SCM_HWA_GetData_UIDH(void) +{ + return SCM->UIDH; +} + +/** + * @brief Get Family Identification + * + * @return return value + */ +LOCAL_INLINE uint8_t SCM_HWA_GetData_FamilyID(void) +{ + return (uint8_t)((SCM->PARTID0 & (uint32_t)SCM_PARTID0_FAM_ID_MASK) >> (uint32_t)SCM_PARTID0_FAM_ID_SHIFT); +} + +/** + * @brief Get Revision Identification + * + * @return return value + */ +LOCAL_INLINE uint8_t SCM_HWA_GetData_RevID(void) +{ + return (uint8_t)((SCM->PARTID0 & (uint32_t)SCM_PARTID0_REVID_MASK)); +} + +/** + * @brief Get CHIPCFG0 register status + * + * @return return value + */ +LOCAL_INLINE uint32_t SCM_HWA_GetStatus_CHIPCFG0(void) +{ + return SCM->CHIPCFG0; +} + +/** + * @brief Get CPU lock step enable/disable status + * + * @return 1: CPU lock step is enabled + * 0: CPU lock step is disabled + */ +LOCAL_INLINE uint32_t SCM_HWA_GetLockStepStatus_Cpu0(void) +{ + return ((SCM->CHIPCFG0 & (uint32_t)SCM_CHIPCFG0_CPU0_LOCKSTEP_EN_MASK)>>(uint32_t)SCM_CHIPCFG0_CPU0_LOCKSTEP_EN_SHIFT); +} + +/** + * @brief Get CANFD enable/disable status + * + * @return 1: CANFD is enabled + * 0: CANFD is disabled + */ +LOCAL_INLINE uint32_t SCM_HWA_GetStatus_CANFD(void) +{ + return ((SCM->CHIPCFG0 & (uint32_t)SCM_CHIPCFG0_CAN_FD_MASK)>>(uint32_t)SCM_CHIPCFG0_CAN_FD_SHIFT); +} + +/** + * @brief Get device ID + * + * @return The device ID + */ +LOCAL_INLINE uint32_t SCM_HWA_GetData_DeviceID(void) +{ + return ((SCM->CHIPCFG1 & (uint32_t)SCM_CHIPCFG1_DEVICE_ID_MASK) >> (uint32_t)SCM_CHIPCFG1_DEVICE_ID_SHIFT); +} + +/** + * @brief Lock the CPU permission(WPB) in MAMECCEN0 register, and WPB cannot be written until a power-on reset + * + */ +LOCAL_INLINE void SCM_HWA_MAMECCEN0_LockWritePermit(void) +{ + SCM->MAMECCEN0 |= (uint32_t)SCM_MAMECCEN0_WPB_LOCK_MASK; +} + +/** + * @brief Get the lock status of CPU permission(WPB) in MAMECCEN0 register + * + * @return 1: The WPB of MAMECCEN0 register is locked + * 0: The WPB of MAMECCEN0 register is not locked + */ +LOCAL_INLINE uint32_t SCM_HWA_MAMECCEN0_GetWPBLockStatus(void) +{ + return (SCM->MAMECCEN0 & (uint32_t)SCM_MAMECCEN0_WPB_LOCK_MASK) >> SCM_MAMECCEN0_WPB_LOCK_SHIFT; +} + +/** + * @brief Get the CPU type of writing permission to MAMECCEN0 register + * + * @return SCM_WPB_CpuType The CPU which has the write permission + */ +LOCAL_INLINE SCM_WPB_CpuType SCM_HWA_MAMECCEN0_GetCpuWritePermit(void) +{ + uint32_t u32RegVal = ((SCM->MAMECCEN0 & (uint32_t)SCM_MAMECCEN0_WPB_MASK) >> SCM_MAMECCEN0_WPB_SHIFT); + return (SCM_WPB_CpuType)u32RegVal; +} + +/** + * @brief Set CPU to control the MAMECCEN0 register + * + * @param eCpuType CPU allowed to control peripheral + */ +LOCAL_INLINE void SCM_HWA_MAMECCEN0_SetCpuWritePermit(SCM_WPB_CpuType eCpuType) +{ + SCM->MAMECCEN0 = ((SCM->MAMECCEN0 & (~(uint32_t)SCM_MAMECCEN0_WPB_MASK)) | SCM_MAMECCEN0_WPB(eCpuType)); +} + +/** + * @brief Get the value of MAMECCEN0 register + * @return register value + */ +LOCAL_INLINE uint32_t SCM_HWA_MAMECCEN0_GetValue(void) +{ + return SCM->MAMECCEN0; +} + +/** + * @brief Set the value of MAMECCEN0 register + * @param u32Value value to be set, the value must be the or value of SCM_MAMEccCtrlGrp0Type + */ +LOCAL_INLINE void SCM_HWA_MAMECCEN0_SetValue(uint32_t u32Value) +{ + SCM->MAMECCEN0 = u32Value & 0x03FFCFCFu; +} + +/** + * @brief Set the MAMECCEN0 ECC enable + * @param eMamEccType the MAM peripheral to enable ECC + * @param eEnable the ECC enable mode + */ +LOCAL_INLINE void SCM_HWA_MAMECCEN0_Ctrl(SCM_MAMEccCtrlGrp0Type eMamEccType, SCM_EccEnModeType eEnable) +{ + + SCM->MAMECCEN0 = (SCM->MAMECCEN0 & (~(SCM_MAMECCEN0_ECC_MASK << ((uint32_t)eMamEccType * SCM_MAMECCEN0_ECC_WIDTH)))) | + SCM_MAMECCEN0_ECC(eEnable) << ((uint32_t)eMamEccType * SCM_MAMECCEN0_ECC_WIDTH); +} + +/** + * @brief Lock the CPU permission(WPB) in MAMECCEN1 register, and WPB cannot be written until a power-on reset + * + */ +LOCAL_INLINE void SCM_HWA_MAMECCEN1_LockWritePermit(void) +{ + SCM->MAMECCEN1 |= (uint32_t)SCM_MAMECCEN1_WPB_LOCK_MASK; +} + +/** + * @brief Get the lock status of CPU permission(WPB) in MAMECCEN1 register + * + * @return 1: The WPB of MAMECCEN1 register is locked + * 0: The WPB of MAMECCEN1 register is not locked + */ +LOCAL_INLINE uint32_t SCM_HWA_MAMECCEN1_GetWPBLockStatus(void) +{ + return (SCM->MAMECCEN1 & (uint32_t)SCM_MAMECCEN1_WPB_LOCK_MASK) >> SCM_MAMECCEN1_WPB_LOCK_SHIFT; +} + +/** + * @brief Get the CPU type of writing permission to MAMECCEN1 register + * + * @return SCM_WPB_CpuType The CPU which has the write permission + */ +LOCAL_INLINE SCM_WPB_CpuType SCM_HWA_MAMECCEN1_GetCpuWritePermit(void) +{ + uint32_t u32RegVal = ((SCM->MAMECCEN1 & (uint32_t)SCM_MAMECCEN1_WPB_MASK) >> SCM_MAMECCEN1_WPB_SHIFT); + return (SCM_WPB_CpuType)u32RegVal; +} + +/** + * @brief Set CPU to control the MAMECCEN1 register + * + * @param eCpuType CPU allowed to control peripheral + */ +LOCAL_INLINE void SCM_HWA_MAMECCEN1_SetCpuWritePermit(SCM_WPB_CpuType eCpuType) +{ + SCM->MAMECCEN1 = ((SCM->MAMECCEN1 & (~(uint32_t)SCM_MAMECCEN1_WPB_MASK)) | SCM_MAMECCEN1_WPB(eCpuType)); +} + +/** + * @brief Get the value of MAMECCEN1 register + * @return register value + */ +LOCAL_INLINE uint32_t SCM_HWA_MAMECCEN1_GetValue(void) +{ + return SCM->MAMECCEN1; +} + +/** + * @brief Set the value of MAMECCEN1 register + * @param u32Value value to be set + */ +LOCAL_INLINE void SCM_HWA_MAMECCEN1_SetValue(uint32_t u32Value) +{ + SCM->MAMECCEN1 = u32Value & 0x00003D33u; +} + +/** + * @brief Set the MAMECCEN1 ECC enable + * @param eMamEccType the MAM peripheral to enable ECC + * @param eEnable the ECC enable mode + */ +LOCAL_INLINE void SCM_HWA_MAMECCEN1_Ctrl(SCM_MAMEccCtrlGrp1Type eMamEccType, SCM_EccEnModeType eEnable) +{ + if(SCM_DMA0_CFG_ECC == eMamEccType) + { + SCM->MAMECCEN1 = (SCM->MAMECCEN1 & (~(SCM_MAMECCEN1_DMA0_CFG_ECC_MASK))) | + SCM_MAMECCEN1_DMA0_CFG_ECC(eEnable); + } + else + { + SCM->MAMECCEN1 = (SCM->MAMECCEN1 & (~(SCM_MAMECCEN1_ECC_MASK << ((uint32_t)eMamEccType * SCM_MAMECCEN1_ECC_WIDTH)))) | + SCM_MAMECCEN1_ECC(eEnable) << ((uint32_t)eMamEccType * SCM_MAMECCEN1_ECC_WIDTH); + } +} + +/** + * @brief Lock the CPU permission(WPB) in CPU0ECCEN register, and WPB cannot be written until a power-on reset + * + */ +LOCAL_INLINE void SCM_HWA_CPU0ECCEN_LockWritePermit(void) +{ + SCM->CPU0ECCEN |= (uint32_t)SCM_CPU0ECCEN_WPB_LOCK_MASK; +} + +/** + * @brief Get the lock status of CPU permission(WPB) in CPU0ECCEN register + * + * @return 1: The WPB of CPU0ECCEN register is locked + * 0: The WPB of CPU0ECCEN register is not locked + */ +LOCAL_INLINE uint32_t SCM_HWA_CPU0ECCEN_GetWPBLockStatus(void) +{ + return (SCM->CPU0ECCEN & (uint32_t)SCM_CPU0ECCEN_WPB_LOCK_MASK) >> SCM_CPU0ECCEN_WPB_LOCK_SHIFT; +} + +/** + * @brief Get the CPU type of writing permission to CPU0ECCEN register + * + * @return SCM_WPB_CpuType The CPU which has the write permission + */ +LOCAL_INLINE SCM_WPB_CpuType SCM_HWA_CPU0ECCEN_GetCpuWritePermit(void) +{ + uint32_t u32RegVal = ((SCM->CPU0ECCEN & (uint32_t)SCM_CPU0ECCEN_WPB_MASK) >> SCM_CPU0ECCEN_WPB_SHIFT); + return (SCM_WPB_CpuType)u32RegVal; +} + +/** + * @brief Set CPU to control the CPU0ECCEN register + * + * @param eCpuType CPU allowed to control peripheral + */ +LOCAL_INLINE void SCM_HWA_CPU0ECCEN_SetCpuWritePermit(SCM_WPB_CpuType eCpuType) +{ + uint32_t u32RegVal = SCM->CPU0ECCEN; + SCM->CPU0ECCEN = ((u32RegVal & (~(uint32_t)SCM_CPU0ECCEN_WPB_MASK)) | SCM_CPU0ECCEN_WPB(eCpuType)); +} + +/** + * @brief Get the value of CPU0ECCEN register + * @return register value + */ +LOCAL_INLINE uint32_t SCM_HWA_CPU0ECCEN_GetValue(void) +{ + return SCM->CPU0ECCEN; +} + +/** + * @brief Set the value of CPU0ECCEN register + * @param u32Value value to be set + */ +LOCAL_INLINE void SCM_HWA_CPU0ECCEN_SetValue(uint32_t u32Value) +{ + SCM->CPU0ECCEN = u32Value & 0x00000FFFu; +} + +/** + * @brief Set the peripheral ECC enable of CPU0 + * @param eCpuEccType the peripheral to enable ECC + * @param eEnable the ECC enable mode + */ +LOCAL_INLINE void SCM_HWA_CPU0ECCEN_Ctrl(SCM_CPUEccCtrlType eCpuEccType, SCM_EccEnModeType eEnable) +{ + SCM->CPU0ECCEN = (SCM->CPU0ECCEN & (~(SCM_CPU0ECCEN_CPU0_ECC_MASK << ((uint32_t)eCpuEccType * SCM_CPU0ECCEN_CPU0_ECC_WIDTH)))) | + SCM_CPU0ECCEN_CPU0_ECC(eEnable) << ((uint32_t)eCpuEccType * SCM_CPU0ECCEN_CPU0_ECC_WIDTH); +} + +/** + * @brief Get SRAM1 ECC Detect Control + * @return 0: Disable EDC error when SRAM1 Multi Bit ECC Error Exist + * 1: Only Enable EDC error when SRAM1 Multi Bit ECC Error Exist + */ +LOCAL_INLINE uint32_t SCM_HWA_SRAM1_EDCErrorEnStatus(void) +{ + return (SCM->SRAM_EDC_CTRL & SCM_SRAM_EDC_CTRL_SRAM1_EDC_MASK) >> SCM_SRAM_EDC_CTRL_SRAM1_EDC_SHIFT; +} + +/** + * @brief Set SRAM1 ECC Detect Control + * @param bEnable true: Disable EDC error when SRAM1 Multi Bit ECC Error Exist + * false: Only Enable EDC error when SRAM1 Multi Bit ECC Error Exist + */ +LOCAL_INLINE void SCM_HWA_SRAM1_EDCErrorEnable(bool bEnable) +{ + SCM->SRAM_EDC_CTRL = (SCM->SRAM_EDC_CTRL & (~SCM_SRAM_EDC_CTRL_SRAM1_EDC_MASK)) | SCM_SRAM_EDC_CTRL_SRAM1_EDC(bEnable); +} + +/** + * @brief Get SRAM0 ECC Detect Control + * @return 0: Disable EDC error when SRAM0 Multi Bit ECC Error Exist + * 1: Only Enable EDC error when SRAM0 Multi Bit ECC Error Exist + */ +LOCAL_INLINE uint32_t SCM_HWA_SRAM0_EDCErrorEnStatus(void) +{ + return (SCM->SRAM_EDC_CTRL & SCM_SRAM_EDC_CTRL_SRAM0_EDC_MASK) >> SCM_SRAM_EDC_CTRL_SRAM0_EDC_SHIFT; +} + +/** + * @brief Set SRAM0 ECC Detect Control + * @param bEnable false: Disable EDC error when SRAM0 Multi Bit ECC Error Exist + * true: Only Enable EDC error when SRAM0 Multi Bit ECC Error Exist + */ +LOCAL_INLINE void SCM_HWA_SRAM0_EDCErrorEnable(bool bEnable) +{ + SCM->SRAM_EDC_CTRL = (SCM->SRAM_EDC_CTRL & (~SCM_SRAM_EDC_CTRL_SRAM0_EDC_MASK)) | SCM_SRAM_EDC_CTRL_SRAM0_EDC(bEnable); +} + +/** + * @brief Lock ROM Configuration Register + * + */ +LOCAL_INLINE void SCM_HWA_LockROMCFG(void) +{ + SCM->ROMCFG |= (uint32_t)SCM_ROMCFG_LOCK_MASK; +} + +/** + * @brief Get ROMCFG register lock status + * + * @return Lock status + */ +LOCAL_INLINE uint32_t SCM_HWA_ROMCFG_GetLockStatus(void) +{ + return(SCM->ROMCFG & (uint32_t)SCM_ROMCFG_LOCK_MASK) >> SCM_ROMCFG_LOCK_SHIFT; +} + +/** + * @brief Get HSM ROM Power Gating Enable status + * @return 0: Not Power Gating + * 1: Power Gating + */ +LOCAL_INLINE uint32_t SCM_HWA_GetHsmRomPowerGatingEnStatus(void) +{ + return (SCM->ROMCFG & SCM_ROMCFG_HSMROM_PGEN_MASK) >> SCM_ROMCFG_HSMROM_PGEN_SHIFT; +} + +/** + * @brief Set HSM ROM Power Gating Enable + * @param bEnable false: Not Power Gating + * true: Power Gating + */ +LOCAL_INLINE void SCM_HWA_HsmRomPowerGatingEnable(bool bEnable) +{ + SCM->ROMCFG = (SCM->ROMCFG & (~SCM_ROMCFG_HSMROM_PGEN_MASK)) | SCM_ROMCFG_HSMROM_PGEN(bEnable); +} + +/** + * @brief Get System ROM Power Gating Enable status + * @return 0: Not Power Gating + * 1: Power Gating + */ +LOCAL_INLINE uint32_t SCM_HWA_GetSysRomPowerGatingEnStatus(void) +{ + return (SCM->ROMCFG & SCM_ROMCFG_SYSROM_PGEN_MASK) >> SCM_ROMCFG_SYSROM_PGEN_SHIFT; +} + +/** + * @brief Set System ROM Power Gating Enable + * @param bEnable false: Not Power Gating + * true: Power Gating + */ +LOCAL_INLINE void SCM_HWA_SysRomPowerGatingEnable(bool bEnable) +{ + SCM->ROMCFG = (SCM->ROMCFG & (~SCM_ROMCFG_SYSROM_PGEN_MASK)) | SCM_ROMCFG_SYSROM_PGEN(bEnable); +} + +/** + * @brief Use FCSPI5 to monitor other FCSPI's transmit interface + * + * @param eSPIxType SPI type + */ +LOCAL_INLINE void SCM_HWA_FCSPI5MonSPIx(SCM_FCSPIxType eSPIxType) +{ + uint32_t u32RegVal = SCM->FCSPI_ROUTING; + SCM->FCSPI_ROUTING = ((u32RegVal & (~(uint32_t)SCM_FCSPI_ROUTING_SPI5_ROUTER_MASK)) | SCM_FCSPI_ROUTING_SPI5_ROUTER(eSPIxType)); +} + +/** + * @brief Use FCSPI4 to monitor other FCSPI's transmit interface + * + * @param eSPIxType SPI type + */ +LOCAL_INLINE void SCM_HWA_FCSPI4MonSPIx(SCM_FCSPIxType eSPIxType) +{ + uint32_t u32RegVal = SCM->FCSPI_ROUTING; + SCM->FCSPI_ROUTING = ((u32RegVal & (~(uint32_t)SCM_FCSPI_ROUTING_SPI4_ROUTER_MASK)) | SCM_FCSPI_ROUTING_SPI4_ROUTER(eSPIxType)); +} + +/** + * @brief Use FCSPI3 to monitor other FCSPI's transmit interface + * + * @param eSPIxType SPI type + */ +LOCAL_INLINE void SCM_HWA_FCSPI3MonSPIx(SCM_FCSPIxType eSPIxType) +{ + uint32_t u32RegVal = SCM->FCSPI_ROUTING; + SCM->FCSPI_ROUTING = ((u32RegVal & (~(uint32_t)SCM_FCSPI_ROUTING_SPI3_ROUTER_MASK)) | SCM_FCSPI_ROUTING_SPI3_ROUTER(eSPIxType)); +} + +/** + * @brief Use FCSPI2 to monitor other FCSPI's transmit interface + * + * @param eSPIxType SPI type + */ +LOCAL_INLINE void SCM_HWA_FCSPI2MonSPIx(SCM_FCSPIxType eSPIxType) +{ + uint32_t u32RegVal = SCM->FCSPI_ROUTING; + SCM->FCSPI_ROUTING = ((u32RegVal & (~(uint32_t)SCM_FCSPI_ROUTING_SPI2_ROUTER_MASK)) | SCM_FCSPI_ROUTING_SPI2_ROUTER(eSPIxType)); +} + +/** + * @brief Use FCSPI1 to monitor other FCSPI's transmit interface + * + * @param eSPIxType SPI type + */ +LOCAL_INLINE void SCM_HWA_FCSPI1MonSPIx(SCM_FCSPIxType eSPIxType) +{ + uint32_t u32RegVal = SCM->FCSPI_ROUTING; + SCM->FCSPI_ROUTING = ((u32RegVal & (~(uint32_t)SCM_FCSPI_ROUTING_SPI1_ROUTER_MASK)) | SCM_FCSPI_ROUTING_SPI1_ROUTER(eSPIxType)); +} + +/** + * @brief Use FCSPI0 to monitor other FCSPI's transmit interface + * + * @param eSPIxType SPI type + */ +LOCAL_INLINE void SCM_HWA_FCSPI0MonSPIx(SCM_FCSPIxType eSPIxType) +{ + uint32_t u32RegVal = SCM->FCSPI_ROUTING; + SCM->FCSPI_ROUTING = ((u32RegVal & (~(uint32_t)SCM_FCSPI_ROUTING_SPI0_ROUTER_MASK)) | SCM_FCSPI_ROUTING_SPI0_ROUTER(eSPIxType)); +} + +/** + * @brief Use FCUART7 to monitor other FCSPI's transmit interface + * + * @param eUartxType Uart type + */ +LOCAL_INLINE void SCM_HWA_FCUART7MonUARTx(SCM_MON_FCUARTxType eUartxType) +{ + uint32_t u32RegVal = SCM->FCUART_ROUTING0; + SCM->FCUART_ROUTING0 = ((u32RegVal & (~(uint32_t)SCM_FCUART_ROUTING0_UART7_ROUTER_MASK)) | SCM_FCUART_ROUTING0_UART7_ROUTER(eUartxType)); +} + +/** + * @brief Use FCUART6 to monitor other FCSPI's transmit interface + * + * @param eUartxType Uart type + */ +LOCAL_INLINE void SCM_HWA_FCUART6MonUARTx(SCM_MON_FCUARTxType eUartxType) +{ + uint32_t u32RegVal = SCM->FCUART_ROUTING0; + SCM->FCUART_ROUTING0 = ((u32RegVal & (~(uint32_t)SCM_FCUART_ROUTING0_UART6_ROUTER_MASK)) | SCM_FCUART_ROUTING0_UART6_ROUTER(eUartxType)); +} + +/** + * @brief Use FCUART5 to monitor other FCSPI's transmit interface + * + * @param eUartxType Uart type + */ +LOCAL_INLINE void SCM_HWA_FCUART5MonUARTx(SCM_MON_FCUARTxType eUartxType) +{ + uint32_t u32RegVal = SCM->FCUART_ROUTING0; + SCM->FCUART_ROUTING0 = ((u32RegVal & (~(uint32_t)SCM_FCUART_ROUTING0_UART5_ROUTER_MASK)) | SCM_FCUART_ROUTING0_UART5_ROUTER(eUartxType)); +} + +/** + * @brief Use FCUART4 to monitor other FCSPI's transmit interface + * + * @param eUartxType Uart type + */ +LOCAL_INLINE void SCM_HWA_FCUART4MonUARTx(SCM_MON_FCUARTxType eUartxType) +{ + uint32_t u32RegVal = SCM->FCUART_ROUTING0; + SCM->FCUART_ROUTING0 = ((u32RegVal & (~(uint32_t)SCM_FCUART_ROUTING0_UART4_ROUTER_MASK)) | SCM_FCUART_ROUTING0_UART4_ROUTER(eUartxType)); +} + +/** + * @brief Use FCUART3 to monitor other FCSPI's transmit interface + * + * @param eUartxType Uart type + */ +LOCAL_INLINE void SCM_HWA_FCUART3MonUARTx(SCM_MON_FCUARTxType eUartxType) +{ + uint32_t u32RegVal = SCM->FCUART_ROUTING0; + SCM->FCUART_ROUTING0 = ((u32RegVal & (~(uint32_t)SCM_FCUART_ROUTING0_UART3_ROUTER_MASK)) | SCM_FCUART_ROUTING0_UART3_ROUTER(eUartxType)); +} + +/** + * @brief Use FCUART2 to monitor other FCSPI's transmit interface + * + * @param eUartxType Uart type + */ +LOCAL_INLINE void SCM_HWA_FCUART2MonUARTx(SCM_MON_FCUARTxType eUartxType) +{ + uint32_t u32RegVal = SCM->FCUART_ROUTING0; + SCM->FCUART_ROUTING0 = ((u32RegVal & (~(uint32_t)SCM_FCUART_ROUTING0_UART2_ROUTER_MASK)) | SCM_FCUART_ROUTING0_UART2_ROUTER(eUartxType)); +} + +/** + * @brief Use FCUART1 to monitor other FCSPI's transmit interface + * + * @param eUartxType Uart type + */ +LOCAL_INLINE void SCM_HWA_FCUART1MonUARTx(SCM_MON_FCUARTxType eUartxType) +{ + uint32_t u32RegVal = SCM->FCUART_ROUTING0; + SCM->FCUART_ROUTING0 = ((u32RegVal & (~(uint32_t)SCM_FCUART_ROUTING0_UART1_ROUTER_MASK)) | SCM_FCUART_ROUTING0_UART1_ROUTER(eUartxType)); +} + +/** + * @brief Use FCUART0 to monitor other FCSPI's transmit interface + * + * @param eUartxType Uart type + */ +LOCAL_INLINE void SCM_HWA_FCUART0MonUARTx(SCM_MON_FCUARTxType eUartxType) +{ + uint32_t u32RegVal = SCM->FCUART_ROUTING0; + SCM->FCUART_ROUTING0 = ((u32RegVal & (~(uint32_t)SCM_FCUART_ROUTING0_UART0_ROUTER_MASK)) | SCM_FCUART_ROUTING0_UART0_ROUTER(eUartxType)); +} + +/** + * @brief Set PTIMER Loop Mode selection + * + * @param ePTimerLoopMode PTIMER Loop Mode + */ +LOCAL_INLINE void SCM_HWA_PTimerLoopModeSel(SCM_PTimerLMSelType ePTimerLoopMode) +{ + uint32_t u32RegVal = SCM->ADC_ROUTING; + SCM->ADC_ROUTING = ((u32RegVal & + (~(uint32_t)(SCM_ADC_ROUTING_PTIMER01LOOP_MASK | + SCM_ADC_ROUTING_PTIMER01LOOP_1_MASK | + SCM_ADC_ROUTING_PTIMER01LOOP_2_MASK))) | + SCM_ADC_ROUTING_PTIMER01LOOP((uint32_t)ePTimerLoopMode >> 2U)) | + SCM_ADC_ROUTING_PTIMER01LOOP_1((uint32_t)ePTimerLoopMode >> 1U) | + SCM_ADC_ROUTING_PTIMER01LOOP_2((uint32_t)ePTimerLoopMode); +} + +/** + * @brief Set ADC1 Trigger Source selection + * + * @param eAdcTriggerSrc ADC1 Trigger Source + */ +LOCAL_INLINE void SCM_HWA_ADC1TriggerSrcSel(SCM_AdcTriggerSrcType eAdcTriggerSrc) +{ + uint32_t u32RegVal = SCM->ADC_ROUTING; + SCM->ADC_ROUTING = ((u32RegVal & (~(uint32_t)SCM_ADC_ROUTING_ADC1_TRGSEL_MASK)) | + SCM_ADC_ROUTING_ADC1_TRGSEL(eAdcTriggerSrc)); +} + +/** + * @brief Set ADC1 Pre-trigger Source selection + * + * @param eAdcTriggerSrc ADC1 Pre-trigger Source + */ +LOCAL_INLINE void SCM_HWA_ADC1PreTriggerSrcSel(SCM_AdcPreTriggerSrcType eAdcPreTriggerSrc) +{ + uint32_t u32RegVal = SCM->ADC_ROUTING; + SCM->ADC_ROUTING = ((u32RegVal & (~(uint32_t)SCM_ADC_ROUTING_ADC1_PRETRGSEL_MASK)) | + SCM_ADC_ROUTING_ADC1_PRETRGSEL(eAdcPreTriggerSrc)); +} + +/** + * @brief Set ADC1 SCM Pre-trigger Source selection + * + * @param eScmSoftwarePreTriggerSrc ADC1 SCM software Pre-trigger Source + */ +LOCAL_INLINE void SCM_HWA_ADC1ScmSoftWarePreTriggerSrcSel(SCM_SoftwarePreTriggerType eScmSoftwarePreTriggerSrc) +{ + uint32_t u32RegVal = SCM->ADC_ROUTING; + SCM->ADC_ROUTING = ((u32RegVal & (~(uint32_t)SCM_ADC_ROUTING_ADC1_SWPRETRG_MASK)) | + SCM_ADC_ROUTING_ADC1_SWPRETRG(eScmSoftwarePreTriggerSrc)); +} + +/** + * @brief Set ADC0 Trigger Source selection + * + * @param eAdcTriggerSrc ADC0 Trigger Source + */ +LOCAL_INLINE void SCM_HWA_ADC0TriggerSrcSel(SCM_AdcTriggerSrcType eAdcTriggerSrc) +{ + uint32_t u32RegVal = SCM->ADC_ROUTING; + SCM->ADC_ROUTING = ((u32RegVal & (~(uint32_t)SCM_ADC_ROUTING_ADC0_TRGSEL_MASK)) | + SCM_ADC_ROUTING_ADC0_TRGSEL(eAdcTriggerSrc)); +} + +/** + * @brief Set ADC0 Pre-trigger Source selection + * + * @param eAdcTriggerSrc ADC0 Pre-trigger Source + */ +LOCAL_INLINE void SCM_HWA_ADC0PreTriggerSrcSel(SCM_AdcPreTriggerSrcType eAdcPreTriggerSrc) +{ + uint32_t u32RegVal = SCM->ADC_ROUTING; + SCM->ADC_ROUTING = ((u32RegVal & (~(uint32_t)SCM_ADC_ROUTING_ADC0_PRETRGSEL_MASK)) | + SCM_ADC_ROUTING_ADC0_PRETRGSEL(eAdcPreTriggerSrc)); +} + +/** + * @brief Set ADC0 SCM Pre-trigger Source selection + * + * @param eScmSoftwarePreTriggerSrc ADC0 SCM software Pre-trigger Source + */ +LOCAL_INLINE void SCM_HWA_ADC0ScmSoftWarePreTriggerSrcSel(SCM_SoftwarePreTriggerType eScmSoftwarePreTriggerSrc) +{ + uint32_t u32RegVal = SCM->ADC_ROUTING; + SCM->ADC_ROUTING = ((u32RegVal & (~(uint32_t)SCM_ADC_ROUTING_ADC0_SWPRETRG_MASK)) | + SCM_ADC_ROUTING_ADC0_SWPRETRG(eScmSoftwarePreTriggerSrc)); +} + +/** + * @brief Select the FTU3 output source, should be ignored when FTU3 in input mode + * + * @param eOutSelType FTU3 output source selection type + */ +LOCAL_INLINE void SCM_HWA_SetOutSel_FTU3(SCM_FTU_OutputSelType eOutSelType) +{ + uint32_t u32RegVal = SCM->FTU_ROUTING; + SCM->FTU_ROUTING = ((u32RegVal & (~(uint32_t)SCM_FTU_ROUTING_FTU3_OUTSEL_MASK)) | SCM_FTU_ROUTING_FTU3_OUTSEL(eOutSelType)); +} + +/** + * @brief Select the FTU0 output source, should be ignored when FTU0 in input mode + * + * @param eOutSelType FTU0 output source selection type + */ +LOCAL_INLINE void SCM_HWA_SetOutSel_FTU0(SCM_FTU_OutputSelType eOutSelType) +{ + uint32_t u32RegVal = SCM->FTU_ROUTING; + SCM->FTU_ROUTING = ((u32RegVal & (~(uint32_t)SCM_FTU_ROUTING_FTU0_OUTSEL_MASK)) | SCM_FTU_ROUTING_FTU0_OUTSEL(eOutSelType)); +} + +/** + * @brief Selects FTU2 CH1 input + * + * @param eInputSelType FTU2 CH1 input selection type + */ +LOCAL_INLINE void SCM_HWA_SetInSel_FTU2_CH1(SCM_FTU2_CH1_InputSelType eInputSelType) +{ + uint32_t u32RegVal = SCM->FTU_ROUTING; + SCM->FTU_ROUTING = ((u32RegVal & (~(uint32_t)SCM_FTU_ROUTING_FTU2_CH1SEL_MASK)) | SCM_FTU_ROUTING_FTU2_CH1SEL(eInputSelType)); +} + +/** + * @brief Selects FTU2 CH0 input + * + * @param eInputSelType FTU2 CH0 input selection type + */ +LOCAL_INLINE void SCM_SetInSel_FTU2_CH0(SCM_FTUx_CH0_InputSelType eInputSelType) +{ + uint32_t u32RegVal = SCM->FTU_ROUTING; + SCM->FTU_ROUTING = ((u32RegVal & (~(uint32_t)SCM_FTU_ROUTING_FTU2_CH0SEL_MASK)) | SCM_FTU_ROUTING_FTU2_CH0SEL(eInputSelType)); +} + +/** + * @brief Selects FTU1 CH0 input + * + * @param eInputSelType FTU1 CH0 input selection type + */ +LOCAL_INLINE void SCM_SetInSel_FTU1_CH0(SCM_FTUx_CH0_InputSelType eInputSelType) +{ + uint32_t u32RegVal = SCM->FTU_ROUTING; + SCM->FTU_ROUTING = ((u32RegVal & (~(uint32_t)SCM_FTU_ROUTING_FTU1_CH0SEL_MASK)) | SCM_FTU_ROUTING_FTU1_CH0SEL(eInputSelType)); +} + +/** + * @brief Lock FTU Routing Register + * + */ +LOCAL_INLINE void SCM_HWA_LockFTU_ROUTING(void) +{ + SCM->FTU_ROUTING |= (uint32_t)SCM_FTU_ROUTING_LOCK_MASK; +} + +/** + * @brief Get FTU_ROUTING register lock status + * + * @return Lock status + * 1: FTU_ROUTING register is lock + * 0: FTU_ROUTING register is not lock + */ +LOCAL_INLINE uint32_t SCM_HWA_FTU_ROUTING_GetLockStatus(void) +{ + return (SCM->FTU_ROUTING & (uint32_t)SCM_FTU_ROUTING_LOCK_MASK) >> SCM_FTU_ROUTING_LOCK_SHIFT; +} + +/** + * @brief Lock FTU Global Time Base Control Register + * + */ +LOCAL_INLINE void SCM_HWA_LockFTU_GTB(void) +{ + SCM->FTU_GTBC |= (uint32_t)SCM_FTU_GTBC_LOCK_MASK; +} + +/** + * @brief Get FTU GTB register lock status + * + * @return Lock status + */ +LOCAL_INLINE uint32_t SCM_HWA_FTU_GTB_GetLockStatus(void) +{ + return (SCM->FTU_GTBC & (uint32_t)SCM_FTU_GTBC_LOCK_MASK) >> SCM_FTU_GTBC_LOCK_SHIFT; +} + +/** + * @brief Configure FTU global time base control selection + * + * @param u32SelectedFtu The GTBC mask of Selected Ftu instance,it is the or value of SCM_FTUGTBCtrlType. + * eg.u32SelectedFtu == 1 means FTU0 selected, u32SelectedFtu == 5 means FTU0 and FTU2 selected. + */ +LOCAL_INLINE void SCM_HWA_ConfigFtuGTBSelect(uint32_t u32SelectedFtu) +{ + SCM->FTU_GTBC &= ~(uint32_t)SCM_FTU_GTBC_FTU_GTBC_MASK; + SCM->FTU_GTBC |= (uint32_t)SCM_FTU_GTBC_FTU_GTBC(u32SelectedFtu); +} + +/** + * @brief Set FTU global time base control selection + * + * @param u32SelectedFtu The GTBC mask of Selected Ftu instance,it is the or value of SCM_FTUGTBCtrlType. + * eg.u32SelectedFtu == 1 means FTU0 selected, u32SelectedFtu == 5 means FTU0 and FTU2 selected. + */ +LOCAL_INLINE void SCM_HWA_SetFtuGTBSelect(uint32_t u32SelectedFtu) +{ + SCM->FTU_GTBC |= (uint32_t)SCM_FTU_GTBC_FTU_GTBC(u32SelectedFtu); +} + +/** + * @brief Clear FTU global time base control selection + * + * @param u32SelectedFtu The GTBC mask of Selected Ftu instance,it is the or value of SCM_FTUGTBCtrlType. + * eg.u32SelectedFtu == 1 means FTU0 selected, u32SelectedFtu == 5 means FTU0 and FTU2 selected. + */ +LOCAL_INLINE void SCM_HWA_ClearFtuGTBSelect(uint32_t u32SelectedFtu) +{ + SCM->FTU_GTBC &= ~(uint32_t)SCM_FTU_GTBC_FTU_GTBC(u32SelectedFtu); +} + +/** + * @brief Configure TPU global time base control selection + * + * @param bEn Enable or disable TPU Global Time Base + */ +LOCAL_INLINE void SCM_HWA_ConfigTpuGTBSelect(bool bEn) +{ + SCM->FTU_GTBC &= ~(uint32_t)SCM_FTU_GTBC_TPU_GTBC_MASK; + SCM->FTU_GTBC |= (uint32_t)SCM_FTU_GTBC_TPU_GTBC(bEn); +} + +/** + * @brief Set the value of TPU Global Time Base Control Mask Register + * + * @param u32Value Value to be set + */ +LOCAL_INLINE void SCM_HWA_SetTpuGTBMValue(uint32_t u32Value) +{ + SCM->FTU_GTBCM = u32Value; +} + +/** + * @brief Configure TPU Channel [31:24] Source Select + * + * @param eTrgSelMask The TPU Channel [31:24] Source Select mask bits + */ +LOCAL_INLINE void SCM_HWA_ConfigTpuTrgSel(uint8_t eTrgSelMask) +{ + SCM->FTU_GTBCM = (SCM->FTU_GTBCM & (~(uint32_t)SCM_TPU_GTBCM_TPU_TRGSEL_MASK)) | + (uint32_t)SCM_TPU_GTBCM_TPU_TRGSEL(eTrgSelMask); +} + +/** + * @brief Configure TPU GTBC Mask is corresponding to channel trigger of TSTMP1 + * + * @param eTpuGTBMask The TPU GTBC Mask (must be 0 ~ 15) + */ +LOCAL_INLINE void SCM_HWA_ConfigTpuGTBMask(uint8_t eTpuGTBMask) +{ + SCM->FTU_GTBCM = (SCM->FTU_GTBCM & (~(uint32_t)SCM_TPU_GTBCM_TPU_GTBCM_MASK)) | + (uint32_t)SCM_TPU_GTBCM_TPU_GTBCM(eTpuGTBMask); +} + +/** + * @brief Configure FTU Global Time Base Control Mask Register + * + * @param u8FtuIndex The selected FTU instance (must be 0 ~ 7) + * @param u32Value Value to be set (must be 0 ~ 15) + */ +LOCAL_INLINE void SCM_HWA_ConfigFtuGTBMask(uint8_t u8FtuIndex, uint32_t u32Value) +{ + SCM->FTU_GTBCM &= ~ ((uint32_t)SCM_FTU_GTBCM_FTU0_GTBCM_MASK << (SCM_FTU_GTBCM_FTU0_GTBCM_WIDTH * u8FtuIndex)); + SCM->FTU_GTBCM |= (((uint32_t)u32Value & SCM_FTU_GTBCM_FTU0_GTBCM_MASK) << (SCM_FTU_GTBCM_FTU0_GTBCM_WIDTH * u8FtuIndex)); +} + +/** + * @brief Clear FTU Global Time Base Control Mask Register + * + * @param u8FtuIndex The selected FTU instance (must be 0 ~ 7) + */ +LOCAL_INLINE void SCM_HWA_ClearFtuGTBMask(uint8_t u8FtuIndex) +{ + SCM->FTU_GTBCM &= ~ ((uint32_t)SCM_FTU_GTBCM_FTU0_GTBCM_MASK << (SCM_FTU_GTBCM_FTU0_GTBCM_WIDTH * u8FtuIndex)); +} + +/** + * @brief Set FTU sync control + * + * @param u32Value The sync mask of selected FTU instance + * u32Value must be the or value of SCM_FTUSyncCtrlType + */ +LOCAL_INLINE void SCM_HWA_SetFTUSync(uint32_t u32Value) +{ + SCM->FTU_SYNC = u32Value & SCM_FTU_SYNC_MASK; +} + +/** + * @brief Lock FTU GTB Register + * + */ +LOCAL_INLINE void SCM_HWA_LockDEBUG_TRACE(void) +{ + SCM->DEBUG_TRACE |= (uint32_t)SCM_DEBUG_TRACE_LOCK_MASK; +} + +/** + * @brief Get FTU GTB register lock status + * + * @return Lock status + */ +LOCAL_INLINE uint32_t SCM_HWA_DEBUG_TRACE_GetLockStatus(void) +{ + return(SCM->DEBUG_TRACE & (uint32_t)SCM_DEBUG_TRACE_LOCK_MASK) >> SCM_DEBUG_TRACE_LOCK_SHIFT; +} + +/** + * @brief Set debug atclk enable/disable + * + * @param bEnable Enable/Disable + */ +LOCAL_INLINE void SCM_HWA_SetEnable_DebugATClk(bool bEnable) +{ + SCM->DEBUG_TRACE = (SCM->DEBUG_TRACE & (~(SCM_DEBUG_TRACE_DEBUG_ATCLK_EN_MASK))) | + SCM_DEBUG_TRACE_DEBUG_ATCLK_EN(bEnable); +} + +/** + * @brief Set trace clock divider value + * + * @param u32Value The divider value to be set + */ +LOCAL_INLINE void SCM_HWA_SetTraceClkDiv(uint32_t u32Value) +{ + SCM->DEBUG_TRACE = ((SCM->DEBUG_TRACE & (~(uint32_t)SCM_DEBUG_TRACE_TRACECLK_DIV_MASK)) | + SCM_DEBUG_TRACE_TRACECLK_DIV(u32Value)); +} + +/** + * @brief Set trace clock selection + * + * @param eSrcClkType Clock selection + */ +LOCAL_INLINE void SCM_HWA_SetTraceClkSrc(SCM_TraceClkSrcType eSrcClkType) +{ + SCM->DEBUG_TRACE = ((SCM->DEBUG_TRACE & (~(uint32_t)SCM_DEBUG_TRACE_TRACECLK_SEL_MASK)) | + SCM_DEBUG_TRACE_TRACECLK_SEL(eSrcClkType)); +} + +/** + * @brief Set trace clock divider enable/disable + * + * @param bEnable Enable/Disable + */ +LOCAL_INLINE void SCM_HWA_SetEnable_TraceClk(bool bEnable) +{ + SCM->DEBUG_TRACE = (SCM->DEBUG_TRACE & (~(SCM_DEBUG_TRACE_TRACECLK_EN_MASK))) | + SCM_DEBUG_TRACE_TRACECLK_EN(bEnable); +} + +/** + * @brief Lock the SOCMISC register + * + */ +LOCAL_INLINE void SCM_HWA_SOCMISC_LockWritePermit(void) +{ + SCM->SOCMISC |= (uint32_t)SCM_SOCMISC_WPB_LOCK_MASK; +} + +/** + * @brief Get the SOCMISC register lock status + * + * @return Lock status + */ +LOCAL_INLINE uint32_t SCM_HWA_SOCMISC_GetWPBLockStatus(void) +{ + return (SCM->SOCMISC & (uint32_t)SCM_SOCMISC_WPB_LOCK_MASK) >> SCM_SOCMISC_WPB_LOCK_SHIFT; +} + +/** + * @brief Get the CPU type of writing permission to SOCMISC register + * + * @return SCM_WPB_CpuType The CPU which has the write permission + */ +LOCAL_INLINE SCM_WPB_CpuType SCM_HWA_SOCMISC_GetCpuWritePermit(void) +{ + uint32_t u32RegVal = (SCM->SOCMISC & (uint32_t)SCM_SOCMISC_WPB_MASK) >> SCM_SOCMISC_WPB_SHIFT; + return (SCM_WPB_CpuType)u32RegVal; +} + +/** + * @brief Set cpu to control SOCMISC register + * + * @param eCpuType Cpu allowed to control peripheral + */ +LOCAL_INLINE void SCM_HWA_SOCMISC_SetCpuWritePermit(SCM_WPB_CpuType eCpuType) +{ + SCM->SOCMISC = ((SCM->SOCMISC & (~(uint32_t)SCM_SOCMISC_WPB_MASK)) | SCM_SOCMISC_WPB(eCpuType)); +} + +/** + * @brief Set software trigger 4~7 to TRGSEL1 & TRGSEL5 + * + * @param eTriggerType software trigger number (SCM_SW_TRIG_0 ~ SCM_SW_TRIG_3) + */ +LOCAL_INLINE void SCM_HWA_SetSwTrigx_Trgsel15(SCM_SwTrigxType eTriggerType) +{ + SCM->SOCMISC = ((SCM->SOCMISC & (~(uint32_t)SCM_SOCMISC_GPR_SW_TRIG_7_4_MASK)) | + SCM_SOCMISC_GPR_SW_TRIG_7_4(eTriggerType)); +} + +/** + * @brief Set software trigger 0~3 to TRGSEL0 & TRGSEL4 + * + * @param eTriggerType software trigger number (SCM_SW_TRIG_4 ~ SCM_SW_TRIG_7) + */ +LOCAL_INLINE void SCM_HWA_SetSwTrigx_Trgsel04(SCM_SwTrigxType eTriggerType) +{ + SCM->SOCMISC = ((SCM->SOCMISC & (~(uint32_t)SCM_SOCMISC_GPR_SW_TRIG_3_0_MASK)) | + SCM_SOCMISC_GPR_SW_TRIG_3_0(eTriggerType)); +} + +/** + * @brief Get CCM0 status + * + * @return CCM0 Status, it is the or value of SCM_CCMxStatusType + */ +LOCAL_INLINE uint32_t SCM_HWA_GetStatus_CCM0( void ) +{ + return SCM->CCM0_STATUS & SCM_CCM0_STATUS_MASK; +} + +/** + * @brief Lock FLEXCAN_ROUTING Register + * + */ +LOCAL_INLINE void SCM_HWA_LockFLEXCAN_ROUTING(void) +{ + SCM->FLEXCAN_ROUTING |= (uint32_t)SCM_FLEXCAN_ROUTING_LOCK_MASK; +} + +/** + * @brief Get FLEXCAN_ROUTING register lock status + * + * @return Lock status + * 1: FLEXCAN_ROUTING register is lock + * 0: FLEXCAN_ROUTING register is not lock + */ +LOCAL_INLINE uint32_t SCM_HWA_FLEXCAN_ROUTING_GetLockStatus(void) +{ + return (SCM->FLEXCAN_ROUTING & (uint32_t)SCM_FLEXCAN_ROUTING_LOCK_MASK) >> SCM_FLEXCAN_ROUTING_LOCK_SHIFT; +} + +/** + * @brief Select TRESEL input from pad TRGSEL_IN0~TRGSEL_IN15 for FLEXCAN0/1/2/3 RX + * + * @param u16TrgSel Enable Select TRESEL input from pad TRGSEL_IN0~TRGSEL_IN15 for FLEXCAN0/1/2/3 RX + */ +LOCAL_INLINE void SCM_HWA_FLEXCAN_ROUTING_SetTriggerSel(uint16_t u16TrgSel) +{ + SCM->FLEXCAN_ROUTING = ((SCM->FLEXCAN_ROUTING & (~(uint32_t)SCM_FLEXCAN_ROUTING_FLEXCAN_TRIGGER_MASK_MASK)) | + SCM_FLEXCAN_ROUTING_FLEXCAN_TRIGGER_MASK(u16TrgSel)); +} + +/** + * @brief Set MSC0 ALTIN high higher bits[31:24] source selection + * + * @param eInSelType Router selection + */ +LOCAL_INLINE void SCM_HWA_SetSel_MSC0AltInHH(SCM_MSCAltInSelType eInSelType) +{ + uint32_t u32RegVal = SCM->MSC0_ROUTING; + SCM->MSC0_ROUTING = ((u32RegVal & (~(uint32_t)SCM_MSC0_ROUTING_MSC0_31_24_SEL_MASK)) | SCM_MSC0_ROUTING_MSC0_31_24_SEL(eInSelType)); +} + +/** + * @brief Set MSC0 ALTIN high lower bits[23:16] source selection + * + * @param eInSelType Router selection + */ +LOCAL_INLINE void SCM_HWA_SetSel_MSC0AltInHL(SCM_MSCAltInSelType eInSelType) +{ + uint32_t u32RegVal = SCM->MSC0_ROUTING; + SCM->MSC0_ROUTING = ((u32RegVal & (~(uint32_t)SCM_MSC0_ROUTING_MSC0_23_16_SEL_MASK)) | SCM_MSC0_ROUTING_MSC0_23_16_SEL(eInSelType)); +} + +/** + * @brief Set MSC0 ALTIN low higher bits[15:8] source selection + * + * @param eInSelType Router selection + */ +LOCAL_INLINE void SCM_HWA_SetSel_MSC0AltInLH(SCM_MSCAltInSelType eInSelType) +{ + uint32_t u32RegVal = SCM->MSC0_ROUTING; + SCM->MSC0_ROUTING = ((u32RegVal & (~(uint32_t)SCM_MSC0_ROUTING_MSC0_15_8_SEL_MASK)) | SCM_MSC0_ROUTING_MSC0_15_8_SEL(eInSelType)); +} + +/** + * @brief Set MSC0 ALTIN low lower bits[7:0] source selection + * + * @param eInSelType Router selection + */ +LOCAL_INLINE void SCM_HWA_SetSel_MSC0AltInLL(SCM_MSCAltInSelType eInSelType) +{ + uint32_t u32RegVal = SCM->MSC0_ROUTING; + SCM->MSC0_ROUTING = ((u32RegVal & (~(uint32_t)SCM_MSC0_ROUTING_MSC0_7_0_SEL_MASK)) | SCM_MSC0_ROUTING_MSC0_7_0_SEL(eInSelType)); +} + +/** + * @brief Lock MSC0_ROUTING Register + * + */ +LOCAL_INLINE void SCM_HWA_LockMSC0_ROUTING(void) +{ + SCM->MSC0_ROUTING |= (uint32_t)SCM_MSC0_ROUTING_LOCK_MASK; +} + +/** + * @brief Get MSC0_ROUTING register lock status + * + * @return Lock status + */ +LOCAL_INLINE uint32_t SCM_HWA_MSC0_ROUTING_GetLockStatus(void) +{ + return(SCM->MSC0_ROUTING & (uint32_t)SCM_MSC0_ROUTING_LOCK_MASK) >> SCM_MSC0_ROUTING_LOCK_SHIFT; +} + +/** + * @brief Set FCSMU software trigger enable/disable + * + * @param bEnable Enable/Disable + */ +LOCAL_INLINE void SCM_HWA_SetEnable_FCSMUSwTrigger(bool bEnable) +{ + SCM->FCSMU_SW = (SCM->FCSMU_SW & (~(SCM_FCSMU_SW_FCSMU_SW_MASK))) | + SCM_FCSMU_SW_FCSMU_SW(bEnable); +} + +/** + * @brief FTU_IN[15:8] Source Select + * + * @param eRouterType Router source selection + */ +LOCAL_INLINE void SCM_HWA_SetIsmRouterFtuD(SCM_ISMRouterType eRouterType) +{ + SCM->ISM_ROUTING = ((SCM->ISM_ROUTING & (~(uint32_t)SCM_ISM_ROUTING_ISM_ROUT_FTU_D_MASK)) | + SCM_ISM_ROUTING_ISM_ROUT_FTU_D(eRouterType)); +} + +/** + * @brief FTU_IN[7:0] Source Select + * + * @param eRouterType Router source selection + */ +LOCAL_INLINE void SCM_HWA_SetIsmRouterFtuC(SCM_ISMRouterType eRouterType) +{ + SCM->ISM_ROUTING = ((SCM->ISM_ROUTING & (~(uint32_t)SCM_ISM_ROUTING_ISM_ROUT_FTU_C_MASK)) | + SCM_ISM_ROUTING_ISM_ROUT_FTU_C(eRouterType)); +} + +/** + * @brief Set ISM_FTU_ROUT[15:8] source select + * + * @param eRouterType Router source selection + */ +LOCAL_INLINE void SCM_HWA_SetIsmRouterFtuB(SCM_ISMRouterType eRouterType) +{ + SCM->ISM_ROUTING = ((SCM->ISM_ROUTING & (~(uint32_t)SCM_ISM_ROUTING_ISM_ROUT_FTU_B_MASK)) | + SCM_ISM_ROUTING_ISM_ROUT_FTU_B(eRouterType)); +} + +/** + * @brief Set ISM_FTU_ROUT[7:0] source select + * + * @param eRouterType Router source selection + */ +LOCAL_INLINE void SCM_HWA_SetIsmRouterFtuA(SCM_ISMRouterType eRouterType) +{ + SCM->ISM_ROUTING = ((SCM->ISM_ROUTING & (~(uint32_t)SCM_ISM_ROUTING_ISM_ROUT_FTU_A_MASK)) | + SCM_ISM_ROUTING_ISM_ROUT_FTU_A(eRouterType)); +} + +/** + * @brief Get matrix status register 0 status + * + * @return Register status + */ +LOCAL_INLINE uint32_t SCM_HWA_GetStatus_MATRIX_STATUS0(void) +{ + return SCM->MATRIX_STATUS0; +} + +/** + * @brief clear matrix status register 0 status + * + * @u32Status Matrix status + */ +LOCAL_INLINE void SCM_HWA_Clear_MATRIX_STATUS0(uint32_t u32Status) +{ + SCM->MATRIX_STATUS0 |= u32Status & SCM_MATRIX_STATUS0_MASK; +} + +/** + * @brief Get matrix status register 1 status + * + * @return Register status + */ +LOCAL_INLINE uint32_t SCM_HWA_GetStatus_MATRIX_STATUS1(void) +{ + return SCM->MATRIX_STATUS1; +} + +/** + * @brief clear matrix status register 1 status + * + * @u32Status Matrix status + */ +LOCAL_INLINE void SCM_HWA_Clear_MATRIX_STATUS1(uint32_t u32Status) +{ + SCM->MATRIX_STATUS1 |= u32Status & SCM_MATRIX_STATUS1_MASK; +} + +/** + * @brief Get matrix status register 2 status + * + * @return Register status + */ +LOCAL_INLINE uint32_t SCM_HWA_GetStatus_MATRIX_STATUS2(void) +{ + return SCM->MATRIX_STATUS2; +} + +/** + * @brief clear matrix status register 2 status + * + * @u32Status Matrix status + */ +LOCAL_INLINE void SCM_HWA_Clear_MATRIX_STATUS2(uint32_t u32Status) +{ + SCM->MATRIX_STATUS2 |= u32Status & SCM_MATRIX_STATUS2_MASK; +} + +/** + * @brief Get matrix status register 5 status + * + * @return Register status + */ +LOCAL_INLINE uint32_t SCM_HWA_GetStatus_MATRIX_STATUS5(void) +{ + return SCM->MATRIX_STATUS5; +} + +/** + * @brief clear matrix status register 5 status + * + * @u32Status Matrix status + */ +LOCAL_INLINE void SCM_HWA_Clear_MATRIX_STATUS5(uint32_t u32Status) +{ + SCM->MATRIX_STATUS5 |= u32Status & SCM_MATRIX_STATUS5_MASK; +} + +/** + * @brief Get matrix status register 6 status + * + * @return Register status + */ +LOCAL_INLINE uint32_t SCM_HWA_GetStatus_MATRIX_STATUS6(void) +{ + return SCM->MATRIX_STATUS6; +} + +/** + * @brief clear matrix status register 6 status + * + * @u32Status Matrix status + */ +LOCAL_INLINE void SCM_HWA_Clear_MATRIX_STATUS6(uint32_t u32Status) +{ + SCM->MATRIX_STATUS6 |= u32Status & SCM_MATRIX_STATUS6_MASK; +} + +/** + * @brief Get matrix status register 7 status + * + * @return Register status + */ +LOCAL_INLINE uint32_t SCM_HWA_GetStatus_MATRIX_STATUS7(void) +{ + return SCM->MATRIX_STATUS7; +} + +/** + * @brief clear matrix status register 7 status + * + * @u32Status Matrix status + */ +LOCAL_INLINE void SCM_HWA_Clear_MATRIX_STATUS7(uint32_t u32Status) +{ + SCM->MATRIX_STATUS7 |= u32Status & SCM_MATRIX_STATUS7_MASK; +} + +/** + * @brief Get matrix ID status register status + * + * @return Register status + */ +LOCAL_INLINE uint32_t SCM_HWA_GetStatus_MATRIX_ID_STATUS0(void) +{ + return SCM->MATRIX_ID_STATUS0; +} + +/** + * @brief clear matrix ID status register status + * + * @u32Status Matrix ID status + */ +LOCAL_INLINE void SCM_HWA_Clear_MATRIX_ID_STATUS0(uint32_t u32Status) +{ + SCM->MATRIX_ID_STATUS0 |= u32Status & SCM_MATRIX_ID_STATUS0_MASK; +} + +/** + * @brief Set SCM module mailbox data out, output from device to debug + * + * @param u32Value Ouputdata value + */ +LOCAL_INLINE void SCM_HWA_SetData_MDO(uint32_t u32Value) +{ + SCM->SYSAP_MDO = u32Value; +} + +/** + * @brief Get SCM module mailbox data in, input from debug to device + * + * @return u32Value Input data value + */ +LOCAL_INLINE uint32_t SCM_HWA_GetData_MDI(void) +{ + return SCM->SYSAP_MDI; +} + +/** + * @brief Select the type of Status2 Register + * + * @param eStatus2Sel Selected Status2 type + */ +LOCAL_INLINE void SCM_HWA_Status2RegisterSelection(SCM_SysAPStatus2SelType eStatus2Sel) +{ + SCM->SYSAP_CTRL = (SCM->SYSAP_CTRL & (~(SCM_SYSAP_CTRL_STATUS2_REG_SEL_MASK))) | + SCM_SYSAP_CTRL_STATUS2_REG_SEL(eStatus2Sel); +} + +/** + * @brief Get new mailbox data input available flag, + * device read MDI regiser will automatically clear the bit + * + * @return Mailbox data input available/disable + */ +LOCAL_INLINE uint32_t SCM_HWA_GetStatus_NewMDIAvailable(void) +{ + return ((SCM->SYSAP_CTRL & (uint32_t)SCM_SYSAP_CTRL_NEW_MDI_AVAILABLE_MASK)>>(uint32_t)SCM_SYSAP_CTRL_NEW_MDI_AVAILABLE_SHIFT); +} + +/** + * @brief Control if CPU0 hold in wait at the end of reset sequence + * + * @param bEnable Enable/Disable + */ +LOCAL_INLINE void SCM_HWA_SetEnable_Cpu0HoldInWait(bool bEnable) +{ + SCM->SYSAP_CTRL = (SCM->SYSAP_CTRL & (~(SCM_SYSAP_CTRL_CPU0_HOLD_IN_WAIT_MASK))) | + SCM_SYSAP_CTRL_CPU0_HOLD_IN_WAIT(bEnable); +} + +/** + * @brief Control if hold CPU0 in reset at the end of reset sequence + * + * @param bEnable Enable/Disable + */ +LOCAL_INLINE void SCM_HWA_SetEnable_Cpu0HoldInReset(bool bEnable) +{ + SCM->SYSAP_CTRL = (SCM->SYSAP_CTRL & (~(SCM_SYSAP_CTRL_CPU0_HOLD_IN_RESET_MASK))) | + SCM_SYSAP_CTRL_CPU0_HOLD_IN_RESET(bEnable); +} + +/** + * @brief Set to force a system reset, clear the bit to release system from reset + * + * @param bEnable Enable/Disable + */ +LOCAL_INLINE void SCM_HWA_SetEnable_SystemReset(bool bEnable) +{ + SCM->SYSAP_CTRL = (SCM->SYSAP_CTRL & (~(SCM_SYSAP_CTRL_SYSTEM_RESET_REQ_MASK))) | + SCM_SYSAP_CTRL_SYSTEM_RESET_REQ(bEnable); +} + +/** + * @brief Set to force all CPU debug restarted, CPU to exit halt state + * + * @param bEnable Enable/Disable + */ +LOCAL_INLINE void SCM_HWA_SetEnable_AllCpuDebugRestart(bool bEnable) +{ + SCM->SYSAP_CTRL = (SCM->SYSAP_CTRL & (~(SCM_SYSAP_CTRL_CPU_DEBUG_RESTART_MASK))) | + SCM_SYSAP_CTRL_CPU_DEBUG_RESTART(bEnable); +} + +/** + * @brief Set to force core to halt, if core is in stop mode. + * This bit can be used to wakeup the core and transition to halt state + * + * @param eSelType Cpu type selection + */ +LOCAL_INLINE void SCM_HWA_SetSel_CpuDebugRequest(SCM_SysApCpuDebugReqType eSelType) +{ + SCM->SYSAP_CTRL = ((SCM->SYSAP_CTRL & (~(uint32_t)SCM_SYSAP_CTRL_CPU_DEBUG_REQ_MASK)) | + SCM_SYSAP_CTRL_CPU_DEBUG_REQ(eSelType)); +} + +/** + * @brief Set to disable the debug, clear to allow debug operation + * + * @param bDisable Disable/Enable + */ +LOCAL_INLINE void SCM_HWA_SetDisable_Debug(bool bDisable) +{ + SCM->SYSAP_CTRL = ((SCM->SYSAP_CTRL & (~(uint32_t)SCM_SYSAP_CTRL_DEBUG_DIS_MASK)) | + SCM_SYSAP_CTRL_DEBUG_DIS(bDisable)); +} + +/** + * @brief Set to Trigger Flash Mass Erase.Cleared by hardware after mass erase is done + * + */ +LOCAL_INLINE void SCM_HWA_TriggerFlashMassErase(void) +{ + SCM->SYSAP_CTRL |= SCM_SYSAP_CTRL_FLASH_MASS_ERASE_MASK; +} + +/** + * @brief Lock the CPU permission(WPB) in SUBSYS_PCC register, and WPB cannot be written until a power-on reset + * + */ +LOCAL_INLINE void SCM_HWA_SUBSYS_PCC_LockWritePermit(void) +{ + SCM->SUBSYS_PCC |= (uint32_t)SCM_SUBSYS_PCC_WPB_LOCK_MASK; +} + +/** + * @brief Get the lock status of CPU permission(WPB) in SUBSYS_PCC register + * + * @return 1: The WPB of SUBSYS_PCC register is locked + * 0: The WPB of SUBSYS_PCC register is not locked + */ +LOCAL_INLINE uint32_t SCM_HWA_SUBSYS_PCC_GetWPBLockStatus(void) +{ + return (SCM->SUBSYS_PCC & (uint32_t)SCM_SUBSYS_PCC_WPB_LOCK_MASK) >> SCM_SUBSYS_PCC_WPB_LOCK_SHIFT; +} + +/** + * @brief Get the CPU type of writing permission to SUBSYS_PCC register + * + * @return SCM_WPB_CpuType The CPU which has the write permission + */ +LOCAL_INLINE SCM_WPB_CpuType SCM_HWA_SUBSYS_PCC_GetCpuWritePermit(void) +{ + uint32_t u32RegVal = ((SCM->SUBSYS_PCC & (uint32_t)SCM_SUBSYS_PCC_WPB_MASK) >> SCM_SUBSYS_PCC_WPB_SHIFT); + return (SCM_WPB_CpuType)u32RegVal; +} + +/** + * @brief Set CPU to control the SUBSYS_PCC register + * + * @param eCpuType CPU allowed to control peripheral + */ +LOCAL_INLINE void SCM_HWA_SUBSYS_PCC_SetCpuWritePermit(SCM_WPB_CpuType eCpuType) +{ + SCM->SUBSYS_PCC = ((SCM->SUBSYS_PCC & (~(uint32_t)SCM_SUBSYS_PCC_WPB_MASK)) | SCM_SUBSYS_PCC_WPB(eCpuType)); +} + +/** + * @brief Get TPU clock enable/disable status + * + * @return 1: TPU clock disabled + * 0: TPU clock enabled + */ +LOCAL_INLINE uint32_t SCM_HWA_SUBSYS_PCC_GetStatus_TPUClock(void) +{ + return (SCM->SUBSYS_PCC & SCM_SUBSYS_PCC_CLKEN_TPU_MASK) >> SCM_SUBSYS_PCC_CLKEN_TPU_SHIFT; +} + +/** + * @brief Set TPU clock enable/disable + * + * @param bEnable Enable/Disable + */ +LOCAL_INLINE void SCM_HWA_SUBSYS_PCC_SetEnable_TPUClock(bool bEnable) +{ + SCM->SUBSYS_PCC = ((SCM->SUBSYS_PCC & (~(uint32_t)SCM_SUBSYS_PCC_CLKEN_TPU_MASK)) | + SCM_SUBSYS_PCC_CLKEN_TPU(bEnable)); +} + +/** + * @brief Get HSM clock enable/disable status + * + * @return 1: HSM clock disabled + * 0: HSM clock enabled + */ +LOCAL_INLINE uint32_t SCM_HWA_SUBSYS_PCC_GetStatus_HSMClock(void) +{ + return (SCM->SUBSYS_PCC & SCM_SUBSYS_PCC_CLKEN_HSM_ENGINE_MASK) >> SCM_SUBSYS_PCC_CLKEN_HSM_ENGINE_SHIFT; +} + +/** + * @brief Set HSM clock enable/disable + * + * @param bEnable Enable/Disable + */ +LOCAL_INLINE void SCM_HWA_SUBSYS_PCC_SetEnable_HSMClock(bool bEnable) +{ + SCM->SUBSYS_PCC = ((SCM->SUBSYS_PCC & (~(uint32_t)SCM_SUBSYS_PCC_CLKEN_HSM_ENGINE_MASK)) | + SCM_SUBSYS_PCC_CLKEN_HSM_ENGINE(bEnable)); +} + +/** + * @brief Get SubSystem clock enable/disable status + * + * @return 1: SubSystem clock disabled + * 0: SubSystem clock enabled + */ +LOCAL_INLINE uint32_t SCM_HWA_SUBSYS_PCC_GetStatus_SubSystemClock(void) +{ + return (SCM->SUBSYS_PCC & SCM_SUBSYS_PCC_CLKEN_SUBSYS_MASK) >> SCM_SUBSYS_PCC_CLKEN_SUBSYS_SHIFT; +} + +/** + * @brief Set SubSystem clock enable/disable + * + * @param bEnable Enable/Disable + */ +LOCAL_INLINE void SCM_HWA_SUBSYS_PCC_SetEnable_SubSystemClock(bool bEnable) +{ + SCM->SUBSYS_PCC = ((SCM->SUBSYS_PCC & (~(uint32_t)SCM_SUBSYS_PCC_CLKEN_SUBSYS_MASK)) | + SCM_SUBSYS_PCC_CLKEN_SUBSYS(bEnable)); +} + +/** + * @brief Set SubSystem software reset + * + * @param bEnable Enable/Disable + */ +LOCAL_INLINE void SCM_HWA_SUBSYS_PCC_SetEnable_SwReset(bool bEnable) +{ + SCM->SUBSYS_PCC = ((SCM->SUBSYS_PCC & (~(uint32_t)SCM_SUBSYS_PCC_SWRST_MASK)) | + SCM_SUBSYS_PCC_SWRST(bEnable)); +} + +/** + * @brief Set SubSystem watchdog reset + * + * @param bEnable Enable/Disable + */ +LOCAL_INLINE void SCM_HWA_SUBSYS_PCC_SetEnable_SubsysWdgReset(bool bEnable) +{ + SCM->SUBSYS_PCC = ((SCM->SUBSYS_PCC & (~(uint32_t)SCM_SUBSYS_PCC_WDG_RSTEN_MASK)) | + SCM_SUBSYS_PCC_WDG_RSTEN(bEnable)); +} + +/** + * @brief Set SubSystem stop mode request + * + * @param bEnable Enable/Disable + */ +LOCAL_INLINE void SCM_HWA_SUBSYS_PCC_SetEnable_SubsysStopModReq(bool bEnable) +{ + SCM->SUBSYS_PCC = ((SCM->SUBSYS_PCC & (~(uint32_t)SCM_SUBSYS_PCC_STOP_REQ_MASK)) | + SCM_SUBSYS_PCC_STOP_REQ(bEnable)); +} + +/** + * @brief Subsystem status register value + * + * @return Subsystem status register + */ +LOCAL_INLINE uint32_t SCM_HWA_GetValue_SUBSYS_STATUS(void) +{ + return SCM->SUBSYS_STATUS; +} + +/** + * @brief Get Subsystem Error Report + * + * @return Subsystem Error Report + */ +LOCAL_INLINE uint16_t SCM_HWA_GetStatus_SUBSYS_ERR(void) +{ + return (SCM->SUBSYS_STATUS & SCM_SUBSYS_STATUS_HSM_SYS_ERR_MASK) >> SCM_SUBSYS_STATUS_HSM_SYS_ERR_SHIFT; +} + +/** + * @brief Get Subsystem status + * + * @return true: Subsystem status asserted + * false: Subsystem status not asserted + */ +LOCAL_INLINE bool SCM_HWA_GetStatus_SUBSYS_STATUS(SCM_SUBSYSStatusType eStatusType) +{ + return ((SCM->SUBSYS_STATUS & (uint32_t)eStatusType) != 0U) ? true : false; +} + +/** + * @brief Get mailbox data output from device to debug flag + * + * @return Flag status + */ +LOCAL_INLINE uint32_t SCM_HWA_GetStatus_MDOFlag(void) +{ + return (SCM->MDO_FLAG & SCM_MDO_FLAG_MDO_FLAG_MASK) >> SCM_MDO_FLAG_MDO_FLAG_SHIFT; +} + +/** + * @brief Lock the CPU permission(WPB) in MASTER_HALT_REQ register, and WPB cannot be written until a power-on reset + * + */ +LOCAL_INLINE void SCM_HWA_MASTER_HALT_REQ_LockWritePermit(void) +{ + SCM->MASTER_HALT_REQ |= (uint32_t)SCM_MASTER_HALT_REQ_WPB_LOCK_MASK; +} + +/** + * @brief Get the lock status of CPU permission(WPB) in MASTER_HALT_REQ register + * + * @return 1: The WPB of MASTER_HALT_REQ register is locked + * 0: The WPB of MASTER_HALT_REQ register is not locked + */ +LOCAL_INLINE uint32_t SCM_HWA_MASTER_HALT_REQ_GetWPBLockStatus(void) +{ + return (SCM->MASTER_HALT_REQ & (uint32_t)SCM_MASTER_HALT_REQ_WPB_LOCK_MASK); +} + +/** + * @brief Get the CPU type of writing permission to MASTER_HALT_REQ register + * + * @return SCM_WPB_CpuType The CPU which has the write permission + */ +LOCAL_INLINE SCM_WPB_CpuType SCM_HWA_MASTER_HALT_REQ_GetCpuWritePermit(void) +{ + uint32_t u32RegVal = ((SCM->MASTER_HALT_REQ & (uint32_t)SCM_MASTER_HALT_REQ_WPB_MASK) >> SCM_MASTER_HALT_REQ_WPB_SHIFT); + return (SCM_WPB_CpuType)u32RegVal; +} + +/** + * @brief Set CPU to control the MASTER_HALT_REQ register + * + * @param eCpuType CPU allowed to control peripheral + */ +LOCAL_INLINE void SCM_HWA_MASTER_HALT_REQ_SetCpuWritePermit(SCM_WPB_CpuType eCpuType) +{ + SCM->MASTER_HALT_REQ = ((SCM->MASTER_HALT_REQ & (~(uint32_t)SCM_MASTER_HALT_REQ_WPB_MASK)) | + SCM_MASTER_HALT_REQ_WPB(eCpuType)); +} + +/** + * @brief Set MASTER_HALT_REQ halt request + * + * @param eHaltReq halt request defined in SCM_HaltReqType + */ +LOCAL_INLINE void SCM_HWA_SetSel_MASTER_HALT_REQ(SCM_HaltReqType eHaltReq) +{ + SCM->MASTER_HALT_REQ |= (uint32_t)1U << ((uint32_t)eHaltReq * 8U); +} + +/** + * @brief Get MASTER_HALT_ACK halt ACK status + * + * @return SCM_HaltReqAckType Ack status + */ +LOCAL_INLINE SCM_HaltReqAckType SCM_HWA_GetStatus_MASTER_HALT_ACK(SCM_HaltReqType eHaltReq) +{ + uint32_t u32RegVal = (SCM->MASTER_HALT_ACK >> ((uint32_t)eHaltReq * 8U)) & 0x7U; + return (SCM_HaltReqAckType)u32RegVal; +} + +/** + * @brief Set CPU0 NMI interrupt router enable/disable + * + * @param bEnable Enable/Disable + */ +LOCAL_INLINE void SCM_HWA_SetEnable_Cpu0NMIIrqRouter(bool bEnable) +{ + SCM->INT_ROUTER_NMI = (SCM->INT_ROUTER_NMI & (~(SCM_INT_ROUTER_NMI_C0_EN_MASK))) | + SCM_INT_ROUTER_NMI_C0_EN(bEnable); +} + +/** + * @brief Lock SCM_INT_ROUTER_NMI register + * + */ +LOCAL_INLINE void SCM_HWA_LockINT_ROUTER_NMI(void) +{ + SCM->INT_ROUTER_NMI |= (uint32_t)SCM_INT_ROUTER_NMI_LOCK_MASK; +} + +/** + * @brief Get SCM_INT_ROUTER_NMI register lock status + * + * @return Lock status + */ +LOCAL_INLINE uint32_t SCM_HWA_INT_ROUTER_NMI_GetLockStatus(void) +{ + return (SCM->INT_ROUTER_NMI & (uint32_t)SCM_INT_ROUTER_NMI_LOCK_MASK) >> SCM_INT_ROUTER_NMI_LOCK_SHIFT; +} + +/** + * @brief Get CRC done Flag + * + * @return CRC done Flag + */ +LOCAL_INLINE uint32_t SCM_HWA_GetStatus_CrcDoneFlag(void) +{ + return((SCM->CRCCSR & (uint32_t)SCM_CRCCSR_DONE_MASK)>>(uint32_t)SCM_CRCCSR_DONE_SHIFT); +} + +/** + * @brief Get CRC Error Flag + * + * @return CRC Error Flag + */ +LOCAL_INLINE uint32_t SCM_HWA_GetStatus_CrcErrFlag(void) +{ + return((SCM->CRCCSR & (uint32_t)SCM_CRCCSR_ERR_MASK)>>(uint32_t)SCM_CRCCSR_ERR_SHIFT); +} + +/** + * @brief Clear CRC error flag + */ +LOCAL_INLINE void SCM_HWA_ClearCrcErrorFlag(void) +{ + SCM->CRCCSR |= (uint32_t)SCM_CRCCSR_ERR_MASK; +} + +/** + * @brief Get CRC Busy Flag + * + * @return CRC Busy Flag + */ +LOCAL_INLINE uint32_t SCM_HWA_GetStatus_CrcBusyFlag(void) +{ + return((SCM->CRCCSR & (uint32_t)SCM_CRCCSR_BUY_MASK)>>(uint32_t)SCM_CRCCSR_BUY_SHIFT); +} + +/** + * @brief Set CRC error out enable/disable + * + * @param bEnable Enable/Disable + */ +LOCAL_INLINE void SCM_HWA_SetEnable_CrcErrOut(bool bEnable) +{ + SCM->CRCCSR = (SCM->CRCCSR & (~(SCM_CRCCSR_EOEN_MASK))) | SCM_CRCCSR_EOEN(bEnable); +} + +/** + * @brief Set CRC check enable/disable + * + * @param bEnable Enable/Disable + */ +LOCAL_INLINE void SCM_HWA_SetEnable_CrcCheck(bool bEnable) +{ + SCM->CRCCSR = (SCM->CRCCSR & (~(SCM_CRCCSR_CHKEN_MASK))) | SCM_CRCCSR_CHKEN(bEnable); +} + +/** + * @brief Set CRC trigger enable/disable + * + * @param bEnable Enable/Disable + */ +LOCAL_INLINE void SCM_HWA_SetEnable_CrcTrigger(bool bEnable) +{ + SCM->CRCCSR = (SCM->CRCCSR & (~(SCM_CRCCSR_TRGEN_MASK))) | SCM_CRCCSR_TRGEN(bEnable); +} + +/** + * @brief Set CRC software generate enable/disable + * + * @param bEnable Enable/Disable + */ +LOCAL_INLINE void SCM_HWA_SetEnable_CrcSwGen(bool bEnable) +{ + SCM->CRCCSR = (SCM->CRCCSR & (~(SCM_CRCCSR_GEN_MASK))) | SCM_CRCCSR_GEN(bEnable); +} + +/** + * @brief Get CRC result + * + * @return CRC result + */ +LOCAL_INLINE uint32_t SCM_HWA_GetCrcResult(void) +{ + return SCM->CRCRES; +} + + + + +#endif /*#ifndef _HWA_SCM_H_ */ diff --git a/MODULES/HwA_Flagchip_FC7240/Inc/HwA_sec.h b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_sec.h new file mode 100644 index 0000000..2e4752a --- /dev/null +++ b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_sec.h @@ -0,0 +1,859 @@ +/** + * @file HwA_sec.h + * @author Flagchip + * @brief FC7xxx sec hardware access layer + * @version 0.2.0 + * @date 2023-2-7 + * + * @copyright Copyright (c) 2023 Flagchip Semiconductors Co., Ltd. + * + * @details + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.2.0 2023-2-7 Flagchip076 N/A First version for FC7300 + ******************************************************************************** */ + +#ifndef HWA_INCLUDE_HWA_SEC_H_ +#define HWA_INCLUDE_HWA_SEC_H_ +#include "device_header.h" + +/** + * @addtogroup HwA_SEC + * @{ + * + */ + +/* DEN Bit Fields */ +/** + *@brief Enable the debug module + * */ +LOCAL_INLINE void SEC_HWA_EnDebug(void) +{ + SEC->DEN = SEC_DEN_DEN(0X5) ; +} + +/* FSEC0 Bit Fields */ +/** + * @brief Get the system security KEY0 + * */ +LOCAL_INLINE uint16_t SEC_HWA_GetSScontrol0(void) +{ + return (uint16_t)((SEC->FSEC0) & (SEC_FSEC0_SSC0_MASK)); +} + +/* FSEC1 Bit Fields */ +/** + * @brief Get the system security KEY1 + * */ +LOCAL_INLINE uint16_t SEC_HWA_GetSScontrol1(void) +{ + return (uint16_t)((SEC->FSEC1) & (SEC_FSEC1_SSC1_MASK)); +} + +/* DCWOR Bit Fields */ +/** + * @brief Re-enable the Debug mode. + * @note This register can only be write once. startup_fc4150.s has lock the register. + * */ +LOCAL_INLINE void SEC_HWA_ReEnDebug(void) +{ + SEC->DCWOR = ((SEC->DCWOR & (~SEC_DCWOR_DEA_MASK)) | SEC_DCWOR_DEA(0X5)); +} + +/** + * @brief Get the Re-enable Debug permission. + * */ +LOCAL_INLINE bool SEC_HWA_GetReEnDebug(void) +{ + bool ret = false; + uint8_t dea = (uint8_t)((SEC->DCWOR & (SEC_DCWOR_DEA_MASK)) >> SEC_DCWOR_DEA_SHIFT); + if (dea == 0x5U) + { + ret = true; + } + return ret; +} + +/** + * @brief Enable the write operation for SEC register. + * @note This register can only be write once. startup_fc4150.s has lock the register. + * */ +LOCAL_INLINE void SEC_HWA_WriteUnlock(void) +{ + SEC->DCWOR = ((SEC->DCWOR & (~SEC_DCWOR_RWL_MASK)) | SEC_DCWOR_RWL(0X5)); +} + +/** + * @brief Get the sec write permission + * @return true means allow write. false means forbid write. +*/ +LOCAL_INLINE bool SEC_HWA_GetWritePer(void) +{ + bool ret = false; + uint8_t rwl = (uint8_t)((SEC->DCWOR & (SEC_DCWOR_RWL_MASK)) >> SEC_DCWOR_RWL_SHIFT); + if ((rwl == 0x5U) || (rwl == 0xFU)) + { + ret = true; + } + return ret; +} + +/* DEK Bit Fields */ +/** + * @brief Enable the write operation for SEC register. + * */ +LOCAL_INLINE void SEC_HWA_ChangeDBK(uint8_t count, uint32_t key) +{ + + SEC->DEK[count] = SEC_DEK_DEK(key) ; + +} + +/* TME Bit Fields */ +/** + *@brief Enable the Test module + * */ +LOCAL_INLINE void SEC_HWA_EnTest(void) +{ + SEC->TME = SEC_TME_TME(0X5) ; +} + +/* TMEA Bit Fields */ +/** + * @brief Re-Enable Test mode + * */ +LOCAL_INLINE void SEC_HWA_ReEnTest(void) +{ + SEC->TMEA = SEC_TMEA_TMEA(0X5) ; +} + +/** + * @brief Get the Re-enable Test permission. + * */ +LOCAL_INLINE bool SEC_HWA_GetReEnTest(void) +{ + bool ret = false; + uint8_t tmea = (uint8_t)((SEC->TMEA & (SEC_TMEA_TMEA_MASK)) >> SEC_TMEA_TMEA_SHIFT); + if ((tmea == 0x5U) || (tmea == 0xFU)) + { + ret = true; + } + return ret; +} + +/* TMEK Bit Fields */ +/** + *@brief write Test re-enable mode key + * + */ +LOCAL_INLINE void SEC_HWA_ReEnTestKey(uint32_t testkey) +{ + SEC->TMEK = SEC_TMEK_TMEK(testkey) ; +} + +/* FCR0 Bit Fields */ +/** + * @brief Enable the Mass Erase + */ +LOCAL_INLINE void SEC_HWA_EnME(void) +{ + SEC->FCR0 = ((SEC->FCR0 & (~SEC_FCR0_MED_MASK)) | SEC_FCR0_MED(0x5)); +} + +/** + * @brief Enable the Block 0 NVR write . + */ +LOCAL_INLINE void SEC_HWA_EnWriteB0NVR(void) +{ + SEC->FCR0 = ((SEC->FCR0 & (~SEC_FCR0_NWP_MASK)) | SEC_FCR0_NWP(0x5)) ; +} + +/** + * @brief Disable the Block 0 NVR write . + */ +LOCAL_INLINE void SEC_HWA_DisWriteB0NVR(void) +{ + SEC->FCR0 = ((SEC->FCR0 & (~SEC_FCR0_NWP_MASK)) | SEC_FCR0_NWP(0xA)) ; +} + +/** + * @brief Enable the Block 0 NVR erase . + */ +LOCAL_INLINE void SEC_HWA_EnEraseB0NVR(void) +{ + SEC->FCR0 = ((SEC->FCR0 & (~SEC_FCR0_NEP_MASK)) | SEC_FCR0_NEP(0x5)) ; +} + +/** + * @brief Disable the Block 0 NVR erase . + */ +LOCAL_INLINE void SEC_HWA_DisEraseB0NVR(void) +{ + SEC->FCR0 = ((SEC->FCR0 & (~SEC_FCR0_NEP_MASK)) | SEC_FCR0_NEP(0xA)) ; +} + +/* NKRP Bit Fields */ +/** + * @brief NVR Key Read Protection. + * @brief Enable the Block 0 NVR read. + */ +LOCAL_INLINE void SEC_HWA_EnReadB0NVR(void) +{ + SEC->FCR0 = ((SEC->NKRP & (~SEC_NKRP_NKRP_MASK)) | SEC_NKRP_NKRP(0x5)) ; +} + +/** + * @brief Disable the Block 0 NVR read . + */ +LOCAL_INLINE void SEC_HWA_DisReadB0NVR(void) +{ + SEC->FCR0 = ((SEC->FCR0 & (~SEC_NKRP_NKRP_MASK)) | SEC_NKRP_NKRP(0xA)) ; +} + + +/* BCS Bit Fields */ +/** + * @brief Get the Fast Boot Select. + * @return 0b - Select PLL0 as the core clock source; the core clock is 300MHz + * 1b - Select FIRC as the core clock source; the core clock is 96MHz. + * */ +LOCAL_INLINE uint8_t SEC_HWA_GetFastBootClock(void) +{ + return (uint8_t)((SEC->BCS & SEC_BCS_FBS_MASK) >> SEC_BCS_FBS_SHIFT); +} + +/** + * @brief NMI Function Enable/Disable + * @return false - NMI pin function is disabled after reset. + * true - NMI pin function is enabled + * */ +LOCAL_INLINE bool SEC_HWA_GetNmiPin(void) +{ + return (bool)((SEC->BCS & SEC_BCS_NMIDIS_MASK) >> SEC_BCS_NMIDIS_SHIFT); +} + +/** + * @brief ISP Function Enable/Disable ISP Mode Status + * @return false - ISP mode is inactive. + * true - ISP mode is active. + * */ +LOCAL_INLINE bool SEC_HWA_GetIspStatus(void) +{ + return (bool)((SEC->BCS & SEC_BCS_ISPMODE_MASK) >> SEC_BCS_ISPMODE_SHIFT); +} + +/** + * @brief Boot Rom Configuration + * @return false - Boot from GPR defined address (except ROM). + * true - Boot from ROM. + * */ +LOCAL_INLINE bool SEC_HWA_GetBootRom(void) +{ + return (bool)((SEC->BCS & SEC_BCS_BOOTROM_MASK) >> SEC_BCS_BOOTROM_SHIFT); +} + +/** + * @brief Get Chip Part Mode + * @return false - Chip is in FlexCore part mode. + * true - Chip is in HSM part mode. + * */ +LOCAL_INLINE bool SEC_HWA_GetPartMode(void) +{ + return (bool)((SEC->BCS & SEC_BCS_PART_MODE_MASK) >> SEC_BCS_PART_MODE_SHIFT); +} + +/** + * @brief Get PF_128BIT_MODE + * @return false - Chip is in FlexCore part mode. + * true - Chip is in HSM part mode. + * */ +LOCAL_INLINE bool SEC_HWA_GetPF128BitMode(void) +{ + return (bool)((SEC->BCS & SEC_BCS_PF_128BIT_MODE_MASK) >> SEC_BCS_PF_128BIT_MODE_SHIFT); +} + +/* UKAC Bit Fields */ + +/** + * @brief User Key Access Enable. Only valid under non-secure boot + * @return true means User key can be read/programmed/erased by host CPU ,false means User key is not available for host cpu + * */ +LOCAL_INLINE bool SEC_HWA_GetUKAS(void) +{ + bool ret = false; + uint8_t uake =(uint8_t)((SEC->UKAC & SEC_UKAC_UKAE_MASK) >> SEC_UKAC_UKAE_SHIFT); + if ((uake == 0x5U) || (uake == 0xFU)) + { + ret = true; + } + return ret; +} + +/* BRC0 Bit Fields */ +/** + * @brief Secure Boot Disable (Value loaded from NVR sector) + * @return true means Secure boot mode , false means Non secure boot mode. + */ +LOCAL_INLINE bool SEC_HWA_GetSB(void) +{ + bool ret = false; + uint8_t sbdis = (uint8_t)((SEC->BRC0 & SEC_BRC0_SECURE_BOOT_DIS_MASK) >> SEC_BRC0_SECURE_BOOT_DIS_SHIFT); + if (sbdis == 0x0u) + { + ret = true; + } + return ret; +} + +/** + * @brief Host Debug Auth Enable. Only valid in secure boot. (Value loaded from NVR sector) + * @return true means Host debug authentication enable. false means Host debug authentication disable. + */ +LOCAL_INLINE bool SEC_HWA_GetDEAUEn(void) +{ + bool ret = false; + uint8_t dean = (uint8_t)((SEC->BRC0 & SEC_BRC0_DEBUG_AUTH_EN_MASK) >> SEC_BRC0_DEBUG_AUTH_EN_SHIFT); + if ((dean == 0x5u) || (dean == 0xFu)) + { + ret = true; + } + return ret; +} + +/** + * @brief ISP Auth Enable. Only valid in secure boot. (Value loaded from NVR sector) + * @return true means ISP authentication enable, false means ISP authentication disable. + */ +LOCAL_INLINE bool SEC_HWA_GetISPAU(void) +{ + bool ret = false; + uint8_t isp = (uint8_t)((SEC->BRC0 & SEC_BRC0_ISP_AUTH_EN_MASK) >> SEC_BRC0_ISP_AUTH_EN_SHIFT); + if ((isp == 0x5u) || (isp == 0xFu)) + { + ret = true; + } + return ret; +} + +/* BRC1 Bit Fields */ +/** + * @brief Get the FCUART Baud Rate for ISP + * @return FCUART Baud Rate for ISP + * */ +LOCAL_INLINE uint8_t SEC_HWA_GetUartBR(void) +{ + return (uint8_t)((SEC->BRC1 & SEC_BRC1_UARTBR_MASK) >> SEC_BRC1_UARTBR_SHIFT); +} + +/** + * @brief Get CAN Baud Rate for ISP + * @return CAN Baud Rate for ISP + * */ +LOCAL_INLINE uint8_t SEC_HWA_GetCanBR(void) +{ + return (uint8_t)((SEC->BRC1 & SEC_BRC1_CANBR_MASK) >> SEC_BRC1_CANBR_SHIFT); +} + +/** + * @brief Get OSC Frequency + * @return OSC Frequency + * */ +LOCAL_INLINE uint8_t SEC_HWA_GetOSCFre(void) +{ + return (uint8_t)((SEC->BRC1 & SEC_BRC1_OSCFREQ_MASK) >> SEC_BRC1_OSCFREQ_SHIFT); +} + +/** + * @brief Get whether OSC Available. + * @return true means OSC is available. false means -OSC is not available + * */ +LOCAL_INLINE bool SEC_HWA_GetOSCAvail(void) +{ + bool ret = false; + uint8_t osc = (uint8_t)((SEC->BRC1 & SEC_BRC1_OSCA_MASK) >> SEC_BRC1_OSCA_SHIFT); + if (osc == 0x0U) + { + ret = true; + } + return ret; +} + +/** + * @brief Get Debug Backdoor Key Input Enable. + * @return + * 0011b - User can input DBK through debug mailbox, ISP is not valid + * 1100b - User can input DBK through ISP, debug mailbox is not valid. + * 1111b - User can input DBK through both debug mailbox and ISP. + * Other Values - User cannot input DBK through both debug mailbox andISP + * */ +LOCAL_INLINE uint32_t SEC_HWA_GetMBBKEN(void) +{ + return (uint32_t)((SEC->BRC1 & SEC_BRC1_DBK_IN_EN_MASK) >> SEC_BRC1_DBK_IN_EN_SHIFT); +} + +/** + * @brief Get Debug Backdoor Key Encryption Algorithm + * @return false-User code verification enable in non-secure boot mode + true- User code verification disable in non-secure boot mode. + * */ +LOCAL_INLINE bool SEC_HWA_GetNonSecVerifEN(void) +{ + bool ret = false; + uint8_t dean = (uint8_t)((SEC->BRC0 & SEC_BRC1_NON_SEC_VERIF_EN_MASK) >> SEC_BRC1_NON_SEC_VERIF_EN_SHIFT); + if (dean == 1u) + { + ret = true; + } + return ret; +} + +/** + * @brief Get User Code Verification Enable under Non-secure Boot Mode + * @return Bootloader Verification Algorithm + * 000b - AES256-CBC + * 111b - SM4-CBC. + * */ +LOCAL_INLINE uint8_t SEC_HWA_GetDBDkeyEncrypAlg(void) +{ + return (uint8_t)((SEC->BRC1 & SEC_BRC1_DBKEA_MASK) >> SEC_BRC1_DBKEA_SHIFT); +} + +/** + * @brief ISP Function Enable/Disable,Only valid in non-secure mode + * @return false - ISP pin function is disabled after reset. + * true - ISP pin function is enabled. + * */ +LOCAL_INLINE bool SEC_HWA_GetIspEn(void) +{ + return (bool)((SEC->BRC1 & SEC_BRC1_ISP_PIN_EN_MASK) >> SEC_BRC1_ISP_PIN_EN_SHIFT); +} + +/** + * @brief GET ISP Mode whether Allowed in Recovery Mode + * @return false - ISP mode is not allowed in recovery mode + * true - ISP mode is allowed in recovery mode. + * */ +LOCAL_INLINE bool SEC_HWA_GetIspIsAllowedInRec(void) +{ + return (bool)((SEC->BRC1 & SEC_BRC1_ISPAIRM_MASK) >> SEC_BRC1_ISPAIRM_SHIFT); +} + +/** + * @brief GET Enable the Output of Plaintext Decrypted ROOT Key + * @return false - The output of plaintext decrypted ROOT key is enabled + * true - The output of plaintext decrypted ROOT key is disabled. + * */ +LOCAL_INLINE bool SEC_HWA_GetKeyPlaRoot(void) +{ + return (bool)((SEC->BRC1 & SEC_BRC1_KEY_PROT_MASK) >> SEC_BRC1_KEY_PROT_SHIFT); +} + +/** + * @brief Get ROM Loop Control Flag + * @return false - ROM executes normal run under VIRGIN and FT state. + * true - ROM enters debug loop under VIRGIN and FT state. + * */ +LOCAL_INLINE bool SEC_HWA_GetLoopCtrFlag(void) +{ + return (bool)((SEC->BRC1 & SEC_BRC1_ROM_LOOP_CTRL_MASK) >> SEC_BRC1_ROM_LOOP_CTRL_SHIFT); +} + +/** + * @brief Get Enable Software Configuration to Enter ISP + * @return false - Software configuration to enter ISP is enabled. + * true - Software configuration to enter ISP is disabled. + * */ +LOCAL_INLINE bool SEC_HWA_GetIspSoftConfig(void) +{ + return (bool)((SEC->BRC1 & SEC_BRC1_SW_CFG_ISP_EN_MASK) >> SEC_BRC1_SW_CFG_ISP_EN_SHIFT); +} + + +/* SW_CFG_ISP_FLG Bit Fields */ +/** + * @brief Software Configuration to Enter ISP Flag + * @return ISP Flag. + * */ +LOCAL_INLINE uint8_t SEC_HWA_GetSwCfgIspFlg(void) +{ + return (uint8_t)((SEC->SW_CFG_ISP_FLG & SEC_SW_CFG_ISP_FLG_SW_CFG_ISP_FLG_MASK) >> SEC_SW_CFG_ISP_FLG_SW_CFG_ISP_FLG_SHIFT); +} + + +/* BRC2 Bit Fields */ +/** + * @brief Get USERCODE_VERIFY_MASK_MASK + * @return USERCODE_VERIFY_MASK_MASK. + * */ +LOCAL_INLINE uint32_t SEC_HWA_GetBLMask(void) +{ + return (uint32_t)((SEC->BRC2 & SEC_BRC2_USERCODE_VERIFY_MASK_MASK) >> SEC_BRC2_USERCODE_VERIFY_MASK_SHIFT); +} + +/** + * @brief Get the ISP Instance Select. + * @return ISP Instance Select + * */ +LOCAL_INLINE uint8_t SEC_HWA_GetIspIns(void) +{ + return (uint8_t)((SEC->BRC2 & SEC_BRC2_ISP_INST_SEL_MASK) >> SEC_BRC2_ISP_INST_SEL_SHIFT); +} + +/** + * @brief Get Bootloader Verification Algorithm + * @return Bootloader Verification Algorithm + * */ +LOCAL_INLINE uint8_t SEC_HWA_GetBLVer(void) +{ + return (uint8_t)((SEC->BRC2 & SEC_BRC2_USERCODE_VERIFICATION_ALG_MASK) >> SEC_BRC2_USERCODE_VERIFICATION_ALG_SHIFT); +} + +/** + * @brief Get Debug/ISP/PREFA Authentication and USRK decryption algorithm + * @return 1b - SM2, 0b - ECC256 + * */ +LOCAL_INLINE uint8_t SEC_HWA_GetDecrypt(void) +{ + return (uint8_t)((SEC->BRC2 & SEC_BRC2_DECRP_ALG_MASK) >> SEC_BRC2_DECRP_ALG_SHIFT); +} + +/* IMAGEA Bit Fields */ +/** + * @brief Get the bootloader address. + * @return Bootloader Address. + * */ +LOCAL_INLINE uint32_t SEC_HWA_GetBLAddr(void) +{ + return (uint32_t)((SEC->IMGEA & SEC_IMGEA_IMAGE_ADDR_MASK) >> SEC_IMGEA_IMAGE_ADDR_SHIFT); +} + + +/* NVR VER Bit Fields */ +/** + * @brief Get C version. + * @return C version. + * */ +LOCAL_INLINE uint32_t SEC_HWA_GetCVer(void) +{ + return (uint32_t)((SEC->NVR_VER & SEC_NVR_VER_C_VER_MASK) >> SEC_NVR_VER_C_VER_SHIFT); +} + +/** + * @brief Set C version. + * @return C version. + * */ +LOCAL_INLINE void SEC_HWA_SetCVer(uint32_t C_Ver) +{ + SEC->NVR_VER=((SEC->NVR_VER & (~SEC_NVR_VER_C_VER_MASK)) | SEC_NVR_VER_C_VER(C_Ver)); +} + +/** + * @brief Get R version. + * @return R version. + * */ +LOCAL_INLINE uint32_t SEC_HWA_GetRVer(void) +{ + return (uint32_t)((SEC->NVR_VER & SEC_NVR_VER_R_VER_MASK) >> SEC_NVR_VER_R_VER_SHIFT); +} + +/** + * @brief Set R version. + * */ +LOCAL_INLINE void SEC_HWA_SetRVer(uint32_t R_Ver) +{ + SEC->NVR_VER=((SEC->NVR_VER & (~SEC_NVR_VER_R_VER_MASK)) | SEC_NVR_VER_R_VER(R_Ver)); +} + +/** + * @brief Get V version. + * @return V version. + * */ +LOCAL_INLINE uint32_t SEC_HWA_GetVVer(void) +{ + return (uint32_t)((SEC->NVR_VER & SEC_NVR_VER_V_VER_MASK) >> SEC_NVR_VER_V_VER_SHIFT); +} + +/** + * @brief Set V version. + * */ +LOCAL_INLINE void SEC_HWA_SetVVer(uint32_t V_Ver) +{ + SEC->NVR_VER=((SEC->NVR_VER & (~SEC_NVR_VER_V_VER_MASK)) | SEC_NVR_VER_V_VER(V_Ver)); +} + +/** + * @brief Get CHIP version. + * @return CHIP version. + * */ +LOCAL_INLINE uint32_t SEC_HWA_GetChipVer(void) +{ + return (uint32_t)((SEC->NVR_VER & SEC_NVR_VER_CHIP_VER_MASK) >> SEC_NVR_VER_CHIP_VER_SHIFT); +} + +/** + * @brief Set CHIP version. + * */ +LOCAL_INLINE void SEC_HWA_SetChipVer(uint32_t CHIP_Ver) +{ + SEC->NVR_VER=((SEC->NVR_VER & (~SEC_NVR_VER_CHIP_VER_MASK)) | SEC_NVR_VER_V_VER(CHIP_Ver)); +} + +/* LCSTAT Bit Fields */ +/** + * @brief Get the life cycle status of the chip. + * @return The lifecycle status + * */ +LOCAL_INLINE uint8_t SEC_HWA_GetLCStaus(void) +{ + return (uint8_t)(SEC->LCSTAT & 0XFFU); +} + +/** + * @brief Get Lifecycle OEM Development + * @return 0b - Chip is not in this lifecycle + * 1b - Chip is in this lifecycle + * */ +LOCAL_INLINE bool SEC_HWA_GetLCOemDev(void) +{ + return (bool)((SEC->LCSTAT & SEC_LCSTAT_LIFECYCLE_OEM_DEV_MASK) >> SEC_LCSTAT_LIFECYCLE_OEM_DEV_SHIFT); +} + +/** + * @brief Get Lifecycle OEM Production + * @return false - Chip is not in this lifecycle + * true - Chip is in this lifecycle + * */ +LOCAL_INLINE bool SEC_HWA_GetLCOemPdt(void) +{ + return (bool)((SEC->LCSTAT & SEC_LCSTAT_LIFECYCLE_OEM_PDT_MASK) >> SEC_LCSTAT_LIFECYCLE_OEM_PDT_SHIFT); +} + +/** + * @brief Get Lifecycle In Field + * @return false - Chip is not in this lifecycle + * true - Chip is in this lifecycle + * */ +LOCAL_INLINE bool SEC_HWA_GetLCInField(void) +{ + return (bool)((SEC->LCSTAT & SEC_LCSTAT_LIFECYCLE_IN_FIELD_MASK) >> SEC_LCSTAT_LIFECYCLE_IN_FIELD_SHIFT); +} + +/** + * @brief Get Lifecycle Software Fault Analysis + * @return false - Chip is not in this lifecycle + * true - Chip is in this lifecycle + * */ +LOCAL_INLINE bool SEC_HWA_GetLCSwFa(void) +{ + return (bool)((SEC->LCSTAT & SEC_LCSTAT_LIFECYCLE_SWFA_MASK) >> SEC_LCSTAT_LIFECYCLE_SWFA_SHIFT); +} + +/** + * @brief Get Lifecycle Hardware Fault Analysis + * @return false - Chip is not in this lifecycle + * true - Chip is in this lifecycle + * */ +LOCAL_INLINE bool SEC_HWA_GetLCHwFa(void) +{ + return (bool)((SEC->LCSTAT & SEC_LCSTAT_LIFECYCLE_HWFA_MASK) >> SEC_LCSTAT_LIFECYCLE_HWFA_SHIFT); +} + +/* FAC Bit Fields */ +/** + * @brief Get the Host User Key Read Protection + * @return true - Host read access to User Key region is enabled + * false - Host read access to User Key region is disabled + * */ +LOCAL_INLINE bool SEC_HWA_GetHUKRead(void) +{ + return (bool)(~(((SEC->FAC) & SEC_FAC_HOST_UKEY_RPROT_MASK) >> SEC_FAC_HOST_UKEY_RPROT_SHIFT)); +} + +/** + * @brief Get the Host User Key write Protection + * @return true - Host write access to User Key region is enabled + * false - Host write access to User Key region is disabled + * */ +LOCAL_INLINE bool SEC_HWA_GetHUKWrite(void) +{ + return (bool)(~(((SEC->FAC) & SEC_FAC_HOST_UKEY_WPROT_MASK) >> SEC_FAC_HOST_UKEY_WPROT_SHIFT)); +} + +/** + * @brief Get the Host User Key erase Protection + * @return true - Host erase access to User Key region is enabled + * false - Host erase access to User Key region is disabled + * */ +LOCAL_INLINE bool SEC_HWA_GetHUKErase(void) +{ + return (bool)(~(((SEC->FAC) & SEC_FAC_HOST_UKEY_EPROT_MASK) >> SEC_FAC_HOST_UKEY_EPROT_SHIFT)); +} + +/** + * @brief Get the Host NVR Read Protection + * @return true - Host read access to NVR region is enabled + * false - Host read access to NVR region is disabled + * */ +LOCAL_INLINE bool SEC_HWA_GetHostNvrRead(void) +{ + return (bool)(~(((SEC->FAC) & SEC_FAC_HOST_NVR_RPROT_MASK) >> SEC_FAC_HOST_NVR_RPROT_SHIFT)); +} + +/** + * @brief Get the Host NVR write Protection + * @return true - Host write access to NVR region is enabled + * false - Host write access to NVR region is disabled + * */ +LOCAL_INLINE bool SEC_HWA_GetHostNvrWrite(void) +{ + return (bool)(~(((SEC->FAC) & SEC_FAC_HOST_NVR_WPROT_MASK) >> SEC_FAC_HOST_NVR_WPROT_SHIFT)); +} + +/** + * @brief Get the Host NVR erase Protection + * @return true - Host erase access to NVR region is enabled + * false - Host erase access to NVR region is disabled- + * */ +LOCAL_INLINE bool SEC_HWA_GetHostNvrErase(void) +{ + return (bool)(~(((SEC->FAC) & SEC_FAC_HOST_NVR_EPROT_MASK) >> SEC_FAC_HOST_NVR_EPROT_SHIFT)); +} + +/** + * @brief Get HSM User Key Read Protection + * @return true - HSM Read access to User Key region is disabled + * false - HSM Read access to User Key region is enabled + * */ +LOCAL_INLINE bool SEC_HWA_GetHsmUKRead(void) +{ + return (bool)(~(((SEC->FAC) & SEC_FAC_HSM_UKEY_RPROT_MASK) >> SEC_FAC_HSM_UKEY_RPROT_SHIFT)); +} + +/** + * @brief Get HSM User Key Program Protection + * @return true - HSM Program access to User Key region is disabled + * false - HSM Program access to User Key region is enabled + * */ +LOCAL_INLINE bool SEC_HWA_GetHsmUKProg(void) +{ + return (bool)(~(((SEC->FAC) & SEC_FAC_HSM_UKEY_WPROT_MASK) >> SEC_FAC_HSM_UKEY_WPROT_SHIFT)); +} + +/** + * @brief Get the HSM User Key Erase Protection + * @return true - HSM erase access to User Key region is enabled + * false -HSM erase access to User Key region is disabled + * */ +LOCAL_INLINE bool SEC_HWA_GetHsmUKErase(void) +{ + return (bool)(~(((SEC->FAC) & SEC_FAC_HSM_UKEY_EPROT_MASK) >> SEC_FAC_HSM_UKEY_EPROT_SHIFT)); +} + +/** + * @brief Get HSM NVR Key Read Protection + * @return true - HSM Read access to NVR key region is disabled + * false - HSM Read access to NVR key region is enabled + * */ +LOCAL_INLINE bool SEC_HWA_GetHsmNvrKRead(void) +{ + return (bool)(~(((SEC->FAC) & SEC_FAC_HSM_NVR_RPROT_MASK) >> SEC_FAC_HSM_NVR_RPROT_SHIFT)); +} + +/** + * @brief Get HSM NVR Program Protection + * @return true - HSM Program access to NVR region is disabled + * false - HSM Program access to NVR region is enabled + * */ +LOCAL_INLINE bool SEC_HWA_GetHsmNvrProg(void) +{ + return (bool)(~(((SEC->FAC) & SEC_FAC_HSM_NVR_WPROT_MASK) >> SEC_FAC_HSM_NVR_WPROT_SHIFT)); +} + +/** + * @brief Get the HSM NVR Erase Protection + * @return true - HSM erase access to NVR region is enabled + * false -HSM erase access to NVR region is disabled + * */ +LOCAL_INLINE bool SEC_HWA_GetHsmNvrErase(void) +{ + return (bool)(~(((SEC->FAC) & SEC_FAC_HSM_NVR_EPROT_MASK) >> SEC_FAC_HSM_NVR_EPROT_SHIFT)); +} + +/* FLEXCORE_EN Bit Fields */ +/** + * @brief Get the FlexCore Enable. + * @return true means enable ,false means disable. + * */ +LOCAL_INLINE bool SEC_HWA_GetFlexCoreEn(void)//? +{ + bool ret = false; + uint8_t srk = (uint8_t)((SEC->FLEXCORE_EN & SEC_FLEXCORE_EN_FLEXCORE_EN_MASK) >> SEC_FLEXCORE_EN_FLEXCORE_EN_SHIFT); + if (srk == 0xFU||srk == 0x5U) + { + ret = true; + } + return ret; +} +/** + * @brief Set the FlexCore Enable. + * @return true means set sucess ,false means set fail,0x5 and 0xf is enable,others is disable. + * */ +LOCAL_INLINE bool SEC_HWA_SetFlexCoreEn(uint8_t CoreEn) +{ + if(CoreEn>0xF) + return false; + SEC->FLEXCORE_EN = ((SEC->FLEXCORE_EN & (~SEC_FLEXCORE_EN_FLEXCORE_EN_MASK)) | SEC_FLEXCORE_EN_FLEXCORE_EN(CoreEn)); + return true; +} + +/** + * @brief Get SEC_FLEXCORE_EN FLEXCORE_DBG. + * @return true means enable ,false means disable. + * */ +LOCAL_INLINE bool SEC_HWA_GetFlexCoreDbgEn(void) +{ + return (bool)((SEC->FLEXCORE_EN & SEC_FLEXCORE_EN_FLEXCORE_DBG_EN_MASK) >> SEC_FLEXCORE_EN_FLEXCORE_DBG_EN_SHIFT); +} + +/** + * @brief Set SEC_FLEXCORE_EN FLEXCORE_DBG. + * */ +LOCAL_INLINE void SEC_HWA_SetFlexCoreDbgEn(uint8_t DbgEn) +{ + SEC->FLEXCORE_EN=((SEC->FLEXCORE_EN & (~SEC_FLEXCORE_EN_FLEXCORE_DBG_EN_MASK)) | SEC_FLEXCORE_EN_FLEXCORE_DBG_EN(DbgEn)); +} + +/* FLEX_CODE_ADDR Bit Fields */ +/** + * @brief Get Code Header Address for FlexCore Always 4-byte aligned + * @return FLEX Code Header Address. + * */ +LOCAL_INLINE uint32_t SEC_HWA_GetFlexCodeHeadAddr(void) +{ + return (uint32_t)((SEC->FLEX_CODE_ADDR & SEC_FLEX_CODE_ADDR_FLEX_CODE_ADDR_MASK) >> SEC_FLEX_CODE_ADDR_FLEX_CODE_ADDR_SHIFT); +} + +/* PFLASH_PRLLL_EN Bit Fields */ +/** + * @brief Get PFLASH Parallel Enable + * @return + * 0101b - Disable + * Others - Enable + * */ +LOCAL_INLINE bool SEC_HWA_GetPflashPrlllEn(void) +{ + bool ret = false; + uint32_t srk=(uint32_t)((SEC->PFLASH_PRLLL_EN & SEC_PFLASH_PRLLL_EN_PFLASH_PRLLL_EN_MASK) >> SEC_PFLASH_PRLLL_EN_PFLASH_PRLLL_EN_SHIFT); + if (srk !=0x5U) + { + ret =true ; + } + return ret; +} + +/** @}*/ /* HwA_SEC */ +#endif /* HWA_INCLUDE_HWA_SEC_H_ */ diff --git a/MODULES/HwA_Flagchip_FC7240/Inc/HwA_sent.h b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_sent.h new file mode 100644 index 0000000..9b2efa4 --- /dev/null +++ b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_sent.h @@ -0,0 +1,1454 @@ +/** + * @file HwA_sent.h + * @author Flagchip073 + * @brief Hardware access layer for SENT + * @version 0.0.1 + * @date 2022-12-14 + * + * @copyright Copyright (c) 2022 Flagchip Semiconductors Co., Ltd. + * + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.0.1 2022-12-14 Flagchip073 N/A First version for FC7300 SENT + ******************************************************************************** */ + +#ifndef _HWA_SENT_H_ +#define _HWA_SENT_H_ + +#include "device_header.h" + +#define DMA_CH_TO_DCHPRI(x) ((x) ^ 3U) + +/** + * @defgroup HwA_sent + * @ingroup fc7xxx_driver_sent + * @{ + */ + +/** + * @brief sent running status + * + */ +typedef enum +{ + SENT_NIBBLE_DATA_MODE_A = 0x0U, /*!< Frame format A */ + SENT_NIBBLE_DATA_MODE_H1 = 0x1U, /*!< Frame format H1 */ + SENT_NIBBLE_DATA_MODE_H2 = 0x2U, /*!< Frame format H2 */ + SENT_NIBBLE_DATA_MODE_H3 = 0x3U, /*!< Frame format H3 */ + SENT_NIBBLE_DATA_MODE_H4 = 0x4U, /*!< Frame format H4 */ + SENT_NIBBLE_DATA_MODE_H5 = 0x5U, /*!< Frame format H5 */ + SENT_NIBBLE_DATA_MODE_H6 = 0x6U, /*!< Frame format H6 */ + SENT_NIBBLE_DATA_MODE_H7 = 0x7U /*!< Frame format H7 */ +} SENT_NibbleDataModeType; + +/** + * @brief sent slow message type + * + */ +typedef enum +{ + SENT_SLOW_MESSAGE_SHORT = 0x0U, /*!< short serial data message */ + SENT_SLOW_MESSAGE_ENHANCE_12DATA_8ID = 0x1U, /*!< enhanced serial data message with 12-bit data and 8-bit ID */ + SENT_SLOW_MESSAGE_ENHANCE_16DATA_4ID = 0x2U, /*!< enhanced serial data message with 16-bit data and 4-bit ID */ +} SENT_SlowMessageType; + +/** + * @brief sent SPC trigger type + * + */ +typedef enum +{ + SENT_SPC_SW_TRIGGER = 0x0U, /*!< SPC pulse triggered by software method */ + SENT_SPC_HW_TRIGGER = 0x1U, /*!< SPC pulse triggered by external trigger */ +} SENT_SPCTriggerType; + +/** + * @brief sent SPC tick base + * + */ +typedef enum +{ + SENT_SPC_TICK_PRE_RECEIVED_MESSAGE = 0x0U, /*!< Previous received message tick base */ + SENT_SPC_TICK_CONFIG = 0x1U, /*!< SENT configured tick base */ +} SENT_SPCTickType; + +/** + * @brief Set SENT Global pre-scaler value + * + * @param pSent the base address of the SENT instance + * @param u8PreScaler the value of the PreSclaer. + */ +LOCAL_INLINE void SENT_HWA_SetGlobalPreScaler(SENT_Type *const pSent, uint8_t u8PreScaler) +{ + pSent->GLBL_CTL = (pSent->GLBL_CTL & ~SENT_GLBL_CTL_PRE_SCALER_MASK) | SENT_GLBL_CTL_PRE_SCALER(u8PreScaler); +} + +/** + * @brief Set SENT Global DMA watermark value + * + * @param pSent the base address of the SENT instance + * @param u8WaterMark the value of the dma watermark. + */ +LOCAL_INLINE void SENT_HWA_SetDMAWaterMark(SENT_Type *const pSent, uint8_t u8WaterMark) +{ + pSent->GLBL_CTL = (pSent->GLBL_CTL & ~SENT_GLBL_CTL_DMA_WATERMARK_MASK) | SENT_GLBL_CTL_DMA_WATERMARK(u8WaterMark); +} + +/** + * @brief Enable SENT Fast message FIFO overflow interrupt + * + * @param pSent the base address of the SENT instance + */ +LOCAL_INLINE void SENT_HWA_EnableFastMessageFIFOOverflowInterrupt(SENT_Type *const pSent) +{ + pSent->GLBL_CTL |= SENT_GLBL_CTL_F_FIFO_OVFL_IE_MASK; +} + +/** + * @brief Disable SENT Fast message FIFO overflow interrupt + * + * @param pSent the base address of the SENT instance + */ +LOCAL_INLINE void SENT_HWA_DisableFastMessageFIFOOverflowInterrupt(SENT_Type *const pSent) +{ + pSent->GLBL_CTL &= ~SENT_GLBL_CTL_F_FIFO_OVFL_IE_MASK; +} + +/** + * @brief Enable SENT Fast message read underflow interrupt + * + * @param pSent the base address of the SENT instance + */ +LOCAL_INLINE void SENT_HWA_EnableFastMessagedmaReadUnderflowInterrupt(SENT_Type *const pSent) +{ + pSent->GLBL_CTL |= SENT_GLBL_CTL_F_DMA_UDFL_IE_MASK; +} + +/** + * @brief Disable SENT Fast message read underflow interrupt + * + * @param pSent the base address of the SENT instance + */ +LOCAL_INLINE void SENT_HWA_DisableFastMessagedmaReadUnderflowInterrupt(SENT_Type *const pSent) +{ + pSent->GLBL_CTL &= ~SENT_GLBL_CTL_F_DMA_UDFL_IE_MASK; +} + +/** + * @brief Enable SENT slow message read underflow interrupt + * + * @param pSent the base address of the SENT instance + */ +LOCAL_INLINE void SENT_HWA_EnableSlowMessagedmaReadUnderflowInterrupt(SENT_Type *const pSent) +{ + pSent->GLBL_CTL |= SENT_GLBL_CTL_S_DMA_UDFL_IE_MASK; +} + +/** + * @brief Disable SENT slow message read underflow interrupt + * + * @param pSent the base address of the SENT instance + */ +LOCAL_INLINE void SENT_HWA_DisableSlowMessagedmaReadUnderflowInterrupt(SENT_Type *const pSent) +{ + pSent->GLBL_CTL &= ~SENT_GLBL_CTL_S_DMA_UDFL_IE_MASK; +} + +/** + * @brief Enable SENT debug mode + * + * @param pSent the base address of the SENT instance + */ +LOCAL_INLINE void SENT_HWA_EnableDebugMode(SENT_Type *const pSent) +{ + pSent->GLBL_CTL |= SENT_GLBL_CTL_DBG_EN_MASK; +} + +/** + * @brief Disable SENT debug mode + * + * @param pSent the base address of the SENT instance + */ +LOCAL_INLINE void SENT_HWA_DisableDebugMode(SENT_Type *const pSent) +{ + pSent->GLBL_CTL &= ~SENT_GLBL_CTL_DBG_EN_MASK; +} + +/** + * @brief Enable Global SENT debug mode + * + * @param pSent the base address of the SENT instance + */ +LOCAL_INLINE void SENT_HWA_EnableGlobal(SENT_Type *const pSent) +{ + pSent->GLBL_CTL |= SENT_GLBL_CTL_SENT_EN_MASK; +} + +/** + * @brief Disable Global SENT debug mode + * + * @param pSent the base address of the SENT instance + */ +LOCAL_INLINE void SENT_HWA_DisableGlobal(SENT_Type *const pSent) +{ + pSent->GLBL_CTL &= ~SENT_GLBL_CTL_SENT_EN_MASK; +} + +/** + * @brief Enable Global SENT debug mode + * + * @param pSent the base address of the SENT instance + */ +LOCAL_INLINE void SENT_HWA_EnableDataOverflowFlagFastClear(SENT_Type *const pSent) +{ + pSent->GLBL_CTL |= SENT_GLBL_CTL_FAST_CLR_MASK; +} + +/** + * @brief Disable Global SENT debug mode + * + * @param pSent the base address of the SENT instance + */ +LOCAL_INLINE void SENT_HWA_DisableDataOverflowFlagFastClear(SENT_Type *const pSent) +{ + pSent->GLBL_CTL &= ~SENT_GLBL_CTL_FAST_CLR_MASK; +} + +/** + * @brief Enable SENT channel receive + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + */ +LOCAL_INLINE void SENT_HWA_EnableChannelReceive(SENT_Type *const pSent, uint8_t u8Channel) +{ + pSent->CHN_EN |= SENT_CHN_EN_CHN_EN((uint32_t)1u << u8Channel); +} + +/** + * @brief Disable SENT channel receive + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + */ +LOCAL_INLINE void SENT_HWA_DisableChannelReceive(SENT_Type *const pSent, uint8_t u8Channel) +{ + pSent->CHN_EN &= ~SENT_CHN_EN_CHN_EN((uint32_t)1u << u8Channel); +} + +/** + * @brief Get SENT channel receive + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + */ +LOCAL_INLINE bool SENT_HWA_GetChannelReceive(const SENT_Type *const pSent, uint8_t u8Channel) +{ + if(SENT_CHN_EN_CHN_EN((uint32_t)1u << u8Channel) == (pSent->CHN_EN & SENT_CHN_EN_CHN_EN((uint32_t)1u << u8Channel))) + { + return true; + } + else + { + return false; + } +} + +/** + * @brief Get Channel slow message dma read underflow flag + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + * @return bool true: the related channel slow message dma is underflow + */ +LOCAL_INLINE bool SENT_HWA_GetSLowMessageUnderflowFlag(const SENT_Type *const pSent, uint8_t u8Channel) +{ + if(((uint32_t)1u << u8Channel) == (pSent->GLBL_STAT & SENT_GLBL_STAT_S_DMA_UDFL((uint32_t)1u << u8Channel))) + { + return true; + } + else + { + return false; + } +} + +/** + * @brief Clear Channel slow message dma read underflow flag + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + */ +LOCAL_INLINE void SENT_HWA_ClearSLowMessageUnderflowFlag(SENT_Type *const pSent, uint8_t u8Channel) +{ + pSent->GLBL_STAT |= SENT_GLBL_STAT_S_DMA_UDFL((uint32_t)1u << u8Channel); +} + +/** + * @brief Get Channel fast message ready flag + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + * @return bool true: the related channel fast message is ready + */ +LOCAL_INLINE bool SENT_HWA_GetFastMessageReadyFlag(const SENT_Type *const pSent, uint8_t u8Channel) +{ + if(SENT_FMSG_STAT_F_MSG_RDY((uint32_t)1u << u8Channel) == (pSent->FMSG_STAT & SENT_FMSG_STAT_F_MSG_RDY((uint32_t)1u << u8Channel))) + { + return true; + } + else + { + return false; + } +} + +/** + * @brief Clear Channel fast message ready flag + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + */ +LOCAL_INLINE void SENT_HWA_ClearFastMessageReadyFlag(SENT_Type *const pSent, uint8_t u8Channel) +{ + pSent->FMSG_STAT |= SENT_FMSG_STAT_F_MSG_RDY((uint32_t)1u << u8Channel); +} + +/** + * @brief Get Channel slow message ready flag + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + * @return bool true: the related channel slow message is ready + */ +LOCAL_INLINE bool SENT_HWA_GetSlowMessageReadyFlag(const SENT_Type *const pSent, uint8_t u8Channel) +{ + if(((uint32_t)1u << u8Channel) == (pSent->SMSG_STAT & ((uint32_t)1u << u8Channel))) + { + return true; + } + else + { + return false; + } +} + +/** + * @brief Clear Channel slow message ready flag + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + */ +LOCAL_INLINE void SENT_HWA_ClearSlowMessageReadyFlag(SENT_Type *const pSent, uint8_t u8Channel) +{ + pSent->SMSG_STAT |= SENT_FMSG_STAT_F_MSG_RDY((uint32_t)1u << u8Channel); +} + +/** + * @brief Enable SENT channel FIFO function + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + */ +LOCAL_INLINE void SENT_HWA_EnableChannelFIFO(SENT_Type *const pSent, uint8_t u8Channel) +{ + pSent->FIFO_EN |= SENT_FIFO_EN_FIFO_EN((uint32_t)1u << u8Channel); +} + +/** + * @brief Disable SENT channel receive function + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + */ +LOCAL_INLINE void SENT_HWA_DisableChannelFIFO(SENT_Type *const pSent, uint8_t u8Channel) +{ + pSent->FIFO_EN &= ~SENT_FIFO_EN_FIFO_EN((uint32_t)1u << u8Channel); +} + +/** + * @brief Set SENT channel data nibble number + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + * @param u8Number the received data number + */ +LOCAL_INLINE void SENT_HWA_SetChannelNibbleNumber(SENT_Type *const pSent, uint8_t u8Channel, uint8_t u8Number) +{ + pSent->DATA_NUM_CTL1 = (pSent->DATA_NUM_CTL1 & ~(SENT_DATA_NUM_CTL1_CH0_DATA_CTL_MASK >> (4u * u8Channel))) | (SENT_DATA_NUM_CTL1_CH0_DATA_CTL(u8Number) >> (4u * u8Channel)); +} + +/** + * @brief Get SENT channel data nibble number + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + * @param uint8_t the config data number + */ +LOCAL_INLINE uint8_t SENT_HWA_GetChannelNibbleNumber(const SENT_Type *const pSent, uint8_t u8Channel) +{ + return (uint8_t)((pSent->DATA_NUM_CTL1 & (SENT_DATA_NUM_CTL1_CH0_DATA_CTL_MASK >> (4u * u8Channel))) >> (SENT_DATA_NUM_CTL1_CH0_DATA_CTL_SHIFT - (4u * u8Channel))); +} + +/** + * @brief Get Channel fast message FIFO overflow flag + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + * @return bool true: the related channel fast message FIFO is overflow + */ +LOCAL_INLINE bool SENT_HWA_GetFastMessageFIFOOverflowFlag(const SENT_Type *const pSent, uint8_t u8Channel) +{ + if(SENT_OVFL_UDFL_STAT_FIFO_F_OVFL_FLAG((uint32_t)1u << u8Channel) == (pSent->OVFL_UDFL_STAT & SENT_OVFL_UDFL_STAT_FIFO_F_OVFL_FLAG((uint32_t)1u << u8Channel))) + { + return true; + } + else + { + return false; + } +} + +/** + * @brief Clear Channel fast message FIFO overflow flag + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + */ +LOCAL_INLINE void SENT_HWA_ClearFastMessageFIFOOverflowFlag(SENT_Type *const pSent, uint8_t u8Channel) +{ + pSent->OVFL_UDFL_STAT |= SENT_OVFL_UDFL_STAT_FIFO_F_OVFL_FLAG((uint32_t)1u << u8Channel); +} + +/** + * @brief Get Channel fast message DMA underflow flag + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + * @return bool true: the related channel fast message DMA read is underflow + */ +LOCAL_INLINE bool SENT_HWA_GetFastMessageDMAUnderflowFlag(const SENT_Type *const pSent, uint8_t u8Channel) +{ + if(SENT_OVFL_UDFL_STAT_DMA_F_UDFL_FLAG((uint32_t)1u << u8Channel) == (pSent->OVFL_UDFL_STAT & SENT_OVFL_UDFL_STAT_DMA_F_UDFL_FLAG((uint32_t)1u << u8Channel))) + { + return true; + } + else + { + return false; + } +} + +/** + * @brief Clear Channel fast message DMA underflow flag + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + */ +LOCAL_INLINE void SENT_HWA_ClearFastMessageDMAUnderflowFlag(SENT_Type *const pSent, uint8_t u8Channel) +{ + pSent->OVFL_UDFL_STAT |= SENT_OVFL_UDFL_STAT_DMA_F_UDFL_FLAG((uint32_t)1u << u8Channel); +} + +/** + * @brief Set SENT channel nibble data mode + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + * @param eMode the nibble data mode + */ +LOCAL_INLINE void SENT_HWA_SetChannelNibbleDataMode(SENT_Type *const pSent, uint8_t u8Channel, SENT_NibbleDataModeType eMode) +{ + pSent->NB_MODE1 = (pSent->NB_MODE1 & ~(SENT_NB_MODE1_CH0_NB_MODE_MASK >> (4u * u8Channel))) | (SENT_NB_MODE1_CH0_NB_MODE(eMode) >> (4u * u8Channel)); +} + +/** + * @brief Enable SENT channel fast message DMA request + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + */ +LOCAL_INLINE void SENT_HWA_EnableChannelFastMessageDmaRequest(SENT_Type *const pSent, uint8_t u8Channel) +{ + pSent->FDMA_CTL |= SENT_FDMA_CTL_FDMA_EN((uint32_t)1u << u8Channel); +} + +/** + * @brief Disable SENT channel fast message DMA request + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + */ +LOCAL_INLINE void SENT_HWA_DisableChannelFastMessageDmaRequest(SENT_Type *const pSent, uint8_t u8Channel) +{ + pSent->FDMA_CTL &= ~SENT_FDMA_CTL_FDMA_EN((uint32_t)1u << u8Channel); +} + +/** + * @brief Enable SENT channel slow message DMA request + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + */ +LOCAL_INLINE void SENT_HWA_EnableChannelSlowMessageDmaRequest(SENT_Type *const pSent, uint8_t u8Channel) +{ + pSent->SDMA_CTL |= SENT_SDMA_CTL_SDMA_EN((uint32_t)1u << u8Channel); +} + +/** + * @brief Disable SENT channel slow message DMA request + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + */ +LOCAL_INLINE void SENT_HWA_DisableChannelSlowMessageDmaRequest(SENT_Type *const pSent, uint8_t u8Channel) +{ + pSent->SDMA_CTL &= ~SENT_SDMA_CTL_SDMA_EN((uint32_t)1u << u8Channel); +} + +/** + * @brief Enable SENT channel Fast message interrupt + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + */ +LOCAL_INLINE void SENT_HWA_EnableChannelFastMessageInterrupt(SENT_Type *const pSent, uint8_t u8Channel) +{ + pSent->FINT_CTL |= SENT_FINT_CTL_FINT_CTL((uint32_t)1u << u8Channel); +} + +/** + * @brief Disable SENT channel Fast message interrupt + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + */ +LOCAL_INLINE void SENT_HWA_DisableChannelFastMessageInterrupt(SENT_Type *const pSent, uint8_t u8Channel) +{ + pSent->FINT_CTL &= ~SENT_FINT_CTL_FINT_CTL((uint32_t)1u << u8Channel); +} + +/** + * @brief Enable SENT channel slow message interrupt + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + */ +LOCAL_INLINE void SENT_HWA_EnableChannelSlowMessageInterrupt(SENT_Type *const pSent, uint8_t u8Channel) +{ + pSent->SINT_CTL |= SENT_SINT_CTL_SINT_CTL((uint32_t)1u << u8Channel); +} + +/** + * @brief Disable SENT channel slow message interrupt + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + */ +LOCAL_INLINE void SENT_HWA_DisableChannelSlowMessageInterrupt(SENT_Type *const pSent, uint8_t u8Channel) +{ + pSent->SINT_CTL &= ~SENT_SINT_CTL_SINT_CTL((uint32_t)1u << u8Channel); +} + +/** + * @brief Enable SENT channel Compensate + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + */ +LOCAL_INLINE void SENT_HWA_EnableChannelCompensate(SENT_Type *const pSent, uint8_t u8Channel) +{ + pSent->SENT_CHN[u8Channel].CHN_CLK_CTL |= SENT_CHN_CLK_CTL_COMP_EN_MASK; +} + +/** + * @brief Disable SENT channel Compensate + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + */ +LOCAL_INLINE void SENT_HWA_DisableChannelCompensate(SENT_Type *const pSent, uint8_t u8Channel) +{ + pSent->SENT_CHN[u8Channel].CHN_CLK_CTL &= ~SENT_CHN_CLK_CTL_COMP_EN_MASK; +} + +/** + * @brief Set SENT channel pre-scaler + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + * @param u16PreScaler the related Channel Prescaler value + */ +LOCAL_INLINE void SENT_HWA_SetChannelPreScaler(SENT_Type *const pSent, uint8_t u8Channel, uint16_t u16PreScaler) +{ + pSent->SENT_CHN[u8Channel].CHN_CLK_CTL = (pSent->SENT_CHN[u8Channel].CHN_CLK_CTL & ~SENT_CHN_CLK_CTL_PRE_SCALER_MASK) | SENT_CHN_CLK_CTL_PRE_SCALER(u16PreScaler); +} + +/** + * @brief Get Channel Prescaler value after compensate + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + * @return uint8_t the related Channel Prescaler value after compensate + */ +LOCAL_INLINE uint16_t SENT_HWA_GetChannelCompensatePreScaler(const SENT_Type *const pSent, uint8_t u8Channel) +{ + return (uint16_t)((pSent->SENT_CHN[u8Channel].CHN_CLK_CTL & SENT_CHN_CLK_CTL_COMPED_PRE_SCALER_MASK) >> SENT_CHN_CLK_CTL_COMPED_PRE_SCALER_SHIFT); +} + +/** + * @brief Get Channel status + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + * @return uint32_t the related Channel status + */ +LOCAL_INLINE uint32_t SENT_HWA_GetChannelStatus(const SENT_Type *const pSent, uint8_t u8Channel) +{ + return pSent->SENT_CHN[u8Channel].CHN_STAT; +} + +/** + * @brief Clear Channel status + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + * @param u32W1CBit the status bits need to be clear. + */ +LOCAL_INLINE void SENT_HWA_ClearChannelStatus(SENT_Type *const pSent, uint8_t u8Channel, uint32_t u32W1CBit) +{ + pSent->SENT_CHN[u8Channel].CHN_STAT |= u32W1CBit; +} + +/** + * @brief Enable SENT channel all error interrupt + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + */ +LOCAL_INLINE void SENT_HWA_EnableChannelAllErrorInterrupt(SENT_Type *const pSent, uint8_t u8Channel) +{ + pSent->SENT_CHN[u8Channel].CHN_CTL |= (SENT_CHN_CTL_CAL_RESYNC_IE_MASK | SENT_CHN_CTL_CAL_20_25_IE_MASK | SENT_CHN_CTL_SMSG_OVFL_IE_MASK | \ + SENT_CHN_CTL_FMSG_OVFL_IE_MASK | SENT_CHN_CTL_PP_DIAG_ERR_IE_MASK | SENT_CHN_CTL_CAL_DIAG_ERR_IE_MASK | \ + SENT_CHN_CTL_CAL_ERR_IE_MASK | SENT_CHN_CTL_NIB_ERR_IE_MASK | SENT_CHN_CTL_S_CRC_ERR_IE_MASK | \ + SENT_CHN_CTL_F_CRC_ERR_IE_MASK | SENT_CHN_CTL_EDGE_ERR_IE_MASK | SENT_CHN_CTL_SPC_OVERRUN_IE_MASK); +} + +/** + * @brief Disable SENT channel all error interrupt + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + */ +LOCAL_INLINE void SENT_HWA_DisableChannelAllErrorInterrupt(SENT_Type *const pSent, uint8_t u8Channel) +{ + pSent->SENT_CHN[u8Channel].CHN_CTL &= ~(SENT_CHN_CTL_CAL_RESYNC_IE_MASK | SENT_CHN_CTL_CAL_20_25_IE_MASK | SENT_CHN_CTL_SMSG_OVFL_IE_MASK | \ + SENT_CHN_CTL_FMSG_OVFL_IE_MASK | SENT_CHN_CTL_PP_DIAG_ERR_IE_MASK | SENT_CHN_CTL_CAL_DIAG_ERR_IE_MASK | \ + SENT_CHN_CTL_CAL_ERR_IE_MASK | SENT_CHN_CTL_NIB_ERR_IE_MASK | SENT_CHN_CTL_S_CRC_ERR_IE_MASK | \ + SENT_CHN_CTL_F_CRC_ERR_IE_MASK | SENT_CHN_CTL_EDGE_ERR_IE_MASK | SENT_CHN_CTL_SPC_OVERRUN_IE_MASK); +} + +/** + * @brief Enable/disable SENT channel idle flag interrupt + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + * @param bEn Enable or disable the interrupt + */ +LOCAL_INLINE void SENT_HWA_EnableChannelBusIdleInterrupt(SENT_Type *const pSent, uint8_t u8Channel, bool bEn) +{ + if(bEn) + { + pSent->SENT_CHN[u8Channel].CHN_CTL |= SENT_CHN_CTL_BUS_IDLE_IE_MASK; + } + else + { + pSent->SENT_CHN[u8Channel].CHN_CTL &= ~SENT_CHN_CTL_BUS_IDLE_IE_MASK; + } +} + +/** + * @brief Enable/disable SENT channel sync/calibration pulse error interrupt + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + * @param bEn Enable or disable the interrupt + */ +LOCAL_INLINE void SENT_HWA_EnableChannelCalResyncInterrupt(SENT_Type *const pSent, uint8_t u8Channel, bool bEn) +{ + if(bEn) + { + pSent->SENT_CHN[u8Channel].CHN_CTL |= SENT_CHN_CTL_CAL_RESYNC_IE_MASK; + } + else + { + pSent->SENT_CHN[u8Channel].CHN_CTL &= ~SENT_CHN_CTL_CAL_RESYNC_IE_MASK; + } +} + +/** + * @brief Enable/disable Sync/calibration pulse difference eceed 1.5625% error interrupt + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + * @param bEn Enable or disable the interrupt + */ +LOCAL_INLINE void SENT_HWA_EnableChannelCalERRInterrupt(SENT_Type *const pSent, uint8_t u8Channel, bool bEn) +{ + if(bEn) + { + pSent->SENT_CHN[u8Channel].CHN_CTL |= SENT_CHN_CTL_CAL_ERR_IE_MASK; + } + else + { + pSent->SENT_CHN[u8Channel].CHN_CTL &= ~SENT_CHN_CTL_CAL_ERR_IE_MASK; + } +} + +/** + * @brief Enable/disable SENT channel Calibration 20% pass 25% fail interrupt + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + * @param bEn Enable or disable the interrupt + */ +LOCAL_INLINE void SENT_HWA_EnableChannelCalFailInterrupt(SENT_Type *const pSent, uint8_t u8Channel, bool bEn) +{ + if(bEn) + { + pSent->SENT_CHN[u8Channel].CHN_CTL |= SENT_CHN_CTL_CAL_20_25_IE_MASK; + } + else + { + pSent->SENT_CHN[u8Channel].CHN_CTL &= ~SENT_CHN_CTL_CAL_20_25_IE_MASK; + } +} + +/** + * @brief Enable/disable SENT channel Slow message overflow interrupt + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + * @param bEn Enable or disable the interrupt + */ +LOCAL_INLINE void SENT_HWA_EnableChannelSOVFLInterrupt(SENT_Type *const pSent, uint8_t u8Channel, bool bEn) +{ + if(bEn) + { + pSent->SENT_CHN[u8Channel].CHN_CTL |= SENT_CHN_CTL_SMSG_OVFL_IE_MASK; + } + else + { + pSent->SENT_CHN[u8Channel].CHN_CTL &= ~SENT_CHN_CTL_SMSG_OVFL_IE_MASK; + } +} + +/** + * @brief Enable/disable SENT channel fast message overflow interrupt + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + * @param bEn Enable or disable the interrupt + */ +LOCAL_INLINE void SENT_HWA_EnableChannelFOVFLInterrupt(SENT_Type *const pSent, uint8_t u8Channel, bool bEn) +{ + if(bEn) + { + pSent->SENT_CHN[u8Channel].CHN_CTL |= SENT_CHN_CTL_FMSG_OVFL_IE_MASK; + } + else + { + pSent->SENT_CHN[u8Channel].CHN_CTL &= ~SENT_CHN_CTL_FMSG_OVFL_IE_MASK; + } +} + +/** + * @brief Enable/disable SENT channel Nibble value error interrupt + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + * @param bEn Enable or disable the interrupt + */ +LOCAL_INLINE void SENT_HWA_EnableChannelNibbleErrorInterrupt(SENT_Type *const pSent, uint8_t u8Channel, bool bEn) +{ + if(bEn) + { + pSent->SENT_CHN[u8Channel].CHN_CTL |= SENT_CHN_CTL_NIB_ERR_IE_MASK; + } + else + { + pSent->SENT_CHN[u8Channel].CHN_CTL &= ~SENT_CHN_CTL_NIB_ERR_IE_MASK; + } +} + +/** + * @brief Enable/disable SENT channel Previous pulse diagnosis error interrupt + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + * @param bEn Enable or disable the interrupt + */ +LOCAL_INLINE void SENT_HWA_EnableChannelPPDiagInterrupt(SENT_Type *const pSent, uint8_t u8Channel, bool bEn) +{ + if(bEn) + { + pSent->SENT_CHN[u8Channel].CHN_CTL |= SENT_CHN_CTL_PP_DIAG_ERR_IE_MASK; + } + else + { + pSent->SENT_CHN[u8Channel].CHN_CTL &= ~SENT_CHN_CTL_PP_DIAG_ERR_IE_MASK; + } +} + +/** + * @brief Enable/disable SENT channel Calibration diagnosis over 25% error interrupt + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + * @param bEn Enable or disable the interrupt + */ +LOCAL_INLINE void SENT_HWA_EnableChannelCALDiagInterrupt(SENT_Type *const pSent, uint8_t u8Channel, bool bEn) +{ + if(bEn) + { + pSent->SENT_CHN[u8Channel].CHN_CTL |= SENT_CHN_CTL_CAL_DIAG_ERR_IE_MASK; + } + else + { + pSent->SENT_CHN[u8Channel].CHN_CTL &= ~SENT_CHN_CTL_CAL_DIAG_ERR_IE_MASK; + } +} + +/** + * @brief Enable/disable SENT channel SPC overrun error interrupt + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + * @param bEn Enable or disable the interrupt + */ +LOCAL_INLINE void SENT_HWA_EnableChannelSPCOverRunInterrupt(SENT_Type *const pSent, uint8_t u8Channel, bool bEn) +{ + if(bEn) + { + pSent->SENT_CHN[u8Channel].CHN_CTL |= SENT_CHN_CTL_SPC_OVERRUN_IE_MASK; + } + else + { + pSent->SENT_CHN[u8Channel].CHN_CTL &= ~SENT_CHN_CTL_SPC_OVERRUN_IE_MASK; + } +} + +/** + * @brief Enable/disable SENT channel Fast message CRC check error interrupt + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + * @param bEn Enable or disable the interrupt + */ +LOCAL_INLINE void SENT_HWA_EnableChannelFCRCInterrupt(SENT_Type *const pSent, uint8_t u8Channel, bool bEn) +{ + if(bEn) + { + pSent->SENT_CHN[u8Channel].CHN_CTL |= SENT_CHN_CTL_F_CRC_ERR_IE_MASK; + } + else + { + pSent->SENT_CHN[u8Channel].CHN_CTL &= ~SENT_CHN_CTL_F_CRC_ERR_IE_MASK; + } +} + +/** + * @brief Enable/disable SENT channel slow message CRC check error interrupt + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + * @param bEn Enable or disable the interrupt + */ +LOCAL_INLINE void SENT_HWA_EnableChannelSCRCInterrupt(SENT_Type *const pSent, uint8_t u8Channel, bool bEn) +{ + if(bEn) + { + pSent->SENT_CHN[u8Channel].CHN_CTL |= SENT_CHN_CTL_S_CRC_ERR_IE_MASK; + } + else + { + pSent->SENT_CHN[u8Channel].CHN_CTL &= ~SENT_CHN_CTL_S_CRC_ERR_IE_MASK; + } +} + +/** + * @brief Enable/disable SENT channel Falling edge number error interrupt + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + * @param bEn Enable or disable the interrupt + */ +LOCAL_INLINE void SENT_HWA_EnableChannelEdgeERRInterrupt(SENT_Type *const pSent, uint8_t u8Channel, bool bEn) +{ + if(bEn) + { + pSent->SENT_CHN[u8Channel].CHN_CTL |= SENT_CHN_CTL_EDGE_ERR_IE_MASK; + } + else + { + pSent->SENT_CHN[u8Channel].CHN_CTL &= ~SENT_CHN_CTL_EDGE_ERR_IE_MASK; + } +} + +/** + * @brief Enable SENT channel Alternative 4-bit CRC algorithm + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + */ +LOCAL_INLINE void SENT_HWA_EnableChannelAltCRC(SENT_Type *const pSent, uint8_t u8Channel) +{ + pSent->SENT_CHN[u8Channel].CHN_CTL |= SENT_CHN_CTL_ALT_4BIT_CRC_MASK; +} + +/** + * @brief Disable SENT channel Alternative 4-bit CRC algorithm + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + */ +LOCAL_INLINE void SENT_HWA_DisableChannelAltCRC(SENT_Type *const pSent, uint8_t u8Channel) +{ + pSent->SENT_CHN[u8Channel].CHN_CTL &= ~SENT_CHN_CTL_ALT_4BIT_CRC_MASK; +} + +/** + * @brief Enable SENT channel Fast message data change + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + */ +LOCAL_INLINE void SENT_HWA_EnableChannelFastMessageDataChange(SENT_Type *const pSent, uint8_t u8Channel) +{ + pSent->SENT_CHN[u8Channel].CHN_CTL |= SENT_CHN_CTL_DATA_CHANGE_EN_MASK; +} + +/** + * @brief Disable SENT channel Fast message data change + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + */ +LOCAL_INLINE void SENT_HWA_DisableChannelFastMessageDataChange(SENT_Type *const pSent, uint8_t u8Channel) +{ + pSent->SENT_CHN[u8Channel].CHN_CTL &= ~SENT_CHN_CTL_DATA_CHANGE_EN_MASK; +} + +/** + * @brief Enable SENT channel calibration valid range from 20% tp 25% + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + */ +LOCAL_INLINE void SENT_HWA_EnableChannelCalValid20To25(SENT_Type *const pSent, uint8_t u8Channel) +{ + pSent->SENT_CHN[u8Channel].CHN_CTL |= SENT_CHN_CTL_CAL_SEL_MASK; +} + +/** + * @brief Disable SENT channel calibration valid range from 20% tp 25% + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + */ +LOCAL_INLINE void SENT_HWA_DisableChannelCalValid20To25(SENT_Type *const pSent, uint8_t u8Channel) +{ + pSent->SENT_CHN[u8Channel].CHN_CTL &= ~SENT_CHN_CTL_CAL_SEL_MASK; +} + +/** + * @brief Enable SENT channel calibration valid diagnostic + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + */ +LOCAL_INLINE void SENT_HWA_EnableChannelCalValidDiagnostic(SENT_Type *const pSent, uint8_t u8Channel) +{ + pSent->SENT_CHN[u8Channel].CHN_CTL &= ~SENT_CHN_CTL_PP_CHK_DIS_MASK; +} + +/** + * @brief Disable SENT channel calibration valid diagnostic + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + */ +LOCAL_INLINE void SENT_HWA_DisableChannelCalValidDiagnostic(SENT_Type *const pSent, uint8_t u8Channel) +{ + pSent->SENT_CHN[u8Channel].CHN_CTL |= SENT_CHN_CTL_PP_CHK_DIS_MASK; +} + +/** + * @brief Enable SENT channel fast message CRC with Augmentation + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + */ +LOCAL_INLINE void SENT_HWA_EnableChannelFastMessageAugmentation(SENT_Type *const pSent, uint8_t u8Channel) +{ + pSent->SENT_CHN[u8Channel].CHN_CTL &= ~SENT_CHN_CTL_FCRC_SEL_MASK; +} + +/** + * @brief Disable SENT channel fast message CRC with Augmentation + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + */ +LOCAL_INLINE void SENT_HWA_DisableChannelFastMessageAugmentation(SENT_Type *const pSent, uint8_t u8Channel) +{ + pSent->SENT_CHN[u8Channel].CHN_CTL |= SENT_CHN_CTL_FCRC_SEL_MASK; +} + +/** + * @brief Enable SENT channel Fast message crc with S&C + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + */ +LOCAL_INLINE void SENT_HWA_EnableChannelFastMessageCRCWithSC(SENT_Type *const pSent, uint8_t u8Channel) +{ + pSent->SENT_CHN[u8Channel].CHN_CTL |= SENT_CHN_CTL_FCRC_SC_EN_MASK; +} + +/** + * @brief Disable SENT channel Fast message crc with S&C + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + */ +LOCAL_INLINE void SENT_HWA_DisableChannelFastMessageCRCWithSC(SENT_Type *const pSent, uint8_t u8Channel) +{ + pSent->SENT_CHN[u8Channel].CHN_CTL &= ~SENT_CHN_CTL_FCRC_SC_EN_MASK; +} + +/** + * @brief Enable SENT channel slow message CRC with Augmentation + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + */ +LOCAL_INLINE void SENT_HWA_EnableChannelSlowMessageAugmentation(SENT_Type *const pSent, uint8_t u8Channel) +{ + pSent->SENT_CHN[u8Channel].CHN_CTL &= ~SENT_CHN_CTL_SCRC_SEL_MASK; +} + +/** + * @brief Disable SENT channel slow message CRC with Augmentation + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + */ +LOCAL_INLINE void SENT_HWA_DisableChannelSlowMessageAugmentation(SENT_Type *const pSent, uint8_t u8Channel) +{ + pSent->SENT_CHN[u8Channel].CHN_CTL |= SENT_CHN_CTL_SCRC_SEL_MASK; +} + +/** + * @brief Enable SENT channel Pause pulse + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + */ +LOCAL_INLINE void SENT_HWA_EnableChannelPausePulse(SENT_Type *const pSent, uint8_t u8Channel) +{ + pSent->SENT_CHN[u8Channel].CHN_CTL |= SENT_CHN_CTL_PAUSE_DET_EN_MASK; +} + +/** + * @brief Disable SENT channel Successive calibration pulses diagnostic option1 + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + */ +LOCAL_INLINE void SENT_HWA_DisableChannelPausePulse(SENT_Type *const pSent, uint8_t u8Channel) +{ + pSent->SENT_CHN[u8Channel].CHN_CTL &= ~SENT_CHN_CTL_PAUSE_DET_EN_MASK; +} + +/** + * @brief Enable SENT channel Successive calibration pulses diagnostic option1 + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + */ +LOCAL_INLINE void SENT_HWA_EnableChannelSPCOption1(SENT_Type *const pSent, uint8_t u8Channel) +{ + pSent->SENT_CHN[u8Channel].CHN_CTL |= SENT_CHN_CTL_SCP_CHK_MASK; +} + +/** + * @brief Disable SENT channel Pause pulse + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + */ +LOCAL_INLINE void SENT_HWA_DisableChannelSPCOption1(SENT_Type *const pSent, uint8_t u8Channel) +{ + pSent->SENT_CHN[u8Channel].CHN_CTL &= ~SENT_CHN_CTL_SCP_CHK_MASK; +} + +/** + * @brief Enable SENT channel Fast message crc check + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + */ +LOCAL_INLINE void SENT_HWA_EnableChannelFastMessageCRCCheck(SENT_Type *const pSent, uint8_t u8Channel) +{ + pSent->SENT_CHN[u8Channel].CHN_CTL &= ~SENT_CHN_CTL_FMSG_CRC_CHECK_OFF_MASK; +} + +/** + * @brief Disable SENT channel Fast message crc check + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + */ +LOCAL_INLINE void SENT_HWA_DisableChannelFastMessageCRCCheck(SENT_Type *const pSent, uint8_t u8Channel) +{ + pSent->SENT_CHN[u8Channel].CHN_CTL |= SENT_CHN_CTL_FMSG_CRC_CHECK_OFF_MASK; +} + +/** + * @brief Set SENT channel digital filter count + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + * @param u8Count the count of channel digital filter + */ +LOCAL_INLINE void SENT_HWA_SetChannelDigitalFilterCount(SENT_Type *const pSent, uint8_t u8Channel, uint8_t u8Count) +{ + pSent->SENT_CHN[u8Channel].CHN_CTL = (pSent->SENT_CHN[u8Channel].CHN_CTL & ~SENT_CHN_CTL_FILT_CNT_MASK) | SENT_CHN_CTL_FILT_CNT(u8Count); +} + +/** + * @brief Get Channel fast message data nibble + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel(0-3) + * @return uint32_t the corresponding channel data nibble value + */ +LOCAL_INLINE uint32_t SENT_HWA_GetChannelDataNibble(const SENT_Type *const pSent, uint8_t u8Channel) +{ + return pSent->SENT_CHN[u8Channel].CHN_FDATA; +} + +/** + * @brief Get Channel fast message crc nibble + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel(0-3) + * @return uint8_t the corresponding channel crc nibble value + */ +LOCAL_INLINE uint8_t SENT_HWA_GetChannelFastMessageCRCNibble(const SENT_Type *const pSent, uint8_t u8Channel) +{ + return (uint8_t)((pSent->SENT_CHN[u8Channel].CHN_FCRC & SENT_CHN_FCRC_CRC_DATA_MASK) >> SENT_CHN_FCRC_CRC_DATA_SHIFT); +} + +/** + * @brief Get Channel fast message status communication nibble + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel(0-3) + * @return uint8_t the corresponding channel status communication nibble value + */ +LOCAL_INLINE uint8_t SENT_HWA_GetChannelFastMessageStatusNibble(const SENT_Type *const pSent, uint8_t u8Channel) +{ + return (uint8_t)((pSent->SENT_CHN[u8Channel].CHN_FCRC & SENT_CHN_FCRC_SC_NB_MASK) >> SENT_CHN_FCRC_SC_NB_SHIFT); +} + +/** + * @brief Get Channel fast message status timestamp + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel(0-3) + * @return uint32_t the corresponding channel timestamp value + */ +LOCAL_INLINE uint32_t SENT_HWA_GetChannelFastMessageTimeStamp(const SENT_Type *const pSent, uint8_t u8Channel) +{ + return ((pSent->SENT_CHN[u8Channel].CHN_FTS & SENT_CHN_FTS_TIMESTAMP_VAL_MASK) >> SENT_CHN_FTS_TIMESTAMP_VAL_SHIFT); +} + +/** + * @brief Get Channel slow message type + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel(0-3) + * @return SENT_SlowMessageType the corresponding channel slow message type + */ +LOCAL_INLINE SENT_SlowMessageType SENT_HWA_GetChannelSLowMessageType(const SENT_Type *const pSent, uint8_t u8Channel) +{ + SENT_SlowMessageType eRet = SENT_SLOW_MESSAGE_SHORT; + + if(SENT_CHN_SBIT3__MSG_TYPE_MASK == (pSent->SENT_CHN[u8Channel].CHN_SBIT3 & SENT_CHN_SBIT3__MSG_TYPE_MASK)) + { + if(SENT_CHN_SBIT3__CFG_MASK == (pSent->SENT_CHN[u8Channel].CHN_SBIT3 & SENT_CHN_SBIT3__CFG_MASK)) + { + eRet = SENT_SLOW_MESSAGE_ENHANCE_16DATA_4ID; + } + else + { + eRet = SENT_SLOW_MESSAGE_ENHANCE_12DATA_8ID; + } + } + else + { + //do nothing + } + return eRet; +} + +/** + * @brief Get Channel enhanced serial message id bit 7 to bit4 or id bit 3 to id bit 0 + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel(0-3) + * @return uint8_t the corresponding channel enhanced serial message id bit 7 to bit4 or id bit 3 to id bit 0 + */ +LOCAL_INLINE uint8_t SENT_HWA_GetChannelBit3EnhancedID7_4_OR_ID3_0(const SENT_Type *const pSent, uint8_t u8Channel) +{ + return (uint8_t)((pSent->SENT_CHN[u8Channel].CHN_SBIT3 & SENT_CHN_SBIT3__ID7_4_OR_ID3_0_MASK) >> SENT_CHN_SBIT3__ID7_4_OR_ID3_0_SHIFT); +} + +/** + * @brief Get Channel enhanced serial message id bit 3 to bit0 or data bit 15 to id bit 12 + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel(0-3) + * @return uint8_t the corresponding channel enhanced serial message id bit 3 to bit0 or data bit 15 to id bit 12 + */ +LOCAL_INLINE uint8_t SENT_HWA_GetChannelBit3EnhancedID3_0_OR_DATA15_12(const SENT_Type *const pSent, uint8_t u8Channel) +{ + return (uint8_t)((pSent->SENT_CHN[u8Channel].CHN_SBIT3 & SENT_CHN_SBIT3__ID3_0_OR_DATA15_12_MASK) >> SENT_CHN_SBIT3__ID3_0_OR_DATA15_12_SHIFT); +} + +/** + * @brief Get Channel slow message bit2 with CRC + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel(0-3) + * @return uint8_t the corresponding channel slow message CRC value + */ +LOCAL_INLINE uint8_t SENT_HWA_GetChannelBit2CRC(const SENT_Type *const pSent, uint8_t u8Channel) +{ + return (uint8_t)((pSent->SENT_CHN[u8Channel].CHN_SBIT2 & SENT_CHN_SBIT2__SMSG_CRC_MASK) >> SENT_CHN_SBIT2__SMSG_CRC_SHIFT); +} + +/** + * @brief Get Channel slow message bit2 with DATA + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel(0-3) + * @return uint16_t the corresponding channel slow message DATA value + */ +LOCAL_INLINE uint16_t SENT_HWA_GetChannelBit2DATA(const SENT_Type *const pSent, uint8_t u8Channel) +{ + return (uint16_t)((pSent->SENT_CHN[u8Channel].CHN_SBIT2 & SENT_CHN_SBIT2__SMSG_DATA_MASK) >> SENT_CHN_SBIT2__SMSG_DATA_SHIFT); +} + +/** + * @brief Get Channel slow message status timestamp + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel(0-3) + * @return uint32_t the corresponding channel timestamp value + */ +LOCAL_INLINE uint32_t SENT_HWA_GetChannelSlowMessageTimeStamp(const SENT_Type *const pSent, uint8_t u8Channel) +{ + return ((pSent->SENT_CHN[u8Channel].CHN_STS & SENT_CHN_STS_SMSG_TIMESTAMP_MASK) >> SENT_CHN_STS_SMSG_TIMESTAMP_SHIFT); +} + +/** + * @brief Get Channel number of received frames + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel(0-3) + * @return uint32_t the number of received frames + */ +LOCAL_INLINE uint32_t SENT_HWA_GetChanneReceivedFrameNumber(const SENT_Type *const pSent, uint8_t u8Channel) +{ + return ((pSent->SENT_CHN[u8Channel].CHN_MCNT & SENT_CHN_MCNT_FRAME_CNT_MASK) >> SENT_CHN_MCNT_FRAME_CNT_SHIFT); +} + +/** + * @brief Get Channel number of received edges + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel(0-3) + * @return uint32_t the number of received edges + */ +LOCAL_INLINE uint32_t SENT_HWA_GetChanneReceivedEdgeNumber(const SENT_Type *const pSent, uint8_t u8Channel) +{ + return ((pSent->SENT_CHN[u8Channel].CHN_MCNT & SENT_CHN_MCNT_EDGE_CNT_MASK) >> SENT_CHN_MCNT_EDGE_CNT_SHIFT); +} + +/** + * @brief Clear the number of received frames + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + */ +LOCAL_INLINE void SENT_HWA_ClearChannelReceivedFrameNumber(SENT_Type *const pSent, uint8_t u8Channel) +{ + pSent->SENT_CHN[u8Channel].CHN_MCNT |= SENT_CHN_MCNT_FRAME_CNT_CLR_MASK; +} + +/** + * @brief Clear the number of received edges + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + */ +LOCAL_INLINE void SENT_HWA_ClearChannelReceivedEdgeNumber(SENT_Type *const pSent, uint8_t u8Channel) +{ + pSent->SENT_CHN[u8Channel].CHN_MCNT |= SENT_CHN_MCNT_EDGE_CNT_CLR_MASK; +} + +/** + * @brief Enable SENT channel SPC mode + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + */ +LOCAL_INLINE void SENT_HWA_EnableChannelSPCMode(SENT_Type *const pSent, uint8_t u8Channel) +{ + pSent->SENT_CHN[u8Channel].CHN_SPC_CTL |= SENT_CHN_SPC_CTL_SPC_ENABLE_MASK; +} + +/** + * @brief Disable SENT channel SPC mode + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + */ +LOCAL_INLINE void SENT_HWA_DisableChannelSPCMode(SENT_Type *const pSent, uint8_t u8Channel) +{ + pSent->SENT_CHN[u8Channel].CHN_SPC_CTL &= ~SENT_CHN_SPC_CTL_SPC_ENABLE_MASK; +} + +/** + * @brief Enable SENT channel calibration diagnosis in SPC mod + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + */ +LOCAL_INLINE void SENT_HWA_EnableChannelCalibrationDiag(SENT_Type *const pSent, uint8_t u8Channel) +{ + pSent->SENT_CHN[u8Channel].CHN_SPC_CTL &= ~SENT_CHN_SPC_CTL_CAL_DIAG_DIS_MASK; +} + +/** + * @brief Disable SENT channel calibration diagnosis in SPC mod + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + */ +LOCAL_INLINE void SENT_HWA_DisableChannelCalibrationDiag(SENT_Type *const pSent, uint8_t u8Channel) +{ + pSent->SENT_CHN[u8Channel].CHN_SPC_CTL |= SENT_CHN_SPC_CTL_CAL_DIAG_DIS_MASK; +} + + +/** + * @brief Set the SPC pulse trigger method + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + * @param eTrigger the SPC pulse trigger method + */ +LOCAL_INLINE void SENT_HWA_SetChannelSPCTriggerMethod(SENT_Type *const pSent, uint8_t u8Channel, SENT_SPCTriggerType eTrigger) +{ + pSent->SENT_CHN[u8Channel].CHN_SPC_CTL = (pSent->SENT_CHN[u8Channel].CHN_SPC_CTL & ~SENT_CHN_SPC_CTL_SPC_MODE_MASK) | SENT_CHN_SPC_CTL_SPC_MODE(eTrigger); +} + +/** + * @brief Set the delay between SPC-trigger assert and finally generate a SPC pulse + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + * @param eTrigger the delay value + */ +LOCAL_INLINE void SENT_HWA_SetChannelSPCPulseDelay(SENT_Type *const pSent, uint8_t u8Channel, uint8 u8Delay) +{ + pSent->SENT_CHN[u8Channel].CHN_SPC_CTL = (pSent->SENT_CHN[u8Channel].CHN_SPC_CTL & ~SENT_CHN_SPC_CTL_SPC_PULSE_DELAY_MASK) | SENT_CHN_SPC_CTL_SPC_PULSE_DELAY(u8Delay); +} + +/** + * @brief Set the delay between SPC-trigger assert and finally generate a SPC pulse + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + * @param eTick the selected tick base of SPC + */ +LOCAL_INLINE void SENT_HWA_SetChannelSPCTickBase(SENT_Type *const pSent, uint8_t u8Channel, SENT_SPCTickType eTick) +{ + pSent->SENT_CHN[u8Channel].CHN_SPC_CTL = (pSent->SENT_CHN[u8Channel].CHN_SPC_CTL & ~SENT_CHN_SPC_CTL_SPC_TICK_BASE_MASK) | SENT_CHN_SPC_CTL_SPC_TICK_BASE(eTick); +} + +/** + * @brief trigger the SENT to generate a SPC pulse by software + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + */ +LOCAL_INLINE void SENT_HWA_StartChannelSPC(SENT_Type *const pSent, uint8_t u8Channel) +{ + pSent->SENT_CHN[u8Channel].CHN_SPC_CTL |= SENT_CHN_SPC_CTL_SPC_START_MASK; +} + +/** + * @brief Set the width of the SPC pulse. + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + * @param u8Width the width of the SPC pulse. + */ +LOCAL_INLINE void SENT_HWA_SetChannelSPCPulseWidth(SENT_Type *const pSent, uint8_t u8Channel, uint8_t u8Width) +{ + pSent->SENT_CHN[u8Channel].CHN_SPC_CTL = (pSent->SENT_CHN[u8Channel].CHN_SPC_CTL & ~SENT_CHN_SPC_CTL_SPC_PULSE_WIDTH_MASK) | SENT_CHN_SPC_CTL_SPC_PULSE_WIDTH(u8Width); +} + +/** + * @brief Set the idle count determines how long the bus idle flag will assert when bus is idle + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel + * @param u8Count the idle count + */ +LOCAL_INLINE void SENT_HWA_SetChannelIdleCount(SENT_Type *const pSent, uint8_t u8Channel, uint8_t u8Count) +{ + pSent->SENT_CHN[u8Channel].CHN_IDLE_CTL = (pSent->SENT_CHN[u8Channel].CHN_IDLE_CTL & ~SENT_CHN_IDLE_CTL_IDLE_CNT_MASK) | SENT_CHN_IDLE_CTL_IDLE_CNT(u8Count); +} + +/** + * @brief Get the flag indicating the spc is busy + * + * @param pSent the base address of the SENT instance + * @param u8Channel the index of sent channel(0-3) + * @return bool the flag indicating the spc is busy + */ +LOCAL_INLINE bool SENT_HWA_GetChanneSPCBusyFlag(const SENT_Type *const pSent, uint8_t u8Channel) +{ + if(SENT_CHN_SPC_CTL_SPC_BUSY_MASK == (pSent->SENT_CHN[u8Channel].CHN_SPC_CTL & SENT_CHN_SPC_CTL_SPC_BUSY_MASK)) + { + return true; + } + else + { + return false; + } +} + +/** @}*/ + +#endif /* _HWA_SENT_H_ */ diff --git a/MODULES/HwA_Flagchip_FC7240/Inc/HwA_smc.h b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_smc.h new file mode 100644 index 0000000..dd468b6 --- /dev/null +++ b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_smc.h @@ -0,0 +1,74 @@ +/** + * @file HwA_smc.h + * @author Flagchip + * @brief FC7xxx SMC hardware access layer + * @version 0.1.0 + * @date 2022-11-21 + * + * @copyright Copyright (c) 2023 Flagchip Semiconductors Co., Ltd. + * + * @details + */ + +#ifndef _HWA_SMC_H_ +#define _HWA_SMC_H_ + +#include "device_header.h" +/********* Local typedef ************/ +/** @brief SMC stop mode control */ +typedef enum +{ + SMC_STOP_MODE = 0U, + SMC_STANDBY_MODE = 4U +} SMC_LpwModeCtrlType; + +/** @brief SMC standby mode */ +typedef enum +{ + SMC_CFG_STANDBY_0 = 0U, + SMC_CFG_STANDBY_1 = 1U, + SMC_CFG_STANDBY_2 = 2U, + SMC_CFG_STANDBY_3 = 3U +} SMC_StandbyModeType; + +/********* Local inline function ************/ +/** + * @brief Clear stop mode control value + * + */ +LOCAL_INLINE void SMC_HWA_ClearStopModeCtrl(void) +{ + SMC->PMCTRL &= ~(uint32_t)SMC_PMCTRL_STOP_MODE_MASK; +} + +/** + * @brief Set stop mode control + * + * @param eMode Stop mode control type + */ +LOCAL_INLINE void SMC_HWA_SetStopModeCtrl(SMC_LpwModeCtrlType eMode) +{ + SMC->PMCTRL = (uint32_t)eMode; +} + +/** + * @brief Clear standby mode + * + */ +LOCAL_INLINE void SMC_HWA_ClearStandbyMode(void) +{ + SMC->STANDBY_CFG &= ~(uint32_t)SMC_STANDBY_CFG_OPTION_MASK; +} + +/** + * @brief Set standby mode + * + * @param eMode Standby mode type + */ +LOCAL_INLINE void SMC_HWA_SetStandbyMode(SMC_StandbyModeType eMode) +{ + SMC->STANDBY_CFG = (uint32_t)eMode; +} + + +#endif /* #ifndef _HWA_SMC_H_ */ diff --git a/MODULES/HwA_Flagchip_FC7240/Inc/HwA_stcu.h b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_stcu.h new file mode 100644 index 0000000..3f69c69 --- /dev/null +++ b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_stcu.h @@ -0,0 +1,265 @@ +/** + * @file HwA_stcu.h + * @author Flagchip + * @brief Safety Test and Control Unit + * @version 0.1.0 + * @date 2022-11-30 + * + * @copyright Copyright (c) 2022 Flagchip Semiconductors Co., Ltd. + * + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 03/08/2022 Flagchip038 N/A First version for FC7xxx + ******************************************************************************** */ + +#ifndef _HWA_STCU_H_ +#define _HWA_STCU_H_ + +#include "device_header.h" +#include "fc7xxx_driver_stcu.h" + +/** + * \brief Get Self Test Status + * + * \return Status, maybe more than one status, refer to "STCU_SelfTestStatusType" + */ +LOCAL_INLINE uint32_t STCU_HWA_GetSelfTestStatus(void) +{ + return STCU->SELF_TEST_STATUS; +} + +/** + * \brief Clear all Self Test Status + */ +LOCAL_INLINE void STCU_HWA_ClearSelfTestStatus(void) +{ + STCU->SELF_TEST_STATUS = 0x0UL; +} + + +/** + * \brief Mbist select for self-test + * + * \param u32MbistSel maybe more than one + */ +LOCAL_INLINE void STCU_HWA_MbistSelect(uint32_t u32MbistSel) +{ + STCU->MBIST_SEL = u32MbistSel; +} + +/** + * \brief Get Mbist Done Flag + * + * \return All Mbist Done flags, refer to "STCU_MbistDoneType" + */ +LOCAL_INLINE uint32_t STCU_GetMbistDone(void) +{ + return STCU->MBIST_DONE_STATUS; +} + +/** + * \brief Get Mbist Fail Flag + * + * \return All Mbist Fail flags "STCU_MbistFailedType" + */ +LOCAL_INLINE uint32_t STCU_GetMbistFail(void) +{ + return STCU->MBIST_FAIL_STATUS; +} + +/** + * \brief Check Lbist execution failed status + * + * \return LBIST status, refer to "STCU_LbistStatusType" + */ +LOCAL_INLINE uint32_t STCU_HWA_CheckLbistStatus(void) +{ + return STCU->LBIST_STATUS; +} + + +/** + * \brief Get STCU Hardware Ram Initial Status + * + * \return Initial Status, refer to "STCU_HardwareInitRamStatusType" + */ +LOCAL_INLINE uint32_t STCU_HWA_GetHardwareRamInitStatus(void) +{ + return STCU->SRAM_INI_STATUS; +} + +/** + * \brief STCU RAM Init Mode set, can select more than one, for example: STCU_INIT_RAM_TYPE_SRAM0 | STCU_INIT_RAM_TYPE_SRAM1 + * + * \param u32InitRamType Init Mode + */ +LOCAL_INLINE void STCU_HWA_SetRamInitType(uint32_t u32InitRamType) +{ + STCU->SRAM_INI_SEL = u32InitRamType; +} + +/** + * \brief Set STCU Interrupt + * + * \param bIntEn Normal interrupt enable + * \param bSequenceErrorIntEn Sequence error interrupt enable + * \param bSizeErrorIntEn Size error interrupt enable + */ +LOCAL_INLINE void STCU_HWA_SetInterrupt(uint8_t bIntEn, uint8_t bSequenceErrorIntEn, uint8_t bSizeErrorIntEn) +{ + STCU->IRQ = STCU_IRQ_EN(bIntEn) | STCU_IRQ_SEQ_ERR(bSequenceErrorIntEn) | STCU_IRQ_SIZE_ERR(bSizeErrorIntEn); +} + +/** + * \brief STCU Ram Initial Start + * + * \param eInitRamMode Initial mode + * \param bEnable Enable Initial + * \param bLock Lock after initial + */ +LOCAL_INLINE void STCU_HWA_StartRamInit(STCU_InitRamModeType eInitRamMode, uint8_t bLock) +{ + STCU->SRAM_INI_CTRL = STCU_SRAM_INI_CTRL_MODE(eInitRamMode) | STCU_SRAM_INI_CTRL_EN_MASK | STCU_SRAM_INI_CTRL_LOCK(bLock) ; +} + +/** + * \brief Get Ram Initial Done flag + * + * \return All Done flag, maybe more than one flag, refer to "STCU_InitRamDoneType" + */ +LOCAL_INLINE uint32_t STCU_HWA_GetRamInitDone(void) +{ + return STCU->SRAM_INI_DONE_STATUS; +} + +/** + * \brief Get Ram Initial status + * + * \return All Done flag, maybe more than one flag, refer to "STCU_HardwareInitRamStatusType" + */ +LOCAL_INLINE uint32_t STCU_HWA_GetRamInitStatus(void) +{ + return STCU->SRAM_INI_STATUS; +} + +/** + * \brief Set the LBIST pattern amount control value N. + * + * \param u32Amount LBIST pattern amount control value N. (pattern amount = N * 256) + */ +LOCAL_INLINE void STCU_HWA_SetLBISTPatternAmount(uint32_t u32Amount) +{ + STCU->LBIST_PAT_CTRL = u32Amount; +} + +/** + * \brief Set the MBIST algorithm for SW trigger self-test + * + * \param bFullTest Enable Full test for MBIST. + * \param bSRAMInit Enable SRAM initialization at the end of software trigger self-test. + */ +LOCAL_INLINE void STCU_HWA_SetMBISTSWAlg(bool bFullTest, bool bSRAMInit) +{ + STCU->MBIST_ALG = (STCU->MBIST_ALG & ~(STCU_MBIST_ALG_TRIG_ALG_SEL_MASK | STCU_MBIST_ALG_TRIG_INI_EN_MASK)) | \ + (STCU_MBIST_ALG_TRIG_ALG_SEL(bFullTest?0X1FU:0x19U) | STCU_MBIST_ALG_TRIG_INI_EN(bSRAMInit?0x1U:0x0U)); +} + +/** + * \brief Set safety key + * + * \param u32Key Safety Key. + */ +LOCAL_INLINE void STCU_HWA_SetSafetyKey(uint32_t u32Key) +{ + STCU->SELF_TEST_KEY = u32Key; +} + +/** + * \brief Enable A self-test software trigger. + */ +LOCAL_INLINE void STCU_HWA_SwTriggerA(void) +{ + STCU->SELF_TEST_TRIG_A = STCU_SELF_TEST_TRIG_A_MASK; +} + +/** + * \brief Enable B self-test software trigger. + */ +LOCAL_INLINE void STCU_HWA_SwTriggerB(void) +{ + STCU->SELF_TEST_TRIG_B = STCU_SELF_TEST_TRIG_B_MASK; +} + +/** + * \brief Set self test ctrl register + * + * \param u32Reg Register value. + */ +LOCAL_INLINE void STCU_HWA_SetSelfTestCTRL(uint32_t u32Reg) +{ + STCU->SELF_TEST_CTRL = u32Reg; +} + +/** + * \brief Enable interrupt + */ +LOCAL_INLINE void STCU_HWA_EnableInterrupt(void) +{ + STCU->IRQ |= STCU_IRQ_EN_MASK; +} + +/** + * \brief Disable interrupt + */ +LOCAL_INLINE void STCU_HWA_DisableInterrupt(void) +{ + STCU->IRQ &= ~STCU_IRQ_EN_MASK; +} + +/** + * \brief Get STCU interrupt flags + * + * \return Status, maybe more than one status, refer to "STCU_InterruptFlagType" + */ +LOCAL_INLINE uint32_t STCU_HWA_GetInterruptFlag(void) +{ + return ((STCU->IRQ) & (STCU_IRQ_SEQ_ERR_MASK | STCU_IRQ_SIZE_ERR_MASK)); +} + +/** + * \brief Clear STCU interrupt flags + */ +LOCAL_INLINE void STCU_HWA_ClearInterruptFlag(void) +{ + STCU->IRQ &= ~(STCU_IRQ_SEQ_ERR_MASK | STCU_IRQ_SIZE_ERR_MASK); +} + +/** + * \brief Set STCU LBIST expected misr value + */ +LOCAL_INLINE void STCU_HWA_SetExpectedMisr(uint32_t u32Misr) +{ + STCU->LBIST_EXP_MISR = STCU_LBIST_EXP_MISR_MISR(u32Misr); +} + +/** + * \brief Get STCU LBIST expected misr value + */ +LOCAL_INLINE uint32_t STCU_HWA_GetExpectedMisr(void) +{ + return STCU->LBIST_EXP_MISR; +} + +/** + * \brief Get STCU LBIST actual misr value + */ +LOCAL_INLINE uint32_t STCU_HWA_GetActualMisr(void) +{ + return STCU->LBIST_ACT_MISR; +} + +#endif /*#ifndef _HWA_STCU_H_*/ diff --git a/MODULES/HwA_Flagchip_FC7240/Inc/HwA_tmu.h b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_tmu.h new file mode 100644 index 0000000..601ceb6 --- /dev/null +++ b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_tmu.h @@ -0,0 +1,548 @@ +/** + * @file HwA_tmu.h + * @author Flagchip + * @brief Hardware access layer for TMU + * @version 0.1.0 + * @date 2023-12-29 + * + * @copyright Copyright (c) 2023 Flagchip Semiconductors Co., Ltd. + * + */ +/********************************************************************************* +* Revision History: +* +* Version Date Initials CR# Descriptions +* --------- ---------- ------------ ---------- --------------- +* 0.1.0 2023-12-29 qxw074 N/A First version for FC7240 +******************************************************************************** */ + +#ifndef _HWA_TMU_H +#define _HWA_TMU_H + +#include "device_header.h" +#include "HwA_csc.h" + +/** + * @defgroup HwA_tmu + * @ingroup fc7xxx_driver_tmu + * @{ + */ + +/** + * @brief Select the TF_CTRL and TV_CTRL register is lock or not + * + */ +typedef enum +{ + TMU_TF_TV_LOCK = 0U, /*!< TF_CTRL and TV_CTRL register is lock*/ + TMU_TF_TV_UNLOCK = 1U /*!< TF_CTRL and TV_CTRL register is unlock*/ +}TMU_LockType; + +/** + * @brief Select the Flag-based temperature sensor hysteresis control + * + */ +typedef enum +{ + TMU_TF_HYSOFF_ON = 0U, /*!< Flag-based temperature sensor hysteresis is on*/ + TMU_TF_HYSOFF_OFF = 1U /*!< Flag-based temperature sensor hysteresis is off*/ +}TMU_HysteresisType; + +/** + * @brief Select the Flag-based temperature sensor filter control + * + */ +typedef enum +{ + TMU_TF_FILT_BYP_BYPASSED = 0U, /*!< Flag-based temperature sensor filter is bypassed*/ + TMU_TF_FILT_BYP_ENABLED = 1U /*!< Flag-based temperature sensor filter is enabled*/ +}TMU_bypassType; + +/** + * @brief Get the status of whether the temperature sensor register is locked + * + * @param pTmu the base address of the TMU instance + * @return true Temperature register is locked(CTRL) + * @return false Temperature register is unlocked(CTRL) + */ +LOCAL_INLINE TMU_LockType TMU_HWA_GetTemperatureLockStatus(const TMU_Type *const pTmu) +{ + uint32_t u32TmpVal = (pTmu->UNLOCK & TMU_UNLOCK_UNLOCK_MASK) >> TMU_UNLOCK_UNLOCK_SHIFT; + return (TMU_LockType)u32TmpVal; +} + +/** + * @brief Set the status of whether the temperature sensor register is locked or not + * + * @param pTmu the base address of the TMU instance + * @param eLockStatus Select the TF_CTRL and TV_CTRL register is lock or not + */ +LOCAL_INLINE void TMU_HWA_SetTemperatureLockStatus(TMU_Type *const pTmu,TMU_LockType eLockStatus) +{ + if((bool)eLockStatus) + { + pTmu->UNLOCK = 0xA5A50000U | TMU_UNLOCK_UNLOCK(eLockStatus); + }else + { + pTmu->UNLOCK = TMU_UNLOCK_UNLOCK(eLockStatus); + } +} + +/** + * @brief Get the Flag-based temperature sensor over 150 Celsius interrupt flag + * + * @param pTmu the base address of the TMU instance + * @return true Temperature over 150 Celsius interrupt is enabled + * @return false Temperature over 150 Celsius interrupt is disabled + */ +LOCAL_INLINE bool TMU_HWA_GetFlagTemperature150InterruptFlag(const TMU_Type *const pTmu) +{ + uint32_t u32TmpVal = (pTmu->TF_CTRL & TMU_TF_CTRL_TF_150F_IE_MASK) >> TMU_TF_CTRL_TF_150F_IE_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Set the Flag-based temperature sensor over 150 Celsius interrupt flag + * + * @param pTmu the base address of the TMU instance + * @param bEnable whether to enable the temperature over 150 Celsius interrupt + */ +LOCAL_INLINE void TMU_HWA_SetFlagTemperature150InterruptFlag(TMU_Type *const pTmu,bool bEnable) +{ + pTmu->TF_CTRL = (pTmu->TF_CTRL & ~TMU_TF_CTRL_TF_150F_IE_MASK) | TMU_TF_CTRL_TF_150F_IE(bEnable); +} + +/** + * @brief Get the Flag-based temperature sensor over 125 Celsius interrupt flag + * + * @param pTmu the base address of the TMU instance + * @return true Temperature over 125 Celsius interrupt is enabled + * @return false Temperature over 125 Celsius interrupt is disabled + */ +LOCAL_INLINE bool TMU_HWA_GetFlagTemperature125InterruptFlag(const TMU_Type *const pTmu) +{ + uint32_t u32TmpVal = (pTmu->TF_CTRL & TMU_TF_CTRL_TF_125F_IE_MASK) >> TMU_TF_CTRL_TF_125F_IE_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Set the Flag-based temperature sensor over 125 Celsius interrupt flag + * + * @param pTmu the base address of the TMU instance + * @param bEnable whether to enable the temperature over 125 Celsius interrupt + */ +LOCAL_INLINE void TMU_HWA_SetFlagTemperature125InterruptFlag(TMU_Type *const pTmu,bool bEnable) +{ + pTmu->TF_CTRL = (pTmu->TF_CTRL & ~TMU_TF_CTRL_TF_125F_IE_MASK) | TMU_TF_CTRL_TF_125F_IE(bEnable); +} + +/** + * @brief Get the Flag-based temperature sensor ready interrupt flag + * + * @param pTmu the base address of the TMU instance + * @return true Temperature sensor ready interrupt is enabled + * @return false Temperature sensor ready interrupt is disabled + */ +LOCAL_INLINE bool TMU_HWA_GetFlagTemperatureReadyInterruptFlag(const TMU_Type *const pTmu) +{ + uint32_t u32TmpVal = (pTmu->TF_CTRL & TMU_TF_CTRL_TF_RDYF_IE_MASK) >> TMU_TF_CTRL_TF_RDYF_IE_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Set the Flag-based temperature sensor over ready interrupt flag + * + * @param pTmu the base address of the TMU instance + * @param bEnable whether to enable the temperature sensor ready interrupt + */ +LOCAL_INLINE void TMU_HWA_SetFlagTemperatureReadyInterruptFlag(TMU_Type *const pTmu,bool bEnable) +{ + pTmu->TF_CTRL = (pTmu->TF_CTRL & ~TMU_TF_CTRL_TF_RDYF_IE_MASK) | TMU_TF_CTRL_TF_RDYF_IE(bEnable); +} + +/** + * @brief Get the Flag-based temperature sensor hysteresis control status + * + * @param pTmu the base address of the TMU instance + * @return true Temperature sensor Hysteresis is off + * @return false Temperature sensor Hysteresis is on + */ +LOCAL_INLINE bool TMU_HWA_GetFlagTemperatureHysteresisStatus(const TMU_Type *const pTmu) +{ + uint32_t u32TmpVal = (pTmu->TF_CTRL & TMU_TF_CTRL_TF_HYSOFF_MASK) >> TMU_TF_CTRL_TF_HYSOFF_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Set the Flag-based temperature sensor hysteresis control status + * + * @param pTmu the base address of the TMU instance + * @param bEnable whether to off(1)/on(0) the temperature sensor hysteresis + */ +LOCAL_INLINE void TMU_HWA_SetFlagTemperatureHysteresisStatus(TMU_Type *const pTmu,bool bEnable) +{ + pTmu->TF_CTRL = (pTmu->TF_CTRL & ~TMU_TF_CTRL_TF_HYSOFF_MASK) | TMU_TF_CTRL_TF_HYSOFF(bEnable); +} + +/** + * @brief Get the Flag-based temperature sensor startup counter + * + * @param pTmu the base address of the TMU instance + * @return u32TmpVal count of the startup + */ +LOCAL_INLINE uint8_t TMU_HWA_GetFlagTemperatureCounter(const TMU_Type *const pTmu) +{ + uint32_t u32TmpVal = (pTmu->TF_CTRL & TMU_TF_CTRL_TF_START_CNT_MASK) >> TMU_TF_CTRL_TF_START_CNT_SHIFT; + return (uint8_t)u32TmpVal; +} + +/** + * @brief Set the Flag-based temperature sensor startup counter + * + * @param pTmu the base address of the TMU instance + * @param u8Counter the startup counter + */ +LOCAL_INLINE void TMU_HWA_SetFlagTemperatureCounter(TMU_Type *const pTmu,uint8_t u8Counter) +{ + pTmu->TF_CTRL = (pTmu->TF_CTRL & ~TMU_TF_CTRL_TF_START_CNT_MASK) | TMU_TF_CTRL_TF_START_CNT(u8Counter); +} + +/** + * @brief Get the Flag-based temperature sensor filter bypass control status + * + * @param pTmu the base address of the TMU instance + * @return true Temperature sensor Filter is enabled + * @return false Temperature sensor Filter is bypassed + */ +LOCAL_INLINE bool TMU_HWA_GetFlagTemperatureFilterBypassStatus(const TMU_Type *const pTmu) +{ + uint32_t u32TmpVal = (pTmu->TF_CTRL & TMU_TF_CTRL_TF_FILT_BYP_MASK) >> TMU_TF_CTRL_TF_FILT_BYP_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Set the Flag-based temperature sensor filter bypass control status + * + * @param pTmu the base address of the TMU instance + * @param bEnable whether the temperature sensor filter is enabled(1) or bypassed(0) + */ +LOCAL_INLINE void TMU_HWA_SetFlagTemperatureFilterBypassStatus(TMU_Type *const pTmu,bool bEnable) +{ + pTmu->TF_CTRL = (pTmu->TF_CTRL & ~TMU_TF_CTRL_TF_FILT_BYP_MASK) | TMU_TF_CTRL_TF_FILT_BYP(bEnable); +} + +/** + * @brief Get the Flag-based temperature sensor enable status + * + * @param pTmu the base address of the TMU instance + * @return true Temperature sensor is on + * @return false Temperature sensor is off + */ +LOCAL_INLINE bool TMU_HWA_GetFlagTemperatureEnableStatus(const TMU_Type *const pTmu) +{ + uint32_t u32TmpVal = (pTmu->TF_CTRL & TMU_TF_CTRL_TF_EN_MASK) >> TMU_TF_CTRL_TF_EN_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Set the Flag-based temperature sensor enable status + * + * @param pTmu the base address of the TMU instance + * @param bEnable whether the temperature sensor is on(1) or off(0) + */ +LOCAL_INLINE void TMU_HWA_SetFlagTemperatureEnableStatus(TMU_Type *const pTmu,bool bEnable) +{ + pTmu->TF_CTRL = (pTmu->TF_CTRL & ~TMU_TF_CTRL_TF_EN_MASK) | TMU_TF_CTRL_TF_EN(bEnable); +} + +/** + * @brief Check whether the temperature is over 150 Celsius + * + * @param pTmu the base address of the TMU instance + * @return true the temperature is over 150 Celsius + * @return false the temperature is not over 150 Celsius + */ +LOCAL_INLINE bool TMU_HWA_Get150Status(TMU_Type *const pTmu) +{ + uint32_t u32TmpVal = pTmu->TF_STATUS; + u32TmpVal = (u32TmpVal & TMU_TF_STATUS_TF_150_MASK) >> TMU_TF_STATUS_TF_150_SHIFT; + + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Check whether the temperature is over 125 Celsius + * + * @param pTmu the base address of the TMU instance + * @return true the temperature is over 125 Celsius + * @return false the temperature is not over 125 Celsius + */ +LOCAL_INLINE bool TMU_HWA_Get125Status(TMU_Type *const pTmu) +{ + uint32_t u32TmpVal = pTmu->TF_STATUS; + u32TmpVal = (u32TmpVal & TMU_TF_STATUS_TF_125_MASK) >> TMU_TF_STATUS_TF_125_SHIFT; + + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Check whether the flag for temperature over 150 Celsius is set + * + * @param pTmu the base address of the TMU instance + * @return true the temperature has exceeded 150 Celsius since last time W1C + * @return false the temperature has not exceeded 150 Celsius since TF is ready + */ +LOCAL_INLINE bool TMU_HWA_Get150Flag(TMU_Type *const pTmu) +{ + uint32_t u32TmpVal = pTmu->TF_STATUS; + u32TmpVal = (u32TmpVal & TMU_TF_STATUS_TF_150F_MASK) >> TMU_TF_STATUS_TF_150F_SHIFT; + + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Clear the temperature over 150 Celsius flag + * + * @param pTmu the base address of the TMU instance + */ +LOCAL_INLINE void TMU_HWA_Clear150Flag(TMU_Type *const pTmu) +{ + pTmu->TF_STATUS |= TMU_TF_STATUS_TF_150F(1U); +} + +/** + * @brief Check whether the flag for temperature over 125 Celsius is set + * + * @param pTmu the base address of the TMU instance + * @return true the temperature has exceeded 125 Celsius since last time W1C + * @return false the temperature has not exceeded 125 Celsius since TF is ready + */ +LOCAL_INLINE bool TMU_HWA_Get125Flag(TMU_Type *const pTmu) +{ + uint32_t u32TmpVal = pTmu->TF_STATUS; + u32TmpVal = (u32TmpVal & TMU_TF_STATUS_TF_125F_MASK) >> TMU_TF_STATUS_TF_125F_SHIFT; + + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Clear the temperature over 125 Celsius flag + * + * @param pTmu the base address of the TMU instance + */ +LOCAL_INLINE void TMU_HWA_Clear125Flag(TMU_Type *const pTmu) +{ + pTmu->TF_STATUS |= TMU_TF_STATUS_TF_125F(1U); +} + +/** + * @brief Check whether the Flag-based temperature sensor is ready + * + * @param pTmu the base address of the TMU instance + * @return true the Flag-based temperature sensor is ready + * @return false the Flag-based temperature sensor is not ready + */ +LOCAL_INLINE bool TMU_HWA_GetFlagTemperatureReady(TMU_Type *const pTmu) +{ + uint32_t u32TmpVal = pTmu->TF_STATUS; + u32TmpVal = (u32TmpVal & TMU_TF_STATUS_TF_RDYF_MASK) >> TMU_TF_STATUS_TF_RDYF_SHIFT; + + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Clear the Flag-based temperature sensor ready flag + * + * @param pTmu the base address of the TMU instance + */ +LOCAL_INLINE void TMU_HWA_ClearFlagTemperatureReady(TMU_Type *const pTmu) +{ + pTmu->TF_STATUS |= TMU_TF_STATUS_TF_RDYF(1U); +} + +/** + * @brief Get the Vlotage-based temperature sensor ready interrupt flag + * + * @param pTmu the base address of the TMU instance + * @return true Temperature sensor ready interrupt is enabled + * @return false Temperature sensor ready interrupt is disabled + */ +LOCAL_INLINE bool TMU_HWA_GetVoltageTemperatureReadyInterruptFlag(const TMU_Type *const pTmu) +{ + uint32_t u32TmpVal = (pTmu->TV_CTRL & TMU_TV_CTRL_TV_RDYF_IE_MASK) >> TMU_TV_CTRL_TV_RDYF_IE_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Set the Voltage-based temperature sensor over ready interrupt flag + * + * @param pTmu the base address of the TMU instance + * @param bEnable whether to enable the temperature sensor ready interrupt + */ +LOCAL_INLINE void TMU_HWA_SetVoltageTemperatureReadyInterruptFlag(TMU_Type *const pTmu,bool bEnable) +{ + pTmu->TV_CTRL = (pTmu->TV_CTRL & ~TMU_TV_CTRL_TV_RDYF_IE_MASK) | TMU_TV_CTRL_TV_RDYF_IE(bEnable); +} + +/** + * @brief Get the Voltage-based temperature sensor startup counter + * + * @param pTmu the base address of the TMU instance + * @return u32TmpVal count of the startup + */ +LOCAL_INLINE uint8_t TMU_HWA_GetVoltageTemperatureCounter(const TMU_Type *const pTmu) +{ + uint32_t u32TmpVal = (pTmu->TV_CTRL & TMU_TV_CTRL_TV_START_CNT_MASK) >> TMU_TV_CTRL_TV_START_CNT_SHIFT; + return (uint8_t)u32TmpVal; +} + +/** + * @brief Set the Voltage-based temperature sensor startup counter + * + * @param pTmu the base address of the TMU instance + * @param u8Counter the startup counter + */ +LOCAL_INLINE void TMU_HWA_SetVoltageTemperatureCounter(TMU_Type *const pTmu,uint8_t u8Counter) +{ + pTmu->TV_CTRL = (pTmu->TV_CTRL & ~TMU_TV_CTRL_TV_START_CNT_MASK) | TMU_TV_CTRL_TV_START_CNT(u8Counter); +} + +/** + * @brief Get the Voltage-based temperature sensor enable status + * + * @param pTmu the base address of the TMU instance + * @return true Temperature sensor is on + * @return false Temperature sensor is off + */ +LOCAL_INLINE bool TMU_HWA_GetVoltageTemperatureEnableStatus(const TMU_Type *const pTmu) +{ + uint32_t u32TmpVal = (pTmu->TV_CTRL & TMU_TV_CTRL_TV_EN_MASK) >> TMU_TV_CTRL_TV_EN_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Set the Voltage-based temperature sensor enable status + * + * @param pTmu the base address of the TMU instance + * @param bEnable whether the temperature sensor is on(1) or off(0) + */ +LOCAL_INLINE void TMU_HWA_SetVoltageTemperatureEnableStatus(TMU_Type *const pTmu,bool bEnable) +{ + pTmu->TV_CTRL = (pTmu->TV_CTRL & ~TMU_TV_CTRL_TV_EN_MASK) | TMU_TV_CTRL_TV_EN(bEnable); +} + +/** + * @brief Check whether the Voltage-based temperature sensor is ready + * + * @param pTmu the base address of the TMU instance + * @return true the Voltage-based temperature sensor is ready + * @return false the Voltage-based temperature sensor is not ready + */ +LOCAL_INLINE bool TMU_HWA_GetVoltageTemperatureReady(TMU_Type *const pTmu) +{ + uint32_t u32TmpVal = pTmu->TV_STATUS; + u32TmpVal = (u32TmpVal & TMU_TV_STATUS_TV_RDYF_MASK) >> TMU_TV_STATUS_TV_RDYF_SHIFT; + + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Clear the Voltage-based temperature sensor ready flag + * + * @param pTmu the base address of the TMU instance + */ +LOCAL_INLINE void TMU_HWA_ClearVoltageTemperatureReady(TMU_Type *const pTmu) +{ + pTmu->TV_STATUS |= TMU_TV_STATUS_TV_RDYF(1U); +} + +/** + * @brief Get the TMU_TF_CTRL config + * + * @param pTmu the base address of the TMU instance + * @return uint32_t the TMU_TF_CTRL config + */ +LOCAL_INLINE uint32_t TMU_HWA_GetFlagTempCtrl(const TMU_Type *const pTmu) +{ + return pTmu->TF_CTRL; +} + +/** + * @brief Set the TMU_TF_CTRL config + * + * @param pTmu the base address of the TMU instance + * @param u32Config the TMU_TF_CTRL config + */ +LOCAL_INLINE void TMU_HWA_SetFlagTempCtrl(TMU_Type *const pTmu, uint32_t u32Config) +{ + pTmu->TF_CTRL = u32Config; +} + +/** + * @brief Get the TMU_TV_CTRL config + * + * @param pTmu the base address of the TMU instance + * @return uint32_t the TMU_TV_CTRL config + */ +LOCAL_INLINE uint32_t TMU_HWA_GetVoltageTempCtrl(const TMU_Type *const pTmu) +{ + return pTmu->TV_CTRL; +} + +/** + * @brief Set the TMU_TV_CTRL config + * + * @param pTmu the base address of the TMU instance + * @param u32Config the TMU_TV_CTRL config + */ +LOCAL_INLINE void TMU_HWA_SetVoltageTempCtrl(TMU_Type *const pTmu, uint32_t u32Config) +{ + pTmu->TV_CTRL = u32Config; +} + +/** + * @brief Controls the stop ack function enable or not to the TMU0 + * + * @param bEnable set the ACK enable or not + */ +LOCAL_INLINE void TMU_HWA_SetStopAck(bool bEnable) +{ + if(bEnable) + { + CSC0_HWA_MODER0_EnableStopAck(CSC_STOPMODE_TMU); + } + else + { + CSC0_HWA_MODER0_DisableStopAck(CSC_STOPMODE_TMU); + } +} + +/** + * @brief Get the TV_TRIM_TV_TCODE value + * + * @param pTmu the base address of the TMU instance + * @return uint32_t the TV_TRIM_TV_TCODE value + */ +LOCAL_INLINE uint32_t TMU_HWA_GetTemperatureCode(const TMU_Type *const pTmu) +{ + uint32_t u32TmpVal = pTmu->TV_TRIM; + u32TmpVal = (u32TmpVal & TMU_TV_TRIM_TV_TCODE_MASK) >> TMU_TV_TRIM_TV_TCODE_SHIFT; + return u32TmpVal; +} + +/** + * @brief Get the TV_TRIM_TV_SLOPE value + * + * @param pTmu the base address of the TMU instance + * @return uint32_t the TV_TRIM_TV_SLOPE value + */ +LOCAL_INLINE uint32_t TMU_HWA_GetSlopeFactor(const TMU_Type *const pTmu) +{ + uint32_t u32TmpVal = pTmu->TV_TRIM; + u32TmpVal = (u32TmpVal & TMU_TV_TRIM_TV_SLOPE_MASK) >> TMU_TV_TRIM_TV_SLOPE_SHIFT; + return u32TmpVal; +} + +/** @}*/ + +#endif /* _HWA_TMU_H_ */ diff --git a/MODULES/HwA_Flagchip_FC7240/Inc/HwA_tpue.h b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_tpue.h new file mode 100644 index 0000000..370e737 --- /dev/null +++ b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_tpue.h @@ -0,0 +1,2062 @@ +/** + * @file HwA_tpue.h + * @author Flagchip + * @brief FC7xxx TPUE hardware access layer + * @version 0.1.0 + * @date 2024-1-12 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + * @details + */ + +#ifndef _HWA_TPUE_H_ +#define _HWA_TPUE_H_ + +#include "device_header.h" + +/********* Local typedef ************/ + +/** @brief TPU channel digital filter control type */ +typedef enum +{ + TPUE_TWO_SAMPLE_MODE = 0U, + TPUE_BYPASS_MODE = 1U, + TPUE_THREE_SAMPLE_MODE = 2U, + TPUE_CONTINUOUS_MODE = 3U +} TPUE_FilterCtrlType; + +/** @brief TPU filter clock source selection type */ +typedef enum +{ + TPUE_TPU_CLK_DIV2 = 0U, + TPUE_TPU_CLK = 1U +} TPUE_FilterClkSrcType; + +/** @brief TPU channel digital filter control type */ +typedef enum +{ + TPUE_SYSCLK_DIV_1 = 0U, + TPUE_SYSCLK_DIV_2 = 1U, + TPUE_SYSCLK_DIV_4 = 2U, + TPUE_SYSCLK_DIV_8 = 3U, + TPUE_SYSCLK_DIV_16 = 4U, + TPUE_SYSCLK_DIV_32 = 5U, + TPUE_SYSCLK_DIV_64 = 6U, + TPUE_SYSCLK_DIV_128 = 7U +} TPUE_FilterPrescalerCtrlType; + +/** @brief TPU TCR1 clock control mode type */ +typedef enum +{ + TPUE_TCR1CLK_CLK_SRC = 0U, + TPUE_TCR1CLK_UPDOWN_CNT_MODE = 3U, + TPUE_TCR1CLK_CLK_SRC_TPUCLKDIV2 = 4U, + TPUE_TCR1CLK_SRC_TPUCLK = 5U +} TPUE_TCR1ClkCtrlModeType; + +/** @brief TPU angle tick gen clk type */ +typedef enum +{ + TPUE_TCR1_PRESCAL_OUTPUT = 0U, + TPUE_TCR2_PRESCAL_OUTPUT = 1U +} TPUE_AngleTickGenClkType; + +/** @brief TPU Angle Mode Selection type */ +typedef enum +{ + TPUE_TCR2_TIMEBASE_EAC_DISABLE = 0U, + TPUE_TOOTHSIGNAL_AS_TCRCLK_TOOTH_CH_0 = 1U, + TPUE_TOOTHSIGNAL_AS_CH1INPUT_TOOTH_CH_1 = 2U, + TPUE_TOOTHSIGNAL_AS_CH1INPUT_TOOTH_CH_2 = 3U +} TPUE_AngleModeSel; + +/** @brief TPU Angle Mode Selection type */ +typedef enum +{ + TPUE_TWO_SAMPLE_MODE_TPU_CLK_DIV2 = 0U, + TPUE_TWO_SAMPLE_MODE_CH_CLK = 1U, + TPUE_INTEGRATOR_MODE_TPU_CLK_DIV2 = 2U, + TPUE_INTEGRATOR_MODE_CH_CLK = 3U +} TPUE_TCRClkFilterType; + +/** @brief TPU TCR2 clock control mode0 type */ +typedef enum +{ + TPUE_GATED_DIV8_CLK = 0U, + TPUE_RISE_TRANSITION_INCREMENT_TCR2_PRESCALER = 1U, + TPUE_FALL_TRANSITION_INCREMENT_TCR2_PRESCALER = 2U, + TPUE_DIV8_CLK = 4U, + TPUE_UPDOWN_CNT_MODE = 5U, + TPUE_FROZEN = 7U +} TPUE_TCR1ClkCtrlMode0Type; + +typedef enum +{ + TPUE_RSING_EDGE = 1U, + TPUE_FALLING_EDGE = 2U, + TPUE_BOTH_EDGES = 3U, + TPUE_NO_EDGE = 6U, +} TPUE_TCR1ClkCtrlMode1Type; + +/** @brief Missing Tooth Counter */ +typedef enum +{ + TPUE_NOT_A_MISSING_TOOTH = 0U, + TPUE_ONE_MISSING_TOOTH = 1U, + TPUE_TWO_MISSING_TOOTH = 2U, + TPUE_THREE_MISSING_TOOTH = 3U, +} TPUE_MissToothCntType; + +/** @brief Channel Trigger Configuration */ +typedef enum +{ + TPUE_DISABLED = 0U, + TPUE_ANY_EVENT_GATED_BY_MSRTSR = 2U, + TPUE_HSA_EVENT_ON_FLEXCORE_MODE = 3U, + TPUE_MRL1_EVENT_NOT_GATED_BY_MSR = 4U, + TPUE_MRL2_EVENT_NOT_GATED_BY_MSR = 5U, + TPUE_MRL1_OR_MRL2_EVENT_NOT_GATED_BY_MSR = 6U, + TPUE_MRL1_AND_MRL2_EVENT_NOT_GATED_BY_MSR = 7U, + TPUE_TDL1_OR_TDL2_EVENT_NOT_GATED_BY_TSR = 8U, + TPUE_TDL1_AND_TDL2_EVENT_NOT_GATED_BY_TSR = 9U, + TPUE_EVENT_EQUAL_TO_CH_DO_LEVEL = 10U, + TPUE_EVENT_NEGATIVE_TO_CH_DO_LEVEL = 11U, + TPUE_EVENT_EQUAL_TO_CH_DO_PART1_LEVEL = 12U, + TPUE_EVENT_EQUAL_TO_CH_DO_PART2_LEVEL = 13U, + TPUE_EVENT_EQUAL_TO_CH_IND_LEVEL = 14U, + TPUE_EVENT_EQUAL_TO_CH_IND_LATCH_LEVEL = 15U, +} TPUE_ChTrigCFGType; + +/** @brief Filter Grade for 7 value in 1 loop */ +typedef enum +{ + TPUE_FILTER_DISABLE = 0U, + TPUE_FILTER_LOW = 1U, + TPUE_FILTER_MIDDLE = 2U, + TPUE_FILTER_HIGH = 3U, +} TPUE_FilterGradeType; + +/** @brief Channel event triggered interrupt priority */ +typedef enum +{ + TPUE_PRIORITY_DISABLE = 0U, + TPUE_PRIORITY_LOW = 1U, + TPUE_PRIORITY_MIDDLE = 2U, + TPUE_PRIORITY_HIGH = 3U, +} TPUE_EventIntPriorityType; + +/** @brief Channel time base selection of part 1. */ +typedef enum +{ + TPUE_GREATER_OR_EQUAL_CAPBASE_TCR1_MATCHBASE_TCR1 = 0U, + TPUE_GREATER_OR_EQUAL_CAPBASE_TCR1_MATCHBASE_TCR2 = 1U, + TPUE_GREATER_OR_EQUAL_CAPBASE_TCR2_MATCHBASE_TCR1 = 2U, + TPUE_GREATER_OR_EQUAL_CAPBASE_TCR2_MATCHBASE_TCR2 = 3U, + TPUE_EQUAL_ONLY_CAPBASE_TCR1_MATCHBASE_TCR1 = 4U, + TPUE_EQUAL_ONLY_CAPBASE_TCR1_MATCHBASE_TCR2 = 5U, + TPUE_EQUAL_ONLY_CAPBASE_TCR2_MATCHBASE_TCR1 = 6U, + TPUE_EQUAL_ONLY_CAPBASE_TCR2_MATCHBASE_TCR2 = 7U, +} TPUE_TimeBaseSelctionType; + +/** @brief Channel Input Pin Action Control. */ +typedef enum +{ + TPUE_NO_TRANSITIONS = 0U, + TPUE_DETECT_RISING_EDGE_ONLY = 1U, + TPUE_DETECT_FALLING_EDGE_ONLY = 2U, + TPUE_DETECT_EITHER_EDGE_ONLY = 3U, + TPUE_DETECT_SIGNAL_0_ON_MATCH = 4U, + TPUE_DETECT_SIGNAL_1_ON_MATCH = 5U, +} TPUE_IPACType; + +/** @brief Channel output Pin Action Control. */ +typedef enum +{ + TPUE_NO_CHANGE_OUTPUT = 0U, + TPUE_MATCH_SET_OUTPUT_HIGH = 1U, + TPUE_MATCH_SET_OUTPUT_LOW = 2U, + TPUE_MATCH_TOGGLE_OUTPUT = 3U, + TPUE_TRANSITION_SET_OUTPUT_HIGH = 4U, + TPUE_TRANSITION_SET_OUTPUT_LOW = 5U, + TPUE_TRANSITION_TOGGLE_OUTPUT = 6U, + TPUE_NO_CHANGE_OPAC = 7U, +} TPUE_OPACType; + +/** @brief PDCM Encoding. */ +typedef enum +{ + TPUE_EM_B_ST = 0U, + TPUE_EM_B_DT = 1U, + TPUE_EM_NB_ST = 2U, + TPUE_EM_NB_DT = 3U, + TPUE_M2_ST = 4U, + TPUE_M2_DT = 5U, + TPUE_BM_ST = 6U, + TPUE_BM_DT = 7U, + TPUE_M2_O_ST = 8U, + TPUE_M2_O_DT = 9U, + TPUE_SM_ST = 12U, + TPUE_SM_DT = 13U, + TPUE_SM_ST_E = 14U, +} TPUE_PDCMEncodeType; + +/********* Local inline function ************/ +/** + * @brief Get channel digital filter control + * + */ +LOCAL_INLINE TPUE_FilterCtrlType TPU_E_HWA_GetFilterCtrl(const TPU_E_Type *const pTPUE) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->GCR_CR & TPU_E_GCR_CR_CDFC_MASK) >> TPU_E_GCR_CR_CDFC_SHIFT; + return (TPUE_FilterCtrlType)u32TmpVal; +} + +/** + * @brief Set channel digital filter control + * + */ +LOCAL_INLINE void TPU_E_HWA_SetFilterCtrl(TPU_E_Type *const pTPUE, TPUE_FilterCtrlType eControlMode) +{ + pTPUE->GCR_CR = (pTPUE->GCR_CR & ~TPU_E_GCR_CR_CDFC_MASK) | TPU_E_GCR_CR_CDFC(eControlMode); +} + +/** + * @brief Get filter clock source + * + */ +LOCAL_INLINE TPUE_FilterClkSrcType TPU_E_HWA_GetFilterClkSrc(const TPU_E_Type *const pTPUE) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->GCR_CR & TPU_E_GCR_CR_FCSS_MASK) >> TPU_E_GCR_CR_FCSS_SHIFT; + return (TPUE_FilterClkSrcType)u32TmpVal; +} + +/** + * @brief Set filter clock source + * + */ +LOCAL_INLINE void TPU_E_HWA_SetFilterClkSrc(TPU_E_Type *const pTPUE, TPUE_FilterClkSrcType eClkSrc) +{ + pTPUE->GCR_CR = (pTPUE->GCR_CR & ~TPU_E_GCR_CR_FCSS_MASK) | TPU_E_GCR_CR_FCSS(eClkSrc); +} + +/** + * @brief Get filter prescaler clock control + * + */ +LOCAL_INLINE TPUE_FilterPrescalerCtrlType TPU_E_HWA_GetFilterPrescaler(const TPU_E_Type *const pTPUE) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->GCR_CR & TPU_E_GCR_CR_FPSCK_MASK) >> TPU_E_GCR_CR_FPSCK_SHIFT; + return (TPUE_FilterPrescalerCtrlType)u32TmpVal; +} + +/** + * @brief Get filter prescaler clock control + * + */ +LOCAL_INLINE void TPU_E_HWA_SetFilterPrescaler(TPU_E_Type *const pTPUE, TPUE_FilterPrescalerCtrlType ePrescaler) +{ + pTPUE->GCR_CR = (pTPUE->GCR_CR & ~TPU_E_GCR_CR_FPSCK_MASK) | TPU_E_GCR_CR_FPSCK(ePrescaler); +} + +/** + * @brief Whether channel function is disabled in Stop mode + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetFuncDisableInStopMode(const TPU_E_Type *const pTPUE) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->GCR_CR & TPU_E_GCR_CR_HALT_CH_MASK) >> TPU_E_GCR_CR_HALT_CH_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Enable channel function is disabled or normal in Stop mode + * + */ +LOCAL_INLINE void TPU_E_HWA_SetFuncDisableInStopMode(TPU_E_Type *const pTPUE, bool bEnable) +{ + pTPUE->GCR_CR = (pTPUE->GCR_CR & ~TPU_E_GCR_CR_HALT_CH_MASK) | TPU_E_GCR_CR_HALT_CH(bEnable); +} + +/** + * @brief Whether channel function is disabled in Stop mode + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetTimeBaseCntStopInStopMode(const TPU_E_Type *const pTPUE) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->GCR_CR & TPU_E_GCR_CR_HALT_TB_MASK) >> TPU_E_GCR_CR_HALT_TB_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Enable channel function is disabled or normal in Stop mode + * + */ +LOCAL_INLINE void TPU_E_HWA_SetTimeBaseCntStopInStopMode(TPU_E_Type *const pTPUE, bool bEnable) +{ + pTPUE->GCR_CR = (pTPUE->GCR_CR & ~TPU_E_GCR_CR_HALT_TB_MASK) | TPU_E_GCR_CR_HALT_TB(bEnable); +} + +/** + * @brief Enable channel function is disabled or normal in Stop mode + * + */ +LOCAL_INLINE void TPU_E_HWA_TrigReset(TPU_E_Type *const pTPUE) +{ + pTPUE->GCR_SRR = 0xFC005AFEU; +} + +/** + * @brief Get service request status of specific channel + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetSRStatus(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->GCR_VSR & (1U << u8Channel)) >> u8Channel; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get pin input status of specific channel + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetInputStatus(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->GCR_VIR & (1U << u8Channel)) >> u8Channel; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get pin output status of specific channel + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetoutputStatus(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->GCR_VOR & (1U << u8Channel)) >> u8Channel; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get pin output enable status of specific channel + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetoutputEnStatus(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->GCR_VOBR & (1U << u8Channel)) >> u8Channel; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get MRL1 status of specific channel + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetMRL1Status(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->GCR_VM1R & (1U << u8Channel)) >> u8Channel; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get MRL2 status of specific channel + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetMRL2Status(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->GCR_VM2R & (1U << u8Channel)) >> u8Channel; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get TDL1 status of specific channel + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetTDL1Status(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->GCR_VT1R & (1U << u8Channel)) >> u8Channel; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get TDL2 status of specific channel + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetTDL2Status(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->GCR_VT2R & (1U << u8Channel)) >> u8Channel; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get MRL1 event status of specific channel + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetMRL1EventStatus(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->GCR_EM1R & (1U << u8Channel)) >> u8Channel; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get MRL2 event status of specific channel + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetMRL2EventStatus(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->GCR_EM2R & (1U << u8Channel)) >> u8Channel; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get TDL1 event status of specific channel + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetTDL1eventStatus(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->GCR_ET1R & (1U << u8Channel)) >> u8Channel; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get TDL2 event status of specific channel + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetTDL2eventStatus(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->GCR_ET2R & (1U << u8Channel)) >> u8Channel; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get HAS status of specific channel + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetHSRStatus(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->GCR_VHSR & (1U << u8Channel)) >> u8Channel; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get Filter Grade + * + */ +LOCAL_INLINE TPUE_FilterGradeType TPU_E_HWA_GetFilterGrade(const TPU_E_Type *const pTPUE) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->GCR_AFGR & TPU_E_GCR_AFGR_FLT_GRD_MASK) >> TPU_E_GCR_AFGR_FLT_GRD_SHIFT; + return (TPUE_FilterGradeType)u32TmpVal; +} + +/** + * @brief Set Filter Grade + * + */ +LOCAL_INLINE void TPU_E_HWA_SetFilterGrade(TPU_E_Type *const pTPUE, TPUE_FilterGradeType eGrade) +{ + pTPUE->GCR_AFGR = (pTPUE->GCR_AFGR & ~TPU_E_GCR_AFGR_FLT_GRD_MASK) | TPU_E_GCR_AFGR_FLT_GRD(eGrade); +} + +/** + * @brief Get Filter Grade setting results + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetFilterGradeCFGErrFlg(const TPU_E_Type *const pTPUE) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->GCR_ASR & TPU_E_GCR_ASR_ERROR_MASK) >> TPU_E_GCR_ASR_ERROR_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Clear filter grade setting results + * + */ +LOCAL_INLINE void TPU_E_HWA_ClearFilterGradeCFGErrFlg(TPU_E_Type *const pTPUE) +{ + pTPUE->GCR_ASR = (pTPUE->GCR_ASR & ~TPU_E_GCR_ASR_ERROR_MASK) | TPU_E_GCR_ASR_ERROR(1U); +} + +/** + * @brief Get endian configuration + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetEndianCFG(const TPU_E_Type *const pTPUE) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->GCR_ASR & TPU_E_GCR_ASR_ENDIAN_MASK) >> TPU_E_GCR_ASR_ENDIAN_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Set endian configuration + * + */ +LOCAL_INLINE void TPU_E_HWA_SetEndianCFG(TPU_E_Type *const pTPUE) +{ + pTPUE->GCR_ASR = (pTPUE->GCR_ASR & ~TPU_E_GCR_ASR_ENDIAN_MASK) | TPU_E_GCR_ASR_ENDIAN(1U); +} + +/** + * @brief Get channel function entry table select + * + */ +LOCAL_INLINE uint8_t TPU_E_HWA_GetEntryFuncSel(const TPU_E_Type *const pTPUE) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->GCR_AID & TPU_E_GCR_AID_ETCS_MASK) >> TPU_E_GCR_AID_ETCS_SHIFT; + return (uint8_t)u32TmpVal; +} + +/** + * @brief Get channel function entry table condition + * + */ +LOCAL_INLINE uint8_t TPU_E_HWA_GetEntryFuncCond(const TPU_E_Type *const pTPUE) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->GCR_AID & TPU_E_GCR_AID_COND_MASK) >> TPU_E_GCR_AID_COND_SHIFT; + return (uint8_t)u32TmpVal; +} + +/** + * @brief Get channel ID info + * + */ +LOCAL_INLINE uint8_t TPU_E_HWA_GetChIDInfo(const TPU_E_Type *const pTPUE) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->GCR_AID & TPU_E_GCR_AID_ID_MASK) >> TPU_E_GCR_AID_ID_SHIFT; + return (uint8_t)u32TmpVal; +} + +/** + * @brief Get TCR1 prescaler. + * + */ +LOCAL_INLINE uint8_t TPU_E_HWA_GetTCR1Prescaler(const TPU_E_Type *const pTPUE) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->TBR_CR & TPU_E_TBR_CR_TCR1P_MASK) >> TPU_E_TBR_CR_TCR1P_SHIFT; + return (uint8_t)u32TmpVal; +} + +/** + * @brief Get TCR1 prescaler. + * + */ +LOCAL_INLINE void TPU_E_HWA_SetTCR1Prescaler(TPU_E_Type *const pTPUE, uint8_t u8Prescaler) +{ + pTPUE->TBR_CR = (pTPUE->TBR_CR & ~TPU_E_TBR_CR_TCR1P_MASK) | TPU_E_TBR_CR_TCR1P(u8Prescaler); +} + +/** + * @brief Get TCR1 clock control. + * + */ +LOCAL_INLINE TPUE_TCR1ClkCtrlModeType TPU_E_HWA_GetTCR1ClkControl(const TPU_E_Type *const pTPUE) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->TBR_CR & TPU_E_TBR_CR_TCR1CTL_MASK) >> TPU_E_TBR_CR_TCR1CTL_SHIFT; + return (TPUE_TCR1ClkCtrlModeType)u32TmpVal; +} + +/** + * @brief Set TCR1 clock control. + * + */ +LOCAL_INLINE void TPU_E_HWA_SetTCR1ClkControl(TPU_E_Type *const pTPUE, TPUE_TCR1ClkCtrlModeType eMode) +{ + pTPUE->TBR_CR = (pTPUE->TBR_CR & ~TPU_E_TBR_CR_TCR1CTL_MASK) | TPU_E_TBR_CR_TCR1CTL(eMode); +} + +/** + * @brief Get TCR2 prescaler. + * + */ +LOCAL_INLINE uint8_t TPU_E_HWA_GetTCR2Prescaler(const TPU_E_Type *const pTPUE) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->TBR_CR & TPU_E_TBR_CR_TCR2P_MASK) >> TPU_E_TBR_CR_TCR2P_SHIFT; + return (uint8_t)u32TmpVal; +} + +/** + * @brief Set TCR2 prescaler. + * + */ +LOCAL_INLINE void TPU_E_HWA_SetTCR2Prescaler(TPU_E_Type *const pTPUE, uint8_t ePrescaler) +{ + pTPUE->TBR_CR = (pTPUE->TBR_CR & ~TPU_E_TBR_CR_TCR2P_MASK) | TPU_E_TBR_CR_TCR2P(ePrescaler); +} + +/** + * @brief Get Angle tick generator clock. + * + */ +LOCAL_INLINE TPUE_AngleTickGenClkType TPU_E_HWA_GetATGC(const TPU_E_Type *const pTPUE) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->TBR_CR & TPU_E_TBR_CR_ATGC_MASK) >> TPU_E_TBR_CR_ATGC_SHIFT; + return (TPUE_AngleTickGenClkType)u32TmpVal; +} + +/** + * @brief Set Angle tick generator clock. + * + */ +LOCAL_INLINE void TPU_E_HWA_SetATGC(TPU_E_Type *const pTPUE, TPUE_AngleTickGenClkType eSrc) +{ + pTPUE->TBR_CR = (pTPUE->TBR_CR & ~TPU_E_TBR_CR_ATGC_MASK) | TPU_E_TBR_CR_ATGC(eSrc); +} + +/** + * @brief Get Angle Mode Selection. + * + */ +LOCAL_INLINE TPUE_AngleModeSel TPU_E_HWA_GetAM(const TPU_E_Type *const pTPUE) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->TBR_CR & TPU_E_TBR_CR_AM_MASK) >> TPU_E_TBR_CR_AM_SHIFT; + return (TPUE_AngleModeSel)u32TmpVal; +} + +/** + * @brief Set Angle Mode Selection. + * + */ +LOCAL_INLINE void TPU_E_HWA_SetAM(TPU_E_Type *const pTPUE, TPUE_AngleModeSel eMode) +{ + pTPUE->TBR_CR = (pTPUE->TBR_CR & ~TPU_E_TBR_CR_AM_MASK) | TPU_E_TBR_CR_AM(eMode); +} + +/** + * @brief Get TCRCLK signal Filter Control. + * + */ +LOCAL_INLINE TPUE_TCRClkFilterType TPU_E_HWA_GetTCRClkFilter(const TPU_E_Type *const pTPUE) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->TBR_CR & TPU_E_TBR_CR_TCRCF_MASK) >> TPU_E_TBR_CR_TCRCF_SHIFT; + return (TPUE_TCRClkFilterType)u32TmpVal; +} + +/** + * @brief Set TCRCLK signal Filter Control. + * + */ +LOCAL_INLINE void TPU_E_HWA_SetTCRClkFilter(TPU_E_Type *const pTPUE, TPUE_TCRClkFilterType eMode) +{ + pTPUE->TBR_CR = (pTPUE->TBR_CR & ~TPU_E_TBR_CR_TCRCF_MASK) | TPU_E_TBR_CR_TCRCF(eMode); +} + +/** + * @brief Get TCR2 clock control. + * + */ +LOCAL_INLINE TPUE_TCR1ClkCtrlMode0Type TPU_E_HWA_GetTCR2ClkControlAM0(const TPU_E_Type *const pTPUE) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->TBR_CR & TPU_E_TBR_CR_TCR2CTL_MASK) >> TPU_E_TBR_CR_TCR2CTL_SHIFT; + return (TPUE_TCR1ClkCtrlMode0Type)u32TmpVal; +} + +/** + * @brief Get TCR2 clock control. + * + */ +LOCAL_INLINE TPUE_TCR1ClkCtrlMode1Type TPU_E_HWA_GetTCR2ClkControlAM1(const TPU_E_Type *const pTPUE) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->TBR_CR & TPU_E_TBR_CR_TCR2CTL_MASK) >> TPU_E_TBR_CR_TCR2CTL_SHIFT; + return (TPUE_TCR1ClkCtrlMode1Type)u32TmpVal; +} + +/** + * @brief Set TCR2 clock control. + * + */ +LOCAL_INLINE void TPU_E_HWA_SetTCR2ClkControlAM1(TPU_E_Type *const pTPUE, TPUE_TCR1ClkCtrlMode1Type eMode) +{ + pTPUE->TBR_CR = (pTPUE->TBR_CR & ~TPU_E_TBR_CR_TCR2CTL_MASK) | TPU_E_TBR_CR_TCR2CTL(eMode); +} + +/** + * @brief Get TCR1 cnt value. + * + */ +LOCAL_INLINE uint32_t TPU_E_HWA_GetTCR1CntVal(const TPU_E_Type *const pTPUE) +{ + return pTPUE->TBR_T1R; +} + +/** + * @brief Get TCR2 cnt value. + * + */ +LOCAL_INLINE uint32_t TPU_E_HWA_GetTCR2CntVal(const TPU_E_Type *const pTPUE) +{ + return pTPUE->TBR_T2R; +} + +/** + * @brief Get last tooth indication. + * + */ +LOCAL_INLINE bool TPU_E_HWA_NotLastTooth(const TPU_E_Type *const pTPUE) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->TBR_TPR & TPU_E_TBR_TPR_LAST_MASK) >> TPU_E_TBR_TPR_LAST_SHIFT; + return (bool)((u32TmpVal == 0U) ? true : false); +} + +/** + * @brief Set last tooth indication. + * + */ +LOCAL_INLINE void TPU_E_HWA_SetLastTooth(TPU_E_Type *const pTPUE, bool bEnable) +{ + pTPUE->TBR_TPR = (pTPUE->TBR_TPR & ~TPU_E_TBR_TPR_LAST_MASK) | TPU_E_TBR_TPR_LAST(bEnable); +} + +/** + * @brief Get missing tooth counter. + * + */ +LOCAL_INLINE TPUE_MissToothCntType TPU_E_HWA_GetMissingTooth(const TPU_E_Type *const pTPUE) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->TBR_TPR & TPU_E_TBR_TPR_MISSCNT_MASK) >> TPU_E_TBR_TPR_MISSCNT_SHIFT; + return (TPUE_MissToothCntType)u32TmpVal; +} + +/** + * @brief Set missing tooth counter. + * + */ +LOCAL_INLINE void TPU_E_HWA_SetMissingTooth(TPU_E_Type *const pTPUE, TPUE_MissToothCntType eCnt) +{ + pTPUE->TBR_TPR = (pTPUE->TBR_TPR & ~TPU_E_TBR_TPR_MISSCNT_MASK) | TPU_E_TBR_TPR_MISSCNT(eCnt); +} + +/** + * @brief Get last tooth indication. + * + */ +LOCAL_INLINE bool TPU_E_HWA_NoInsertTooth(const TPU_E_Type *const pTPUE) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->TBR_TPR & TPU_E_TBR_TPR_IPH_MASK) >> TPU_E_TBR_TPR_IPH_SHIFT; + return (bool)((u32TmpVal == 0U) ? true : false); +} + +/** + * @brief Set last tooth indication to exit halt mode. + * + */ +LOCAL_INLINE void TPU_E_HWA_InsertPhyTooth(TPU_E_Type *const pTPUE) +{ + pTPUE->TBR_TPR = (pTPUE->TBR_TPR & ~TPU_E_TBR_TPR_IPH_MASK) | TPU_E_TBR_TPR_IPH(1U); +} + +/** + * @brief Get last tooth indication. + * + */ +LOCAL_INLINE bool TPU_E_HWA_NoForceEACHalt(const TPU_E_Type *const pTPUE) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->TBR_TPR & TPU_E_TBR_TPR_HOLD_MASK) >> TPU_E_TBR_TPR_HOLD_SHIFT; + return (bool)((u32TmpVal == 0U) ? true : false); +} + +/** + * @brief Get last tooth indication. + * + */ +LOCAL_INLINE void TPU_E_HWA_HaltEAC(TPU_E_Type *const pTPUE) +{ + pTPUE->TBR_TPR = (pTPUE->TBR_TPR & ~TPU_E_TBR_TPR_HOLD_MASK) | TPU_E_TBR_TPR_HOLD(1U); +} + +/** + * @brief Get angle ticks number. + * + */ +LOCAL_INLINE uint16_t TPU_E_HWA_GetAngleTicksVal(const TPU_E_Type *const pTPUE) +{ + return (uint16_t)(pTPUE->TBR_TPR & TPU_E_TBR_TPR_TICKS_MASK) >> TPU_E_TBR_TPR_TICKS_SHIFT; +} + +/** + * @brief Get angle ticks number. + * + */ +LOCAL_INLINE void TPU_E_HWA_SetAngleTicksVal(TPU_E_Type *const pTPUE, uint16_t u16Tick) +{ + pTPUE->TBR_TPR = (pTPUE->TBR_TPR & ~TPU_E_TBR_TPR_TICKS_MASK) | TPU_E_TBR_TPR_TICKS(u16Tick); +} + +/** + * @brief Get the integer part of TCR1 clocks in one Angle tick. + * + */ +LOCAL_INLINE uint32_t TPU_E_HWA_GetIntergerPerAngleTick(const TPU_E_Type *const pTPUE) +{ + return (pTPUE->TBR_TRR & TPU_E_TBR_TRR_INTEGER_MASK) >> TPU_E_TBR_TRR_INTEGER_SHIFT; +} + +/** + * @brief Set the integer part of TCR1 clocks in one Angle tick. + * + */ +LOCAL_INLINE void TPU_E_HWA_SetIntergerPerAngleTick(TPU_E_Type *const pTPUE, uint16_t u16Integer) +{ + pTPUE->TBR_TRR = (pTPUE->TBR_TRR & ~TPU_E_TBR_TRR_INTEGER_MASK) | TPU_E_TBR_TRR_INTEGER(u16Integer); +} + +/** + * @brief Get the fraction part of TCR1 clocks in one Angle tick. + * + */ +LOCAL_INLINE uint32_t TPU_E_HWA_GetFractionPerAngleTick(const TPU_E_Type *const pTPUE) +{ + return (pTPUE->TBR_TRR & TPU_E_TBR_TRR_FRACTION_MASK) >> TPU_E_TBR_TRR_FRACTION_SHIFT; +} + +/** + * @brief Set the fraction part of TCR1 clocks in one Angle tick. + * + */ +LOCAL_INLINE void TPU_E_HWA_SetFractionPerAngleTick(TPU_E_Type *const pTPUE, uint16_t u16Fraction) +{ + pTPUE->TBR_TRR = (pTPUE->TBR_TRR & ~TPU_E_TBR_TRR_FRACTION_MASK) | TPU_E_TBR_TRR_FRACTION(u16Fraction); +} + +/** + * @brief Get TCR1 overflow flag. + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetTCR1Overflow(const TPU_E_Type *const pTPUE) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->TBR_T1MR & TPU_E_TBR_T1MR_OVF_MASK) >> TPU_E_TBR_T1MR_OVF_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Clear TCR1 overflow flag. + * + */ +LOCAL_INLINE void TPU_E_HWA_ClearTCR1Overflow(TPU_E_Type *const pTPUE) +{ + pTPUE->TBR_T1MR = (pTPUE->TBR_T1MR | TPU_E_TBR_T1MR_OVF_MASK); +} + +/** + * @brief Get TCR1 IRQ enable flag. + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetTCR1OVFIRQEn(const TPU_E_Type *const pTPUE) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->TBR_T1MR & TPU_E_TBR_T1MR_IRQ_EN_MASK) >> TPU_E_TBR_T1MR_IRQ_EN_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get TCR1 IRQ enable flag. + * + */ +LOCAL_INLINE void TPU_E_HWA_EnableTCR1OVFIRQ(TPU_E_Type *const pTPUE, bool bEn) +{ + pTPUE->TBR_T1MR = (pTPUE->TBR_T1MR & ~TPU_E_TBR_T1MR_IRQ_EN_MASK) | TPU_E_TBR_T1MR_IRQ_EN(bEn); +} + +/** + * @brief Get the maximum value of TCR1 counter in TCR1 updown mode. + * + */ +LOCAL_INLINE uint32_t TPU_E_HWA_GetTCR1MaxCnt(const TPU_E_Type *const pTPUE) +{ + return (pTPUE->TBR_T1MR & TPU_E_TBR_T1MR_MAX_MASK) >> TPU_E_TBR_T1MR_MAX_SHIFT; +} + +/** + * @brief Get the maximum value of TCR1 counter in TCR1 updown mode. + * + */ +LOCAL_INLINE void TPU_E_HWA_SetTCR1MaxCnt(TPU_E_Type *const pTPUE, uint32_t u32MaxCnt) +{ + pTPUE->TBR_T1MR = (pTPUE->TBR_T1MR & ~TPU_E_TBR_T1MR_MAX_MASK) | TPU_E_TBR_T1MR_MAX(u32MaxCnt); +} + +/** + * @brief Get TCR2 overflow flag. + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetTCR2Overflow(const TPU_E_Type *const pTPUE) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->TBR_T2MR & TPU_E_TBR_T2MR_OVF_MASK) >> TPU_E_TBR_T2MR_OVF_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Clear TCR2 overflow flag. + * + */ +LOCAL_INLINE void TPU_E_HWA_ClearTCR2Overflow(TPU_E_Type *const pTPUE) +{ + pTPUE->TBR_T2MR = (pTPUE->TBR_T2MR | TPU_E_TBR_T2MR_OVF_MASK); +} + +/** + * @brief Get TCR2 IRQ enable flag. + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetTCR2OVFIRQEnable(const TPU_E_Type *const pTPUE) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->TBR_T2MR & TPU_E_TBR_T2MR_IRQ_EN_MASK) >> TPU_E_TBR_T2MR_IRQ_EN_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Enable TCR2 IRQ enable flag. + * + */ +LOCAL_INLINE void TPU_E_HWA_EnableTCR2OVFIRQ(TPU_E_Type *const pTPUE, bool bEn) +{ + pTPUE->TBR_T2MR = (pTPUE->TBR_T2MR & ~TPU_E_TBR_T2MR_IRQ_EN_MASK) | TPU_E_TBR_T2MR_IRQ_EN(bEn); +} + +/** + * @brief Get the maximum value of TCR2 counter in TCR1 updown mode. + * + */ +LOCAL_INLINE uint32_t TPU_E_HWA_GetTCR2MaxCnt(const TPU_E_Type *const pTPUE) +{ + return (pTPUE->TBR_T2MR & TPU_E_TBR_T2MR_MAX_MASK) >> TPU_E_TBR_T2MR_MAX_SHIFT; +} + +/** + * @brief Set the maximum value of TCR2 counter in TCR2 updown mode. + * + */ +LOCAL_INLINE void TPU_E_HWA_SetTCR2MaxCnt(TPU_E_Type *const pTPUE, uint32_t u32MaxCnt) +{ + pTPUE->TBR_T2MR = (pTPUE->TBR_T2MR & ~TPU_E_TBR_T2MR_MAX_MASK) | TPU_E_TBR_T2MR_MAX(u32MaxCnt); +} + +/** + * @brief Get channel event triggered interrupt enable flag. + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetChEventIntEnable(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->CH[u8Channel].CR & TPU_E_CHn_CR_CIE_MASK) >> TPU_E_CHn_CR_CIE_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Enable channel event triggered interrupt. + * + */ +LOCAL_INLINE void TPU_E_HWA_EnableChEventInt(TPU_E_Type *const pTPUE, uint8_t u8Channel, bool bEn) +{ + pTPUE->CH[u8Channel].CR = (pTPUE->CH[u8Channel].CR & ~TPU_E_CHn_CR_CIE_MASK) | TPU_E_CHn_CR_CIE(bEn); +} + +/** + * @brief Get channel event triggered interrupt priority. + * + */ +LOCAL_INLINE TPUE_EventIntPriorityType TPU_E_HWA_GetChEventIntPriority(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->CH[u8Channel].CR & TPU_E_CHn_CR_CPR_MASK) >> TPU_E_CHn_CR_CPR_SHIFT; + return (TPUE_EventIntPriorityType)u32TmpVal; +} + +/** + * @brief Set channel event triggered interrupt priority. + * + */ +LOCAL_INLINE void TPU_E_HWA_SetChEventIntPriority(TPU_E_Type *const pTPUE, uint8_t u8Channel, TPUE_EventIntPriorityType ePriority) +{ + pTPUE->CH[u8Channel].CR = (pTPUE->CH[u8Channel].CR & ~TPU_E_CHn_CR_CPR_MASK) | TPU_E_CHn_CR_CPR(ePriority); +} + +/** + * @brief Get channel Filter Bypass + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetChFilterBypassEnable(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->CH[u8Channel].CR & TPU_E_CHn_CR_CFB_MASK) >> TPU_E_CHn_CR_CFB_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Set channel Filter Bypass + * + */ +LOCAL_INLINE void TPU_E_HWA_OpenChFilter(TPU_E_Type *const pTPUE, uint8_t u8Channel, bool bEn) +{ + pTPUE->CH[u8Channel].CR = (pTPUE->CH[u8Channel].CR & ~TPU_E_CHn_CR_CFB_MASK) | TPU_E_CHn_CR_CFB(bEn); +} + +/** + * @brief Get channel entry function + * + */ +LOCAL_INLINE uint8_t TPU_E_HWA_GetChEntryFunc(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->CH[u8Channel].CR & TPU_E_CHn_CR_CFS_MASK) >> TPU_E_CHn_CR_CFS_SHIFT; + return (uint8_t)u32TmpVal; +} + +/** + * @brief Set channel entry function + * + */ +LOCAL_INLINE void TPU_E_HWA_SetChEntryFunc(TPU_E_Type *const pTPUE, uint8_t u8Channel, uint8_t u8EntryFunc) +{ + pTPUE->CH[u8Channel].CR = (pTPUE->CH[u8Channel].CR & ~TPU_E_CHn_CR_CFS_MASK) | TPU_E_CHn_CR_CFS(u8EntryFunc); +} + +/** + * @brief Get channel entry table pin direction + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetChEntryTblPinDirOutput(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->CH[u8Channel].CR & TPU_E_CHn_CR_ETPD_MASK) >> TPU_E_CHn_CR_ETPD_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Set channel entry table pin direction + * + */ +LOCAL_INLINE void TPU_E_HWA_SetChEntryTblPinDirOutput(TPU_E_Type *const pTPUE, uint8_t u8Channel, bool bEn) +{ + pTPUE->CH[u8Channel].CR = (pTPUE->CH[u8Channel].CR & ~TPU_E_CHn_CR_ETPD_MASK) | TPU_E_CHn_CR_ETPD(bEn); +} + +/** + * @brief Get channel entry table condition select + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetChEntryTblCondSelAlt(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->CH[u8Channel].CR & TPU_E_CHn_CR_ECTS_MASK) >> TPU_E_CHn_CR_ECTS_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Set channel entry table condition select + * + */ +LOCAL_INLINE void TPU_E_HWA_SetChEntryTblCondSelAlt(TPU_E_Type *const pTPUE, uint8_t u8Channel, bool bEn) +{ + pTPUE->CH[u8Channel].CR = (pTPUE->CH[u8Channel].CR & ~TPU_E_CHn_CR_ECTS_MASK) | TPU_E_CHn_CR_ECTS(bEn); +} + +/** + * @brief Get channel entry table flag1 + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetChEntryTblflag1(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->CH[u8Channel].CR & TPU_E_CHn_CR_FLG1_MASK) >> TPU_E_CHn_CR_FLG1_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Set channel entry table flag1 + * + */ +LOCAL_INLINE void TPU_E_HWA_SetChEntryTblflag1(TPU_E_Type *const pTPUE, uint8_t u8Channel, bool bEn) +{ + pTPUE->CH[u8Channel].CR = (pTPUE->CH[u8Channel].CR & ~TPU_E_CHn_CR_FLG1_MASK) | TPU_E_CHn_CR_FLG1(bEn); +} + +/** + * @brief Get channel entry table flag0 + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetChEntryTblflag0(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->CH[u8Channel].CR & TPU_E_CHn_CR_FLG0_MASK) >> TPU_E_CHn_CR_FLG0_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Set channel entry table flag0 + * + */ +LOCAL_INLINE void TPU_E_HWA_SetChEntryTblflag0(TPU_E_Type *const pTPUE, uint8_t u8Channel, bool bEn) +{ + pTPUE->CH[u8Channel].CR = (pTPUE->CH[u8Channel].CR & ~TPU_E_CHn_CR_FLG0_MASK) | TPU_E_CHn_CR_FLG0(bEn); +} + +/** + * @brief Get channel output polarity + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetChOutputHigh(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->CH[u8Channel].CR & TPU_E_CHn_CR_OPOL_MASK) >> TPU_E_CHn_CR_OPOL_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Set channel output polarity + * + */ +LOCAL_INLINE void TPU_E_HWA_SetChOutputActiveHigh(TPU_E_Type *const pTPUE, uint8_t u8Channel, bool bEn) +{ + pTPUE->CH[u8Channel].CR = (pTPUE->CH[u8Channel].CR & ~TPU_E_CHn_CR_OPOL_MASK) | TPU_E_CHn_CR_OPOL(bEn); +} + +/** + * @brief Get channel output disable + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetChOutputDisable(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->CH[u8Channel].CR & TPU_E_CHn_CR_ODIS_MASK) >> TPU_E_CHn_CR_ODIS_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Set channel output disable + * + */ +LOCAL_INLINE void TPU_E_HWA_SetChOutputDisable(TPU_E_Type *const pTPUE, uint8_t u8Channel, bool bEn) +{ + pTPUE->CH[u8Channel].CR = (pTPUE->CH[u8Channel].CR & ~TPU_E_CHn_CR_ODIS_MASK) | TPU_E_CHn_CR_ODIS(bEn); +} + +/** + * @brief Get channel HSA index. + * + */ +LOCAL_INLINE uint8_t TPU_E_HWA_GetChHSAIdx(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->CH[u8Channel].CR & TPU_E_CHn_CR_CHSA_MASK) >> TPU_E_CHn_CR_CHSA_SHIFT; + return (uint8_t)u32TmpVal; +} + +/** + * @brief Set channel HSA index. + * + */ +LOCAL_INLINE void TPU_E_HWA_SetChHSAIdx(TPU_E_Type *const pTPUE, uint8_t u8Channel, uint8_t u8HSAIdx) +{ + pTPUE->CH[u8Channel].CR = ((pTPUE->CH[u8Channel].CR & ~TPU_E_CHn_CR_CHSA_MASK) | TPU_E_CHn_CR_CHSA(u8HSAIdx)); +} + +/** + * @brief Get channel event trigger interrupt status. + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetChEventTrigISRStatus(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->CH[u8Channel].SR & TPU_E_CHn_SR_CIS_MASK) >> TPU_E_CHn_SR_CIS_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get channel host service request (HSR) status. + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetChHSRStatus(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->CH[u8Channel].SR & TPU_E_CHn_SR_CHRS_MASK) >> TPU_E_CHn_SR_CHRS_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get Channel HSR Info & Index . + * + */ +LOCAL_INLINE uint8_t TPU_E_HWA_GetChHSRIdx(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->CH[u8Channel].SR & TPU_E_CHn_SR_CHRI_MASK) >> TPU_E_CHn_SR_CHRI_SHIFT; + return (uint8_t)u32TmpVal; +} + +/** + * @brief Get channel event as interrupt status. + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetChEventReqISRStatus(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->CH[u8Channel].SR & TPU_E_CHn_SR_CEIS_MASK) >> TPU_E_CHn_SR_CEIS_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get channel event as interrupt status. + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetChDMAReq(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->CH[u8Channel].SR & TPU_E_CHn_SR_CHDS_MASK) >> TPU_E_CHn_SR_CHDS_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get channel trigger status. + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetChTrigStatus(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->CH[u8Channel].SR & TPU_E_CHn_SR_CTS_MASK) >> TPU_E_CHn_SR_CTS_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get channel host service acknowledge (HSA) interrupt status. + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetChHSAReqStatus(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->CH[u8Channel].SR & TPU_E_CHn_SR_CHAS_MASK) >> TPU_E_CHn_SR_CHAS_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Clear channel interrupt by event. + * + */ +LOCAL_INLINE void TPU_E_HWA_ClearChEventISRFlg(TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + pTPUE->CH[u8Channel].SCR = TPU_E_CHn_SCR_CISC_MASK; +} + +/** + * @brief Clear channel HSA Dma. + * + */ +LOCAL_INLINE void TPU_E_HWA_ChReqDMA(TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + pTPUE->CH[u8Channel].SCR = TPU_E_CHn_SCR_CHDT_MASK; +} + +/** + * @brief Clear channel HSA. + * + */ +LOCAL_INLINE void TPU_E_HWA_ClearChHSAISR(TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + pTPUE->CH[u8Channel].SCR = TPU_E_CHn_SCR_CHAT_MASK; +} + +/** + * @brief Clear channel HSR. + * + */ +LOCAL_INLINE void TPU_E_HWA_ClearChHSR(TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + pTPUE->CH[u8Channel].SCR = TPU_E_CHn_SCR_CHRC_MASK; +} + +/** + * @brief Get channel service request. + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetChServiceReq(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->CH[u8Channel].EFR & TPU_E_CHn_EFR_CSR_MASK) >> TPU_E_CHn_EFR_CSR_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get channel service request to HOST. + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetChServiceReqToHost(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->CH[u8Channel].EFR & TPU_E_CHn_EFR_CHSR_MASK) >> TPU_E_CHn_EFR_CHSR_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get match recognition latch 1 event status. + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetChMatchRecLatch1Event(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->CH[u8Channel].EFR & TPU_E_CHn_EFR_EMRL1_MASK) >> TPU_E_CHn_EFR_EMRL1_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get match recognition latch 2 event status. + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetChMatchRecLatch2Event(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->CH[u8Channel].EFR & TPU_E_CHn_EFR_EMRL2_MASK) >> TPU_E_CHn_EFR_EMRL2_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get transition detect latch 1 event status. + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetChTransDetectLatch1Event(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->CH[u8Channel].EFR & TPU_E_CHn_EFR_ETDL1_MASK) >> TPU_E_CHn_EFR_ETDL1_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get transition detect latch 2 event status. + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetChTransDetectLatch2Event(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->CH[u8Channel].EFR & TPU_E_CHn_EFR_ETDL2_MASK) >> TPU_E_CHn_EFR_ETDL2_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get match recognition latch 1 enable status. + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetChMatchRecLatch1En(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->CH[u8Channel].EFR & TPU_E_CHn_EFR_MRLE1_MASK) >> TPU_E_CHn_EFR_MRLE1_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get match recognition latch 2 enable status. + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetChMatchRecLatch2En(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->CH[u8Channel].EFR & TPU_E_CHn_EFR_MRLE2_MASK) >> TPU_E_CHn_EFR_MRLE2_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get match recognition latch 1 enable status. + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetChMatchRecLatch1Status(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->CH[u8Channel].EFR & TPU_E_CHn_EFR_MRL1_MASK) >> TPU_E_CHn_EFR_MRL1_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get match recognition latch 2 enable status. + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetChMatchRecLatch2Status(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->CH[u8Channel].EFR & TPU_E_CHn_EFR_MRL2_MASK) >> TPU_E_CHn_EFR_MRL2_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get Transition Detect latch 1 enable status. + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetChTransDetectLatch1Status(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->CH[u8Channel].EFR & TPU_E_CHn_EFR_TDL1_MASK) >> TPU_E_CHn_EFR_TDL1_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get Transition Detect latch 2 enable status. + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetChTransDetectLatch2Status(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->CH[u8Channel].EFR & TPU_E_CHn_EFR_TDL2_MASK) >> TPU_E_CHn_EFR_TDL2_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get comparator selection for time base selection. + * + */ +LOCAL_INLINE TPUE_TimeBaseSelctionType TPU_E_HWA_GetChTBS1(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->CH[u8Channel].CR2 & TPU_E_CHn_CR2_TBS1_MASK) >> TPU_E_CHn_CR2_TBS1_SHIFT; + return (TPUE_TimeBaseSelctionType)u32TmpVal; +} + +/** + * @brief Set comparator selection for time base selection. + * + */ +LOCAL_INLINE void TPU_E_HWA_SetChTBS1(TPU_E_Type *const pTPUE, uint8_t u8Channel, TPUE_TimeBaseSelctionType eType) +{ + pTPUE->CH[u8Channel].CR2 = (pTPUE->CH[u8Channel].CR2 & ~TPU_E_CHn_CR2_TBS1_MASK) | TPU_E_CHn_CR2_TBS1(eType); +} + +/** + * @brief Get pin state input. + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetChPinStateInputHigh(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->CH[u8Channel].CR2 & TPU_E_CHn_CR2_PSTI_MASK) >> TPU_E_CHn_CR2_PSTI_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get pin state output. + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetChPinStateOutputHigh(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->CH[u8Channel].CR2 & TPU_E_CHn_CR2_PSTO_MASK) >> TPU_E_CHn_CR2_PSTO_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get pin request service sample. + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetChPinReqSrvSample(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->CH[u8Channel].CR2 & TPU_E_CHn_CR2_PRSS_MASK) >> TPU_E_CHn_CR2_PRSS_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get Input Pin Action Control of Part 1 . + * + */ +LOCAL_INLINE TPUE_IPACType TPU_E_HWA_GetIPAC1(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->CH[u8Channel].CR2 & TPU_E_CHn_CR2_IPAC1_MASK) >> TPU_E_CHn_CR2_IPAC1_SHIFT; + return (TPUE_IPACType)u32TmpVal; +} + +/** + * @brief Set Input Pin Action Control of Part 1 . + * + */ +LOCAL_INLINE void TPU_E_HWA_SetIPAC1(TPU_E_Type *const pTPUE, uint8_t u8Channel, TPUE_IPACType eType) +{ + pTPUE->CH[u8Channel].CR2 = (pTPUE->CH[u8Channel].CR2 & ~TPU_E_CHn_CR2_IPAC1_MASK) | TPU_E_CHn_CR2_IPAC1(eType); +} + +/** + * @brief Get Output Buffer Enable. + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetChOutputBufEn(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->CH[u8Channel].CR2 & TPU_E_CHn_CR2_OBE_MASK) >> TPU_E_CHn_CR2_OBE_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get Output Buffer Enable. + * + */ +LOCAL_INLINE void TPU_E_HWA_EnableChOutputBuf(TPU_E_Type *const pTPUE, uint8_t u8Channel, bool bEnable) +{ + pTPUE->CH[u8Channel].CR2 = (pTPUE->CH[u8Channel].CR2 & ~TPU_E_CHn_CR2_OBE_MASK) | TPU_E_CHn_CR2_OBE(bEnable); +} + +/** + * @brief Get Output Pin Action Control of Part 1. + * + */ +LOCAL_INLINE TPUE_OPACType TPU_E_HWA_GetOPAC1(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->CH[u8Channel].CR2 & TPU_E_CHn_CR2_OPAC1_MASK) >> TPU_E_CHn_CR2_OPAC1_SHIFT; + return (TPUE_OPACType)u32TmpVal; +} + +/** + * @brief Set Input Pin Action Control of Part 2 . + * + */ +LOCAL_INLINE void TPU_E_HWA_SetOPAC1(TPU_E_Type *const pTPUE, uint8_t u8Channel, TPUE_OPACType eType) +{ + pTPUE->CH[u8Channel].CR2 = (pTPUE->CH[u8Channel].CR2 & ~TPU_E_CHn_CR2_OPAC1_MASK) | TPU_E_CHn_CR2_OPAC1(eType); +} + +/** + * @brief Get comparator selection for time base selection. + * + */ +LOCAL_INLINE TPUE_TimeBaseSelctionType TPU_E_HWA_GetChTBS2(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->CH[u8Channel].CR2 & TPU_E_CHn_CR2_TBS2_MASK) >> TPU_E_CHn_CR2_TBS2_SHIFT; + return (TPUE_TimeBaseSelctionType)u32TmpVal; +} + +/** + * @brief Set comparator selection for time base selection. + * + */ +LOCAL_INLINE void TPU_E_HWA_SetChTBS2(TPU_E_Type *const pTPUE, uint8_t u8Channel, TPUE_TimeBaseSelctionType eType) +{ + pTPUE->CH[u8Channel].CR2 = (pTPUE->CH[u8Channel].CR2 & ~TPU_E_CHn_CR2_TBS2_MASK) | TPU_E_CHn_CR2_TBS2(eType); +} + +/** + * @brief Get Input Pin Action Control of Part 2. + * + */ +LOCAL_INLINE TPUE_IPACType TPU_E_HWA_GetIPAC2(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->CH[u8Channel].CR2 & TPU_E_CHn_CR2_IPAC2_MASK) >> TPU_E_CHn_CR2_IPAC2_SHIFT; + return (TPUE_IPACType)u32TmpVal; +} + +/** + * @brief Set Input Pin Action Control of Part 2. + * + */ +LOCAL_INLINE void TPU_E_HWA_SetIPAC2(TPU_E_Type *const pTPUE, uint8_t u8Channel, TPUE_IPACType eType) +{ + pTPUE->CH[u8Channel].CR2 = (pTPUE->CH[u8Channel].CR2 & ~TPU_E_CHn_CR2_IPAC2_MASK) | TPU_E_CHn_CR2_IPAC2(eType); +} + +/** + * @brief Get Output Pin Action Control of Part 1. + * + */ +LOCAL_INLINE TPUE_OPACType TPU_E_HWA_GetOPAC2(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->CH[u8Channel].CR2 & TPU_E_CHn_CR2_OPAC2_MASK) >> TPU_E_CHn_CR2_OPAC2_SHIFT; + return (TPUE_OPACType)u32TmpVal; +} + +/** + * @brief Set Input Pin Action Control of Part 2 . + * + */ +LOCAL_INLINE void TPU_E_HWA_SetOPAC2(TPU_E_Type *const pTPUE, uint8_t u8Channel, TPUE_OPACType eType) +{ + pTPUE->CH[u8Channel].CR2 = (pTPUE->CH[u8Channel].CR2 & ~TPU_E_CHn_CR2_OPAC2_MASK) | TPU_E_CHn_CR2_OPAC2(eType); +} + +/** + * @brief Clear sevice request write enable. + * + */ +LOCAL_INLINE void TPU_E_HWA_ClearSrvReqEn(TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + pTPUE->CH[u8Channel].MR = (pTPUE->CH[u8Channel].MR | TPU_E_CHn_MR_SRIE_MASK); +} + +/** + * @brief Get service request inhibit latch. + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetSrvReqEn(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->CH[u8Channel].MR & TPU_E_CHn_MR_SRI_MASK) >> TPU_E_CHn_MR_SRI_SHIFT; + return (bool)((u32TmpVal == 0U) ? true : false); +} + +/** + * @brief Set service request inhibit latch. + * + */ +LOCAL_INLINE void TPU_E_HWA_EnableSrvReq(TPU_E_Type *const pTPUE, uint8_t u8Channel, bool bEn) +{ + if (bEn) + { + pTPUE->CH[u8Channel].MR = (pTPUE->CH[u8Channel].MR & ~TPU_E_CHn_MR_SRI_MASK) | TPU_E_CHn_MR_SRIE_MASK; + } + else + { + pTPUE->CH[u8Channel].MR = (pTPUE->CH[u8Channel].MR & TPU_E_CHn_MR_SRI_MASK) | TPU_E_CHn_MR_SRIE_MASK; + } + +} + +/** + * @brief Clear PDCM Write Enable. + * + */ +LOCAL_INLINE void TPU_E_HWA_ClearPDCMEn(TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + pTPUE->CH[u8Channel].MR = (pTPUE->CH[u8Channel].MR | TPU_E_CHn_MR_PDME_MASK); +} + +/** + * @brief Get Predefined Channel Mode. + * + */ +LOCAL_INLINE uint8_t TPU_E_HWA_GetPDCM(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->CH[u8Channel].MR & TPU_E_CHn_MR_PDCM_MASK) >> TPU_E_CHn_MR_PDCM_SHIFT; + return (uint8_t)u32TmpVal; +} + +/** + * @brief Set Predefined Channel Mode. + * + */ +LOCAL_INLINE void TPU_E_HWA_SetPDCM(TPU_E_Type *const pTPUE, uint8_t u8Channel, TPUE_PDCMEncodeType eMode) +{ + pTPUE->CH[u8Channel].MR = (pTPUE->CH[u8Channel].MR & ~TPU_E_CHn_MR_PDCM_MASK) | TPU_E_CHn_MR_PDCM(eMode) | TPU_E_CHn_MR_PDME_MASK; +} + +/** + * @brief Get transition continuous capture enable. + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetTransContinueEn(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->CH[u8Channel].MR & TPU_E_CHn_MR_TCCE_MASK) >> TPU_E_CHn_MR_TCCE_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Set Predefined Channel Mode. + * + */ +LOCAL_INLINE void TPU_E_HWA_EnableTransContinue(TPU_E_Type *const pTPUE, uint8_t u8Channel, bool bEn) +{ + pTPUE->CH[u8Channel].MR = (pTPUE->CH[u8Channel].MR & ~TPU_E_CHn_MR_TCCE_MASK) | TPU_E_CHn_MR_TCCE(bEn); +} + +/** + * @brief Clear UDCM Write Enable. + * + */ +LOCAL_INLINE void TPU_E_HWA_ClearUDCMWriteEn(TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + pTPUE->CH[u8Channel].MR = (pTPUE->CH[u8Channel].MR | TPU_E_CHn_MR_UDME_MASK); +} + +/** + * @brief Get User Defined Channel Mode. + * + */ +LOCAL_INLINE uint16_t TPU_E_HWA_GetUDCM(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->CH[u8Channel].MR & TPU_E_CHn_MR_UDCM_MASK) >> TPU_E_CHn_MR_UDCM_SHIFT; + return (uint16_t)u32TmpVal; +} + +/** + * @brief Set User Defined Channel Mode. + * + */ +LOCAL_INLINE void TPU_E_HWA_EnableUDCM(TPU_E_Type *const pTPUE, uint8_t u8Channel, uint16_t u16Mode) +{ + pTPUE->CH[u8Channel].MR = (pTPUE->CH[u8Channel].MR & ~TPU_E_CHn_MR_UDCM_MASK) | TPU_E_CHn_MR_UDCM(u16Mode) | TPU_E_CHn_MR_UDME_MASK; +} + +/** + * @brief Clear Match Configuration Enable part1. + * + */ +LOCAL_INLINE void TPU_E_HWA_ClearMatchEn1(TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + pTPUE->CH[u8Channel].ER1 = (pTPUE->CH[u8Channel].ER1 | TPU_E_CHn_ER1_ERW_MASK); +} + +/** + * @brief Get User Defined Channel Mode part1. + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetMatchEn(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->CH[u8Channel].ER1 & TPU_E_CHn_ER1_MEF_MASK) >> TPU_E_CHn_ER1_MEF_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Set User Defined Channel Mode. + * + */ +LOCAL_INLINE void TPU_E_HWA_EnableMatch(TPU_E_Type *const pTPUE, uint8_t u8Channel, bool bEn) +{ + pTPUE->CH[u8Channel].ER1 = (pTPUE->CH[u8Channel].ER1 & ~TPU_E_CHn_ER1_MEF_MASK) | TPU_E_CHn_ER1_MEF(bEn); +} + +/** + * @brief Set ER1 value for match. + * + */ +LOCAL_INLINE void TPU_E_HWA_SetMatchER1(TPU_E_Type *const pTPUE, uint8_t u8Channel, uint32_t u32ER1) +{ + uint32_t u32Temp; + u32Temp = pTPUE->CH[u8Channel].ER1 | TPU_E_CHn_ER1_ERS_MASK; + pTPUE->CH[u8Channel].ER1 = (u32Temp & ~TPU_E_CHn_ER1_ER1_MASK) | TPU_E_CHn_ER1_ER1(u32ER1) | TPU_E_CHn_ER1_ERW_MASK; +} + +/** + * @brief Set ER1 value for capture. + * + */ +LOCAL_INLINE void TPU_E_HWA_SetCaptureER1(TPU_E_Type *const pTPUE, uint8_t u8Channel, uint32_t u32ER1) +{ + uint32_t u32Temp; + u32Temp = (pTPUE->CH[u8Channel].ER1 & ~TPU_E_CHn_ER1_ERS_MASK) | TPU_E_CHn_ER1_ERS(0U); + pTPUE->CH[u8Channel].ER1 = (u32Temp & ~TPU_E_CHn_ER1_ER1_MASK) | TPU_E_CHn_ER1_ER1(u32ER1) | TPU_E_CHn_ER1_ERW_MASK; +} + +/** + * @brief Get Capture/Match Select for Value of ER1/ER2. + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetMatchSelForERx(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->CH[u8Channel].ER1 & TPU_E_CHn_ER1_ERS_MASK) >> TPU_E_CHn_ER1_ERS_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get ER1 value. + * + */ +LOCAL_INLINE uint32_t TPU_E_HWA_GetER1Val(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->CH[u8Channel].ER1 & TPU_E_CHn_ER1_ER1_MASK) >> TPU_E_CHn_ER1_ER1_SHIFT; + return u32TmpVal; +} + +/** + * @brief Get ER1 value. + * + */ +LOCAL_INLINE uint32_t TPU_E_HWA_GetCaptureER1Val(TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + pTPUE->CH[u8Channel].ER1 = (pTPUE->CH[u8Channel].ER1 & ~TPU_E_CHn_ER1_ERS_MASK) | TPU_E_CHn_ER1_ERS(0U); + u32TmpVal = (pTPUE->CH[u8Channel].ER1 & TPU_E_CHn_ER1_ER1_MASK) >> TPU_E_CHn_ER1_ER1_SHIFT; + return u32TmpVal; +} + +/** + * @brief Set ER1 value. + * + */ +LOCAL_INLINE void TPU_E_HWA_SetER1(TPU_E_Type *const pTPUE, uint8_t u8Channel, uint32_t u32ER1) +{ + pTPUE->CH[u8Channel].ER1 = (pTPUE->CH[u8Channel].ER1 & ~TPU_E_CHn_ER1_ER1_MASK) | TPU_E_CHn_ER1_ER1(u32ER1) | TPU_E_CHn_ER1_ERW_MASK; +} + +/** + * @brief Clear Match Configuration Enable part2. + * + */ +LOCAL_INLINE void TPU_E_HWA_ClearMatchEn2(TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + pTPUE->CH[u8Channel].ER2 = (pTPUE->CH[u8Channel].ER2 | TPU_E_CHn_ER2_ERW_MASK); +} + +/** + * @brief Get ER2 value. + * + */ +LOCAL_INLINE uint32_t TPU_E_HWA_GetER2Val(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->CH[u8Channel].ER2 & TPU_E_CHn_ER2_ER2_MASK) >> TPU_E_CHn_ER2_ER2_SHIFT; + return u32TmpVal; +} + +/** + * @brief Get ER2 value. + * + */ +LOCAL_INLINE uint32_t TPU_E_HWA_GetCaptureER2Val(TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + pTPUE->CH[u8Channel].ER1 = (pTPUE->CH[u8Channel].ER1 & ~TPU_E_CHn_ER1_ERS_MASK); + u32TmpVal = (pTPUE->CH[u8Channel].ER2 & TPU_E_CHn_ER2_ER2_MASK) >> TPU_E_CHn_ER2_ER2_SHIFT; + return u32TmpVal; +} + +/** + * @brief Set ER2 value. + * + */ +LOCAL_INLINE void TPU_E_HWA_SetER2(TPU_E_Type *const pTPUE, uint8_t u8Channel, uint32_t u32ER2) +{ + pTPUE->CH[u8Channel].ER2 = (pTPUE->CH[u8Channel].ER2 & ~TPU_E_CHn_ER2_ER2_MASK) | TPU_E_CHn_ER2_ER2(u32ER2) | TPU_E_CHn_ER2_ERW_MASK; +} + +/** + * @brief Clear Match1 Configuration Enable. + * + */ +LOCAL_INLINE void TPU_E_HWA_ClearMatch1CFGFlg(TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + pTPUE->CH[u8Channel].ECR = TPU_E_CHn_ECR_MRE1_CLR_MASK; +} + +/** + * @brief Clear Match1 event Enable. + * + */ +LOCAL_INLINE void TPU_E_HWA_ClearMatch1Event(TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + pTPUE->CH[u8Channel].ECR = TPU_E_CHn_ECR_MRL1_CLR_MASK; +} + +/** + * @brief Clear transition detect1 Enable. + * + */ +LOCAL_INLINE void TPU_E_HWA_ClearTransDetect1Event(TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + pTPUE->CH[u8Channel].ECR = TPU_E_CHn_ECR_TDL1_CLR_MASK; +} + +/** + * @brief Clear Match2 Configuration Enable. + * + */ +LOCAL_INLINE void TPU_E_HWA_ClearMatch2CFGFlg(TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + pTPUE->CH[u8Channel].ECR = TPU_E_CHn_ECR_MRE2_CLR_MASK; +} + +/** + * @brief Clear Match2 event Enable. + * + */ +LOCAL_INLINE void TPU_E_HWA_ClearMatch2Event(TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + pTPUE->CH[u8Channel].ECR = TPU_E_CHn_ECR_MRL2_CLR_MASK; +} + +/** + * @brief Clear transition detect2 Enable. + * + */ +LOCAL_INLINE void TPU_E_HWA_ClearTransDetect2Event(TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + pTPUE->CH[u8Channel].ECR = TPU_E_CHn_ECR_TDL2_CLR_MASK; +} + +/** + * @brief Get output user control, high or low select. + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetOutputSelHigh(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->CH[u8Channel].OCR & TPU_E_CHn_OCR_OUT_HIS_MASK) >> TPU_E_CHn_OCR_OUT_HIS_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Clear output user control. + * + */ +LOCAL_INLINE void TPU_E_HWA_SetOutputSelHigh(TPU_E_Type *const pTPUE, uint8_t u8Channel, bool bEn) +{ + pTPUE->CH[u8Channel].OCR = TPU_E_CHn_OCR_OUT_HIS(bEn); +} + +/** + * @brief Get output user control, select OPAC1. + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetOutputUsrCtrlSelOPAC1(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->CH[u8Channel].OCR & TPU_E_CHn_OCR_OUT_OP1_MASK) >> TPU_E_CHn_OCR_OUT_OP1_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Set output user control, select OPAC1. + * + */ +LOCAL_INLINE void TPU_E_HWA_SetOutputSelOPAC1(TPU_E_Type *const pTPUE, uint8_t u8Channel, bool bEn) +{ + pTPUE->CH[u8Channel].OCR = (pTPUE->CH[u8Channel].OCR & ~TPU_E_CHn_OCR_OUT_OP1_MASK) | TPU_E_CHn_OCR_OUT_OP1(bEn); +} + +/** + * @brief Get output user control, select OPAC2. + * + */ +LOCAL_INLINE bool TPU_E_HWA_GetOutputUsrCtrlSelOPAC2(const TPU_E_Type *const pTPUE, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUE->CH[u8Channel].OCR & TPU_E_CHn_OCR_OUT_OP2_MASK) >> TPU_E_CHn_OCR_OUT_OP2_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Set output user control, select OPAC2. + * + */ +LOCAL_INLINE void TPU_E_HWA_SetOutputSelOPAC2(TPU_E_Type *const pTPUE, uint8_t u8Channel, bool bEn) +{ + pTPUE->CH[u8Channel].OCR = (pTPUE->CH[u8Channel].OCR & ~TPU_E_CHn_OCR_OUT_OP2_MASK) | TPU_E_CHn_OCR_OUT_OP2(bEn); +} + +#endif /* #ifndef _HWA_TPUE_H_ */ diff --git a/MODULES/HwA_Flagchip_FC7240/Inc/HwA_tpuh.h b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_tpuh.h new file mode 100644 index 0000000..d23a900 --- /dev/null +++ b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_tpuh.h @@ -0,0 +1,902 @@ +/** + * @file HwA_tpuh.h + * @author Flagchip + * @brief FC7xxx TPUH hardware access layer + * @version 0.1.0 + * @date 2024-1-12 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + * @details + */ + +#ifndef _HWA_TPUH_H_ +#define _HWA_TPUH_H_ + +#include "device_header.h" +#if 1 +/********* Local typedef ************/ +/** @brief TPU TCR1 clock control mode type */ +typedef enum +{ + TPUH_CLK_SRC_TCRCLK = 0U, + UTPUH_PDOWN_CNT_MODE = 3U, + TPUH_CLK_SRC_TPUCLKDIV2 = 4U, + TPUH_CLK_SRC_TPUCLK = 5U +} TPUH_TCR1ClkCtrlModeType; + +/** @brief TPU angle tick gen clk type */ +typedef enum +{ + TPUH_TCR1_PRESCAL_OUTPUT = 0U, + TPUH_TCR2_PRESCAL_OUTPUT = 1U +} TPUH_AngleTickGenClkType; + +/** @brief TPU Angle Mode Selection type */ +typedef enum +{ + TPUH_TCR2_TIMEBASE_EAC_DISABLE = 0U, + TPUH_TOOTHSIGNAL_AS_TCRCLK_TOOTH_CH_0 = 1U, + TPUH_TOOTHSIGNAL_AS_CH1INPUT_TOOTH_CH_1 = 2U, + TPUH_TOOTHSIGNAL_AS_CH2INPUT_TOOTH_CH_2 = 3U +} TPUH_AngleModeSel; + +/** @brief TPU Angle Mode Selection type */ +typedef enum +{ + TPUH_TWO_SAMPLE_MODE_TPU_CLK_DIV2 = 0U, + TPUH_TWO_SAMPLE_MODE_CH_CLK = 1U, + TPUH_INTEGRATOR_MODE_TPU_CLK_DIV2 = 2U, + TPUH_INTEGRATOR_MODE_CH_CLK = 3U +} TPUH_TCRClkFilterType; + +/** @brief TPU TCR2 clock control mode0 type */ +typedef enum +{ + TPUH_GATED_DIV8_CLK = 0U, + TPUH_RISE_TRANSITION_INCREMENT_TCR2_PRESCALER = 1U, + TPUH_FALL_TRANSITION_INCREMENT_TCR2_PRESCALER = 2U, + TPUH_DIV8_CLK = 4U, + TPUH_UPDOWN_CNT_MODE = 5U, + TPUH_FROZEN = 7U +} TPUH_TCR1ClkCtrlMode0Type; + +typedef enum +{ + TPUH_RSING_EDGE = 1U, + TPUH_FALLING_EDGE = 2U, + TPUH_BOTH_EDGES = 3U, + TPUH_NO_EDGE = 6U, +} TPUH_TCR1ClkCtrlMode1Type; + +/** @brief Missing Tooth Counter */ +typedef enum +{ + TPUH_NOT_A_MISSING_TOOTH = 0U, + TPUH_ONE_MISSING_TOOTH = 1U, + TPUH_TWO_MISSING_TOOTH = 2U, + TPUH_THREE_MISSING_TOOTH = 3U, +} TPUH_MissToothCntType; + +/** @brief Channel Trigger Configuration */ +typedef enum +{ + TPUH_DISABLED = 0U, + TPUH_ANY_EVENT_GATED_BY_MSRTSR = 2U, + TPUH_HSA_EVENT_ON_FLEXCORE_MODE = 3U, + TPUH_MRL1_EVENT_NOT_GATED_BY_MSR = 4U, + TPUH_MRL2_EVENT_NOT_GATED_BY_MSR = 5U, + TPUH_MRL1_OR_MRL2_EVENT_NOT_GATED_BY_MSR = 6U, + TPUH_MRL1_AND_MRL2_EVENT_NOT_GATED_BY_MSR = 7U, + TPUH_TDL1_OR_TDL2_EVENT_NOT_GATED_BY_TSR = 8U, + TPUH_TDL1_AND_TDL2_EVENT_NOT_GATED_BY_TSR = 9U, + TPUH_EVENT_EQUAL_TO_CH_DO_LEVEL = 10U, + TPUH_EVENT_NEGATIVE_TO_CH_DO_LEVEL = 11U, + TPUH_EVENT_EQUAL_TO_CH_DO_PART1_LEVEL = 12U, + TPUH_EVENT_EQUAL_TO_CH_DO_PART2_LEVEL = 13U, + TPUH_EVENT_EQUAL_TO_CH_IND_LEVEL = 14U, + TPUH_EVENT_EQUAL_TO_CH_IND_LATCH_LEVEL = 15U, +} TPUH_ChTrigCFGType; +#endif +/********* Local inline function ************/ +/** + * @brief Get service request status of specific channel + * + */ +LOCAL_INLINE bool TPU_H_HWA_GetSRStatus(const TPU_H_Type *const pTPUH, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUH->GCR_VSR & (1U << u8Channel)) >> u8Channel; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get pin input status of specific channel + * + */ +LOCAL_INLINE bool TPU_H_HWA_GetInputStatus(const TPU_H_Type *const pTPUH, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUH->GCR_VIR & (1U << u8Channel)) >> u8Channel; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get pin output status of specific channel + * + */ +LOCAL_INLINE bool TPU_H_HWA_GetoutputStatus(const TPU_H_Type *const pTPUH, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUH->GCR_VOR & (1U << u8Channel)) >> u8Channel; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get pin output enable status of specific channel + * + */ +LOCAL_INLINE bool TPU_H_HWA_GetoutputEnStatus(const TPU_H_Type *const pTPUH, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUH->GCR_VOBR & (1U << u8Channel)) >> u8Channel; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get MRL1 status of specific channel + * + */ +LOCAL_INLINE bool TPU_H_HWA_GetMRL1Status(const TPU_H_Type *const pTPUH, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUH->GCR_VM1R & (1U << u8Channel)) >> u8Channel; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get MRL2 status of specific channel + * + */ +LOCAL_INLINE bool TPU_H_HWA_GetMRL2Status(const TPU_H_Type *const pTPUH, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUH->GCR_VM2R & (1U << u8Channel)) >> u8Channel; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get TDL1 status of specific channel + * + */ +LOCAL_INLINE bool TPU_H_HWA_GetTDL1Status(const TPU_H_Type *const pTPUH, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUH->GCR_VT1R & (1U << u8Channel)) >> u8Channel; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get TDL2 status of specific channel + * + */ +LOCAL_INLINE bool TPU_H_HWA_GetTDL2Status(const TPU_H_Type *const pTPUH, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUH->GCR_VT2R & (1U << u8Channel)) >> u8Channel; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get MRL1 event status of specific channel + * + */ +LOCAL_INLINE bool TPU_H_HWA_GetMRL1EventStatus(const TPU_H_Type *const pTPUH, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUH->GCR_EM1R & (1U << u8Channel)) >> u8Channel; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get MRL2 event status of specific channel + * + */ +LOCAL_INLINE bool TPU_H_HWA_GetMRL2EventStatus(const TPU_H_Type *const pTPUH, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUH->GCR_EM2R & (1U << u8Channel)) >> u8Channel; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get TDL1 event status of specific channel + * + */ +LOCAL_INLINE bool TPU_H_HWA_GetTDL1eventStatus(const TPU_H_Type *const pTPUH, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUH->GCR_ET1R & (1U << u8Channel)) >> u8Channel; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get TDL2 event status of specific channel + * + */ +LOCAL_INLINE bool TPU_H_HWA_GetTDL2eventStatus(const TPU_H_Type *const pTPUH, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUH->GCR_ET2R & (1U << u8Channel)) >> u8Channel; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get HAS status of specific channel + * + */ +LOCAL_INLINE bool TPU_H_HWA_GetHASStatus(const TPU_H_Type *const pTPUH, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUH->GCR_VHSR & (1U << u8Channel)) >> u8Channel; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get TCR1 prescaler. + * + */ +LOCAL_INLINE uint32_t TPU_H_HWA_GetTCR1Prescaler(const TPU_H_Type *const pTPUH) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUH->TBR_CR & TPU_H_TBR_CR_TCR1P_MASK) >> TPU_H_TBR_CR_TCR1P_SHIFT; + return u32TmpVal; +} + +/** + * @brief Get TCR1 clock control. + * + */ +LOCAL_INLINE TPUH_TCR1ClkCtrlModeType TPU_H_HWA_GetTCR1ClkControl(const TPU_H_Type *const pTPUH) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUH->TBR_CR & TPU_H_TBR_CR_TCR1CTL_MASK) >> TPU_H_TBR_CR_TCR1CTL_SHIFT; + return (TPUH_TCR1ClkCtrlModeType)u32TmpVal; +} + +/** + * @brief Get TCR2 prescaler. + * + */ +LOCAL_INLINE uint32_t TPU_H_HWA_GetTCR2Prescaler(const TPU_H_Type *const pTPUH) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUH->TBR_CR & TPU_H_TBR_CR_TCR2P_MASK) >> TPU_H_TBR_CR_TCR2P_SHIFT; + return u32TmpVal; +} + +/** + * @brief Get Angle tick generator clock. + * + */ +LOCAL_INLINE TPUH_AngleTickGenClkType TPU_H_HWA_GetATGC(const TPU_H_Type *const pTPUH) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUH->TBR_CR & TPU_H_TBR_CR_ATGC_MASK) >> TPU_H_TBR_CR_ATGC_SHIFT; + return (TPUH_AngleTickGenClkType)u32TmpVal; +} + +/** + * @brief Get Angle Mode Selection. + * + */ +LOCAL_INLINE TPUH_AngleModeSel TPU_H_HWA_GetAM(const TPU_H_Type *const pTPUH) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUH->TBR_CR & TPU_H_TBR_CR_AM_MASK) >> TPU_H_TBR_CR_AM_SHIFT; + return (TPUH_AngleModeSel)u32TmpVal; +} + +/** + * @brief Get TCRCLK signal Filter Control. + * + */ +LOCAL_INLINE TPUH_TCRClkFilterType TPU_H_HWA_GetTCRClkFilter(const TPU_H_Type *const pTPUH) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUH->TBR_CR & TPU_H_TBR_CR_TCRCF_MASK) >> TPU_H_TBR_CR_TCRCF_SHIFT; + return (TPUH_TCRClkFilterType)u32TmpVal; +} + +/** + * @brief Get TCR2 clock control. + * + */ +LOCAL_INLINE TPUH_TCR1ClkCtrlMode0Type TPU_H_HWA_GetTCR2ClkControlAM0(const TPU_H_Type *const pTPUH) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUH->TBR_CR & TPU_H_TBR_CR_TCR2CTL_MASK) >> TPU_H_TBR_CR_TCR2CTL_SHIFT; + return (TPUH_TCR1ClkCtrlMode0Type)u32TmpVal; +} + +/** + * @brief Get TCR2 clock control. + * + */ +LOCAL_INLINE TPUH_TCR1ClkCtrlMode1Type TPU_H_HWA_GetTCR2ClkControlAM1(const TPU_H_Type *const pTPUH) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUH->TBR_CR & TPU_H_TBR_CR_TCR2CTL_MASK) >> TPU_H_TBR_CR_TCR2CTL_SHIFT; + return (TPUH_TCR1ClkCtrlMode1Type)u32TmpVal; +} + +/** + * @brief Get TCR1 cnt value. + * + */ +LOCAL_INLINE uint32_t TPU_H_HWA_GetTCR1CntVal(const TPU_H_Type *const pTPUH) +{ + return pTPUH->TBR_T1R; +} + +/** + * @brief Get TCR2 cnt value. + * + */ +LOCAL_INLINE uint32_t TPU_H_HWA_GetTCR2CntVal(const TPU_H_Type *const pTPUH) +{ + return pTPUH->TBR_T2R; +} + +/** + * @brief Get last tooth indication. + * + */ +LOCAL_INLINE bool TPU_H_HWA_NotLastTooth(const TPU_H_Type *const pTPUH) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUH->TBR_TPR & TPU_H_TBR_TPR_LAST_MASK) >> TPU_H_TBR_TPR_LAST_SHIFT; + return (bool)((u32TmpVal == 0U) ? true : false); +} + +/** + * @brief Get missing tooth counter. + * + */ +LOCAL_INLINE TPUH_MissToothCntType TPU_H_HWA_GetMissingTooth(const TPU_H_Type *const pTPUH) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUH->TBR_TPR & TPU_H_TBR_TPR_MISSCNT_MASK) >> TPU_H_TBR_TPR_MISSCNT_SHIFT; + return (TPUH_MissToothCntType)u32TmpVal; +} + +/** + * @brief Get last tooth indication. + * + */ +LOCAL_INLINE bool TPU_H_HWA_NoInsertTooth(const TPU_H_Type *const pTPUH) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUH->TBR_TPR & TPU_H_TBR_TPR_IPH_MASK) >> TPU_H_TBR_TPR_IPH_SHIFT; + return (bool)((u32TmpVal == 0U) ? true : false); +} + +/** + * @brief Get last tooth indication. + * + */ +LOCAL_INLINE bool TPU_H_HWA_NoForceEACHalt(const TPU_H_Type *const pTPUH) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUH->TBR_TPR & TPU_H_TBR_TPR_HOLD_MASK) >> TPU_H_TBR_TPR_HOLD_SHIFT; + return (bool)((u32TmpVal == 0U) ? true : false); +} + +/** + * @brief Get angle ticks number. + * + */ +LOCAL_INLINE uint32_t TPU_H_HWA_GetAngleTicksVal(const TPU_H_Type *const pTPUH) +{ + return (pTPUH->TBR_TPR & TPU_H_TBR_TPR_TICKS_MASK) >> TPU_H_TBR_TPR_TICKS_SHIFT; +} + +/** + * @brief Get the integer part of TCR1 clocks in one Angle tick. + * + */ +LOCAL_INLINE uint32_t TPU_H_HWA_GetIntergerPerAngleTick(const TPU_H_Type *const pTPUH) +{ + return (pTPUH->TBR_TRR & TPU_H_TBR_TRR_INTEGER_MASK) >> TPU_H_TBR_TRR_INTEGER_SHIFT; +} + +/** + * @brief Get the fraction part of TCR1 clocks in one Angle tick. + * + */ +LOCAL_INLINE uint32_t TPU_H_HWA_GetFractionPerAngleTick(const TPU_H_Type *const pTPUH) +{ + return (pTPUH->TBR_TRR & TPU_H_TBR_TRR_FRACTION_MASK) >> TPU_H_TBR_TRR_FRACTION_SHIFT; +} + +/** + * @brief Get TCR1 overflow flag. + * + */ +LOCAL_INLINE bool TPU_H_HWA_GetTCR1Overflow(const TPU_H_Type *const pTPUH) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUH->TBR_T1MR & TPU_H_TBR_T1MR_OVF_MASK) >> TPU_H_TBR_T1MR_OVF_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get TCR1 IRQ enable flag. + * + */ +LOCAL_INLINE bool TPU_H_HWA_TCR1IRQEnable(const TPU_H_Type *const pTPUH) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUH->TBR_T1MR & TPU_H_TBR_T1MR_IRQ_EN_MASK) >> TPU_H_TBR_T1MR_IRQ_EN_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get the maximum value of TCR1 counter in TCR1 updown mode. + * + */ +LOCAL_INLINE uint32_t TPU_H_HWA_GetTCR1MaxCnt(const TPU_H_Type *const pTPUH) +{ + return (pTPUH->TBR_T1MR & TPU_H_TBR_T1MR_MAX_MASK) >> TPU_H_TBR_T1MR_MAX_SHIFT; +} + +/** + * @brief Get TCR2 overflow flag. + * + */ +LOCAL_INLINE bool TPU_H_HWA_TCR2Overflow(const TPU_H_Type *const pTPUH) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUH->TBR_T2MR & TPU_H_TBR_T2MR_OVF_MASK) >> TPU_H_TBR_T2MR_OVF_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get TCR2 IRQ enable flag. + * + */ +LOCAL_INLINE bool TPU_H_HWA_TCR2IRQEnable(const TPU_H_Type *const pTPUH) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUH->TBR_T2MR & TPU_H_TBR_T2MR_IRQ_EN_MASK) >> TPU_H_TBR_T2MR_IRQ_EN_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get the maximum value of TCR2 counter in TCR1 updown mode. + * + */ +LOCAL_INLINE uint32_t TPU_H_HWA_GetTCR2MaxCnt(const TPU_H_Type *const pTPUH) +{ + return (pTPUH->TBR_T2MR & TPU_H_TBR_T2MR_MAX_MASK) >> TPU_H_TBR_T2MR_MAX_SHIFT; +} + +/** + * @brief Get channel HSA enable flag. + * + */ +LOCAL_INLINE bool TPU_H_HWA_GetChHSAEnable(const TPU_H_Type *const pTPUH, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUH->CH[u8Channel].CR & TPU_H_CHn_CR_CHAE_MASK) >> TPU_H_CHn_CR_CHAE_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Set channel HSA enable or disable. + * + */ +LOCAL_INLINE void TPU_H_HWA_SetChHSA(TPU_H_Type *const pTPUH, uint8_t u8Channel, bool benable) +{ + pTPUH->CH[u8Channel].CR = ((pTPUH->CH[u8Channel].CR & ~TPU_H_CHn_CR_CHAE_MASK) | TPU_H_CHn_CR_CHAE(benable)); +} + +/** + * @brief Set channel event trigger dma enable or disable. + * + */ +LOCAL_INLINE void TPU_H_HWA_SetChEventDMAEnable(TPU_H_Type *const pTPUH, uint8_t u8Channel, bool benable) +{ + pTPUH->CH[u8Channel].CR = ((pTPUH->CH[u8Channel].CR & ~TPU_H_CHn_CR_CDFD_MASK) | TPU_H_CHn_CR_CDFD(benable)); +} + +/** + * @brief Set channel request Dma enable or disable. + * + */ +LOCAL_INLINE void TPU_H_HWA_SetChReqDMAEnable(TPU_H_Type *const pTPUH, uint8_t u8Channel, bool benable) +{ + pTPUH->CH[u8Channel].CR = ((pTPUH->CH[u8Channel].CR & ~TPU_H_CHn_CR_CHDE_MASK) | TPU_H_CHn_CR_CHDE(benable)); +} + +/** + * @brief Get channel HSR Dma request enable flag. + * + */ +LOCAL_INLINE bool TPU_H_HWA_GetChDMAEnable(const TPU_H_Type *const pTPUH, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUH->CH[u8Channel].CR & TPU_H_CHn_CR_CHDE_MASK) >> TPU_H_CHn_CR_CHDE_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Set channel Sync isr from flexcore enable or disable. + * + */ +LOCAL_INLINE void TPU_H_HWA_SetChSyncISR(TPU_H_Type *const pTPUH, uint8_t u8Channel, bool benable) +{ + pTPUH->CH[u8Channel].CR = ((pTPUH->CH[u8Channel].CR & ~TPU_H_CHn_CR_CHEE_MASK) | TPU_H_CHn_CR_CHEE(benable)); +} + +/** + * @brief Get channel HSR event as interrupt enable flag. + * + */ +LOCAL_INLINE bool TPU_H_HWA_GetChHSRISREnable(const TPU_H_Type *const pTPUH, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUH->CH[u8Channel].CR & TPU_H_CHn_CR_CHEE_MASK) >> TPU_H_CHn_CR_CHEE_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Set channel channel HSR event as interrupt enable or disable. + * + */ +LOCAL_INLINE void TPU_H_HWA_SetChHSRISR(TPU_H_Type *const pTPUH, uint8_t u8Channel, bool benable) +{ + pTPUH->CH[u8Channel].CR = ((pTPUH->CH[u8Channel].CR & ~TPU_H_CHn_CR_CHEE_MASK) | TPU_H_CHn_CR_CHEE(benable)); +} + +/** + * @brief Get channel trigger configuration. + * + */ +LOCAL_INLINE TPUH_ChTrigCFGType TPU_H_HWA_GetChTrigCondition(const TPU_H_Type *const pTPUH, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUH->CH[u8Channel].CR & TPU_H_CHn_CR_CTC_MASK) >> TPU_H_CHn_CR_CTC_SHIFT; + return (TPUH_ChTrigCFGType)u32TmpVal; +} + +/** + * @brief Set channel trigger configuration. + * + */ +LOCAL_INLINE void TPU_H_HWA_SetChTrig(TPU_H_Type *const pTPUH, uint8_t u8Channel, TPUH_ChTrigCFGType etrgcfg) +{ + pTPUH->CH[u8Channel].CR = ((pTPUH->CH[u8Channel].CR & ~TPU_H_CHn_CR_CTC_MASK) | TPU_H_CHn_CR_CTC(etrgcfg)); +} + +/** + * @brief Get channel trigger DMA enable. + * + */ +LOCAL_INLINE bool TPU_H_HWA_GetChTrigDMAEnable(const TPU_H_Type *const pTPUH, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUH->CH[u8Channel].CR & TPU_H_CHn_CR_CDFD_MASK) >> TPU_H_CHn_CR_CDFD_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Set channel trigger DMA enable. + * + */ +LOCAL_INLINE void TPU_H_HWA_SetChTrigDMAEnable(TPU_H_Type *const pTPUH, uint8_t u8Channel, bool benable) +{ + pTPUH->CH[u8Channel].CR = ((pTPUH->CH[u8Channel].CR & ~TPU_H_CHn_CR_CDFD_MASK) | TPU_H_CHn_CR_CDFD(benable)); +} + +/** + * @brief Get channel HSR index. + * + */ +LOCAL_INLINE uint8 TPU_H_HWA_GetChHSRIdx(const TPU_H_Type *const pTPUH, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUH->CH[u8Channel].CR & TPU_H_CHn_CR_CHSR_MASK) >> TPU_H_CHn_CR_CHSR_SHIFT; + return (uint8)u32TmpVal; +} + +/** + * @brief Get channel HSR index. + * + */ +LOCAL_INLINE void TPU_H_HWA_SetChHSRIdx(TPU_H_Type *const pTPUH, uint8_t u8Channel, uint8_t u8HSRIdx) +{ + pTPUH->CH[u8Channel].CR = ((pTPUH->CH[u8Channel].CR & ~TPU_H_CHn_CR_CHSR_MASK) | TPU_H_CHn_CR_CHSR(u8HSRIdx)); +} + +/** + * @brief Get channel event trigger interrupt status. + * + */ +LOCAL_INLINE bool TPU_H_HWA_GetChEventTrigISRStatus(const TPU_H_Type *const pTPUH, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUH->CH[u8Channel].SR & TPU_H_CHn_SR_CIS_MASK) >> TPU_H_CHn_SR_CIS_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get channel host service request (HSR) status. + * + */ +LOCAL_INLINE bool TPU_H_HWA_GetChHSRStatus(const TPU_H_Type *const pTPUH, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (uint8_t)(pTPUH->CH[u8Channel].SR & TPU_H_CHn_SR_CHRS_MASK) >> TPU_H_CHn_SR_CHRS_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get HSA. + * + */ +LOCAL_INLINE uint8 TPU_H_HWA_GetChHSAIdx(const TPU_H_Type *const pTPUH, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUH->CH[u8Channel].SR & TPU_H_CHn_SR_CHRI_MASK) >> TPU_H_CHn_SR_CHRI_SHIFT; + return (uint8_t)u32TmpVal; +} + + +/** + * @brief Get channel event as interrupt status. + * + */ +LOCAL_INLINE bool TPU_H_HWA_GetChDMAReq(const TPU_H_Type *const pTPUH, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUH->CH[u8Channel].SR & TPU_H_CHn_SR_CHDS_MASK) >> TPU_H_CHn_SR_CHDS_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get channel trigger status. + * + */ +LOCAL_INLINE bool TPU_H_HWA_GetChTrigStatus(const TPU_H_Type *const pTPUH, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUH->CH[u8Channel].SR & TPU_H_CHn_SR_CTS_MASK) >> TPU_H_CHn_SR_CTS_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get channel host service acknowledge (HSA) interrupt status. + * + */ +LOCAL_INLINE bool TPU_H_HWA_GetChHSAReqStatus(const TPU_H_Type *const pTPUH, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUH->CH[u8Channel].SR & TPU_H_CHn_SR_CHAS_MASK) >> TPU_H_CHn_SR_CHAS_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Clear channel interrupt by event. + * + */ +LOCAL_INLINE void TPU_H_HWA_ClearChEventISRFlg(TPU_H_Type *const pTPUH, uint8_t u8Channel) +{ + pTPUH->CH[u8Channel].SCR = TPU_H_CHn_SCR_CEIC_MASK; +} + +/** + * @brief Clear channel HSA. + * + */ +LOCAL_INLINE void TPU_H_HWA_ClearChHSA(TPU_H_Type *const pTPUH, uint8_t u8Channel) +{ + pTPUH->CH[u8Channel].SCR = TPU_H_CHn_SCR_CHAC_MASK; +} + +/** + * @brief Clear channel HSR. + * + */ +LOCAL_INLINE void TPU_H_HWA_ClearChHSR(TPU_H_Type *const pTPUH, uint8_t u8Channel) +{ + pTPUH->CH[u8Channel].SCR = TPU_H_CHn_SCR_CHRT_MASK; +} + +/** + * @brief Get channel service request. + * + */ +LOCAL_INLINE bool TPU_H_HWA_GetChServiceReq(const TPU_H_Type *const pTPUH, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUH->CH[u8Channel].EFR & TPU_H_CHn_EFR_CSR_MASK) >> TPU_H_CHn_EFR_CSR_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get channel service request to HOST. + * + */ +LOCAL_INLINE bool TPU_H_HWA_GetChServiceReqToHost(const TPU_H_Type *const pTPUH, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUH->CH[u8Channel].EFR & TPU_H_CHn_EFR_CHSR_MASK) >> TPU_H_CHn_EFR_CHSR_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get match recognition latch 1 event status. + * + */ +LOCAL_INLINE bool TPU_H_HWA_GetChMatchRecLatch1Event(const TPU_H_Type *const pTPUH, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUH->CH[u8Channel].EFR & TPU_H_CHn_EFR_EMRL1_MASK) >> TPU_H_CHn_EFR_EMRL1_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get match recognition latch 2 event status. + * + */ +LOCAL_INLINE bool TPU_H_HWA_GetChMatchRecLatch2Event(const TPU_H_Type *const pTPUH, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUH->CH[u8Channel].EFR & TPU_H_CHn_EFR_EMRL2_MASK) >> TPU_H_CHn_EFR_EMRL2_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get transition detect latch 1 event status. + * + */ +LOCAL_INLINE bool TPU_H_HWA_GetChTransDetectLatch1Event(const TPU_H_Type *const pTPUH, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUH->CH[u8Channel].EFR & TPU_H_CHn_EFR_ETDL1_MASK) >> TPU_H_CHn_EFR_ETDL1_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get transition detect latch 2 event status. + * + */ +LOCAL_INLINE bool TPU_H_HWA_GetChTransDetectLatch2Event(const TPU_H_Type *const pTPUH, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUH->CH[u8Channel].EFR & TPU_H_CHn_EFR_ETDL2_MASK) >> TPU_H_CHn_EFR_ETDL2_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get match recognition latch 1 enable status. + * + */ +LOCAL_INLINE bool TPU_H_HWA_GetChMatchRecLatch1En(const TPU_H_Type *const pTPUH, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUH->CH[u8Channel].EFR & TPU_H_CHn_EFR_MRLE1_MASK) >> TPU_H_CHn_EFR_MRLE1_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get match recognition latch 2 enable status. + * + */ +LOCAL_INLINE bool TPU_H_HWA_GetChMatchRecLatch2En(const TPU_H_Type *const pTPUH, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUH->CH[u8Channel].EFR & TPU_H_CHn_EFR_MRLE2_MASK) >> TPU_H_CHn_EFR_MRLE2_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get match recognition latch 1 enable status. + * + */ +LOCAL_INLINE bool TPU_H_HWA_GetChMatchRecLatch1Status(const TPU_H_Type *const pTPUH, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUH->CH[u8Channel].EFR & TPU_H_CHn_EFR_MRL1_MASK) >> TPU_H_CHn_EFR_MRL1_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get match recognition latch 2 enable status. + * + */ +LOCAL_INLINE bool TPU_H_HWA_GetChMatchRecLatch2Status(const TPU_H_Type *const pTPUH, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUH->CH[u8Channel].EFR & TPU_H_CHn_EFR_MRL2_MASK) >> TPU_H_CHn_EFR_MRL2_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get Transition Detect latch 1 enable status. + * + */ +LOCAL_INLINE bool TPU_H_HWA_GetChTransDetectLatch1Status(const TPU_H_Type *const pTPUH, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUH->CH[u8Channel].EFR & TPU_H_CHn_EFR_TDL1_MASK) >> TPU_H_CHn_EFR_TDL1_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + +/** + * @brief Get Transition Detect latch 2 enable status. + * + */ +LOCAL_INLINE bool TPU_H_HWA_GetChTransDetectLatch2Status(const TPU_H_Type *const pTPUH, uint8_t u8Channel) +{ + uint32_t u32TmpVal; + + u32TmpVal = (pTPUH->CH[u8Channel].EFR & TPU_H_CHn_EFR_TDL2_MASK) >> TPU_H_CHn_EFR_TDL2_SHIFT; + return (bool)((u32TmpVal != 0U) ? true : false); +} + + +#endif /* #ifndef _HWA_TPUH_H_ */ diff --git a/MODULES/HwA_Flagchip_FC7240/Inc/HwA_trgsel.h b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_trgsel.h new file mode 100644 index 0000000..7ba17ae --- /dev/null +++ b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_trgsel.h @@ -0,0 +1,150 @@ +/** + * @file HwA_trgsel.h + * @author Flagchip0103 + * @brief Hardware access layer for TrgSel + * @version 0.1.0 + * @date 2023-12-19 + * + * @copyright Copyright (c) 2023 Flagchip Semiconductors Co., Ltd. + * + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2023-12-19 Flagchip0103 N/A First version for FC7240 + ******************************************************************************** */ + +#ifndef _HWA_TRGSEL_H_ +#define _HWA_TRGSEL_H_ + +#include "device_header.h" + +#define TRGSEL_REGSIZE 4U + +/** + * @brief Get the trigger source of the selected trigger target + * + * @param pTrgsel the base address of the TrgSel instance + * @param u32TargetIndex the trigger target to get the trigger source + * @return uint32_t the trigger source of the selected trigger target + */ +LOCAL_INLINE uint32_t TRGSEL_HWA_GetTargetTriggerSource(const TRGSEL_Type *const pTrgsel, uint32_t u32TargetIndex) +{ + uint32_t u32RegIdx = u32TargetIndex / TRGSEL_REGSIZE; + uint32_t u32SelIdx = u32TargetIndex % TRGSEL_REGSIZE; + + uint32_t u32Tmp = pTrgsel->OUT_SEL[u32RegIdx]; + switch (u32SelIdx) + { + case 0U: + { + u32Tmp = (u32Tmp & TRGSEL_OUT_SEL_SEL_0_MASK) >> TRGSEL_OUT_SEL_SEL_0_SHIFT; + break; + } + case 1U: + { + u32Tmp = (u32Tmp & TRGSEL_OUT_SEL_SEL_1_MASK) >> TRGSEL_OUT_SEL_SEL_1_SHIFT; + break; + } + case 2U: + { + u32Tmp = (u32Tmp & TRGSEL_OUT_SEL_SEL_2_MASK) >> TRGSEL_OUT_SEL_SEL_2_SHIFT; + break; + } + case 3U: + { + u32Tmp = (u32Tmp & TRGSEL_OUT_SEL_SEL_3_MASK) >> TRGSEL_OUT_SEL_SEL_3_SHIFT; + break; + } + + default: + break; + } + + return (uint32_t)u32Tmp; +} + +/** + * @brief Set the trigger source of the selected trigger target + * + * @param pTrgsel the base address of the TrgSel instance + * @param u32TargetIndex the trigger target to set the trigger source + * @param u32SourceIndex the selected trigger source to trig the target + */ +LOCAL_INLINE void TRGSEL_HWA_SetTargetTriggerSource(TRGSEL_Type *const pTrgsel, uint32_t u32TargetIndex, + uint32_t u32SourceIndex) +{ + uint32_t u32RegIdx = u32TargetIndex / TRGSEL_REGSIZE; + uint32_t u32SelIdx = u32TargetIndex % TRGSEL_REGSIZE; + uint32_t u32Tmp = pTrgsel->OUT_SEL[u32RegIdx]; + + switch (u32SelIdx) + { + case 0U: + { + u32Tmp = (u32Tmp & ~TRGSEL_OUT_SEL_SEL_0_MASK) | TRGSEL_OUT_SEL_SEL_0(u32SourceIndex); + break; + } + case 1U: + { + u32Tmp = (u32Tmp & ~TRGSEL_OUT_SEL_SEL_1_MASK) | TRGSEL_OUT_SEL_SEL_1(u32SourceIndex); + break; + } + case 2U: + { + u32Tmp = (u32Tmp & ~TRGSEL_OUT_SEL_SEL_2_MASK) | TRGSEL_OUT_SEL_SEL_2(u32SourceIndex); + break; + } + case 3U: + { + u32Tmp = (u32Tmp & ~TRGSEL_OUT_SEL_SEL_3_MASK) | TRGSEL_OUT_SEL_SEL_3(u32SourceIndex); + break; + } + + default: + break; + } + + pTrgsel->OUT_SEL[u32RegIdx] = u32Tmp; +} + +/** + * @brief Get wether the trigger source of the selected target is locked + * + * @param pTrgsel the base address of the TrgSel instance + * @param u32TargetIndex the trigger target to get the lock status + * @return true the trigger source of the selected target cannot be modified + * @return false the trigger source of the selected target can be modified + */ +LOCAL_INLINE bool TRGSEL_HWA_GetTargetLockStatus(const TRGSEL_Type *const pTrgsel, uint32_t u32TargetIndex) +{ + uint32_t u32RegIdx = u32TargetIndex / TRGSEL_REGSIZE; + + uint32_t u32Tmp = pTrgsel->OUT_SEL[u32RegIdx]; + u32Tmp = (u32Tmp & TRGSEL_OUT_SEL_LOCK_MASK) >> TRGSEL_OUT_SEL_LOCK_SHIFT; + + return (bool)((u32Tmp != 0U) ? true : false); +} + +/** + * @brief Lock the trigger source of the selected target + * + * @note The trigger target is grouped by four, so if you lock the trigger source of one target, the + * adjacent three trigger targets in the same register group are also be locked. So please ensure the + * trigger sources are not to be modified before lock the trigger target. + * + * @param pTrgsel the base address of the TrgSel instance + * @param u32TargetIndex the trigger target to lock the trigger source + */ +LOCAL_INLINE void TRGSEL_HWA_LockTargetTriggerSource(TRGSEL_Type *const pTrgsel, uint32_t u32TargetIndex) +{ + uint32_t u32RegIdx = u32TargetIndex / TRGSEL_REGSIZE; + + pTrgsel->OUT_SEL[u32RegIdx] |= TRGSEL_OUT_SEL_LOCK_MASK; +} + +/** @}*/ + +#endif /* _HWA_TRGSEL_H_ */ diff --git a/MODULES/HwA_Flagchip_FC7240/Inc/HwA_tstmp.h b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_tstmp.h new file mode 100644 index 0000000..830fcd9 --- /dev/null +++ b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_tstmp.h @@ -0,0 +1,222 @@ +/** + * @file HwA_tstmp.h + * @author Flagchip + * @brief FC7xxx TSTMP hardware access layer + * @version 0.1.0 + * @date 2024-01-14 + * + * @copyright Copyright (c) 2023 Flagchip Semiconductors Co., Ltd. + * + * @details + */ + +/******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-01-14 Flagchip0122 N/A FC7xxx internal release version + ********************************************************************************/ + + +#ifndef _HWA_TSTMP_H_ +#define _HWA_TSTMP_H_ + +#include "device_header.h" +/********* Local typedef ************/ +/** @brief Tstmp modulate number */ +typedef enum +{ + TSTMP_MOD0 = 0U, + TSTMP_MOD1, + TSTMP_MOD2, + TSTMP_MOD3, +} TSTMP_ModulateType; + +/** @brief Tstmp running mode */ +typedef enum +{ + TSTMP_MODE_ALWAYS_RUNNING = 0U, + TSTMP_MODE_PERIOD_RUNNING = 1U +} TSTMP_ModeCounterRunningMode; + +typedef enum +{ + TSTMP_SIRC1M_CLK = 0U, + TSTMP_AON_CLK = 1U +} TSTMP_ClockSourceType; +/********* Local inline function ************/ +/** + * @brief Read TSTMP value + * + * @param pTstmp TSTMP instance + * @return TSTMP value + */ +LOCAL_INLINE uint64_t TSTMP_HWA_ReadTstmpValue(TSTMP_Type *pTstmp) +{ + uint32_t u32TstmpL, u32TstmpH; + uint64_t u64TempValue; + u32TstmpL = pTstmp->VALL; + u32TstmpH = pTstmp->VALH; + + u64TempValue = u32TstmpH; + u64TempValue = (u64TempValue << 32U) + u32TstmpL; + return u64TempValue; +} + +/** + * @brief Read TSTMP interrupt enable bits + * + * @param pTstmp TSTMP instance + * @return TSTMP interrupt enable bits + */ +LOCAL_INLINE uint32_t TSTMP_HWA_ReadTstmpInterruptEnable(TSTMP_Type *pTstmp) +{ + return (uint32_t)pTstmp->MOD_INTEN; +} + +/** + * @brief Enable TSTMP MOD(n) match interrupt + * + * @param pTstmp TSTMP instance + * @param eMod MOD number + */ +LOCAL_INLINE void TSTMP_HWA_EnableModMatchInterrupt(TSTMP_Type *pTstmp, TSTMP_ModulateType eMod) +{ + pTstmp->MOD_INTEN |= ((uint32_t)1U << (uint32_t)eMod); +} + +/** + * @brief Disable TSTMP MOD(n) match interrupt + * + * @param pTstmp TSTMP instance + * @param eMod MOD number + */ +LOCAL_INLINE void TSTMP_HWA_DisableModMatchInterrupt(TSTMP_Type *pTstmp, TSTMP_ModulateType eMod) +{ + pTstmp->MOD_INTEN &= ~((uint32_t)1U << (uint32_t)eMod); +} + +/** + * @brief Set the counting modes of TSTMP MOD(n) + * + * @param pTstmp TSTMP instance + * @param eMod MOD number + * @param eCounterMode Counting mode set + */ +LOCAL_INLINE void TSTMP_HWA_SetModCounterMode(TSTMP_Type *pTstmp, TSTMP_ModulateType eMod, TSTMP_ModeCounterRunningMode eCounterMode) +{ + pTstmp->MOD_INTEN = (pTstmp->MOD_INTEN & ~((uint32_t)0x100U << (uint32_t)eMod)) | + (((uint32_t)eCounterMode << TSTMP_MOD_INTEN_MOD0_MODE_SHIFT) << (uint32_t)eMod); +} + +/** + * @brief Enable TSTMP MOD(n) counter + * + * @param pTstmp TSTMP instance + * @param eMod MOD number + */ +LOCAL_INLINE void TSTMP_HWA_EnableModCounter(TSTMP_Type *pTstmp, TSTMP_ModulateType eMod) +{ + pTstmp->MOD_INTEN |= (TSTMP_MOD_INTEN_MOD0_ENABLE_MASK << (uint32_t)eMod); +} + +/** + * @brief Disable TSTMP MOD(n) counter + * + * @param pTstmp TSTMP instance + * @param eMod MOD number + */ +LOCAL_INLINE void TSTMP_HWA_DisableModCounter(TSTMP_Type *pTstmp, TSTMP_ModulateType eMod) +{ + pTstmp->MOD_INTEN &= ~(TSTMP_MOD_INTEN_MOD0_ENABLE_MASK << (uint32_t)eMod); +} + +/** + * @brief Select TSTMP MOD(n) clock source + * + * @param pTstmp TSTMP instance + * @param eMod MOD number + */ +LOCAL_INLINE void TSTMP_HWA_SelectClkSource(TSTMP_Type *pTstmp, TSTMP_ModulateType eMod, TSTMP_ClockSourceType eClk) +{ + pTstmp->MOD_INTEN |= (((uint32_t)eClk) << (TSTMP_MOD_INTEN_MOD0_CLK_SHIFT + (uint32_t)eMod)); +} + +/** + * @brief Read TSTMP all MOD match flag + * + * @param pTstmp TSTMP instance + * @return TSTMP all MOD match flag + */ +LOCAL_INLINE uint32_t TSTMP_HWA_ReadModMatchFlag(TSTMP_Type *pTstmp) +{ + return ((uint32_t)(pTstmp->MOD_STATUS) & (uint32_t)(TSTMP_MOD_STATUS_MOD0_MATCH_MASK | TSTMP_MOD_STATUS_MOD1_MATCH_MASK + | TSTMP_MOD_STATUS_MOD2_MATCH_MASK | TSTMP_MOD_STATUS_MOD3_MATCH_MASK)); +} + +/** + * @brief Clear TSTMP all MOD(0) match flag + * + * @param pTstmp TSTMP instance + */ +LOCAL_INLINE void TSTMP_HWA_ClearMod0MatchFlag(TSTMP_Type *pTstmp) +{ + pTstmp->MOD_STATUS = (uint32_t)(TSTMP_MOD_STATUS_MOD0_MATCH_MASK); +} + +/** + * @brief Clear TSTMP all MOD(1,2,3) match flag + * + * @param pTstmp TSTMP instance + */ +LOCAL_INLINE void TSTMP_HWA_ClearAllMod123MatchFlag(TSTMP_Type *pTstmp) +{ + pTstmp->MOD_STATUS = (uint32_t)(TSTMP_MOD_STATUS_MOD1_MATCH_MASK | TSTMP_MOD_STATUS_MOD2_MATCH_MASK | + TSTMP_MOD_STATUS_MOD3_MATCH_MASK); +} + +/** + * @brief Clear TSTMP single MOD(1,2,3) match flag + * + * @param pTstmp TSTMP instance + * @param eMod MOD number + */ +LOCAL_INLINE void TSTMP_HWA_ClearSingleMod123MatchFlag(TSTMP_Type *pTstmp, TSTMP_ModulateType eMod) +{ + pTstmp->MOD_STATUS = ((uint32_t)1U << (uint32_t)eMod); +} + +/** + * @brief Set MOD match value + * + * @param pTstmp TSTMP instance + * @param eMod MOD number + * @param u32ModValue MOD value + */ +LOCAL_INLINE void TSTMP_HWA_SetModMatchValue(TSTMP_Type *pTstmp, TSTMP_ModulateType eMod, uint32_t u32ModValue) +{ + switch(eMod) + { + case TSTMP_MOD0: + pTstmp->MOD0_SETVAL = u32ModValue; + break; + + case TSTMP_MOD1: + pTstmp->MOD1_SETVAL = u32ModValue; + break; + + case TSTMP_MOD2: + pTstmp->MOD2_SETVAL = u32ModValue; + break; + + case TSTMP_MOD3: + pTstmp->MOD3_SETVAL = u32ModValue; + break; + + default: + break; + } +} + +#endif /* #ifndef _HWA_TSTMP_H_ */ diff --git a/MODULES/HwA_Flagchip_FC7240/Inc/HwA_wdog.h b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_wdog.h new file mode 100644 index 0000000..5edfd57 --- /dev/null +++ b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_wdog.h @@ -0,0 +1,115 @@ +/** + * @file HwA_WDOG.h + * @author Flagchip + * @brief FC7xxx Wdog hardware access layer + * @version 0.1.0 + * @date 2022-04-16 + * + * @copyright Copyright (c) 2022 Flagchip Semiconductors Co., Ltd. + * + * @details + */ +/********************************************************************************* +* Revision History: +* +* Version Date Initials CR# Descriptions +* --------- ---------- ------------ ---------- --------------- +* 0.1.0 2023-12-29 qxw0074 N/A First version for FC7240 +******************************************************************************** */ + +#ifndef _HWA_WDOG_H_ +#define _HWA_WDOG_H_ + +#include "device_header.h" + +/** + * @addtogroup HwA_WDOG + * @{ + */ + +/********* Local typedef ************/ + +/********* Local inline function ************/ + +/********* Wdog Register interface ************/ +/** + * @brief Set CS register value, for Wdog working mode configuration. + * + * @param WDOG_Type *pWdog. point to wdog instance base register address. + * + * @param uint32_t u32Cs. configured register value + */ +LOCAL_INLINE void WDOG_HWA_SetCs(WDOG_Type *pWdog, uint32_t u32Cs) +{ + pWdog->CS = u32Cs; +} + +/** + * @brief Get CS register value, for WDOG working mode configuration. + * @return uint32_t CS register value. + */ +LOCAL_INLINE uint32_t WDOG_HWA_GetCs(WDOG_Type *pWdog) +{ + uint32_t u32Temp = 0U; + u32Temp = pWdog->CS; + return u32Temp; +} + +/** + * @brief Clear Wdog interrupt flag. + * + * @param WDOG_Type *pWdog. point to wdog instance base register address. + */ +LOCAL_INLINE void WDOG_HWA_ClearInterruptFlag(WDOG_Type *pWdog) +{ + pWdog->CS |= WDOG_CS_FLAG_MASK; +} + +/** + * @brief Get WDOG unlock status, if locked, register can't be written. + * @return bool. true as unlocked. false as locked. + */ +LOCAL_INLINE bool WDOG_HWA_GetUnlockStatus(WDOG_Type *pWdog) +{ + return (bool)((((uint32_t)pWdog->CS & (uint32_t)WDOG_CS_ULK_STAT_MASK) != 0U) ? true : false); +} + +/** + * @brief Set COUNTER register value. for Wdog unlock and refresh usage. + * + * @param pWdog. point to wdog instance base register address. + * + * @param u32Counter. configured register value + */ +LOCAL_INLINE void WDOG_HWA_SetCounter(WDOG_Type *pWdog, uint32_t u32Counter) +{ + pWdog->COUNTER = u32Counter; +} + +/** + * @brief Set TIMEOUT register value. for WDOG timeout value + * + * @param WDOG_Type *pWdog. point to wdog instance base register address. + * + * @param uint16_t u16Timeout configured register value + */ +LOCAL_INLINE void WDOG_HWA_SetTimeout(WDOG_Type *pWdog, uint16_t u16Timeout) +{ + pWdog->TIMEOUT = u16Timeout; +} + +/** + * @brief Set WINDOW register value. for windowed WDOG low threshold value. + * + * @param WDOG_Type *pWdog. point to wdog instance base register address. + * + * @param uint16_t u16Window. configured register value + */ +LOCAL_INLINE void WDOG_HWA_SetWindow(WDOG_Type *pWdog, uint16_t u16Window) +{ + pWdog->WINDOW = u16Window; +} + +/** @}*/ /* HwA_WODG */ + +#endif /* #ifndef _HWA_WDOG_H_ */ diff --git a/MODULES/HwA_Flagchip_FC7240/Inc/HwA_wku.h b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_wku.h new file mode 100644 index 0000000..60a0802 --- /dev/null +++ b/MODULES/HwA_Flagchip_FC7240/Inc/HwA_wku.h @@ -0,0 +1,168 @@ +/** + * @file HwA_wku.h + * @author Flagchip + * @brief FC7xxx WKU hardware access layer + * @version 0.1.0 + * @date 2024-01-05 + * + * @copyright Copyright (c) 2023 Flagchip Semiconductors Co., Ltd. + * + * @details + */ + +#ifndef _HWA_WKU_H_ +#define _HWA_WKU_H_ + +#include "device_header.h" +/********* Local typedef ************/ +/** @brief Wku input */ +/* +typedef enum +{ + WKU_INPUT_FCSPI0 = 0x000040U, + WKU_INPUT_FCUART = 0x000080U, + WKU_INPUT_CMP0 = 0x000400U, + WKU_INPUT_CMP1 = 0x000800U, + WKU_INPUT_TSTMP0 = 0x002000U, + WKU_INPUT_RTC_ALARM = 0x004000U, + WKU_INPUT_RTC_SECONDS = 0x008000U, + WKU_INPUT_FCPIT0 = 0x010000U, + WKU_INPUT_CMU0 = 0x020000U, + WKU_INPUT_AONTIMER = 0x040000U, + WKU_INPUT_GPIOA = 0x080000U, + WKU_INPUT_GPIOC = 0x100000U, + WKU_INPUT_GPIOE = 0x200000U, + WKU_INPUT_GPIOF = 0x400000U, + WKU_INPUT_GPIOG = 0x800000U, + WKU_INPUT_MAX = 0xFFFFFFU +} WKU_WakeupInputType; +*/ +typedef enum +{ + WKU_INPUT_FCSPI0 = 0x000040U, + WKU_INPUT_FCUART = 0x000080U, + WKU_INPUT_CMP0 = 0x000400U, + WKU_INPUT_CMP1 = 0x000800U, + WKU_INPUT_TSTMP0 = 0x002000U, + WKU_INPUT_RTC_ALARM = 0x004000U, + WKU_INPUT_RTC_SECONDS = 0x008000U, + WKU_INPUT_FCPIT0 = 0x010000U, + WKU_INPUT_CMU0 = 0x020000U, + WKU_INPUT_AONTIMER = 0x040000U, + WKU_INPUT_GPIOA = 0x080000U, + WKU_INPUT_GPIOC = 0x100000U, + WKU_INPUT_GPIOD = 0x200000U, // <-- ДОБАВИТЬ (бит 21) + WKU_INPUT_GPIOE = 0x800000U, // <-- СМЕСТИТЬ (было 0x200000) + WKU_INPUT_GPIOF = 0x800000U, + WKU_INPUT_GPIOG = 0x1000000U, // <-- СМЕСТИТЬ (было 0x800000) + WKU_INPUT_MAX = 0xFFFFFFU +} WKU_WakeupInputType; + +/********* mcaro ************/ +#define WKU_INPUT_ALL_MASK (WKU_INPUT_FCSPI0 |\ + WKU_INPUT_FCUART |\ + WKU_INPUT_CMP0 |\ + WKU_INPUT_CMP1 |\ + WKU_INPUT_TSTMP0 |\ + WKU_INPUT_RTC_ALARM |\ + WKU_INPUT_RTC_SECONDS |\ + WKU_INPUT_FCPIT0 |\ + WKU_INPUT_CMU0 |\ + WKU_INPUT_AONTIMER |\ + WKU_INPUT_GPIOA |\ + WKU_INPUT_GPIOC |\ + WKU_INPUT_GPIOE |\ + WKU_INPUT_GPIOF |\ + WKU_INPUT_GPIOG |\ + WKU_INPUT_MAX) + +/********* Local inline function ************/ +/** + * @brief Enable wakeup delay counter + * + */ +LOCAL_INLINE void WKU_HWA_EnableDelayCounter(void) +{ + WKU->MDC |= (uint32_t)WKU_MDC_DLYEN_MASK; +} + +/** + * @brief Disable wakeup delay counter + * + */ +LOCAL_INLINE void WKU_HWA_DisableDelayCounter(void) +{ + WKU->MDC &= ~((uint32_t)WKU_MDC_DLYEN_MASK); +} + +/** + * @brief Set wakeup delay time + * + * @param u8DelayTime delay time + */ +LOCAL_INLINE void WKU_HWA_SetDelayTime(uint8_t u8DelayTime) +{ + uint32_t u32RegVal = WKU->MDC; + WKU->MDC = ((u32RegVal & (~WKU_MDC_DELAYTIME_MASK)) | WKU_MDC_DELAYTIME(u8DelayTime)); +} + +/** + * @brief Enable wakeup source + * + * @param eWakeup Wakeup source type + */ +LOCAL_INLINE void WKU_HWA_EnableWakeupSource(const WKU_WakeupInputType eWakeup) +{ + if (eWakeup < WKU_INPUT_CMP0) + { + WKU->MWER0 |= (uint32_t)eWakeup; + } + else if ((eWakeup < WKU_INPUT_FCPIT0) && (eWakeup > WKU_INPUT_FCUART)) + { + WKU->MWER1 |= ((uint32_t)eWakeup >> 8U); + } + else + { + WKU->MWER2 |= ((uint32_t)eWakeup >> 16U); + } +} + +/** + * @brief Disable wakeup source + * + * @param eWakeup Wakeup source type + */ +LOCAL_INLINE void WKU_HWA_DisableWakeupSource(const WKU_WakeupInputType eWakeup) +{ + if (eWakeup < WKU_INPUT_CMP0) + { + WKU->MWER0 &= ((~((uint32_t)eWakeup)) & (uint32_t)0xFF); + } + else if ((eWakeup < WKU_INPUT_FCPIT0) && (eWakeup > WKU_INPUT_FCUART)) + { + WKU->MWER1 &= ((~(uint32_t)((uint32_t)eWakeup >> 8U)) & (uint32_t)0xFF); + } + else + { + WKU->MWER2 &= ((~(uint32_t)((uint32_t)eWakeup >> 16U)) & (uint32_t)0xFF); + } +} + +/** + * @brief Read WKU wakeup source + * + * @return WKU wakeup source value + */ +LOCAL_INLINE uint32_t WKU_HWA_ReadWakeupSource(void) +{ + uint32_t u32WakeupSource = 0U; + + u32WakeupSource = (uint32_t)(WKU->MWER0); + u32WakeupSource |= (uint32_t)((uint32_t)(WKU->MWER1) << 8U); + u32WakeupSource |= (uint32_t)((uint32_t)(WKU->MWER2) << 16U); + + return u32WakeupSource; +} + + +#endif /* #ifndef _HWA_WKU_H_ */ diff --git a/MODULES/HwA_Flagchip_FC7240/modular.json b/MODULES/HwA_Flagchip_FC7240/modular.json new file mode 100644 index 0000000..174bad2 --- /dev/null +++ b/MODULES/HwA_Flagchip_FC7240/modular.json @@ -0,0 +1,7 @@ +{ + "cmake": { + "inc_dirs": [ + "Inc" + ] + } +} diff --git a/MODULES/InternalFlashPage_Flagchip_FC7240/Inc/InternalFlashPage.h b/MODULES/InternalFlashPage_Flagchip_FC7240/Inc/InternalFlashPage.h new file mode 100644 index 0000000..4bf192a --- /dev/null +++ b/MODULES/InternalFlashPage_Flagchip_FC7240/Inc/InternalFlashPage.h @@ -0,0 +1,113 @@ +// +// Created by cfif on 07.10.22. +// + +#ifndef HVAC_INTERNAL_FLASH_PAGE_H +#define HVAC_INTERNAL_FLASH_PAGE_H + +#include +#include "fc7xxx_driver_flash.h" +#include "stddef.h" + +bool D_bInternalFlashPage_Clear( + uint32_t pageAddress, + void *wdTriggerFct, + void *wdTriggerFct_env +); + +size_t D_sInternalFlashPage_Write( + uint32_t pageAddress, + size_t offset, + uint8_t *data, + size_t size +); + +size_t D_bInternalFlashPage_DumpFromRam( + uint32_t beginPageAddr, + void *sourceRamAddr, + uint32_t size +); + +size_t D_sInternalFlashPage_Read( + uint32_t pageAddress, + size_t offset, + uint8_t *data, + size_t size +); + +bool D_bInternalFlashPage_ClearRange( + uint32_t firstPageAddr, + uint32_t totalSize, + void *wdTriggerFct, + void *wdTriggerFct_env +); + +bool D_bInternalFlashPage_WriteFromRam(uint32_t beginPageAddr, void *sourceRamAddr, uint32_t size); + +bool D_bInternalFlashPage_CopyRange( + uint32_t targetPageAddr, + uint32_t sourcePageAddr, + uint32_t totalCopySize, + void *wdTriggerFct, + void *wdTriggerFct_env +); + +uint32_t D_iInternalFlashPage_ReadWord(uint32_t addressOnFlash); + + + + + + + + + + + + + +bool P_bInternalFlashPage_Clear( + uint32_t pageAddress +); + +size_t P_sInternalFlashPage_Write( + uint32_t pageAddress, + size_t offset, + uint8_t *data, + size_t size +); + +size_t P_bInternalFlashPage_DumpFromRam( + uint32_t beginPageAddr, + void *sourceRamAddr, + uint32_t size +); + +size_t P_sInternalFlashPage_Read( + uint32_t pageAddress, + size_t offset, + uint8_t *data, + size_t size +); + +bool P_bInternalFlashPage_ClearRange( + uint32_t firstPageAddr, + uint32_t totalSize, + void *wdTriggerFct, + void *wdTriggerFct_env +); + +bool P_bInternalFlashPage_WriteFromRam(uint32_t beginPageAddr, void *sourceRamAddr, uint32_t size); + +bool P_bInternalFlashPage_CopyRange( + uint32_t targetPageAddr, + uint32_t sourcePageAddr, + uint32_t totalCopySize, + void *wdTriggerFct, + void *wdTriggerFct_env +); + +uint32_t P_iInternalFlashPage_ReadWord(uint32_t addressOnFlash); + + +#endif //HVAC_INTERNAL_FLASH_PAGE_H diff --git a/MODULES/InternalFlashPage_Flagchip_FC7240/Src/InternalFlashPage_DFlash.c b/MODULES/InternalFlashPage_Flagchip_FC7240/Src/InternalFlashPage_DFlash.c new file mode 100644 index 0000000..1f8ba35 --- /dev/null +++ b/MODULES/InternalFlashPage_Flagchip_FC7240/Src/InternalFlashPage_DFlash.c @@ -0,0 +1,310 @@ +// +// Created by cfif on 07.10.22. +// +#include "InternalFlashPage.h" + +uint32_t D_iInternalFlashPage_ReadWord(uint32_t addressOnFlash) { + return (*(__IO uint32_t *) (addressOnFlash)); +} + +size_t D_sInternalFlashPage_Read( + uint32_t pageAddress, + size_t offset, + uint8_t *data, + size_t size +) { + if ((offset & (uint32_t) 0x3) != 0) { + // The offset is not a multiple of 4 + return 0; + } + + size_t left = size; + + while (left) { + if (left >= 4) { + *((uint32_t *) data) = D_iInternalFlashPage_ReadWord(pageAddress + offset); + data += 4; + offset += 4; + left -= 4; + } else { + uint32_t word = D_iInternalFlashPage_ReadWord(pageAddress + offset); + for (uint8_t sub_byte = 0; sub_byte < left; ++sub_byte) { + *data = ((uint8_t *) &word)[sub_byte]; + ++data; + } + offset += 4; + left = 0; + } + } + + return size; +} + +bool D_bInternalFlashPage_Clear( + uint32_t pageAddress, + void *wdTriggerFct, + void *wdTriggerFct_env +) { + FLASHDRIVER_Init(); + + FLASH_DRIVER_ParamType tFlashParam = {.pData = wdTriggerFct, + .wdTriggerFct = wdTriggerFct_env + }; + + tFlashParam.u32Address = pageAddress; + tFlashParam.u32Length = FLASH_PAGE_D_SIZE; + if (FLASH_ERROR_OK != FLASHDRIVER_DFlashEraseSector(&tFlashParam)) { + return false; + } + + +/* + flash_unlock(); + +// if (FLASH_OPERATE_DONE != flash_block_erase(pageAddress)) { +// return false; +// } + if (FLASH_OPERATE_DONE != flash_sector_erase(pageAddress)) { + flash_lock(); + return false; + } + + flash_lock(); +*/ + return true; +} + +bool D_bInternalFlashPage_ClearRange( + uint32_t firstPageAddr, + uint32_t totalSize, + void *wdTriggerFct, + void *wdTriggerFct_env +) { + if (totalSize % FLASH_PAGE_D_SIZE) { + return false; + } + + uint32_t endAddr = firstPageAddr + totalSize; + for (; firstPageAddr < endAddr; firstPageAddr += FLASH_PAGE_D_SIZE) { + if (!D_bInternalFlashPage_Clear(firstPageAddr, wdTriggerFct, wdTriggerFct_env)) { + return false; + } + } + + return true; +} + +bool D_bInternalFlashPage_CopyRange( + uint32_t targetPageAddr, + uint32_t sourcePageAddr, + uint32_t size, + void *wdTriggerFct, + void *wdTriggerFct_env +) { + if (!D_bInternalFlashPage_ClearRange(targetPageAddr, size, wdTriggerFct, wdTriggerFct_env)) { + return false; + } + + FLASHDRIVER_Init(); + + FLASH_DRIVER_ParamType tFlashParam = {.pData = (uint8_t *) sourcePageAddr, + .wdTriggerFct = (void *) 0 + }; + + tFlashParam.u32Address = targetPageAddr; + tFlashParam.u32Length = size; + FLASHDRIVER_DFlashWrite(&tFlashParam); + + return size; + + /* + flash_unlock(); + + for (size_t i = 0; i < size; ++i) { + + if (FLASH_OPERATE_DONE != flash_byte_program(targetPageAddr + i, (*(__IO uint8_t *) (sourcePageAddr + i)))) { + flash_lock(); + return i; + } + } + + flash_lock(); + + return size; + */ + /* + flash_unlock(); + uint32_t offset = 0; + + uint32_t word; + while (offset < size) { + word = iInternalFlashPage_ReadWord(sourcePageAddr + offset); + + if (FLASH_OPERATE_DONE != flash_word_program(targetPageAddr + offset, word)) { + flash_lock(); + // whole isn't written + return offset; + } + offset += 4; + } + + flash_lock(); + return size; + */ +} + +bool D_bInternalFlashPage_WriteFromRam(uint32_t beginPageAddr, void *sourceRamAddr, uint32_t size) { + FLASHDRIVER_Init(); + + FLASH_DRIVER_ParamType tFlashParam = {.pData = (uint8_t *) sourceRamAddr, + .wdTriggerFct = (void *) 0 + }; + + tFlashParam.u32Address = beginPageAddr; + tFlashParam.u32Length = size; + + if (FLASH_ERROR_OK != FLASHDRIVER_DFlashWrite(&tFlashParam)) { + return false; + } + + return true; +} + +size_t D_bInternalFlashPage_DumpFromRam( + uint32_t beginPageAddr, + void *sourceRamAddr, + uint32_t size +) { + size_t alignedSize = ((size / FLASH_PAGE_D_SIZE) + (size % FLASH_PAGE_D_SIZE ? 1 : 0)) * FLASH_PAGE_D_SIZE; + + if (!D_bInternalFlashPage_ClearRange(beginPageAddr, alignedSize,NULL, 0)) { + return 0; + } + + FLASHDRIVER_Init(); + + FLASH_DRIVER_ParamType tFlashParam = {.pData = (uint8_t *) sourceRamAddr, + .wdTriggerFct = (void *) 0 + }; + + tFlashParam.u32Address = beginPageAddr; + tFlashParam.u32Length = size; + if (FLASH_ERROR_OK != FLASHDRIVER_DFlashWrite(&tFlashParam)) { + return 0; + } + + return size; +/* + flash_unlock(); + + for (size_t i = 0; i < size; ++i) { + if (FLASH_OPERATE_DONE != flash_byte_program(beginPageAddr + i, ((uint8_t*)sourceRamAddr)[i])) { + flash_lock(); + return i; + } + } + + flash_lock(); + + return size; + */ +/* + flash_unlock(); + + uint32_t offset = 0; + + uint32_t word; + while (offset < size) { + word = *(uint32_t *) (sourceRamAddr + offset); + + if (size < 4) { + word = word & (0xFFFFFFFF >> (8 * (4 - size))); + } + + if (FLASH_OPERATE_DONE != flash_word_program(beginPageAddr + offset, word)) { + flash_lock(); + // whole isn't written + return offset; + } + offset += 4; + } + + flash_lock(); + return offset; +*/ +} + +size_t D_sInternalFlashPage_Write( + uint32_t pageAddress, + size_t offset, + uint8_t *data, + size_t size +) { + + FLASHDRIVER_Init(); + + FLASH_DRIVER_ParamType tFlashParam = {.pData = (uint8_t *) data, + .wdTriggerFct = (void *) 0 + }; + + tFlashParam.u32Address = pageAddress + offset; + tFlashParam.u32Length = size; + FLASH_StatusType ret = FLASHDRIVER_DFlashWrite(&tFlashParam); + + return size; + + /* + flash_unlock(); + + for (size_t i = 0; i < size; ++i) { + if (FLASH_OPERATE_DONE != flash_byte_program(pageAddress + i + offset, data[i])) { + flash_lock(); + return i; + } + } + + flash_lock(); + + return size; +*/ + +/* + flash_unlock(); + size_t left = size; + + while (left) { + if (left >= 4) { + if (FLASH_OPERATE_DONE != flash_word_program(pageAddress + offset, *((uint32_t *) data))) { + // whole isn't written + return size - left; + } + data += 4; + offset += 4; + left -= 4; + } else { + uint32_t word; + for (uint8_t sub_byte = 0; sub_byte < 4; ++sub_byte) { + if (sub_byte < left) { + ((uint8_t *) &word)[sub_byte] = *data; + ++data; + } else { + ++size; + ((uint8_t *) &word)[sub_byte] = 0; + } + } + + if (FLASH_OPERATE_DONE != flash_word_program(pageAddress + offset, word)) { + // whole isn't written + return size - left; + } + offset += 4; + left = 0; + + } + + } + flash_lock(); + + return size; +*/ +} diff --git a/MODULES/InternalFlashPage_Flagchip_FC7240/Src/InternalFlashPage_PFlash.c b/MODULES/InternalFlashPage_Flagchip_FC7240/Src/InternalFlashPage_PFlash.c new file mode 100644 index 0000000..38001c3 --- /dev/null +++ b/MODULES/InternalFlashPage_Flagchip_FC7240/Src/InternalFlashPage_PFlash.c @@ -0,0 +1,331 @@ +// +// Created by cfif on 07.10.22. +// +#include "InternalFlashPage.h" + +uint32_t P_iInternalFlashPage_ReadWord(uint32_t addressOnFlash) { + return (*(__IO uint32_t *) (addressOnFlash)); +} + +size_t P_sInternalFlashPage_Read( + uint32_t pageAddress, + size_t offset, + uint8_t *data, + size_t size +) { + if ((offset & (uint32_t) 0x3) != 0) { + // The offset is not a multiple of 4 + return 0; + } + + size_t left = size; + + while (left) { + if (left >= 4) { + *((uint32_t *) data) = P_iInternalFlashPage_ReadWord(pageAddress + offset); + data += 4; + offset += 4; + left -= 4; + } else { + uint32_t word = P_iInternalFlashPage_ReadWord(pageAddress + offset); + for (uint8_t sub_byte = 0; sub_byte < left; ++sub_byte) { + *data = ((uint8_t *) &word)[sub_byte]; + ++data; + } + offset += 4; + left = 0; + } + } + + return size; +} + +bool P_bInternalFlashPage_Clear( + uint32_t pageAddress +) { + FLASHDRIVER_Init(); + + FLASH_DRIVER_ParamType tFlashParam = {.pData = NULL, + .wdTriggerFct = (void *) 0 + }; + + + tFlashParam.u32Address = pageAddress; + tFlashParam.u32Length = FLASH_PAGE_P_SIZE; + if (FLASH_ERROR_OK != FLASHDRIVER_PFlashEraseSector(&tFlashParam)) { + return false; + } + + +/* + flash_unlock(); + +// if (FLASH_OPERATE_DONE != flash_block_erase(pageAddress)) { +// return false; +// } + if (FLASH_OPERATE_DONE != flash_sector_erase(pageAddress)) { + flash_lock(); + return false; + } + + flash_lock(); +*/ + return true; +} + +bool P_bInternalFlashPage_ClearRange( + uint32_t firstPageAddr, + uint32_t totalSize, + void *wdTriggerFct, + void *wdTriggerFct_env +) { + if (totalSize % FLASH_PAGE_P_SIZE) { + return false; + } + + FLASHDRIVER_Init(); + + FLASH_DRIVER_ParamType tFlashParam = { + .pData = 0, + .wdTriggerFct = wdTriggerFct, + .wdTriggerFct_env = wdTriggerFct_env, + .u32Address = firstPageAddr, + .u32Length = totalSize + }; + + FLASH_StatusType Res = FLASHDRIVER_PFlashEraseSector(&tFlashParam); + + bool result = false; + if (FLASH_ERROR_OK == Res) { + result = true; + } + + return result; + /* + uint32_t endAddr = firstPageAddr + totalSize; + for (; firstPageAddr < endAddr; firstPageAddr += FLASH_PAGE_SIZE) { + if (!P_bInternalFlashPage_Clear(firstPageAddr)) { + return false; + } + } + + return true; +*/ + +} + +bool P_bInternalFlashPage_CopyRange( + uint32_t targetPageAddr, + uint32_t sourcePageAddr, + uint32_t size, + void *wdTriggerFct, + void *wdTriggerFct_env +) { + if (!P_bInternalFlashPage_ClearRange(targetPageAddr, size, wdTriggerFct, wdTriggerFct_env)) { + return false; + } + + FLASHDRIVER_Init(); + + FLASH_DRIVER_ParamType tFlashParam = {.pData = (uint8_t *) sourcePageAddr, + .wdTriggerFct = wdTriggerFct, + .wdTriggerFct_env = wdTriggerFct_env + }; + + tFlashParam.u32Address = targetPageAddr; + tFlashParam.u32Length = size; + FLASH_StatusType result = FLASHDRIVER_PFlashWrite(&tFlashParam); + + return size; + + /* + flash_unlock(); + + for (size_t i = 0; i < size; ++i) { + + if (FLASH_OPERATE_DONE != flash_byte_program(targetPageAddr + i, (*(__IO uint8_t *) (sourcePageAddr + i)))) { + flash_lock(); + return i; + } + } + + flash_lock(); + + return size; + */ + /* + flash_unlock(); + uint32_t offset = 0; + + uint32_t word; + while (offset < size) { + word = iInternalFlashPage_ReadWord(sourcePageAddr + offset); + + if (FLASH_OPERATE_DONE != flash_word_program(targetPageAddr + offset, word)) { + flash_lock(); + // whole isn't written + return offset; + } + offset += 4; + } + + flash_lock(); + return size; + */ +} + +bool P_bInternalFlashPage_WriteFromRam(uint32_t beginPageAddr, void *sourceRamAddr, uint32_t size) { + FLASHDRIVER_Init(); + + FLASH_DRIVER_ParamType tFlashParam = {.pData = (uint8_t *) sourceRamAddr, + .wdTriggerFct = (void *) 0 + }; + + tFlashParam.u32Address = beginPageAddr; + tFlashParam.u32Length = size; + + if (FLASH_ERROR_OK != FLASHDRIVER_PFlashWrite(&tFlashParam)) { + return false; + } + + return true; +} + +size_t P_bInternalFlashPage_DumpFromRam( + uint32_t beginPageAddr, + void *sourceRamAddr, + uint32_t size +) { + size_t alignedSize = ((size / FLASH_PAGE_P_SIZE) + (size % FLASH_PAGE_P_SIZE ? 1 : 0)) * FLASH_PAGE_P_SIZE; + + if (!P_bInternalFlashPage_ClearRange(beginPageAddr, alignedSize, NULL, 0)) { + return 0; + } + + FLASHDRIVER_Init(); + + FLASH_DRIVER_ParamType tFlashParam = {.pData = (uint8_t *) sourceRamAddr, + .wdTriggerFct = (void *) 0 + }; + + tFlashParam.u32Address = beginPageAddr; + tFlashParam.u32Length = size; + if (FLASH_ERROR_OK != FLASHDRIVER_PFlashWrite(&tFlashParam)) { + return 0; + } + + return size; +/* + flash_unlock(); + + for (size_t i = 0; i < size; ++i) { + if (FLASH_OPERATE_DONE != flash_byte_program(beginPageAddr + i, ((uint8_t*)sourceRamAddr)[i])) { + flash_lock(); + return i; + } + } + + flash_lock(); + + return size; + */ +/* + flash_unlock(); + + uint32_t offset = 0; + + uint32_t word; + while (offset < size) { + word = *(uint32_t *) (sourceRamAddr + offset); + + if (size < 4) { + word = word & (0xFFFFFFFF >> (8 * (4 - size))); + } + + if (FLASH_OPERATE_DONE != flash_word_program(beginPageAddr + offset, word)) { + flash_lock(); + // whole isn't written + return offset; + } + offset += 4; + } + + flash_lock(); + return offset; +*/ +} + +size_t P_sInternalFlashPage_Write( + uint32_t pageAddress, + size_t offset, + uint8_t *data, + size_t size +) { + + FLASHDRIVER_Init(); + + FLASH_DRIVER_ParamType tFlashParam = {.pData = (uint8_t *) data, + .wdTriggerFct = (void *) 0 + }; + + tFlashParam.u32Address = pageAddress + offset; + tFlashParam.u32Length = size; + FLASH_StatusType ret = FLASHDRIVER_PFlashWrite(&tFlashParam); + + return size; + + /* + flash_unlock(); + + for (size_t i = 0; i < size; ++i) { + if (FLASH_OPERATE_DONE != flash_byte_program(pageAddress + i + offset, data[i])) { + flash_lock(); + return i; + } + } + + flash_lock(); + + return size; +*/ + +/* + flash_unlock(); + size_t left = size; + + while (left) { + if (left >= 4) { + if (FLASH_OPERATE_DONE != flash_word_program(pageAddress + offset, *((uint32_t *) data))) { + // whole isn't written + return size - left; + } + data += 4; + offset += 4; + left -= 4; + } else { + uint32_t word; + for (uint8_t sub_byte = 0; sub_byte < 4; ++sub_byte) { + if (sub_byte < left) { + ((uint8_t *) &word)[sub_byte] = *data; + ++data; + } else { + ++size; + ((uint8_t *) &word)[sub_byte] = 0; + } + } + + if (FLASH_OPERATE_DONE != flash_word_program(pageAddress + offset, word)) { + // whole isn't written + return size - left; + } + offset += 4; + left = 0; + + } + + } + flash_lock(); + + return size; +*/ +} diff --git a/MODULES/InternalFlashPage_Flagchip_FC7240/modular.json b/MODULES/InternalFlashPage_Flagchip_FC7240/modular.json new file mode 100644 index 0000000..71971cd --- /dev/null +++ b/MODULES/InternalFlashPage_Flagchip_FC7240/modular.json @@ -0,0 +1,10 @@ +{ + "cmake": { + "inc_dirs": [ + "Inc" + ], + "srcs": [ + "Src/**.c" + ] + } +} \ No newline at end of file diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_board_conf.h b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_board_conf.h new file mode 100644 index 0000000..5ce82ab --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_board_conf.h @@ -0,0 +1,58 @@ +/** + * @file fc7xxx_board_conf.h + * @author Flagchip032 + * @brief FC7xxx board configuration file + * @version 0.1.0 + * @date 2024-01-12 + * + * @copyright Copyright (c) 2022 Flagchip Semiconductors Co., Ltd. + * + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-01-12 Flagchip032 N/A First version for FC7240 + ******************************************************************************** */ + +#ifndef _DRIVER_FC7XXX_BOARD_CONF_H_ +#define _DRIVER_FC7XXX_BOARD_CONF_H_ +#include "device_header.h" + +#if defined(__cplusplus) +extern "C" { +#endif +/** + * @addtogroup fc7xxx_board_conf + * @{ + */ + +/******************* Oscillator Values *******************/ +/** + * @brief Fast OSC frequency + */ +#ifndef FOSC_FREQUENCY +#define FOSC_FREQUENCY 24000000U +#endif + +/** + * @brief Slow OSC frequency + */ +#ifndef SOSC_FREQUENCY +#define SOSC_FREQUENCY 32768U +#endif + +/** + * @brief FTU input TCLK frequency + */ +#ifndef PCC_FTU_TCLK_FREQ +#define PCC_FTU_TCLK_FREQ 0U +#endif + + +/** @}*/ /* fc7xxx_board_conf */ +#if defined(__cplusplus) +} +#endif +#endif diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_adc.h b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_adc.h new file mode 100644 index 0000000..51b715f --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_adc.h @@ -0,0 +1,422 @@ +/** + * @file fc7xxx_driver_adc.h + * @author Flagchip0126 + * @brief FC7xxx ADC driver type definition and API + * @version 0.1.0 + * @date 2024-01-15 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-01-15 Flagchip0126 N/A First version for FC7240 + ******************************************************************************** */ + +#ifndef _DRIVER_FC7XXX_DRIVER_ADC_H_ +#define _DRIVER_FC7XXX_DRIVER_ADC_H_ +#include "device_header.h" +#include "HwA_adc.h" +#include "fc7xxx_driver_dma.h" + +#if defined(__cplusplus) +extern "C" { +#endif +/** + * @addtogroup fc7xxx_driver_adc + * @{ + */ + +/** + * @name ADC0 Internal Channels + * @brief Available internal ADC channels for ADC Instance 0 + * + * @{ + */ +#define ADC0_CHANNEL_VBG_BUFFER ADC_CHANNEL_INTERNAL_0 +#define ADC0_CHANNEL_V25 ADC_CHANNEL_INTERNAL_1 +#define ADC0_CHANNEL_V11 ADC_CHANNEL_INTERNAL_2 +#define ADC0_CHANNEL_CMP0_DAC ADC_CHANNEL_INTERNAL_4 +#define ADC0_CHANNEL_TEMPSENSOR_OUT ADC_CHANNEL_INTERNAL_5 /* Must be in differential mode */ +/** @}*/ + +/** + * @name ADC1 Internal channels + * @brief Available internal ADC channels for ADC Instance 1 + * + * @{ + */ +#define ADC1_CHANNEL_V11_PD0 ADC_CHANNEL_INTERNAL_0 +#define ADC1_CHANNEL_VREFH ADC_CHANNEL_INTERNAL_1 +#define ADC1_CHANNEL_VDDA ADC_CHANNEL_INTERNAL_2 +#define ADC1_CHANNEL_V15 ADC_CHANNEL_INTERNAL_3 +#define ADC1_CHANNEL_CMP1_DAC ADC_CHANNEL_INTERNAL_4 +/** @}*/ + +/** + * @brief The ADC conversion complete callback function prototype + * + */ +typedef void (*ADC_ConvCompleteCallbackType)(const uint32_t *const pBuff); + +/** + * @brief The ADC overrun callback function prototype + * + */ +typedef void (*ADC_OverRunInterruptCallbackType)(void); + +/** + * @brief The ADC compare callback function prototype + * + */ +typedef void (*ADC_CompareInterruptCallbackType)(void); + +/** + * @brief The ADC end of sequence group callback function prototype + * + */ +typedef void (*ADC_EndOfSeqGroupInterruptCallbackType)(uint8_t u8SeqGroupIdx); + +/** + * @brief The instance index of the ADC peripheral + * + */ +typedef enum +{ + ADC_INSTANCE_0 = 0U, /*!< ADC instance 0 is selected */ + ADC_INSTANCE_1 = 1U, /*!< ADC instance 1 is selected */ +} ADC_InstanceType; + +/** + * @brief The channel selected for ADC conversion + * + */ +typedef enum +{ + ADC_CHANNEL_0 = 0U, + ADC_CHANNEL_1 = 1U, + ADC_CHANNEL_2 = 2U, + ADC_CHANNEL_3 = 3U, + ADC_CHANNEL_4 = 4U, + ADC_CHANNEL_5 = 5U, + ADC_CHANNEL_6 = 6U, + ADC_CHANNEL_7 = 7U, + ADC_CHANNEL_8 = 8U, + ADC_CHANNEL_9 = 9U, + ADC_CHANNEL_10 = 10U, + ADC_CHANNEL_11 = 11U, + ADC_CHANNEL_12 = 12U, + ADC_CHANNEL_13 = 13U, + ADC_CHANNEL_14 = 14U, + ADC_CHANNEL_15 = 15U, + ADC_CHANNEL_16 = 16U, + ADC_CHANNEL_17 = 17U, + ADC_CHANNEL_18 = 18U, + ADC_CHANNEL_19 = 19U, + ADC_CHANNEL_20 = 20U, + ADC_CHANNEL_21 = 21U, + ADC_CHANNEL_22 = 22U, + ADC_CHANNEL_23 = 23U, + ADC_CHANNEL_24 = 24U, + ADC_CHANNEL_25 = 25U, + ADC_CHANNEL_26 = 26U, + ADC_CHANNEL_27 = 27U, + ADC_CHANNEL_28 = 28U, + ADC_CHANNEL_29 = 29U, + ADC_CHANNEL_30 = 30U, + ADC_CHANNEL_31 = 31U, + ADC_CHANNEL_INTERNAL_0 = 32U, + ADC_CHANNEL_INTERNAL_1 = 33U, + ADC_CHANNEL_INTERNAL_2 = 34U, + ADC_CHANNEL_INTERNAL_3 = 35U, + ADC_CHANNEL_INTERNAL_4 = 36U, + ADC_CHANNEL_INTERNAL_5 = 37U +} ADC_ChannelType; + +/** + * @brief The channel selected for ADC conversion in differential mode + * + */ +typedef enum +{ + ADC_CHANNEL_0_4 = 0U, + ADC_CHANNEL_1_5 = 1U, + ADC_CHANNEL_2_6 = 2U, + ADC_CHANNEL_3_7 = 3U, + ADC_CHANNEL_TEMPSENSOR = 37U +} ADC_DifferentialChannelType; + +/** + * @brief The ADC sample time option for selection + * + */ +typedef enum +{ + ADC_SAMPLE_TIME_OPTION_0 = 0U, + ADC_SAMPLE_TIME_OPTION_1 = 1U, + ADC_SAMPLE_TIME_OPTION_2 = 2U, + ADC_SAMPLE_TIME_OPTION_3 = 3U +} ADC_SampleTimeOptionType; + +/** + * @brief The ADC SequenceGroup Index + * + */ +typedef enum +{ + ADC_SEQUENCE_GROUP_0 = 0U, + ADC_SEQUENCE_GROUP_1 = 1U, + ADC_SEQUENCE_GROUP_2 = 2U, + ADC_SEQUENCE_GROUP_3 = 3U +} ADC_SequenceGroupIndex; + +/** + * @brief ADC operation return values + * + */ +typedef enum +{ + ADC_STATUS_SUCCESS = 0x0U, /*!< The ADC operation is succeed */ + ADC_STATUS_ERROR = 0x1U, /*!< The ADC operation is failed */ + ADC_STATUS_TIMEOUT = 0x2U /*!< The ADC operation is failed because of time out */ +} ADC_StatusType; + +/** + * @brief Defines the converter configuration + * + * This structure is used to configure the ADC converter + * + * Implements : ADC_InitType + */ +typedef struct +{ + ADC_ResolutionType eResolution; /*!< ADC eResolution (8,10,12 bit) */ + ADC_AlignType eAlign; /*!< ADC alignment (left, right) */ + ADC_TrigModeType eTriggerMode; /*!< ADC trigger type (software, hardware) + - affects only the first control channel */ + bool bWaitEnable; /*!< Whether to enable ADC wait conversion mode */ + bool bSequenceGroupModeEnable; /*!< Whether to enable ADC sequence group mode, if true, ignore eSequenceMode*/ + bool bCalEnable; /*!< Whether to enable ADC calibration > */ + int32_t s32CalOffset; /*!< ADC calibration offset value > */ + int32_t s32CalGain; /*!< ADC calibration gain value > */ + ADC_TrgLatchUnitPri eTrgLatchUnitPri; /*!< Select priority of Trigger Latch Unit */ + ADC_ClockDivideType eClockDivider; /*!< ADC clock divider */ + ADC_SeqModeType eSequenceMode; /*!< ADC sequence mode (single, continuous, discontinuous) */ + bool bAutoDis; /*!< Whether to enable audo disable mode, only set this when adc in off state */ + ADC_OvrModeType eOverrunMode; /*!< Whether to preserve data when ADC overruns */ + ADC_RefType eVoltageRef; /*!< Voltage reference used (external, internal) */ + bool bHwAvgEnable; /*!< Enable averaging functionality */ + ADC_AverageType eHwAverage; /*!< Selection for number of samples used for averaging */ + uint8_t aSampleTimes[ADC_SAMPLE_TIME_OPTION_CNT]; /*!< ADC sample time options, range: 4 ~ 257 */ +} ADC_InitType; + +/** + * @brief The configuration option for the ADC channel + * + */ +typedef struct +{ + ADC_ChannelType eChannel; /*!< Selected ADC channel */ + ADC_SampleTimeOptionType eSampleTimeOption; /*!< The sample time selection for the channel */ + bool bDiff; /*!< Whether diff mode, if a channel do not support differential mode, ignore this */ +} ADC_ChannelCfgType; + +/** + * @brief The configuration option for the ADC sequence group + * + */ +typedef struct +{ + uint8_t u8Start; /*!< Sequence channel start */ + uint8_t u8Len; /*!< Sequence group length, is must be >= 0 */ +} ADC_SequenceGroupType; + + +/** + * @brief Defines the hardware compare configuration + * + * This structure is used to configure the hardware compare feature for the ADC + * + * Implements : ADC_CompareType + */ +typedef struct +{ + /* ADC_CMP_CTRL */ + bool bCmpEnable; /*!< Enable hardware compare */ + ADC_CmpChannelType eCmpSingleChn; /*!< 0: ADC compare on all channels; + 1: ADC compare on the selected channel */ + uint8_t u8CmpChnSel; /*!< Compare channel selection */ + + /* ADC_CMP_TR */ + uint16_t u16HighThres; /*!< Compare high threshold */ + uint16_t u16LowThres; /*!< Compare low threshold */ +} ADC_CompareType; + +/** + * @brief Defines the interrupt configuration + * + * This structure is used to configure the enabled interrupts and interrupt + * callbacks for ADC + * + */ +typedef struct +{ + /* ADC_INT_ENABLE */ + bool bConversionCompleteIntEn; /*!< Enable interrupt when conversion completed */ + bool bOverRunIntEn; /*!< Enable interrupt when overrun occured */ + bool bAnalogCmpIntEn; /*!< Enable interrupt when conversion result lays in the compare threshold */ + bool bEndOfSeqGroupIntEn; /*!< Enable interrupt when sequence group complete >*/ + uint32_t *pResultBuffer; /*!< When conversion complete interrupt is enabled, you shall provide the + result buffer to store the conversion results, this buffer only used for mode 0 ~ 3 */ + uint32_t *pSequenceGroupResultBuffer[ADC_SEQUENCE_GROUP_CNT]; /*!< When conversion complete interrupt is enabled, you shall provide the + result buffer to store the conversion results, these buffer only used for mode 4 */ + ADC_ConvCompleteCallbackType pConvCompleteNotify; /*!< Conversion complete interrupt callback */ + ADC_OverRunInterruptCallbackType pOverRunNotify; /*!< Overrun interrupt callback */ + ADC_CompareInterruptCallbackType pCompareNotify; /*!< Compare interrupt callback */ + ADC_EndOfSeqGroupInterruptCallbackType pEndOfSeqGroupNotify; /*!< End of Sequence End callback >*/ +} ADC_InterruptType; + +/** + * @brief Defines the DMA configuretion + * + * This structure is used to configure the DMA result transfer feature for ADC + * + */ +typedef struct +{ + bool bDmaEnable; /*!< Enable DMA for the ADC */ + ADC_SequenceGroupIndex eSeqGroupIndex; /*!< Only valid when SequenceGroupEn = true, otherwish ignore this */ + DMA_InstanceType eDmaInstance; /*!< The instance of DMA to use */ + DMA_ChannelType eDmaChannel; /*!< The DMA channel used to transfer the ADC conversion results */ + uint8_t u8ChannelPriority; /*!< The DMA channel priority, higher value means higher priority. + The priority for different channels must be unique. Default priority + value is same the channel number */ + uint32_t *pResultBuffer; /*!< Buffer to store the ADC conversion results */ + ADC_ConvCompleteCallbackType pConvCompleteNotify; /*!< DMA transfer complete callback */ +} ADC_DmaType; + +/** + * @brief Provide the default values of ADC_InitType + * + * @param pInitCfg the structure to initialize + */ +void ADC_InitStructure(ADC_InitType *const pInitCfg); + +/** + * @brief Initialize the ADC instance + * + * @param eInstance the ADC instance to init + * @param pInitCfg the configurations of the ADC instance + */ +void ADC_Init(const ADC_InstanceType eInstance, const ADC_InitType *const pInitCfg); + +/** + * @brief De-initialize the ADC instance + * + * Restore the ADC instance to its reset state + * + * @param eInstance the ADC instance to de-init + */ +void ADC_DeInit(const ADC_InstanceType eInstance); + +/** + * @brief Configure the ADC sample channels + * + * @param eInstance the ADC instance to use + * @param pChannels the channels to use + * @param u8ChnCnt the quantity of channels + */ +void ADC_InitChannel(const ADC_InstanceType eInstance, const ADC_ChannelCfgType aChannels[], + const uint8_t u8ChnCnt); + +/** + * @brief Configure the Sequence groups + * + * @param eInstance the ADC instance to use + * @param aSeqGroup the sequence groups to use + * @param u8SeqGroupCnt the quantity of sequence groups + */ +void ADC_InitSequenceGroup(const ADC_InstanceType eInstance, const ADC_SequenceGroupType aSeqGroup[], + const uint8_t u8SeqGroupCnt); + +/** + * @brief Configure the hardware compare feature of ADC + * + * @param eInstance the ADC instance to use + * @param pCmpCfg the compare paremeters + */ +void ADC_InitCompare(const ADC_InstanceType eInstance, const ADC_CompareType *const pCmpCfg); + +/** + * @brief Configure the interrupt of ADC + * + * @param eInstance the ADC instance to use + * @param pInterruptCfg the interrupt paremeters + */ +void ADC_InitInterrupt(const ADC_InstanceType eInstance, + const ADC_InterruptType *const pInterruptCfg); + +/** + * @brief Configure the DMA feature of ADC + * + * @param eInstance the ADC instance to use + * @param pAdcDmaCfg the DMA paremeters for the ADC instance + */ +void ADC_InitDmaChannel(const ADC_InstanceType eInstance, const ADC_DmaType *const pAdcDmaCfg); + +/** + * @brief Enable the ADC instance + * + * @param eInstance the ADC instance to enable + * @return ADC_StatusType whether ADC is enabled successfully + */ +ADC_StatusType ADC_Enable(const ADC_InstanceType eInstance); + +/** + * @brief Disable the ADC instance + * + * @param eInstance the ADC instance to disable + * @return ADC_StatusType whether ADC is disabled successfully + */ +ADC_StatusType ADC_Disable(const ADC_InstanceType eInstance); + +/** + * @brief Start the ADC conversion + * + * If the ADC sequence mode is single or continuous, and the trigger mode is ADC_TRIGMODE_SW, + * the adc conversion will start immediately. Otherwise, the ADC will wait for the trigger + * signal to start the conversion + * + * @param eInstance the ADC instance to start + */ +void ADC_Start(const ADC_InstanceType eInstance); + +/** + * @brief Stop the ADC conversion + * + * If the ADC sequence mode is single, it will stop the ongoing conversion. If no ongoing + * conversion, it will have no effect. If the ADC sequence mode is continuous or discontinuous, + * it will stop the ongoing conversion and meanwhile the further conversions. + * + * @param eInstance the ADC instance to stop + * @return ADC_StatusType whether ADC is stopped successfully + */ +ADC_StatusType ADC_Stop(const ADC_InstanceType eInstance); + +/** + * @brief Reset the ADC hardware + * + * @param eInstance the ADC instance to reset + */ +void ADC_Reset(const ADC_InstanceType eInstance); + +/** @}*/ + +/** @}*/ /* fc7xxx_driver_adc */ +#if defined(__cplusplus) +} +#endif +#endif diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_aontimer.h b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_aontimer.h new file mode 100644 index 0000000..56fc655 --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_aontimer.h @@ -0,0 +1,140 @@ +/** + * @file fc7xxx_driver_aontimer.h + * @author Flagchip + * @brief FC7xxx aontimer driver type definition and API + * @version 0.1.0 + * @date 2024-01-10 + * + * @copyright Copyright (c) 2023 Flagchip Semiconductors Co., Ltd. + * + * @details + */ +/******************************************************************************** +* Revision History: +* +* Version Date Initials CR# Descriptions +* --------- ---------- ------------ ---------- --------------- +* 0.1.0 2024-01-10 Flagchip0076 N/A First version for FC7240 +********************************************************************************/ + + +#ifndef DRIVER_INCLUDE_FC7XXX_DRIVER_AONTIMER_H_ +#define DRIVER_INCLUDE_FC7XXX_DRIVER_AONTIMER_H_ + +#include "HwA_aontimer.h" + +/** + * @addtogroup fc7xxx_driver_aontimer + * @{ + */ + +/** @brief Aontimer return type. */ +typedef enum +{ + AONTIMER_STATUS_SUCCESS = 0U, /**< Aontimer status is success.*/ + AONTIMER_STATUS_PARAM_INVALID = 1U, /**< Aontimer failed for param invalid.*/ + AONTIMER_STATUS_CLOCK_INVALID = 2U /**< Aontimer failed for colck invalid.*/ +} AONTIMER_StatusType; + +/** @brief Aontimer debug mode */ +typedef enum +{ + AONTIMER_DBG_COUNTER_STOP = 0x00U, /**< Aontimer is stop in debug mode.*/ + AONTIMER_DBG_COUNTER_RUNNING = 0x01U /**< Aontimer is running in debug mode.*/ +} AONTIMER_DebugType; + +/** @brief Aontimer mode. */ +typedef enum +{ + AONTIMER_COUNTER_MODE = 0, /**< In this mode ,the clock source is internal.*/ + AONTIMER_PULSE_MODE /**< In this mode ,the clock source is external(pin/trgsel).*/ +} AONTIMER_ModeType; + +/** @brief callback function type */ + +typedef void (*Aontimer_InterruptCallBackType)(void); + +typedef struct +{ + bool bIntEn; /**< whether to use interrupt */ + Aontimer_InterruptCallBackType pIsrNotify; /**< the notification function of interrupt */ +} AONTIMER_IntType; + +/** @brief Aontimer Initialization struct type */ +typedef struct +{ + AONTIMER_ModeType eMode; /**< enumeration of aontier mode */ + + AONTIMER_DebugType eDbgMode; /**< enumeration of aontier debug mode */ + + bool bBypassEn; /**< Whether to use prescaler in counter mode or use glitch filter in pulse mode, + if set input value is true ,then not use the prescaler or glitch filter.*/ + AONTIMER_PulseClkSrcType ePulseClkSrc; /**< clock source of pulse mode */ + AONTIMER_PulsePolarityType ePulsePol; /**< polarity of pulse mode */ + uint8_t u8PulseFilterWidth; /**< the width of glitch filter in pulse mode , the range of the input value is :1~15, + and the range of glitch filter is :2^1 ~ 2^15. */ + uint8_t u8Prescaler; /**< the width of prescaler in counter mode, the range of the input value is :0~15, + and the range of prescaler is :2^1 ~ 2^16. */ + AONTIMER_ClkSrcType eClkSrc; /**< clock source of counter mode */ + uint16_t u16StartValue; /**< start value of counter mode ,the range is : 0 ~ 65535 */ +} AONTIMER_InitType; + +/* global function */ +/** + * @brief Initialize aontimer instance + * + * @param pInitStruct Aontimer Initialize structure + */ +void AONTIMER_Init(const AONTIMER_InitType *const pInitStruct); + +/** + * @brief De-initialize aontimer instance + * + */ +void AONTIMER_Deinit(void); + +/** + * @brief Initialize aontimer interrupt functionality + * + * @param pIntStruct Aontimer interrupt structure + * @return Aontimer return type + * @note this function will disable timer + */ +AONTIMER_StatusType AONTIMER_InitInterrupt(const AONTIMER_IntType *const pIntStruct); + +/** + * @brief Enable AONTIMER interrupt + * @note this function will enable AONTIEMR timer. + */ +void AONTIMER_EnableInterrupt(void); + +/** + * @brief Disable AONTIMER interrupt + * @note this function will enable AONTIEMR timer. + * + */ +void AONTIMER_DisableInterrupt(void); + +/** + * @brief Start Aontimer + * + */ +void AONTIMER_StartTimer(void); + +/** + * @brief Stop Aontimer + * + */ +void AONTIMER_StopTimer(void); + +/** + * @brief Update value of aontimer counter + * + * @param u16StartValue input value, range : 0~65535 + */ +void AONTIMER_UpdateCounterValue(const uint16_t u16StartValue); + + +/** @}*/ /* fc7xxx_driver_aontimer */ + +#endif /* DRIVER_INCLUDE_FC7XXX_DRIVER_AONTIMER_H_ */ diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_cmp.h b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_cmp.h new file mode 100644 index 0000000..d41657c --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_cmp.h @@ -0,0 +1,295 @@ +/** + * @file fc7xxx_driver_cmp.h + * @author Flagchip + * @brief FC7xxx CMP driver type definition and API + * @version 0.1.0 + * @date 2024-01-15 + * + * @copyright Copyright (c) 2023 Flagchip Semiconductors Co., Ltd. + * + */ +/******************************************************************************** +* Revision History: +* +* Version Date Initials CR# Descriptions +* --------- ---------- ------------ ---------- --------------- +* 0.1.0 2024-01-15 Flagchip0126 N/A First version for FC7240 +********************************************************************************/ +#ifndef _DRIVER_FC7XXX_DRIVER_CMP_H_ +#define _DRIVER_FC7XXX_DRIVER_CMP_H_ +#include "HwA_cmp.h" + + + +#if defined(__cplusplus) +extern "C" { +#endif + +/********* Local typedef ************/ + +/** + * @brief The CMP complete interrupt callback function prototype + * + */ +typedef void (*CMP_CompleteIntCallback)(void); + +/** + * @brief The instance index of the CMP Dac parts + */ +typedef struct +{ + bool bDacEn; /*!< CMP DAC enable/disable */ + uint8_t u8DacData; /*!< CMP DAC output voltage, output = Vin / 256 * (aDacData + 1) */ + CMP_DacEnableSrcType eDacEnsrc; /*!< CMP DAC enable selection(DCR,CCR0) */ + CMP_DacVinRefSelType eVinRefSel; /*!< CMP DAC high voltage reference (vrefh0,vrefh1) */ +} CMP_DacType; + +/** + * @brief The instance index of the CMP Mux parts + */ +typedef struct +{ + CMP_INSrcSelType eINPSel; /*!< CMP input positive select(DAC or analog mux) */ + CMP_INSrcSelType eINNSel; /*!< CMP input negative select(DAC or analog mux) */ + CMP_MuxSelType ePSelMux; /*!< CMP input positive mux select, this is ignored in channel scan mode */ + CMP_MuxSelType eNSelMux; /*!< CMP input negative mux select, this is ignored in channel scan mode */ + CMP_MuxSelType eChannelScanFixedChannel; /*!< CMP channel scan fixed channel select, this is ignored if DAC is enabled */ + CMP_PortSelType eChannelScanFixedPort; /*!< CMP channel scan fixed channel port select */ +} CMP_MuxType; + +/** + * @brief The instance index of the CMP Comparator parts + */ +typedef struct +{ + bool bStopModEn; /*!< CMP stop mode enable */ + bool bOutToPackagePinEn; /*!< CMP output to package pin enable */ + bool bWinSampleInvertEn; /*!< CMP window/sample signal invert enable */ + bool bEventCloseWinEn; /*!< CMP out event close window enable */ + bool bAnalogConfTransByp; /*!< CMP analog configuration transition bypass enable */ + uint16 u16AnalogConfTransBypCnt; /*!< Target count value for bypass function */ + uint8_t u8FilterPeriod; /*!< CMP set Filter Sample Period */ + CMP_ModSelType eModSel; /*!< CMP set function mode */ + CMP_InvertType eInvert; /*!< CMP output Invert or not(invert, non-invert) */ + CMP_OutSelectType eOutSelect; /*!< CMP output filter or not(CMPO = CMPOUT_FILTER/CMPOUT_WIN) */ + CMP_OutWinLevelType eOutWinLevel; /*!< CMP output when window close(hold, userdefine) */ + CMP_OutWinLevel_UserDefType eOutWin; /*!< CMP output under userdefine (0, 1) */ + CMP_EventType eEventSelect; /*!< CMP output event cause window close(rising edge, falling edge) */ + CMP_FilterCntType eFilterCnt; /*!< CMP filter count numbers(0,1,2,3,4) */ + CMP_SpeedModSelType eSpeedMod; /*!< CMP speed mode(low,high) */ + CMP_HystCtrlType eHystCrtl; /*!< CMP hysteresis internal control(0,1,2,3) */ +} CMP_ComparatorType; + +/** + * @brief Defines the comparator interrupt configuration + * + * @note This structure is used to configure CMP interrupt + * Implements : CMP_InterruptType + */ +typedef struct +{ + bool bRisingIntEn; /*!< Enable/disable rising interrupt */ + bool bFallingIntEn; /*!< Enable/disable falling interrupt */ + bool bChannelScanFlagIntEn; /*!< Enable/disable channel scan flag interrupt */ + CMP_CompleteIntCallback pInterrupterNotify; /*!< CMP complete interrupt callback */ +} CMP_InterruptType; + +/** + * @brief Defines the comparator dma configuration + * + * @note This structure is used to configure CMP dma + * Implements : CMP_DmaType + */ +typedef struct +{ + bool bRisingDmaEn; /*!< Enable/disable rising edge trigger dma */ + bool bFallingDmaEn; /*!< Enable/disable falling edge trigger dma */ +} CMP_DmaType; + +/** + * @brief Defines the comparator channel selected in channel scan mode + * + * @note This structure is used to configure a CMP channel that want to be enabled in channel scan sequence + * Implements : CMP_ChannelScanChannelCfgType + */ +typedef struct +{ + CMP_MuxSelType eChannel; /*!< Enabled channel */ + bool bPreSetState; /*!< Preset state for the given channel */ + bool bCurState; /*!< Current state for the given channel */ +} CMP_ChannelScanChannelCfgType; + +/** + * @brief Defines the comparator channel scan configuration + * + * @note This structure is used to configure CMP channel scan + * Implements : CMP_ChannelScanType + */ +typedef struct +{ + uint8_t u8ChannelScanInitModulus; /*! C/C++ Build -> Settings -> Tool Settings -> Target Processor -> Float ABI -> FP instructions(hard) -> FPU Type set to "fpv5-sp-d16" +2) configure FCIDE to enable FPU compiler support, "Properties" -> C/C++ Build -> Settings -> Tool Settings -> GNU Arm Cross C Compiler -> Preprocessor -> Defined symbols(-D) -> Add "__FPU_PRESENT=1" (without ") +3) and call FPU_Enable to enable FPU at the beginning of program. + +If want to use DSP, +1) configure FCIDE to enable FPU compiler support, Properties -> C/C++ Build -> Settings -> Tool Settings -> Target Processor -> Float ABI -> FP instructions(hard) +2) add MACRO "DRIVER_CM7_DSP_ENABLE" in FCIDE Properties -> C/C++ General -> Paths and Symbols -> Symbols -> GNU C and GNU C++ and Assembly +3) add Include Path to project Properties -> C/C++ General -> Paths and Symbols -> Includes -> GNU C and GNU C++ and Assembly: + ../../../../../Template/Device/CMSIS5_590/DSP/Include + ../../../../../Template/Device/CMSIS5_590/Core/Include + ../../../../../Template/Device/CMSIS5_590/DSP/PrivateInclude +4) and call FPU_Enable to enable FPU at the beginning of program. + @endverbatim + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-01-11 Flagchip054 N/A First version for FC7240 + ******************************************************************************** */ +#ifndef _DRIVER_FC4XXX_DRIVER_DSP_H_ +#define _DRIVER_FC4XXX_DRIVER_DSP_H_ + +#include "device_header.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +#if defined(__cplusplus) +} +#endif +#endif /* _DRIVER_FC4XXX_DRIVER_DSP_H_ */ diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_eim.h b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_eim.h new file mode 100644 index 0000000..2978ac6 --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_eim.h @@ -0,0 +1,87 @@ +/** + * @file fc7xxx_driver_eim.h + * @author Flagchip + * @brief FC7xxx EIM driver type definition and API + * @version 0.1.0 + * @date 2024-01-14 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + */ +/******************************************************************************** +* Revision History: +* +* Version Date Initials CR# Descriptions +* --------- ---------- ------------ ---------- ------------------- +* 0.1.0 2024-01-14 qxw0100 N/A First version for FC7240 +********************************************************************************/ +#ifndef _DRIVER_FC7XXX_DRIVER_EIM_H_ +#define _DRIVER_FC7XXX_DRIVER_EIM_H_ + +#include "HwA_eim.h" +#include "device_header.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +/** + * @addtogroup fc4xxx_driver_eim + * @{ + */ + + +/** + * @brief Initialize EIM function + * + * @param pEimInitCfg Initialization structure of EIM + * @return return 0: initialize successful. 1: invalid parameter + */ +EIM_RetType EIM_Init(const EIM_InitType *pEimInitCfg); + +/** + * @brief Initialize EIM function + * + * @param eEimChannel channel want to set + * @param eDwpType Cpu to use + * @param bLockStatus Lock the cpu control settings + * @return Set operation success/failed + */ +EIM_RetType EIM_SetDwpMode(const EIM_ChannelType eEimChannel, const EIM_DWPType eDwpType, bool bLockStatus); + +/** + * @brief Deinin EIM function + * + */ +void Eim_Deinit(void); + +/** + * @brief Enable CPU lockstep monitor + * + * @param eEimCpuType EIM_CPU0_LOCKSTEP or EIM_CPU1_LOCKSTEP + * @param eMonitorType EIM_MONITOR0 or EIM_MONITOR1 + */ +void EIM_CpuLockStepMonitorSet_MonSet(const EIM_CPU_ChnType eEimCpuType,const EIM_MONType eMonitorType); + +/** + * @brief Clear CPU lockstep monitor + * + * @param eEimCpuType EIM_CPU0_LOCKSTEP or EIM_CPU1_LOCKSTEP + * @param eMonitorType EIM_MONITOR0 or EIM_MONITOR1 + */ +void EIM_CpuLockStepMonitorSet_MonClr(const EIM_CPU_ChnType eEimCpuType,const EIM_MONType eMonitorType); + +/** + * @brief Clean CPU lockstep monitor bit + * + * @param eEimCpuType EIM_CPU0_LOCKSTEP or EIM_CPU1_LOCKSTEP + * @param eMonitorType EIM_MONITOR0 or EIM_MONITOR1 + */ +void EIM_CpuLockStepMonitorClr(const EIM_CPU_ChnType eEimCpuType, const EIM_MONType eMonitorType); + +/** @} */ /* fc7xxx_driver_eim */ + +#if defined(__cplusplus) +} +#endif +#endif /* _DRIVER_FC4XXX_DRIVER_EIM_H_ */ diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_erm.h b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_erm.h new file mode 100644 index 0000000..2b74128 --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_erm.h @@ -0,0 +1,107 @@ +/** + * @file fc7xxx_driver_erm.h + * @author Flagchip + * @brief FC7xxx ERM driver type definition and API + * @version 0.1.0 + * @date 2024-01-14 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + */ +/******************************************************************************** +* Revision History: +* +* Version Date Initials CR# Descriptions +* --------- ---------- ------------ ---------- --------------- +* 0.1.0 2024-01-14 qxw0100 N/A First version for FC7240 +********************************************************************************/ +#ifndef _DRIVER_FC7XXX_DRIVER_ERM_H_ +#define _DRIVER_FC7XXX_DRIVER_ERM_H_ + +#include "HwA_erm.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +/* @addtogroup fc7xxx_driver_erm + * @{ + */ + +typedef enum +{ + ERM_STATUS_SUCCESS = 0U, /**< ERM status success */ + ERM_STATUS_PARAM_INVALID = 1U /**< ERM status parameter invalid */ +} ERM_RetType; + +/** @brief Erm interrupt notification type */ +typedef void (*ERM_InterruptCallBackType)(void); + +/** + * @brief Structure to configure ERM Init type + * + */ +typedef struct +{ + ERM_ChannelType eChannel; /*!< ERM enable memory No, No 0-31 */ + ERM_InterruptType eInt; /*!< ERM Interrupt type */ + uint8 u8ErmEnable; /*!< ERM enable Interrupt */ + ERM_InterruptCallBackType pIsrNotify; /**< Erm interrupt notification function pointer */ +} ERM_MemorytInitType; +/** + * @brief Initialize ERM function + * + * @param pErmInt_cfg Initialization structure of ERM + * @return return 0: initialize successful. 1: invalid parameter + */ + +ERM_RetType Erm_Init(const ERM_MemorytInitType *pErmInt_cfg); + +/** + * @brief De-initialize ERM function + * Restore the ERM instance to its reset state + */ +void Erm_DeInit(void); +/** + * @brief ERM Read EARn address. + * @param eChannel The channel type + * @return u32Address The error address + */ +//uint32_t ERM_ReadAddress(ERM_channelType eChannel); + +/** + * @brief ERM Clear SRn register. + * + * This function Clear ERM SR0 register. + */ +void ERM_ClearSRnRegister(void); + +/** + * @brief ERM read SRn register. + * + * This function Clear ERM SR0 register. + * @param u8Index the SRn channel + */ +uint32_t ERM_ReadSRnVal(uint8_t u8Index); + +/** + * @brief ERM clear CRn register. + * + * This function Clear ERM CRn register. + * @param u8Index of the CRn channel + */ +void ERM_ClearCRnVal(uint8_t u8Index); + +/** + * @brief ERM clear SRn register. + * + * This function Clear ERM SR0 register. + * @param u8Index the SRn channel + */ +uint32_t ERM_ClearSRnVal(uint8_t u8Index); +/** @} */ /* fc7xxx_driver_erm */ + +#if defined(__cplusplus) +} +#endif +#endif /* _DRIVER_FC4XXX_DRIVER_ERM_H_ */ diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_fciic.h b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_fciic.h new file mode 100644 index 0000000..6915170 --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_fciic.h @@ -0,0 +1,209 @@ +/** + * @file fc7xxx_driver_fciic.h + * @author Flagchip + * @brief FC7xxx FCIIC driver type definition and API + * @version 0.2.0 + * @date 2022-12-05 + * + * @copyright Copyright (c) 2023 Flagchip Semiconductors Co., Ltd. + * + */ + +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2022/12/31 qxw0052 N/A First version for FC7300 + * 0.2.0 2023/02/14 qxw0052 N/A Fix MISRA issues + *********************************************************************************/ + +#ifndef _DRIVER_FC7XXX_DRIVER_FCIIC_H_ +#define _DRIVER_FC7XXX_DRIVER_FCIIC_H_ + +#include "HwA_fciic.h" + +/** + * @addtogroup fc7xxx_driver_iic + * @{ + */ + +/** + * \brief IIC initial data define + * + */ +typedef struct +{ + uint32_t u32ClkSrcHz; /**< module clock hz */ + uint8_t bMasterMode; /**< bMasterMode=1 master mode */ + uint8_t u8SlaveAddr; /**< if bMasterMode=0, this is used, and address format is 7bits , not ended with R/W bit */ + uint8_t bTxFifoWMrk; /**< Tx FIFO Water Mark, FIFO always on, transmit FIFO is equal or less than TXWATER, set TDF */ + uint8_t bRxFifoWMrk; /**< Tx FIFO Water Mark, FIFO always on, receive FIFO is greater than RXWATER, set RDF */ + uint8_t bEnDma; /**< Enable DMA) */ + uint32_t u32Frequency; /**< normal frequency, only used in master mode */ + +} FCIIC_InitType; + + + +/** + * \brief IIC transmit data define + * + */ +typedef struct +{ + FCIIC_TX_CMDType eCmd; /**< command type */ + uint8_t u8Data; /**< 8bit data */ +} FCIIC_TxDataType; + + +/** + * \brief IIC receive data define + * + */ +typedef struct +{ + uint8_t u8Data; /**< 8bit data */ +} FCIIC_RxDataType; + + +/** Error call back function type */ +typedef void (*FCIIC_ErrorInterrupt_CallBackType)(uint8_t u8IicIndex, uint8_t bMaster, uint32_t u32Error); + +/** Receive call back function type */ +typedef void (*FCIIC_RxInterrupt_CallBackType)(uint8_t u8IicIndex, FCIIC_RxDataType *pRxCfg); + +/** + * \brief IIC interrupt callback setting + * + */ +typedef struct +{ + uint8_t bEnErrorInterrupt; /**< enable error interrupt */ + FCIIC_ErrorInterrupt_CallBackType pErrorNotify; /**< error interrupt callback function address */ + uint8_t bEnRxInterrupt; /**< enable receive interrupt */ + FCIIC_RxInterrupt_CallBackType pRxNotify; /**< receive interrupt callback function address */ + +} FCIIC_InterruptType; + + +/** + * \brief This Function is used to initial IIC instance + * + * \param u8IicIndex Iic Index, 0,1 + * \param pInitCfg is the structure address of IIC initial configuration parameters, and it contains IIC instance + * \return 0 is ok, others are not ok + */ +uint8_t FCIIC_Init(uint8_t u8IicIndex, FCIIC_InitType *pInitCfg); + +/** + * \brief This Function is used to de-initial IIC instance + * + * \param u8IicIndex Iic Index, 0,1 + * \param pInitCfg is the structure address of IIC initial configuration parameters, bMaster should be set + * \return 0 is ok, others are not ok + */ +uint8_t FCIIC_DeInit(uint8_t u8IicIndex, FCIIC_InitType *pInitCfg); + +/** + * \brief This Function is used to configure IIC master interrupt + * + * \param u8IicIndex Iic Index, 0,1 + * \param pIntCfg contains IIC instance and interrupt callback functions + * \return 0 is ok, others are not ok + */ +uint8_t FCIIC_Master_SetInterrupt(uint8_t u8IicIndex, FCIIC_InterruptType *pIntCfg); + +/** + * \brief This Function is used to transmit data in master mode + * + * \param u8IicIndex Iic Index, 0,1 + * \param pTxData contains IIC instance and buffer address + * \return 0 is ok, others are not ok + */ +uint8_t FCIIC_Master_Transmit(uint8_t u8IicIndex, FCIIC_TxDataType *pTxData); + +/** + * \brief This Function is used to get master status + * + * \param u8IicIndex Iic Index, 0,1 + * \param eStatus is status type enumeration + * \return 0 is ok, others are not ok + */ +uint8_t FCIIC_Master_GetStatus(uint8_t u8IicIndex, FCIIC_MasterStatusType eStatus); + +/** + * \brief This Function is used to receive data when polling (not used when rx interrupt enabled) in master mode + * + * \param u8IicIndex Iic Index, 0,1 + * \param pRxData contains IIC instance + * \return 0 is ok, others are not ok + */ +uint8_t FCIIC_Master_Receive(uint8_t u8IicIndex, FCIIC_RxDataType *pRxData); + +/** + * \brief This Function is used to get master error value + * + * \param u8IicIndex Iic Index, 0,1 + * \return error value + */ +uint32_t FCIIC_Master_GetError(uint8_t u8IicIndex); + +/** + * \brief This Function is used to clear master error value + * + * \param u8IicIndex Iic Index, 0,1 + */ +void FCIIC_Master_ClrError(uint8_t u8IicIndex); + +/** + * \brief This Function is used to configure IIC slave interrupt + * + * \param u8IicIndex Iic Index, 0,1 + * \param pIntCfg contains IIC instance and interrupt callback functions + * \return 0 is ok, others are not ok + */ +uint8_t FCIIC_Slave_SetInterrupt(uint8_t u8IicIndex, FCIIC_InterruptType *pIntCfg); + +/** + * \brief This Function is used to transmit data in slave mode + * + * \param u8IicIndex Iic Index, 0,1 + * \param pTxData contains IIC instance and buffer address + * \return 0 is ok, others are not ok + */ +uint8_t FCIIC_Slave_Transmit(uint8_t u8IicIndex, FCIIC_TxDataType *pTxData); + +/** + * \brief This Function is used to receive data when polling (not used when rx interrupt enabled) in slave mode + * + * \param u8IicIndex Iic Index, 0,1 + * \param pRxData contains IIC instance and buffer address + * \return 0 is ok, others are not ok + */ +uint8_t FCIIC_Slave_Receive(uint8_t u8IicIndex, FCIIC_RxDataType *pRxData); + +/** + * \brief This Function is used to get slave error value + * + * \param u8IicIndex Iic Index, 0,1 + * \return error value + */ +uint32_t FCIIC_Slave_GetError(uint8_t u8IicIndex); + +/** + * \brief This Function is used to clear slave error value + * + * \param u8IicIndex Iic Index, 0,1 + */ +void FCIIC_Slave_ClrError(uint8_t u8IicIndex); + + +#ifdef FCIIC_MASTER_STOP + uint8_t FCIIC_Master_Stop(uint8_t u8IicIndex); +#endif + + +/** @}*/ + +#endif diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_fcpit.h b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_fcpit.h new file mode 100644 index 0000000..6eb08e9 --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_fcpit.h @@ -0,0 +1,179 @@ +/** + * @file fc7xxx_driver_fcpit.h + * @author Flagchip + * @brief FC7xxx FCPIT driver type definition and API + * @version 0.1.0 + * @date 2024-01-10 + * + * @copyright Copyright (c) 2023 Flagchip Semiconductors Co., Ltd. + * + * @details + */ +/******************************************************************************** +* Revision History: +* +* Version Date Initials CR# Descriptions +* --------- ---------- ------------ ---------- --------------- +* 0.1.0 2024-01-10 Flagchip0076 N/A First version for FC7240 +********************************************************************************/ + +#ifndef _DRIVER_FC7XXX_DRIVER_FCPIT_H_ +#define _DRIVER_FC7XXX_DRIVER_FCPIT_H_ +#include "HwA_fcpit.h" + +/** + * @addtogroup fc7xxx_driver_fcpit + * @{ + */ + +/** @brief Fcpit return type. */ +typedef enum +{ + FCPIT_STATUS_SUCCESS = 0U, + FCPIT_STATUS_PARAM_INVALID = 1U, + FCPIT_STATUS_FUNCTION_ERROR = 2U +} FCPIT_StatusType; + +/** @brief Fcpit trigger source */ +typedef enum +{ + FCPIT_TRIGGER_INTERNAL_0 = 0, + FCPIT_TRIGGER_INTERNAL_1, + FCPIT_TRIGGER_INTERNAL_2, + FCPIT_TRIGGER_INTERNAL_3, + FCPIT_TRIGGER_EXTERNAL +} FCPIT_TriggerSelectType; + +/** @brief callback function type */ +typedef void (*FCPIT_InterruptCallBackType)(void); + +typedef struct +{ + FCPIT_ChannelType eFcpitChannel; /**< Fcpit channel number */ + FCPIT_TriggerSelectType eTriggerSel; /**< trigger source */ + bool bStartOnTrigger; /**< Fcpit timer start when triggered */ + bool bStopOnInterrupt; /**< Fcpit timer stop on interrupt */ + bool bReloadOnTrigger; /**< Fcpit timer reload when triggered */ +} FCPIT_TrggerType; + +/** @brief Fcpit interrupt structure */ +typedef struct +{ + FCPIT_ChannelType eFcpitChannel; /**< Fcpit channel number */ + bool bChannelIsrEn; /**< whether to use interrupt */ + FCPIT_InterruptCallBackType pIsrNotify; /**< interrupt notification function */ +} FCPIT_IntType; + +/** @brief Fcpit initialization type */ +typedef struct +{ + FCPIT_ChannelType eFcpitChannel; /**< Fcpit channel number */ + FCPIT_TimerModeType eMode; /**< Fcpit counter mode */ + bool bChainModeEn; /**< whether to use chain mode, if use this mode, channel must not be the channel 0 */ + uint32_t u32TimerValue; /**< timer compare value, the range of value is related to the counter mode */ + + bool bDebugEn; /**< whether to use debug mode ,if enable this mode, the counter will stop when debugging. */ + bool bLowPowerModeEn; /**< Configure the timer channels to continue running or stop when the device enters the LPM mode */ +} FCPIT_InitType; + +/** @brief FCPIT instance number */ +typedef enum +{ + FCPIT_0 = 0U, +} FCPIT_InstanceType; + + +/* global functions */ +/** + * @brief Initialize Fcpit instance. + * @param eFcpit instance + * @param pInitStruct Fcpit initialization structure + * @return Fcpit return type + */ +FCPIT_StatusType FCPIT_Init(const FCPIT_InstanceType eFcpit, const FCPIT_InitType *const pInitStruct); + +/** + * @brief Initialize Fcpit trigger configuration + * @param eFcpit instance + * @param pTrgStruct Fcpit trigger structure + * @return Fcpit return type + */ +FCPIT_StatusType FCPIT_InitTrigger(const FCPIT_InstanceType eFcpit, const FCPIT_TrggerType *const pTrgStruct); + +/** + * @brief De-initialize Fcpit instance. + * @param eFcpit instance + */ +FCPIT_StatusType FCPIT_Deinit(const FCPIT_InstanceType eFcpit); + +/** + * @brief Initialize Fcpit interrupt functionality + * @param eFcpit instance + * @param pTrgStruct Fcpit interrupt structure + * @return Fcpit return type + * @note this function will stop timer + */ +FCPIT_StatusType FCPIT_InitInterrupt(const FCPIT_InstanceType eFcpit, const FCPIT_IntType *const pIntStruct); + +/** + * @brief Enable Fcpit interrupt + * @param eFcpit instance + * @param pIntStruct Fcpit interrupt structure + * @return Fcpit return type + */ +FCPIT_StatusType FCPIT_EnableInterrupt(const FCPIT_InstanceType eFcpit, const FCPIT_ChannelType eChannel); + +/** + * @brief Disable Fcpit interrupt + * @param eFcpit instance + * @param eChannel Fcpit channel + * @return Fcpit return type + */ +FCPIT_StatusType FCPIT_DisableInterrupt(const FCPIT_InstanceType eFcpit, const FCPIT_ChannelType eChannel); + +/** + * @brief Fcpit start timer + * @param eFcpit instance + * @param eChannel Fcpit channel + * @return Fcpit return type + */ +FCPIT_StatusType FCPIT_Start(const FCPIT_InstanceType eFcpit, const FCPIT_ChannelType eChannel); + +/** + * @brief Fcpit stop + * @param eFcpit instance + * @param eChannel Fcpit channel + * @return Fcpit return type + */ +FCPIT_StatusType FCPIT_Stop(const FCPIT_InstanceType eFcpit, const FCPIT_ChannelType eChannel); + +/** + * @brief Update Fcpit channel value + * @param eFcpit instance + * @param eChannel Fcpit channel + * @param u32ChannelValue in/Out value + * @return Fcpit return type + */ +FCPIT_StatusType FCPIT_UpdateChannelValue(const FCPIT_InstanceType eFcpit, const FCPIT_ChannelType eChannel, const uint32_t u32ChannelValue); + +/** + * @brief read Fcpit channel time stamps. + * @param eFcpit instance + * @param eChannel Fcpit channel + * @param *u32timeStampValue channel value + * @return Fcpit return type + */ + +FCPIT_StatusType FCPIT_ReadTimstamp(const FCPIT_InstanceType eFcpit, const FCPIT_ChannelType eChannel,uint32_t *u32timeStampValue); + +/** + * @brief Immediately update Fcpit channel value + * @param eFcpit instance + * @param eChannel Fcpit channel + * @param u32ChannelValue in/Out value + * @return Fcpit return type + */ +FCPIT_StatusType FCPIT_ImmediateUpdateChannelValue(const FCPIT_InstanceType eFcpit, const FCPIT_ChannelType eChannel, const uint32_t u32ChannelValue); + +/** @}*/ /* fc7xxx_driver_fcpit */ +#endif diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_fcsmu.h b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_fcsmu.h new file mode 100644 index 0000000..1b3d75a --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_fcsmu.h @@ -0,0 +1,251 @@ +/** + * @file fc7xxx_driver_fcsmu.h + * @author Flagchip + * @brief FC7xxx FCSMU driver type definition and API + * @version 0.1.0 + * @date 2024-01-14 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-01-14 qxw0100 N/A First version for FC7240 + ******************************************************************************** */ +#ifndef _DRIVER_FC7XXX_DRIVER_FCSMU_H_ +#define _DRIVER_FC7XXX_DRIVER_FCSMU_H_ +#include "device_header.h" +#include "HwA_fcsmu.h" +/** + * @addtogroup fc7xxx_driver_fcsmu + * @{ +. */ + +typedef enum +{ + FCSMU_INSTANCE_0 = 0U, /*!< FCSMU instance 0 is selected. */ +} FCSMU_InstanceType; + +typedef enum +{ + FCSMU_STATUS_SUCCESS = 0U, /*!< FCSMU operation is succeed. */ + FCSMU_STATUS_ERROR = 1U /*!< FCSMU operation is failed. */ +} FCSMU_StatusType; + +typedef enum +{ + FCSMU_STATE_NORMAL = 0U, /*!< FCSMU state normal */ + FCSMU_STATE_CONGIG = 1U, /*!< FCSMU state config */ + FCSMU_STATE_WARN = 2U, /*!< FCSMU state warn */ + FCSMU_STATE_FAULT = 3U /*!< FCSMU state fault */ +} FCSMU_StateType; + +typedef enum +{ + FCSMU_OP_STATE_IDLE = 0U, /*!< FCSMU operation status idle */ + FCSMU_OP_STATE_BUSY = 1U, /*!< FCSMU operation status busy */ + FCSMU_OP_STATE_FAILED = 2U, /*!< FCSMU operation status failed */ + FCSMU_OP_STATE_SUCCESSFUL = 3U /*!< FCSMU operation status successful */ +} FCSMU_OperationStatusType; + +typedef enum +{ + FCSMU_CRC_SW_MODE = 0U, /*!< FCSMU crc software mode. */ + FCSMU_CRC_TRIGGER_MODE = 1U /*!< FCSMU crc trigger mode. */ +} FCSMU_CrcModeType; + +typedef enum +{ + FCSMU_SOUT_CTRL_BY_FSM = 0U, /*!< SOUT is controlled by the FSM. */ + FCSMU_SOUT_CTRL_KEEP_LOW = 1U, /*!< SOUT keeps low. */ + FCSMU_SOUT_CTRL_BY_FSM2 = 2U, /*!< SOUT is controlled by the FSM. */ + FCSMU_SOUT_CTRL_KEEP_HIGH_THEN_FSM = 3U /*!< SOUT keeps high until a fault occures on a channel, then controlled by FSM. */ +} FCSMU_SoutControlType; + +typedef enum +{ + FCSMU_SOUT_DEFAUT_POLARITY = 0U, /*!< Default polarity. */ + FCSMU_SOUT_SWITCH_POLARITY = 1U /*!< Switch polarity. */ +} FCSMU_SoutPolarityType; + +typedef enum +{ + FCSMU_SOUT_PROTOCOL_DUAL_RAIL = 0U, + FCSMU_SOUT_PROTOCOL_TIME_SWITCH = 1U, + FCSMU_SOUT_PROTOCOL_BISTABLE = 2U, + FCSMU_SOUT_PROTOCOL_FAULT_TOGGLE = 3U, + FCSMU_SOUT_PROTOCOL_TIME_DUAL_RAIL = 4U, + FCSMU_SOUT_PROTOCOL_DIAG0 = 5U, + FCSMU_SOUT_PROTOCOL_DIAG1 = 6U, + FCSMU_SOUT_PROTOCOL_DIAG2 = 7U, +} FCSMU_SoutProtocolType; + +typedef enum +{ + FCSMU_WARNING_IRQ = 0U, + FCSMU_FAULT_IRQ = 1U, + FCSMU_CFG_TIMEOUT = 2U +} FCSMU_IQRType; + +typedef enum +{ + FCSMU_FAULT_CHANNEL_NONE = 0x0U, + FCSMU_FAULT_CHANNEL_TEMP_ERROR = 0x1U, /*!< Event from temperature sensor. */ + FCSMU_FAULT_CHANNEL_PMC_ERROR = 0x2U, /*!< Voltage out of range indication from PMC. */ + FCSMU_FAULT_CHANNEL_NVR_ERROR = 0x4U, /*!< NVR load error/System abnormal alarm signal. */ + FCSMU_FAULT_CHANNEL_STCU_BIST_ERROR = 0x8U, /*!< STCU MBIST or LBIST fail. */ + FCSMU_FAULT_CHANNEL_STCU_LS0_ERROR = 0x10U, /*!< Lockstep compare fault. */ + FCSMU_FAULT_CHANNEL_SYSTEM_CPU0_ERROR = 0x40U, /*!< System RAM CPU0 access error. */ + FCSMU_FAULT_CHANNEL_SYSTEM_NON_CPU_ERROR = 0x200U, /*!< System RAM None CPU access error. */ + FCSMU_FAULT_CHANNEL_SCM_CPU0_ERROR = 0x400U, /*!< Matrix Access Monitor ECC check CPU0 error. */ + FCSMU_FAULT_CHANNEL_SCM_NON_CPU_ERROR = 0x2000U, /*!< Matrix Access Monitor ECC check non CPU error. */ + FCSMU_FAULT_CHANNEL_CPU0_ECC_ERROR = 0x4000U, /*!< Including ITCM/DTCM/ICACHE/DCACHE. */ + FCSMU_FAULT_CHANNEL_CMU4_FAIL_ERROR = 0x80000U, /*!< CMU4 failure interrupt. */ + FCSMU_FAULT_CHANNEL_CMU_FAIL_ERROR = 0x100000U, /*!< CMU1/2 failure interrupt. */ + FCSMU_FAULT_CHANNEL_FLASH_ECC_ERROR = 0x200000U, /*!< Flash ECC error. */ + FCSMU_FAULT_CHANNEL_SCG_PLL_FOSC_ERROR = 0x400000U, /*!< PLL/FOSC loss of clock. */ + FCSMU_FAULT_CHANNEL_DMA0_ERROR = 0x800000U, /*!< DM0 AHB Error/LS Error/CFG RAM Error. */ + FCSMU_FAULT_CHANNEL_INTM0_ERROR = 0x2000000U, /*!< Interrupt Monitor error. */ + FCSMU_FAULT_CHANNEL_FMC_ERROR = 0x10000000U, /*!< FMC ECC error. */ + FCSMU_FAULT_CHANNEL_SCG_SCM_CRC_ERROR = 0x20000000U, /*!< SCG and SCM etc. CRC check error. */ + FCSMU_FAULT_CHANNEL_MAM_WDG_ERROR = 0x80000000U, /*!< MAM master access time out error. */ +} FCSMU_ChannelAssignmentType; + +/** + * @brief FCSMU Channel ISR callback function prototype + * + */ +typedef void (*FCSMU_ISRCallbackType)(FCSMU_IQRType eIrqType, uint32_t u32IrqChannel); + +typedef struct +{ + bool bEnable; /*!< Enable or disable status output. */ + bool eFastMode; /*!< Enable or disable fast mode. */ + bool bDivex; /*!< SOUT Divider Extend Control. */ + FCSMU_SoutControlType eSoutCtrl; /*!< Configure Sout Control. */ + FCSMU_SoutPolarityType ePolarity; /*!< Status output polarity. */ + FCSMU_SoutProtocolType eProtocal; /*!< Status output protocal. */ + uint32_t u32Delaytimer; /*!< Configure the safe mode request delay in cycles of CLKSAFE. */ + uint32_t u32Divder; /*!< Configure the status output divider ratio. + bDevex = 0, SOUT_freq = CLKSAFE_freq/((SOUT_DIV+1)*2*256) + bDevex = 1, SOUT_freq = CLKSAFE_freq/((SOUT_DIV+1)*2*64) + */ + uint32_t u32SoutChannel; /*!< Configure the status output channel. */ +} FCSMU_StatusOutputConfigType; + +typedef struct +{ + uint32_t u32WarnTo; /*!< FCSMU warning timeoout value. */ + uint32_t u32WarnChannel; /*!< FCSMU warning channel. */ + uint32_t u32FaultChannel; /*!< FCSMU fault channel. */ + uint32_t u32WarnInterruptChannel; /*!< FCSMU warning interrupt channel. */ + uint32_t u32FaultInterruptChannel; /*!< FCSMU fault interrupt channel. */ + uint32_t u32FaultResetChannel; /*!< FCSMU fault reset channel. */ + uint32_t u32SoftwareClearedChannel; /*!< FCSMU fault is Cleard by software. */ + FCSMU_ISRCallbackType pISRCallback; /*!< ISR callback. */ +} FCSMU_InitCfgType; + +/** + * @brief Init the FCSMU. + * + * @param pInitConfig FCSMU initial configuration. + */ +FCSMU_StatusType FCSMU_init(const FCSMU_InitCfgType *pInitConfig); + +/** + * @brief Config the FCSMU status output. + * + * @param pInitConfig FCSMU status output configuration. + */ +FCSMU_StatusType FCSMU_ConfigStatusOutput(FCSMU_StatusOutputConfigType *pInitConfig); + +/** + * @brief Generate the CRC. + * + */ +void FCSMU_CrcGen(void); + +/** + * @brief Query CRC busy status. + * + * @return FCSMU_CrcModeType CRC status. + */ +bool FCSMU_IsCrcBusy(void); + +/** + * @brief Configure the FCSMU CRC. + * + * @param eMode Crc mode. + * @return FCSMU_StatusType Status of configuration. + */ +FCSMU_StatusType FCSMU_CrcConfig(FCSMU_CrcModeType eMode); + +/** + * @brief Clear the falut flag. + * + * @param u32FaultChannel Channel flag to be cleared. + * @return FCSMU_StatusType Status of clear. + */ +FCSMU_StatusType FCSMU_ClearFaultFlag(uint32_t u32FaultChannel); + +/** + * @brief Transform state from configuration to normal. + * + * @return FCSMU_StatusType Status of Transformation. + */ +FCSMU_StatusType FCSMU_TransStateCTN(void); + +/** + * @brief Transform state from normal to configuration. + * + * @return FCSMU_StatusType Status of Transformation. + */ +FCSMU_StatusType FCSMU_TransStateNTC(void); + +/** + * @brief Inject the fault tp fcsmu. + * + * @param u32ChannelIndex channel to be injected. + */ +void FCSMU_InjectionFault(uint32_t u32ChannelIndex); + +/** + * @brief Get the fault channels fcsmu. + * + * @return Fault channels. + */ +uint32_t FCSMU_GetFaultChannel(void); + +/** + * @brief Get the interrupt state of fcsmu. + * + * @return interrupt state. + */ +uint32_t FCSMU_GetIrqState(void); + +/** + * @brief Get the NTF flags of fcsmu. + * + * @return NTF flags. + */ +uint32_t FCSMU_GetNtfFlag(void); + +/** + * @brief Get the WTF flags of fcsmu. + * + * @return WTF flags. + */ +uint32_t FCSMU_GetWtfFlag(void); + +/** + * @brief Get the NTW flags of fcsmu. + * + * @return NTW flags. + */ +uint32_t FCSMU_GetNtwFlag(void); + +/** @}*/ /* fc7xxx_driver_fcsmu. */ +#endif diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_fcspi.h b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_fcspi.h new file mode 100644 index 0000000..d6c4513 --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_fcspi.h @@ -0,0 +1,620 @@ +/** + * @file fc7xxx_driver_fcspi.h + * @author Flagchip + * @brief FC7xxx FCSPI driver type definition and API + * @version 0.1.0 + * @date 2024-1-12 + * + * @copyright Copyright (c) 2023 Flagchip Semiconductors Co., Ltd. + * + */ +/******************************************************************************** +* Revision History: +* +* Version Date Initials CR# Descriptions +* --------- ---------- ------------ ---------- --------------- +* 0.1.0 2024/01/12 Flagchip071 N/A First version for FC7240 +********************************************************************************/ +#ifndef _DRIVER_FC7XXX_DRIVER_FCSPI_H_ +#define _DRIVER_FC7XXX_DRIVER_FCSPI_H_ + +#include "device_header.h" +#include "HwA_fcspi.h" +#include "fc7xxx_driver_dma.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +/** + * @addtogroup fc4xxx_driver_fcspi + * @{ + */ + +/** + * @brief Status returned by FCSpi APIs + * + */ +typedef enum { + FCSPI_STATUS_SUCCESS = 0, /*!< API execute successfully */ + FCSPI_STATUS_INSTANCE_ERROR, /*!< FCSpi instance index parameter error */ + FCSPI_STATUS_PARAM_ERR, /*!< parameter error */ + FCSPI_STATUS_ERROR, /*!< some error occur in API */ + FCSPI_STATUS_NO_DATA, /*!< user want to transfer nothing */ + FCSPI_STATUS_BUSY, /*!< FCSpi hardware is busy, not available */ + FCSPI_STATUS_SYNC_TIMEOUT, /*!< FCSpi synchronous transfer timeout */ + FCSPI_STATUS_TRANSFER_FAIL, /*!< FCSpi transfer fail */ + + FCSPI_STATUS_TRIGGER_OK, /*!< FCSpi user trigger successfully */ + FCSPI_STATUS_TRIGGER_ABORT_TX_FAIL, /*!< FCSpi user trigger fail due to send underrun */ + FCSPI_STATUS_TRIGGER_ABORT_RX_FAIL, /*!< FCSpi user trigger fail due to receive overflow */ + FCSPI_STATUS_TRIGGER_FINISH /*!< FCSpi user trigger finish, all data already send */ +} FCSPI_StatusType; + +/** + * @name Type definition for FCSpi master/slave mode + * + */ +/**@{*/ + +/** + * @brief FCSpi hardware instances + * + * FCSpi consist of multiple hardware instances, for example, FCSPI0, FCSPI1... + * Just as the enumeration type "FCSPI_InstanceType" definition shows. + * We use variables of this type to indicate which hardware instance to use. + */ +typedef enum { + FCSPI_0 = 0, + FCSPI_1 = 1, + FCSPI_2 = 2, + FCSPI_3 = 3, + FCSPI_4 = 4, + FCSPI_5 = 5, +} FCSPI_InstanceType; + + +/** + * @brief PCS(Peripheral Chip Select) pin select + * + * FCSPI has four PCS lines, in our driver code, + * we use FCSPI_PCS_0/FCSPI_PCS_1/FCSPI_PCS_2/FCSPI_PCS_3 to present them. + * Like the above, we use enumeration type "FCSPI_PCSType" to indicate + * which PCS to connect to the external device, + * "PCS" is short for Peripheral Chip Select, + * which usually use low level voltage to select the external chip to communicate. + */ +typedef enum { + FCSPI_PCS_0 = 0U, + FCSPI_PCS_1 = 1U, + FCSPI_PCS_2 = 2U, + FCSPI_PCS_3 = 3U +} FCSPI_PCSType; + +/** + * @brief Valid PCS pin voltage polarity + * + * The external device determines the voltage polarity (low or high) of PCS to enable it. + * So, FCSpi use enumeration type "FCSPI_PcsPolarityType" to indicate + * the polarity the PCS output when select the external device + */ +typedef enum { + FCSPI_PCS_POL_ACTIVE_HIGH = 1, /*!< pcs use high level to select external device */ + FCSPI_PCS_POL_ACTIVE_LOW = 0 /*!< pcs use low level to select external device */ +} FCSPI_PcsPolarityType; + +/** + * @brief SCK(serial clock) active phase + * + * Just as the SPI bus specification says, clock polarity (CPOL) and clock phase (CPHA) determine the sample point. + * FCSpi use enumeration type "FCSPI_SckPolarityType" to present CPOL configuration. + */ +typedef enum { + FCSPI_SCK_ACTIVE_HIGH = 0, /*!< sck is high level when active (idles low). */ + FCSPI_SCK_ACTIVE_LOW = 1 /*!< sck is low level when active (idles high). */ +} FCSPI_SckPolarityType; + +/** + * @brief SCK(serial clock) sample edge + * + * Just as the SPI bus specification says, + * clock polarity (CPOL) and clock phase (CPHA) determine the sample point. + * FCSpi use enumeration type "FCSPI_SckSamplePhaseType" to present CPHA configuration. + */ +typedef enum { + FCSPI_SCK_SAMPLE_FIRST_EDGE = 0, /*!< sample on first edge of sck active polarity, change on second */ + FCSPI_SCK_SAMPLE_SECOND_EDGE = 1 /*!< changed on first edge of sck active polarity, sample on second */ +} FCSPI_SckSamplePhaseType; + +/** + * @brief The order of rx/tx handles bit + * + * When send or receive data, the MOSI and MISO handle only one bit at a time, + * FCSpi map the bit data order according to the specific configuration. + * FCSpi driver provides the enumeration type "FCSPI_BitFirstOrderType" to indicate the order. + */ +typedef enum { + FCSPI_MSB_FIRST = 0, /*!< most significant bit first handle, from msb to lsb */ + FCSPI_LSB_FIRST = 1 /*!< least significant bit first handle, from lsb to msb */ +} FCSPI_BitFirstOrderType; + + +/** + * @brief Transfer method between memory and FCSpi's registers + * + * FCSpi support transferring data by ISR, DMA, or user poll. + * + * If use ISR method, in interrupt handler function, + * the driver will write data to register "FCSPI_TX_DATA" to push it into Tx FIFO + * and read the register "FCSPI_RX_DATA" to pop data from Rx FIFO. + * When finish, the hardware will create an interrupt to notify the end. + * + * If use DMA, the DMA channel and priority should also be configured. + * After configuring these, driver user doesn't need to take care of the detail of transferring. + * Just send data or send & receive at same time. When finish, the hardware will create an interrupt to notify the end. + * + * If use User Poll mode, driver user should call + * "FCSPI_SyncTransfer" API to move the data until it return error or finished. + * In this mode, the interrupt in driver is disabled. + */ +typedef enum { + FCSPI_TRANSFER_TRIGGER_SRC_ISR = 0, /*!< software(interrupt function) move data between register and memory, when finish, notified by interrupt */ + FCSPI_TRANSFER_TRIGGER_SRC_DMA_ISR, /*!< hardware(DMA) move data between register and memory, when finish, notified by interrupt */ + FCSPI_TRANSFER_TRIGGER_SRC_USER_POLL /*!< NOT use ISR and DMA!!! driver user use API to move data between register and memory, notified by return value when finish */ +} FCSPI_TriggerSrcType; + + +/** + * @brief transfer stop callback function's prototype + * + * FCSpi use this type to define one function pointer variable, + * which is called when the transfer is aborted or finished. + */ +typedef void (*FCSPI_StopCbType)(FCSPI_InstanceType eInst, FCSPI_AtomicBoolType bIsInIsr); + + +/** + * @brief Type return by semaphore callback function + * + * If want to use synchronous tranfer API, driver user need to provide semaphore callback, + * these callback function should return value of this enumeration defined. + */ +typedef enum { + FCSPI_SEMAPHORE_SUCCESS = 0, /*!< semaphore function execute successfully */ + FCSPI_SEMAPHORE_FAIL = 1, /*!< semaphore function execute fail */ + FCSPI_SEMAPHORE_TIMEOUT = 2 /*!< wait to get semaphore until reaching deadline */ +} FCSPI_SemaphoreStatType; + +/** + * @brief Callback function to reset semaphore + * + * After calling this function, the semaphore variable has a zero semaphore count. + * Then if try to take the semaphore, the take API will blocks. + * + * If the RTOS is FreeRTOS, the reference code as following. + * + * @code + * FCSPI_SemaphoreStatType SpiSemaphoreReset(FCSPI_InstanceType eInst) + * { + * while ( xSemaphoreTake( xSemaphore, ( TickType_t ) 0 ) == pdTRUE ); + * return FCSPI_SEMAPHORE_SUCCESS; + * } + * @endcode + */ +typedef FCSPI_SemaphoreStatType (*FCSPI_SemaphoreResetCbType)(FCSPI_InstanceType eInst); + +/** + * @brief Callback function to obtain semaphore + * + * This function will only try to obtain the semaphore before the time expires. + * + * If the RTOS is FreeRTOS, the reference code as following. + * + * @code + * FCSPI_SemaphoreStatType SpiSemaphoreTake(FCSPI_InstanceType eInst, uint32_t u32Timeout) + * { + * if ( xSemaphoreTake( xSemaphore, ( TickType_t ) u32Timeout ) == pdTRUE ) + * return FCSPI_SEMAPHORE_SUCCESS; + * else + * return FCSPI_SEMAPHORE_TIMEOUT; + * } + * @endcode + */ +typedef FCSPI_SemaphoreStatType (*FCSPI_SemaphoreTakeCbType)(FCSPI_InstanceType eInst, uint32_t u32Timeout); + + +/** + * @brief Callback function to release semaphore + * + * This function will only release semaphore. + * + * If the RTOS is FreeRTOS, the reference code as following. + * + * @code + * static FCSPI_SemaphoreStatType SpiSemaphorePost(FCSPI_InstanceType eInst, FCSPI_AtomicBoolType bIsInIsr) + * { + * FCSPI_SemaphoreStatType eRet = FCSPI_SEMAPHORE_SUCCESS; + * + * (void)eInst; + * if (FCSPI_TRUE == bIsInIsr) + * { + * BaseType_t tBase = pdFALSE; + * + * if ( xSemaphoreGiveFromISR( xSemaphore, &tBase ) == pdPASS ) + * { + * portYIELD_FROM_ISR(tBase); + * eRet = FCSPI_SEMAPHORE_SUCCESS; + * } + * else + * { + * eRet = FCSPI_SEMAPHORE_FAIL; + * } + * } + * else + * { + * if ( xSemaphoreGive( xSemaphore ) == pdPASS ) + * eRet = FCSPI_SEMAPHORE_SUCCESS; + * else + * eRet = FCSPI_SEMAPHORE_FAIL; + * } + * + * return eRet; + * } + * @endcode + */ +typedef FCSPI_SemaphoreStatType (*FCSPI_SemaphorePostCbType)(FCSPI_InstanceType eInst, FCSPI_AtomicBoolType bIsInIsr); + + +/** + * @brief Asynchronous Transfer data buffer information + * + * @note @verbatim +if init frame bit count need N bytes to store, for example, 7bits need N=1 byte, 9bits need N=2bytes, 23bits need N=3bytes. +N = 1, one frame data stored in pSendBuffer using uint8_t, driver read data using step 1byte. +N = 2, one frame data stored in pSendBuffer using uint16_t, driver read data using step 2byte. +N = 3, one frame data stored in pSendBuffer using uint32_t, driver read data using step 4byte.The highest byte is dropped. +N > 3, byte count of frame data stored in the parameter pointer pSendBuffer aligned with 4bytes, + for example, one frame uses 5bytes, it will need two uint32_t, the highest 3bytes are dropped, + driver API user need declare as "uint32_t data[N]"; it use index 0 to 1, the next frame is 2 to 3. + @endverbatim + */ +typedef struct { + const uint8_t *pSendBuffer; /*!< The buffer containing data to be send, must keep valid before sending is terminated or finished, can be NULL */ + uint8_t *pReceiveBuffer; /*!< Optional, can be NULL. Buffer to store the data received.The data received is 1byte aligned, no dummy data insert. */ + uint16_t u16FrameCount; /*!< The frame count to be sent, the data stored in pSendBuffer is divided into many frames. */ +} FCSPI_AsyncDataInfType; + + +/** + * @brief Synchronous Transfer data buffer information + * + * @note @verbatim +if init frame bit count need N bytes to store, for example, 7bits need N=1 byte, 9bits need N=2bytes, 23bits need N=3bytes. +N = 1, one frame data stored in pSendBuffer using uint8_t, driver read data using step 1byte. +N = 2, one frame data stored in pSendBuffer using uint16_t, driver read data using step 2byte. +N = 3, one frame data stored in pSendBuffer using uint32_t, driver read data using step 4byte.The highest byte is dropped. +N > 3, byte count of frame data stored in the parameter pointer pSendBuffer aligned with 4bytes, + for example, one frame uses 5bytes, it will need two uint32_t, the highest 3bytes are dropped, + driver API user need declare as "uint32_t data[N]"; it use index 0 to 1, the next frame is 2 to 3. + @endverbatim + */ +typedef struct { + const uint8_t *pSendBuffer; /*!< The buffer containing data to be send, must keep valid before sending is terminated or finished, can be NULL */ + uint8_t *pReceiveBuffer; /*!< Optional, can be NULL. Buffer to store the data received.The data received is 1byte aligned, no dummy data insert. */ + uint16_t u16FrameCount; /*!< The frame count to be sent, the data stored in pSendBuffer is divided into many frames. */ + uint32_t u32Timeout; /*!< The timeout value, it will only be passed to the semaphore callback API configured by driver user */ +} FCSPI_SyncDataInfType; + +/** + * @brief tx/rx remain information + * + * + */ +typedef struct { + uint32_t u32ByteCountSendRemained; /*!< byte count remains to be sent */ + uint32_t u32ByteCountReceiveRemained; /*!< byte count remains to be get */ +} FCSPI_TransferRemainInfType; + + +/** + * @brief configuration when use DMA + * + * + */ +typedef struct { + DMA_InstanceType eDMAInstance; /*!< DMA Instance number, if DMA not used, this ignored */ + uint8_t u8RxDMAChannel; /*!< DMA channel number for Rx, if DMA not used, this ignored */ + uint8_t u8TxDMAChannel; /*!< DMA channel number for Tx, if DMA not used, this ignored */ + uint8_t u8RxDMAChannelPriority; /*!< DMA channel priority for Rx, should differ from others in project scope */ + uint8_t u8TxDMAChannelPriority; /*!< DMA channel priority for Tx, should differ from others in project scope */ +} FCSPI_TriggerDmaInfType; +/**@}*/ + + + +/** + * @name Type definition for FCSpi master mode + * + */ +/**@{*/ +/** + * @brief FCSpi Master mode configuration + * + * When One FCSpi instance used as master side, API "FCSPI_Master_Init" need this parameter to configure the driver. + * + */ +typedef struct { + uint32_t u32FCSpiSrcClk; /*!< fcspi hardware module source clock */ + + /* peripheral chip select configuration */ + FCSPI_PCSType ePcs; /*!< chip select pin */ + FCSPI_PcsPolarityType ePcsPolarity; /*!< chip select pin polarity */ + FCSPI_AtomicBoolType eIsPcsContinuous; /*!< keep PCS select enable until transfer finish */ + + /* about sample point, sample bit order */ + FCSPI_SckSamplePhaseType eSckSamplePhase; /*!< select which edge of active sck clock to capture data */ + FCSPI_SckPolarityType eSckPolarity; /*!< select output sclk clock polarity */ + FCSPI_BitFirstOrderType eBitFirstOrder; /*!< transmit LSB/MSB first */ + uint32_t u32BitCntPerSecond; /*!< baud rate in bits per second, actual baudrate is calculated in driver, it's the nearest value to this parameter */ + uint16_t u16BitCountPerFrame; /*!< bit count of one frame, should >= 8, we call the data after pcs select, before pcs become invalid, as a frame, */ + + FCSPI_TriggerSrcType eTransferTriggerSrc; /*!< type of transfer data between memory and data register of FCSPI */ + + /* if eTransferTriggerSrc is "FCSPI_TRANSFER_TRIGGER_SRC_DMA_ISR", these following fields should be set, or ingore */ + FCSPI_TriggerDmaInfType tTriggerDmaInf; /*!< if trigger src is DMA, this MUST configure */ + + /* if to be notified when transmittion successfully or aborted, need set these following fields */ + FCSPI_StopCbType pStopNotifyCb; /*!< transfer stop(transfer successfully or aborted) callback function, can be NULL */ + + /* if want to use semaphore to synchronous transfer, the following need to be set */ + FCSPI_SemaphoreResetCbType pSemaResetCb; /*!< function to reset the semaphore to init state */ + FCSPI_SemaphoreTakeCbType pSemaTakeCb; /*!< function pointer to get the semaphore */ + FCSPI_SemaphorePostCbType pSemaPostCb; /*!< function pointer to release the semaphore */ +} FCSPI_MasterCfgType; + +/** + * @brief parameters about the holding time (in us) between PCS and SCK + * + * Configure the duration (in us) of the clock voltage between PCS and SCK + */ +typedef struct { + uint32_t u32PCStoPCSHoldUs; /*!< Configures the delay cycles from the PCS negation to the next PCS assertion, in microsecond(us) */ + uint32_t u32SCKtoPCSHoldUs; /*!< Configure the delay cycles from the last SCK edge to the PCS negation, in microsecond(us) */ + uint32_t u32PCStoSCKHoldUs; /*!< Configure the delay cycles from the PCS assertion to the first SCK edge, in microsecond(us) */ +} FCSPI_MasterSckPcsHoldTimeType; + +/** + * @brief parameters about the holding time (in PCS/100) between PCS and SCK + * + * Configure the duration (in PCS/100) of the clock voltage between PCS and SCK + */ +typedef struct { + uint32_t u32PCStoPCSHoldPercentage; /*!< Configure the delay cycles from the PCS negation to the next PCS assertion, in PCS/100 */ + uint32_t u32SCKtoPCSHoldPercentage; /*!< Configure the delay cycles from the last SCK edge to the PCS negation, in PCS/100 */ + uint32_t u32PCStoSCKHoldPercentage; /*!< Configure the delay cycles from the PCS assertion to the first SCK edge, in PCS/100 */ +} FCSPI_MasterSckPcsHoldSckCycleType; + +/** + * @brief parameters about the PCS and its Polarity + * + * Configure the specific PCS to be used and its active polarity when FCSPI running as master side + */ +typedef struct { + FCSPI_PCSType ePcs; /*!< Which PCS pin to configure */ + FCSPI_PcsPolarityType ePolarity; /*!< Pin's active polarity */ +} FCSPI_MasterPcsConfType; +/**@}*/ + + +/** + * @name Type definition for FCSpi slave mode + * + */ +/**@{*/ +/** + * @brief FCSpi Slave mode configuration + * + * When One FCSpi instance used as slave side, API "FCSPI_Slave_Init" need this parameter to configure the driver. + */ +typedef struct { + FCSPI_BitFirstOrderType eBitFirstOrder; /*!< transmit LSB/MSB first */ + uint16_t u16BitCountPerFrame; /*!< bit count of one frame, should >= 8 */ + + FCSPI_PcsPolarityType ePcsPolarity; /*!< pcs polarity */ + FCSPI_PCSType ePcs; /*!< chip select pin */ + + + FCSPI_SckSamplePhaseType eSckSamplePhase; /*!< select which edge of active sck clock to capture data */ + FCSPI_SckPolarityType eSckPolarity; /*!< selects clock polarity */ + + + + FCSPI_TriggerSrcType eTransferTriggerSrc; /*!< type of transfer data between memory and data register of FCSPI */ + + /* if eTransferTriggerSrc is "FCSPI_TRANSFER_TRIGGER_SRC_DMA_ISR", these following fields should be set, or ingore */ + FCSPI_TriggerDmaInfType tTriggerDmaInf; /*!< if trigger src is DMA, this MUST configure */ + + /* if to be notified when transmittion stop(successfully, fail, aborted), need set these following fields */ + FCSPI_StopCbType pStopNotifyCb; /*!< transfer stop(successfully or fail, or aborted) callback function, can be NULL */ + + /* if want to use semaphore to synchronous transfer, the following need to be set */ + FCSPI_SemaphoreResetCbType pSemaResetCb; /*!< function to reset the semaphore to init state */ + FCSPI_SemaphoreTakeCbType pSemaTakeCb; /*!< function pointer to get the semaphore */ + FCSPI_SemaphorePostCbType pSemaPostCb; /*!< function pointer to release the semaphore */ +} FCSPI_SlaveCfgType; +/**@}*/ + +/** + * @name API declaration for FCSpi master mode + * + */ +/**@{*/ +/** + * @brief Init the FCSpi instance as spi master side + * + * @param eInst Which FCSpi Hardware instance + * @param pCfg Configuration of the FCSpi, MUST NOT NULL + * @return FCSPI_StatusType FCSPI_STATUS_SUCCESS when configure successfully. Others, some error occur. + */ +FCSPI_StatusType FCSPI_Master_Init(const FCSPI_InstanceType eInst, const FCSPI_MasterCfgType *pCfg); + +/** + * @brief Configure the holding time (in us) between PCS and SCK + * + * @param eInst Which FCSpi Hardware instance + * @param pCfg Configure the delay parameters between PCS and SCK, MUST NOT null + * @return FCSPI_StatusType FCSPI_STATUS_SUCCESS when configure successfully. Others, the hardware is busy now. + */ +FCSPI_StatusType FCSPI_Master_SetSckPcsHoldTime(const FCSPI_InstanceType eInst, const FCSPI_MasterSckPcsHoldTimeType *pCfg); + +/** + * @brief Configure the holding time (in SCK/100) between PCS and SCK + * + * @param eInst Which FCSpi Hardware instance + * @param pCfg Configure the delay parameters between PCS and SCK, MUST NOT null + * @return FCSPI_StatusType FCSPI_STATUS_SUCCESS when configure successfully. Others, the hardware is busy now. + */ +FCSPI_StatusType FCSPI_Master_SetSckPcsHoldSckPercentage(const FCSPI_InstanceType eInst, const FCSPI_MasterSckPcsHoldSckCycleType *pCfg); +/** + * @brief Select the PCS to use and configure + * + * @param eInst Which FCSpi Hardware instance + * @param pCfg Parameters about PCS configuration, MUST NOT null + * @return FCSPI_StatusType FCSPI_STATUS_SUCCESS when configure successfully. Others, the hardware is busy now. + */ +FCSPI_StatusType FCSPI_Master_SelectPcs(const FCSPI_InstanceType eInst, const FCSPI_MasterPcsConfType *pCfg); +/**@}*/ + +/** + * @name API declaration for FCSpi slave mode + * + */ +/**@{*/ +/** + * @brief Init the FCSpi instance as spi slave side + * + * @param eInst Which FCSpi Hardware instance + * @param pCfg Configuration of the FCSpi + * @return FCSPI_StatusType FCSPI_STATUS_SUCCESS when configure successfully. Others, some error occur. + */ +FCSPI_StatusType FCSPI_Slave_Init(const FCSPI_InstanceType eInst, const FCSPI_SlaveCfgType *pCfg); +/**@}*/ + +/** + * @name Type definition for FCSpi master/slave mode + * + */ +/**@{*/ +/** + * @brief Send and receive asynchronously + * 1) If the trigger source is driver user poll, this api not support this mode. + * 2) If the trigger source is interrupt or DMA, this api will start the transmission, then return immediately. + * After transmission stop, it will trigger an interrupt. + * During the transmission, the send data buffer and receive data buffer + * should keep valid until the transmission stop. + * @param eInst Which FCSpi Hardware instance + * @param pCfg the data information, MUST NOT null + * @return FCSPI_StatusType FCSPI_STATUS_SUCCESS when start transfer successfully. Others, some error occur. + */ +FCSPI_StatusType FCSPI_AsyncTransfer(const FCSPI_InstanceType eInst, const FCSPI_AsyncDataInfType *pCfg); + +/** + * @brief Send and receive synchronously + * 1) If the semaphore callbacks are configured, + * and the driver is configured transmitting triggered by interrupt, or by DMA, + * the driver will use semaphore to wait the transmission stopped. + * In this case, the timeout value is passed to semaphore callback directly. + * 2) If the semaphore callbacks are not configured, + * this api will poll the status when triggered by interrupt or DMA, + * or poll to trigger the transmission when the mode is "FCSPI_TRANSFER_TRIGGER_SRC_USER_POLL". + * In this case, the timeout value has different meaning for different trigger mode. + * Read the source code for detail. + * @param eInst Which FCSpi Hardware instance + * @param pCfg the data information, MUST NOT null + * @return FCSPI_StatusType FCSPI_STATUS_SUCCESS when transfer successfully. Others, some error occur. + */ +FCSPI_StatusType FCSPI_SyncTransfer(const FCSPI_InstanceType eInst, const FCSPI_SyncDataInfType *pCfg); + +/** + * @brief If it's in transfer, get its stat, or get the last transfer's stat. + * + * @param eInst Which FCSpi Hardware instance + * @param pCfg the transfer information, can be null + * @return FCSPI_StatusType FCSPI_STATUS_SUCCESS when the last transfer is finish successfully. Others, busy or error occur. + */ +FCSPI_StatusType FCSPI_GetLatestTransferStat(const FCSPI_InstanceType eInst, FCSPI_TransferRemainInfType *pCfg); + +/** + * @brief Abort current transfer if exist, or just recovery the hardware. + * + * @param eInst Which FCSpi Hardware instance + */ +void FCSPI_AbortTransfer(const FCSPI_InstanceType eInst); + +/** + * @brief Deinit the FCSpi + * + * @param eInst Which FCSpi Hardware instance + * @return FCSPI_StatusType FCSPI_STATUS_SUCCESS when deinit the FCSpi successfully. Others, the hardware is busy now. + */ +FCSPI_StatusType FCSPI_Deinit(const FCSPI_InstanceType eInst); + +/** + * @brief Select the trigger source(DMA with interrupt / interrupt / user poll) + * + * @param eInst Which FCSpi Hardware instance + * @param eSrc three source, 1) DMA move data between memory and registers, notified when finish by interrupt; 2) purely by interrupt; 3) purely by user poll. + * @return FCSPI_StatusType FCSPI_STATUS_SUCCESS when successfully. Others, error. + */ +FCSPI_StatusType FCSPI_SelectTriggerSrc(FCSPI_InstanceType eInst, FCSPI_TriggerSrcType eSrc); + +/** + * @brief fcspi 0 interrupt handler + * + * @note This function should be called as/in FCSPI 0 interrupt handler + */ +void FCSPI0_IRQHandler(void); + +/** + * @brief fcspi 1 interrupt handler + * + * @note This function should be called as/in FCSPI 1 interrupt handler + */ +void FCSPI1_IRQHandler(void); + +/** + * @brief fcspi 2 interrupt handler + * + * @note This function should be called as/in FCSPI 2 interrupt handler + */ +void FCSPI2_IRQHandler(void); + +/** + * @brief fcspi 3 interrupt handler + * + * @note This function should be called as/in FCSPI 3 interrupt handler + */ +void FCSPI3_IRQHandler(void); + +/** + * @brief fcspi 4 interrupt handler + * + * @note This function should be called as/in FCSPI 4 interrupt handler + */ +void FCSPI4_IRQHandler(void); + +/** + * @brief fcspi 5 interrupt handler + * + * @note This function should be called as/in FCSPI 5 interrupt handler + */ +void FCSPI5_IRQHandler(void); + +/**@}*/ + +/** @}*/ /* fc7xxx_driver_fcspi */ + +#if defined(__cplusplus) +} +#endif +#endif /* _DRIVER_FC7XXX_DRIVER_FCSPI_H_ */ diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_fcuart.h b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_fcuart.h new file mode 100644 index 0000000..1ae3a21 --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_fcuart.h @@ -0,0 +1,437 @@ +/** + * @file fc7xxx_driver_fcuart.h + * @author Flagchip + * @brief FC7xxx FCUart driver type definition and API + * @version 0.1.0 + * @date 2024-01-10 + * + * @copyright Copyright (c) 2023 Flagchip Semiconductors Co., Ltd. + * + */ + +/******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-01-10 Flagchip0122 N/A FC7xxx internal release version + ********************************************************************************/ + + +#ifndef _DRIVER_FC7XXX_DRIVER_FCUART_H_ +#define _DRIVER_FC7XXX_DRIVER_FCUART_H_ + + +#include "HwA_fcuart.h" + +/** + * @addtogroup fc7xxx_driver_fcuart + * @{ + */ + +/********* Macro ************/ +#define FCUART_FIFO_DEPTH 16U + +#define ESCAPE_CHARACTER (char)0x5c +#define ENTER (uint8_t)0x0d +#define NEW_LINE (uint8_t)0x0a +#define SPACE (uint8_t)0x20 +#define FLOAT_ZERO 0.00000001 + + +/********* Local typedef ************/ +/** + * @brief FCUART error status + * + */ +typedef enum +{ + FCUART_ERROR_OK = 0x00U, /**< FCUART_ERROR_OK means no error */ + FCUART_ERROR_INVALID_VERSION = 0x01U, /**< FCUART_ERROR_INVALID_VERSION means version is not same */ + FCUART_ERROR_FAILED = 0x02U, /**< FCUART_ERROR_FAILED means operation is failed */ + FCUART_ERROR_INVALID_PARAM = 0x04U, /**< FCUART_ERROR_INVALID_PARAM means parameters are invalid */ + FCUART_ERROR_INVALID_SIZE = 0x08U, /**< FCUART_ERROR_INVALID_SIZE means size is invalid */ + FCUART_ERROR_INVALID_SEQUENCE = 0x10U, /**< FCUART_ERROR_INVALID_SEQUENCE means sequence is error */ + FCUART_ERROR_TIMEOUT = 0x20U, /**< FCUART_ERROR_TIMEOUT means operation is timeout */ +}FCUART_ErrorTypeEnum; + +/** + * @brief UART fifo receive idle character number + */ +typedef enum +{ + FCUART_FIFO_RX_IDLE_DISABLE = 0U, + FCUART_FIFO_RX_IDLE_CHARACTER_1, + FCUART_FIFO_RX_IDLE_CHARACTER_2, + FCUART_FIFO_RX_IDLE_CHARACTER_4, + FCUART_FIFO_RX_IDLE_CHARACTER_8, + FCUART_FIFO_RX_IDLE_CHARACTER_16, + FCUART_FIFO_RX_IDLE_CHARACTER_32, + FCUART_FIFO_RX_IDLE_CHARACTER_64 +} FCUART_Fifo_RxIdleCharNumType; + + +/** + * @brief UART CTRL register interrupt + * + */ +typedef enum +{ + FCUART_INT_CTRL_ORIE = FCUART_CTRL_ORIE_MASK, + FCUART_INT_CTRL_NEIE = FCUART_CTRL_NEIE_MASK, + FCUART_INT_CTRL_FEIE = FCUART_CTRL_FEIE_MASK, + FCUART_INT_CTRL_PEIE = FCUART_CTRL_PEIE_MASK, + FCUART_INT_CTRL_TIE = FCUART_CTRL_TIE_MASK, + FCUART_INT_CTRL_TCIE = FCUART_CTRL_TCIE_MASK, + FCUART_INT_CTRL_RIE = FCUART_CTRL_RIE_MASK, + FCUART_INT_CTRL_IIE = FCUART_CTRL_IIE_MASK, + FCUART_INT_CTRL_TE = FCUART_CTRL_TE_MASK, + FCUART_INT_CTRL_RE = FCUART_CTRL_RE_MASK, + FCUART_INT_CTRL_M0IE = FCUART_CTRL_M0IE_MASK, + FCUART_INT_CTRL_M1IE = FCUART_CTRL_M1IE_MASK +} FCUART_InterruptSel; + +/** + * @brief UART error status type + * + */ +typedef enum +{ + FCUART_ERROR_NONE = 0x0000U, /**< FCUART_ERROR_NONE No Error, */ + FCUART_ERROR_RORF = 0x0001U, /**< FCUART_ERROR_RORF Receiver Overrun Flag, */ + FCUART_ERROR_NF = 0x0002U, /**< FCUART_ERROR_NF Noise Flag, */ + FCUART_ERROR_FEF = 0x0004U, /**< FCUART_ERROR_FEF Frame Error Flag, */ + FCUART_ERROR_PEF = 0x0008U, /**< FCUART_ERROR_PEF Parity Error Flag, */ + FCUART_ERROR_RPEF = 0x0010U, /**< FCUART_ERROR_RPEF Receive Data Parity Error Flag, */ + FCUART_ERROR_TPEF = 0x0020U /**< FCUART_ERROR_TPEF Transmit Data Parity Error Flag, */ +}FCUART_ErrorStatusType; + +/** + * @brief UART idle character number + */ +typedef enum +{ + FCUART_IDLE_CHARCTER_1 = 0U, + FCUART_IDLE_CHARCTER_2, + FCUART_IDLE_CHARCTER_4, + FCUART_IDLE_CHARCTER_8, + FCUART_IDLE_CHARCTER_16, + FCUART_IDLE_CHARCTER_32, + FCUART_IDLE_CHARCTER_64, + FCUART_IDLE_CHARCTER_128 +} FCUART_IdleCharNumType; + +/** + * @brief UART idle type + */ +typedef enum +{ + FCUART_START_AFTER_STARTBIT = 0U, + FCUART_START_AFTER_STOPBIT +} FCUART_IdleStartType; + +/** + * @brief UART initial data define + * + */ +typedef struct +{ + uint32_t u32ClkSrcHz; /**< module clock hz */ + FCUART_BitModeType eBitMode; /**< 8bits or 9bits */ + bool bParityEnable; /**< Parity Enable=1 */ + FCUART_ParityType eParityType; /**< parity type */ + FCUART_StopBitNumType eStopBit; /**< stop bit num; */ + bool bEnTxFifo; /**< Enable Tx FIFO, 16 data words depth */ + uint8_t u8TxFifoWaterMark; /**< Tx FIFO,When FIFO/buffer number equal or less than this + an interrupt or a DMA request will be generated */ + bool bEnRxFifo; /**< Enable Rx FIFO, 16 data words depth */ + uint8_t u8RxFifoWaterMark; /**< Rx FIFO, When FIFO/buffer number greater than this + an interrupt or a DMA request will be generated */ + FCUART_Fifo_RxIdleCharNumType eFifoRxIdleCharNum; /**< Fifo Rx idle character number */ + bool bEnTxEmptyDma; /**< Enable transmit DMA */ + bool bEnRxFullDma; /**< Enable receiver full DMA */ + bool bEnRxIdleDma; /**< Enable Rx Idle DMA */ + FCUART_IdleCharNumType eIdleCharNum; /**< Idle character number */ + FCUART_IdleStartType eIdleStart; /**< Idle character start type */ + uint32_t u32Baudrate; /**< normal baud-rate */ + uint32_t u32TransmitTimeout; /**< transmit timeout tick, default 3000U */ +} FCUART_InitType; + +/** + * @brief UART transmit and receive data define + * + */ +typedef struct +{ + uint8_t* pDatas; /**< Data buffer point, Must be initial with a array address */ + uint32_t u32DataLen; /**< data length */ +}FCUART_DataType; + +/** Error call back function type, errors are combine with FCUART_ErrorStatusType */ +typedef void (*FCUART_ErrorInterrupt_CallBackType)(uint8_t u8UartIndex, uint32_t u32Error); + +/** Transmit/Receive call back function type */ +typedef void (*FCUART_TxRxInterrupt_CallBackType)(uint8_t u8UartIndex, FCUART_DataType *pTxRxCfg); + +/** Idle call back function type */ +typedef void (*FCUART_IdleInterrupt_CallBackType)(uint8_t u8UartIndex); + +/** + * @brief UART callback functions data define + * + */ +typedef struct +{ + bool bEnErrorInterrupt; /**< enable error interrupt */ + FCUART_ErrorInterrupt_CallBackType pErrorNotify; /**< error interrupt callback function address */ + bool bEnRxInterrupt; /**< enable receive interrupt */ + FCUART_DataType *pRxBuf; /**< receive interrupt message buffer */ + FCUART_TxRxInterrupt_CallBackType pRxNotify; /**< receive interrupt callback function address */ + bool bEnTxInterrupt; /**< enable receive interrupt */ + FCUART_DataType *pTxBuf; /**< transfer interrupt message buffer */ + FCUART_TxRxInterrupt_CallBackType pTxEmptyNotify; /**< transfer empty interrupt callback function address */ + FCUART_TxRxInterrupt_CallBackType pTxCompleteNotify; /**< transfer complete interrupt callback function address */ + bool bEnIdleInterrupt; /**< enable idle interrupt */ + FCUART_IdleInterrupt_CallBackType pIdleNotify; /**< idle interrupt callback function address */ +} FCUART_InterruptType; + +/** + * @brief UART WakeUp functions data define + * + */ +typedef struct +{ + bool bEnWakeup; /**< enable wake-up */ + uint32_t u32WakeUpData; /**< wake-up data */ + +} FCUART_WakeupType; + + + +/** Errortype Define as uint8 */ +typedef uint8_t FCUART_ErrorType; + +/* ################################################################################## */ +/* ########################### Global Prototype Functions ########################### */ + + +/** + * @brief Initial UART variables Memory + * + */ +void FCUART_InitMemory(uint8_t u8UartIndex); + +/** + * @brief This Function is used to initial UART instance + * + * @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U) + * @param pInitCfg contains clock, baud-rate, Bit Mode, parity and so on. + * @return FCUART_ERROR_OK is ok, others are not ok + */ +FCUART_ErrorType FCUART_Init(uint8_t u8UartIndex, FCUART_InitType *pInitCfg); + +/** + * @brief This Function is used to de-initial UART instance + * + * @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U) + * @return FCUART_ERROR_OK is ok, others are not ok + */ +FCUART_ErrorType FCUART_DeInit(uint8_t u8UartIndex); + +/** + * @brief This Function is used to set UART interrupt + * + * @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U) + * @param pInterruptCfg contains callback functions + * @return FCUART_ERROR_OK is ok, others are not ok + */ +FCUART_ErrorType FCUART_SetInterrupt(uint8_t u8UartIndex, FCUART_InterruptType *pInterruptCfg); + +/** + * @brief This Function is used to set UART WakeUp + * + * @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U) + * @param pWakeupCfg contains UART wake-up parameters + * @return FCUART_ERROR_OK is ok, others are not ok + */ +FCUART_ErrorType FCUART_SetWakeup(uint8_t u8UartIndex, FCUART_WakeupType *pWakeupCfg); + +/** + * @brief This Function is used to start receiving + * + * @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U) + * @return FCUART_ERROR_OK is ok, others are not ok + */ +FCUART_ErrorType FCUART_StartReceive(uint8_t u8UartIndex); + +/** + * @brief This Function is used to stop receiving + * + * @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U) + * @return FCUART_ERROR_OK is ok, others are not ok + */ +FCUART_ErrorType FCUART_StopReceive(uint8_t u8UartIndex); + +/** + * @brief This Function is used to start transmit + * + * @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U) + * @return FCUART_ERROR_OK is ok, others are not ok + */ +FCUART_ErrorType FCUART_StartTransmit(uint8_t u8UartIndex); + +/** + * @brief This Function is used to stop transmitting + * + * @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U) + * @return FCUART_ERROR_OK is ok, others are not ok + */ +FCUART_ErrorType FCUART_StopTransmit(uint8_t u8UartIndex); + +/** + * @brief This Function is used to transmit UART data + * + * @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U) + * @param pUartData contains UART data and length + * @return FCUART_ERROR_OK is ok, others are not ok + */ +FCUART_ErrorType FCUART_Transmit(uint8_t u8UartIndex, FCUART_DataType *pUartData); + + +/** + * @brief This Function is used to print ASCII char from UART + * + * @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U) + * @param fmt is char format + * @return FCUART_ERROR_OK is ok, others are not ok + */ +FCUART_ErrorType FCUART_Printf(uint8_t u8UartIndex, char* fmt,...); + +/** + * @brief Get Stat Flag + * + * @param u8UartIndex UART instance + * @param eStatusType stat type + * @return FCUART STAT status flag + */ +uint32_t FCUART_GetStatus(uint8_t u8UartIndex, FCUART_StatType eStatusType); + +/** + * @brief This Function is used to receive data when polling (not used when rx interrupt enabled) + * + * @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U) + * @param pRxMsg is data buffer address, and pDatas need to be initialed with external buffer + * @return FCUART_ERROR_OK is ok, others are not ok + */ +FCUART_ErrorType FCUART_Receive_Polling(uint8_t u8UartIndex, FCUART_DataType *pRxMsg); + + +/** + * @brief This Function is used to get error when polling (not used when error interrupt enabled) + * + * @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U) + * @param pErrorValue is error value + * @return FCUART_ERROR_OK is ok, others are not ok + */ +FCUART_ErrorType FCUART_Error_Polling(uint8_t u8UartIndex, uint32_t *pErrorValue); + +/** + * @brief This Function is used to enable fcuart loop mode + * + * @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U) + * @param bStatus enable/disable status of loop mode + * @return FCUART_ERROR_OK is ok, others are not ok + * + */ +FCUART_ErrorType FCUART_SetLoopMode(uint8_t u8UartIndex, bool bStatus); + +/** + * @brief This Function is used to deal with FCUART TxRx interrupt + * + * @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U) + * + */ +void FCUARTN_RxTx_IRQHandler(uint8_t u8UartIndex); + +/** + * @brief This Function is used to send 9 bits data + * + * @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U) + * @param u16Data data to send + * @return FCUART_ERROR_OK is ok, others are not ok + * + */ +FCUART_ErrorType FCUART_SendData_9Bits(uint8_t u8UartIndex, uint16_t u16Data); + +/** + * @brief This Function is used to Get 9 bits data + * + * @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U) + * @param pData pointer to data + * @return FCUART_ERROR_OK is ok, others are not ok + * + */ +FCUART_ErrorType FCUART_GetData_9Bits(uint8_t u8UartIndex, uint16_t *pData); + +/** + * @brief This Function is used to send 10 bits data + * + * @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U) + * @param u16Data data to send + * @return FCUART_ERROR_OK is ok, others are not ok + * + */ +FCUART_ErrorType FCUART_SendData_10Bits(uint8_t u8UartIndex, uint16_t u16Data); + +/** + * @brief This Function is used to Get 10 bits data + * + * @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U) + * @param pData pointer to data + * @return FCUART_ERROR_OK is ok, others are not ok + * + */ +FCUART_ErrorType FCUART_GetData_10Bits(uint8_t u8UartIndex, uint16_t *pData); + +/** + * @brief This Function is used to set bit mode,parity and stop bit + * + * @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U) + * @param pData pointer to data + * @return FCUART_ERROR_OK is ok, others are not ok + * + */ +FCUART_ErrorType FCUART_SetBitModeAndParity( uint8_t u8UartIndex, + FCUART_BitModeType eBitMode, + FCUART_StopBitNumType eStopBit, + FCUART_ParityType eParityType, + bool bParityEnable + ); + +/** + * @brief This Function is used to Get current interrupt mode + * + * @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U) + * @param u32Data Interrupt type to get + * @return true/false + * + */ +bool FCUART_GetInterruptMode(uint8_t u8UartIndex, uint32_t u32Data); + +/** + * @brief This Function is used to assign data to send through interrupt + * + * @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U) + * @param pData data pointer + * @param u32Length data length to send + * @return FCUART_ERROR_OK is ok, others are not ok + * + */ +FCUART_ErrorType FCUART_AssignTxInterruptData(uint8_t u8UartIndex, uint8_t * pData, uint32_t u32Length); + +/** @}*/ + + +FCUART_ErrorType FCUART_BufTransmitted(uint8_t u8UartIndex, FCUART_InterruptType *pInterruptCfg); + +#endif diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_flash.h b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_flash.h new file mode 100644 index 0000000..8382b95 --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_flash.h @@ -0,0 +1,183 @@ +/** + * @file fc7xxx_driver_flash.c + * @author Flagchip + * @brief FC7xxx Flash driver type definition and API + * @version 0.1.0 + * @date 2024-01-11 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-01-11 Flagchip054 N/A First version for FC7200 + ******************************************************************************** */ +#ifndef _DRIVER_FC7XXX_DRIVER_FLASH_H_ +#define _DRIVER_FC7XXX_DRIVER_FLASH_H_ + +#include "device_header.h" + + +/** + * @addtogroup fc7xxx_driver_flash + * @{ + */ +/*********************************************************************************************************************** + * DEFINES + **********************************************************************************************************************/ + +/* ------------------------- PFlash ------------------------ */ +/** PFlash start address */ +#define PFLASH_ADDR_START 0x01000000U + +#define PFLASH_ADDR_END 0x011FFFFFU + +#define PFLASH_SIZE 0x00200000U /* 256KB */ + +#define PFLASH_BANK_SIZE 0x00100000U + +#define PFLASH_LAST256K_OFFSET 0xC0000UL + +/** Program minimum size */ +#define PFLASH_PROGRAM_PAGE_MIN_SIZE 0x08U /* 8 bytes */ +/** Program maximum */ +#define PFLASH_PROGRAM_PAGE_MAX_SIZE 0x80U /* 128 bytes */ + +/** Erase size */ +#define PFLASH_ERASE_SECTOR_SIZE 0x800U /* 2 KBytes */ + +/** Erase value of flash memory */ +#define PFLASH_ERASED_VALUE 0xFFU + +/** 4 PFlash Banks, every bank is 2MB */ +#define PFLASH_BANK_NUM 0x02U + + +/* ------------------------- DFlash ------------------------ */ + +/** DFlash total size */ +#define DFLASH_SIZE 0x00040000U /* 256KB */ +/** DFlash start address */ +#define DFLASH_ADDR_START 0x04000000U +/** DFlash end address */ +#define DFLASH_ADDR_END 0x0401FFFFU + +/** Program minimum size */ +#define DFLASH_PROGRAM_PAGE_MIN_SIZE 0x08U /* 16 bytes */ +/** Program maximum */ +#define DFLASH_PROGRAM_PAGE_MAX_SIZE 0x80U /* 128 bytes */ + +/** Erase size */ +#define DFLASH_ERASE_SECTOR_SIZE 0x800U /* 8 KBytes */ + +/** Erase value of flash memory */ +#define DFLASH_ERASED_VALUE 0xFFU + +/** 1 DFlash Banks, every bank is 2MB */ +#define DFLASH_BANK_NUM 0x01U + +/** DFlash Bank 0 size */ +#define DFLASH_BANK0_SIZE 0x00040000U + + + +#define FLASH_256KB_SIZE 0x00040000U + + +/** ########################################## Error Code ################################################ */ + + +/** + * \brief FLASH API error status + * + */ +typedef enum +{ + FLASH_ERROR_OK = 0x00U,/**< FLASH_ERROR_OK means no error */ + FLASH_ERROR_NO_INIT, /**< FLASH_ERROR_NO_INIT means rom code api address is not initialed */ + FLASH_ERROR_INVALID_VERSION, /**< FLASH_ERROR_INVALID_VERSION means rom code api version is not same */ + FLASH_ERROR_FAILED, /**< FLASH_ERROR_FAILED means operation is failed */ + FLASH_ERROR_INVALID_PARAM, /**< FLASH_ERROR_INVALID_PARAM means parameters are invalid */ + FLASH_ERROR_INVALID_ADDR, /**< FLASH_ERROR_INVALID_ADDR means address is invalid */ + FLASH_ERROR_INVALID_SIZE, /**< FLASH_ERROR_INVALID_SIZE means size is invalid */ + FLASH_ERROR_INVALID_SEQUENCE, /**< FLASH_ERROR_INVALID_SEQUENCE means sequence is error */ + FLASH_ERROR_TIMEOUT, /**< FLASH_ERROR_TIMEOUT means operation is timeout */ + FLASH_ERROR_END = 0xFFFFFFFFU /**< FLASH_ERROR_END make aligned 32bits */ +}FLASH_StatusType; + +typedef enum +{ + FLASH_BLOCK_SELECT0 =0x000u, + FLASH_BLOCK_SELECT1 =0x001u, + FLASH_DATA_BLOCK_SELECT0 =0x002u +}FLASH_API_BLOCK_SELECT_TYPE; + +/** ########################################## Type define ################################################ */ + + +/** + * \brief Flash driver parameter define + * + */ +typedef struct +{ + uint32_t u32Address; /**< Logical target address */ + uint32_t u32Length; /**< Length in logical sectors or bytes */ + uint8_t *pData; /**< Pointer to data buffer (read only) */ + uint8_t (*wdTriggerFct)(void*); /**< Pointer to watchdog handling function */ + void *wdTriggerFct_env; + uint32_t u32ErrorAddress; /**< Error address */ + +} FLASH_DRIVER_ParamType; + +/** + * \brief Initial Flash api address + * + */ +void FLASHDRIVER_Init(void); + +/** + * \brief flash driver erase block function + * + * \param blk_sel c + * \return ErrorType + */ +FLASH_StatusType FLASHDRIVER_FlashEraseBlock ( FLASH_API_BLOCK_SELECT_TYPE blk_sel ); + +/** + * \brief Pflash driver erase function, called after FLASHDRIVER_ArrayCopyToRam + * + * \param pFlashParam contains flash erase function parameter, address is align to 0x400, and length is align to 0x400 + * \return ErrorType + */ +FLASH_StatusType FLASHDRIVER_PFlashEraseSector ( FLASH_DRIVER_ParamType * pFlashParam ); + +/** + * \brief Pflash driver write function, called after FLASHDRIVER_ArrayCopyToRam + * + * \param pFlashParam contains flash write function parameter, address is align to 0x08, and length is align to 0x08 + * \return ErrorType + */ +FLASH_StatusType FLASHDRIVER_PFlashWrite ( FLASH_DRIVER_ParamType * pFlashParam ); + +/** + * \brief DFlash Driver Function for Erasing + * + * \param pFlashParam flash driver erase parameter + * \return ErrorType + */ +FLASH_StatusType FLASHDRIVER_DFlashEraseSector(FLASH_DRIVER_ParamType *pFlashParam); + +/** + * \brief DFlash Driver Function for Writing + * + * \param pFlashParam flash driver write parameter + * \return ErrorType + */ +FLASH_StatusType FLASHDRIVER_DFlashWrite(FLASH_DRIVER_ParamType *pFlashParam); + + +#endif /* end of DRIVER_FLASH_H_ */ diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_flexcan.h b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_flexcan.h new file mode 100644 index 0000000..43073c5 --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_flexcan.h @@ -0,0 +1,463 @@ +/** + * @file fc7xxx_driver_flexcan.h + * @author Flagchip + * @brief FC7xxx CAN driver type definition and API + * @version 0.1.0 + * @date 2022-02-20 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + */ + +/* ******************************************************************************** + * Revision History: + * + * Version Date Author Descriptions + * --------- ---------- ------------ --------------- + * 0.1.0 2024-1-13 Flagchip0112 First version for FC7240 + ******************************************************************************** */ + +#ifndef _DRIVER_FC4XXX_DRIVER_FLEXCAN_H_ +#define _DRIVER_FC4XXX_DRIVER_FLEXCAN_H_ + +#include "HwA_flexcan.h" + + +/* ################################################################################## */ +/* ####################################### Macro #################################### */ + +#define FLEXCAN_CHECK_PARAMETERS STD_ON + + +/* ################################################################################## */ +/* ################################### Type define ################################## */ + +/** + * @addtogroup fc7xxx_driver_can + * @{ + */ + + + + + +/** + * @brief FLEXCAN ID Type + * + */ +typedef enum +{ + FLEXCAN_ID_STD = 0x00U, /**< FLEXCAN_ID_STD standard id */ + FLEXCAN_ID_EXT = 0x01U /**< FLEXCAN_ID_EXT extended id */ +} FLEXCAN_IdType; + +/** + * @brief FLEXCAN Data Frame Type + * + */ +typedef enum +{ + FLEXCAN_FRAME_DATA = 0x00U, /**< FLEXCAN_FRAME_DATA data frame */ + FLEXCAN_FRAME_REMOTE = 0x01U /**< FLEXCAN_FRAME_REMOTE remote frame */ +} FLEXCAN_DataType; + + +/** + * @brief FLEXCAN baud-rate clock source + * + */ +typedef enum +{ + FLEXCAN_BAUDCLK_HZ_8M = 8000000U, /**< FLEXCAN_BAUDCLK_HZ_8M 8MHz clock source */ + FLEXCAN_BAUDCLK_HZ_12M = 12000000U, /**< FLEXCAN_BAUDCLK_HZ_12M 12MHz clock source */ + FLEXCAN_BAUDCLK_HZ_16M = 16000000U, /**< FLEXCAN_BAUDCLK_HZ_16M 16MHz clock source */ + FLEXCAN_BAUDCLK_HZ_24M = 24000000U, /**< FLEXCAN_BAUDCLK_HZ_24M 24MHz clock source */ + FLEXCAN_BAUDCLK_HZ_48M = 48000000U, /**< FLEXCAN_BAUDCLK_HZ_48M 48MHz clock source */ + FLEXCAN_BAUDCLK_HZ_96M = 96000000U, /**< FLEXCAN_BAUDCLK_HZ_96M 96MHz clock source */ + FLEXCAN_BAUDCLK_HZ_120M = 120000000U,/**< FLEXCAN_BAUDCLK_HZ_120M 120MHz clock source */ + FLEXCAN_BAUDCLK_HZ_150M = 150000000U /**< FLEXCAN_BAUDCLK_HZ_150M 150MHz clock source */ +} FLEXCAN_BaudClkType; + + + +/** + * @brief FLEXCAN baud-rate source + * + */ +typedef enum +{ + FLEXCAN_BAUD_100K = 100000U, /**< FLEXCAN_BAUD_100K normal bit 100Kbps */ + FLEXCAN_BAUD_125K = 125000U, /**< FLEXCAN_BAUD_100K normal bit 125Kbps */ + FLEXCAN_BAUD_250K = 250000U, /**< FLEXCAN_BAUD_250K normal bit 250Kbps */ + FLEXCAN_BAUD_500K = 500000U, /**< FLEXCAN_BAUD_500K normal bit 500Kbps */ + FLEXCAN_BAUD_800K = 800000U, /**< FLEXCAN_BAUD_500K normal bit 800Kbps */ + FLEXCAN_BAUD_1M = 1000000U,/**< FLEXCAN_BAUD_1M normal bit 1Mbps */ + FLEXCAN_BAUD_2M = 2000000U,/**< FLEXCAN_BAUD_2M normal bit 2Mbps */ + FLEXCAN_BAUD_3M = 3000000U,/**< FLEXCAN_BAUD_3M normal bit 3Mbps */ + FLEXCAN_BAUD_4M = 4000000U,/**< FLEXCAN_BAUD_4M normal bit 4Mbps */ + FLEXCAN_BAUD_5M = 5000000U,/**< FLEXCAN_BAUD_5M normal bit 5Mbps */ + FLEXCAN_BAUD_6M = 6000000U,/**< FLEXCAN_BAUD_6M normal bit 6Mbps */ + FLEXCAN_BAUD_8M = 8000000U /**< FLEXCAN_BAUD_8M normal bit 8Mbps */ +} FLEXCAN_BaudType; + +/** + * @brief FLEXCAN data length type + * + */ +typedef enum +{ + FLEXCAN_DATAWIDTH_8 = 8U, /**< FLEXCAN_DATALEN_8 8 bytes data width */ + FLEXCAN_DATAWIDTH_16 = 16U,/**< FLEXCAN_DATALEN_16 16 bytes data width */ + FLEXCAN_DATAWIDTH_32 = 32U,/**< FLEXCAN_DATALEN_32 32 bytes data width */ + FLEXCAN_DATAWIDTH_64 = 64U /**< FLEXCAN_DATALEN_64 64 bytes data width */ + +} FLEXCAN_DataWidthType; + +/** + * @brief FLEXCAN data length type + * + */ +typedef enum +{ + FLEXCAN_DIR_DISABLE = 0U, /**< FLEXCAN_DATALEN_8 8 bytes data width */ + FLEXCAN_DIR_ENABLE_WITHOUT_TRIG = 1U, /**< FLEXCAN_DATALEN_8 8 bytes data width */ + FLEXCAN_DIR_ENABLE_WITH_TRIG = 3U /**< FLEXCAN_DATALEN_8 8 bytes data width */ +} FLEXCAN_DirectType; + +/** + * @brief FLEXCAN init structure definition + */ +typedef struct +{ + FLEXCAN_ClockSrcType eClkSrcSel; /**< Clock Source Select */ + FLEXCAN_BaudClkType eClkSrcHz; /**< clock hz for baud-rate */ + uint8_t bListenOnly; + uint8_t bEnFd; /**< enable FLEXCAN fd */ + uint8_t bEnBrs; /**< data bit baud-rate used */ + uint8_t bEnRxFifo; /**< Rx FIFO */ + uint8_t bEnDma; /**< The DMA feature FLEXCAN only be used in Rx FIFO */ + uint8_t u8EnhancedFifoDmaWM; /**< The DMA watermark only work in CANFD FIFO mode, range 1- 12 */ + FLEXCAN_BaudType eBaudrate; /**< normal baud-rate */ + FLEXCAN_BaudType eDataBaud; /**< data baud-rate */ + FLEXCAN_DataWidthType eMbDataWidth; /**< when bEnFd=0, only FLEXCAN be set 8; when bEnFd=1, FLEXCAN be set as 8/16/32/64 */ + FLEXCAN_DirectType eDirect; /** C/C++ Build -> Settings -> Tool Settings -> Target Processor -> Float ABI -> FP instructions(hard) -> FPU Type set to "fpv5-sp-d16" +2) configure FCIDE to enable FPU compiler support, "Properties" -> C/C++ Build -> Settings -> Tool Settings -> GNU Arm Cross C Compiler -> Preprocessor -> Defined symbols(-D) -> Add "__FPU_PRESENT=1" (without ") +3) and call FPU_Enable to enable FPU at the beginning of program. + +If want to use DSP, +1) configure FCIDE to enable FPU compiler support, Properties -> C/C++ Build -> Settings -> Tool Settings -> Target Processor -> Float ABI -> FP instructions(hard) +2) add MACRO "DRIVER_CM7_DSP_ENABLE" in FCIDE Properties -> C/C++ General -> Paths and Symbols -> Symbols -> GNU C and GNU C++ and Assembly +3) add Include Path to project Properties -> C/C++ General -> Paths and Symbols -> Includes -> GNU C and GNU C++ and Assembly: + ../../../../../../Template/Device/CMSIS5_590/DSP/Include + ../../../../../../Template/Device/CMSIS5_590/Core/Include + ../../../../../../Template/Device/CMSIS5_590/DSP/PrivateInclude +4) and call FPU_Enable to enable FPU at the beginning of program. + @endverbatim + */ +void FPU_Enable(void); + +/** + * @brief Disable the FPU hardware. + * + */ +void FPU_Disable(void); + +/** @} */ /* fc7xxx_driver_fpu */ +#if defined(__cplusplus) +} +#endif +#endif /* _DRIVER_FC4XXX_DRIVER_FPU_H_ */ diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_freqm.h b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_freqm.h new file mode 100644 index 0000000..14a6d02 --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_freqm.h @@ -0,0 +1,143 @@ +/** + * @file fc7xxx_driver_freqm.h + * @author Flagchip + * @brief FC7xxx FREQM driver type definition and API + * @version 0.1.0 + * @date 2024-01-14 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + * @details + */ +/******************************************************************************** +* Revision History: +* +* Version Date Initials CR# Descriptions +* --------- ---------- ------------ ---------- --------------- +* 0.1.0 2024-01-14 qxw0100 N/A First version for FC7240 +********************************************************************************/ + +#ifndef _DRIVER_FC4XXX_DRIVER_FREQM_H_ +#define _DRIVER_FC4XXX_DRIVER_FREQM_H_ + +#include "HwA_freqm.h" +#include "stddef.h" +#if defined(__cplusplus) +extern "C" { +#endif + +/** + * @brief FREQM operation return values + * + */ +typedef enum +{ + FREQM_STATUS_SUCCESS = 0U, /*!< The FREQM operation is succeed */ + FREQM_STATUS_PARAM_INVALID, /*!< The FREQM operation is failed because of parameter error */ + FREQM_STATUS_TIMEOUT, /*!< The FREQM operation is failed because of time out */ +} FREQM_StatusType; + +/** + * @brief The FREQM measure counter start interrupt callback function prototype + * + */ +typedef void (*FREQM_MesCntStartCallBackType)(void); + +/** + * @brief The FREQM measure counter stop interrupt callback function prototype + * + */ +typedef void (*FREQM_MesCntStopCallBackType)(void); + +/** + * @brief The FREQM reference counter stop interrupt callback function prototype + * + */ +typedef void (*FREQM_RefCntStopCallBackType)(void); +/** + * @brief The FREQM fault interrupt callback function prototype + * + */ +typedef void (*FREQM_FaultCallBackType)(void); + + +/** + * @brief The configuration option for the FREQM interrupt + * + */ +typedef struct +{ + bool bIntEnable; /*!< interrupt enable mask */ + FREQM_MesCntStartCallBackType pMesCntStartCallback; /*!< Measure Counter Start interrupt callback */ + FREQM_MesCntStopCallBackType pMesCntStopCallback; /*!< Measure Counter Stop interrupt callback */ + FREQM_RefCntStopCallBackType pRefCntStopCallback; /*!< Reference Counter Stop interrupt callback */ + FREQM_FaultCallBackType pFaultCallback; /*!< Fault interrupt callback */ +} FREQM_InterruptType; + +/** + * @brief The basic configuration option for the FREQM peripheral + * + */ +typedef struct +{ + uint32_t u32MesLen; + uint32_t u32RefTo; + FREQM_MesClkSelType eClkSel; /*!< Ftu clock source */ + uint8_t u8PredivVal; /*!< Frequency of the Reload Opportunities. Range is 0-31, */ +} FREQM_InitType; + + +/** + * @brief Initialize FREQM configuration + * + * @param pInitStruct the basic configurations of the FREQM + * @return FREQM_StatusType whether the operation is successfully + */ +FREQM_StatusType FREQM_Init(const FREQM_InitType *const pInitStruct); + +/** + * @brief De-initialize the FREQM + * + * @param eInstance the selected FREQM + * @return FREQM_StatusType whether the operation is successfully + */ +FREQM_StatusType FREQM_DeInit(void); + +/** + * @brief Start the FREQM + * + * @return FREQM_StatusType whether the operation is successfully + */ +FREQM_StatusType FREQM_ClearStatus(void); + +/** + * @brief Start the reference/measure counter + * + */ +void FREQM_StartMeasureCnt(void); + +/** + * @brief Get saved reference counter value + * + * @return uint32_t saved reference counter value + */ +uint32_t FREQM_GetRefCntSave(void); + +/** + * @brief Interrupt IRQ handle of FREQM + * + */ +void FREQM_IRQHandler(void); +/** + * @brief FREQM initialize interrupt function + * + * @param pIntStruct FREQM interrupt structure + * @return FREQM_StatusType whether the operation is successfully + */ +FREQM_StatusType FREQM_InterruptInit(const FREQM_InterruptType *const pIntrStruct); + +/** @}*/ /* fc7xxx_driver_freqm */ +#if defined(__cplusplus) +} +#endif +#endif diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_ftu.h b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_ftu.h new file mode 100644 index 0000000..120ac10 --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_ftu.h @@ -0,0 +1,855 @@ +/** + * @file fc7xxx_driver_ftu.h + * @author Flagchip070 + * @brief FC7xxx FTU driver type definition and API + * @version 0.1.0 + * @date 2022-11-15 + * + * @copyright Copyright (c) 2022 Flagchip Semiconductors Co., Ltd. + * + * @details + */ +/******************************************************************************** +* Revision History: +* +* Version Date Initials CR# Descriptions +* --------- ---------- ------------ ---------- --------------- +* 0.1.0 2022-11-15 Flagchip070 N/A First version for FC7300 +********************************************************************************/ + +#ifndef _DRIVER_FC4XXX_DRIVER_FTU_H_ +#define _DRIVER_FC4XXX_DRIVER_FTU_H_ +#include "HwA_ftu.h" +#include "stddef.h" +#if defined(__cplusplus) +extern "C" { +#endif + +/** + * @addtogroup fc7xxx_driver_ftu + * @{ + */ + +/** + * @name FTU Channel Bit Flag + * @brief Bit of channel indicate channel number + * + * @{ + */ +#define BIT_FTU_CHANNEL_0 0x01U +#define BIT_FTU_CHANNEL_1 0x02U +#define BIT_FTU_CHANNEL_2 0x04U +#define BIT_FTU_CHANNEL_3 0x08U +#define BIT_FTU_CHANNEL_4 0x10U +#define BIT_FTU_CHANNEL_5 0x20U +#define BIT_FTU_CHANNEL_6 0x40U +#define BIT_FTU_CHANNEL_7 0x80U +/** @}*/ + +/** + * @name FTU Fault Bit Flag + * @brief Bit of fault flag + * + * @{ + */ +#define FTU_FAULT_INPUT_0 0x01U +#define FTU_FAULT_INPUT_1 0x02U +/** @}*/ + +/** + * @brief Max number of Ftu fault + * + */ +#define FTU_FAULT_COUNT 2u + +/** + * @brief Max number of Ftu input count + * + */ +#define FTU_INPUT_FILTER_COUNT 4u +/** + * @brief FTU operation return values + * + */ +typedef enum +{ + FTU_STATUS_SUCCESS = 0U, /*!< The FTU operation is success */ + FTU_STATUS_PARAM_INVALID, /*!< The FTU operation is failed because of parameter error */ + FTU_STATUS_NO_CLOCK_SOURCE, /*!< The FTU operation is failed because of instance clock source is not set */ +} FTU_StatusType; + +/** + * @brief The FTU overflow and reload point callback function prototype + * + */ +typedef void (*FTU_InterruptCallBackType)(void); + +/** + * @brief The FTU fault callback function prototype + * + */ +typedef void (*FTU_FaultCallBackType)(uint32_t); + +/** + * @brief The FTU channel callback function prototype + * + */ +typedef void (*FTU_ChannelCallBackType)(uint32_t, uint32_t); + +/** + * @brief The instance index of the FTU peripheral + * + */ +typedef enum +{ + FTU_INSTANCE_0 = 0U, + FTU_INSTANCE_1, + FTU_INSTANCE_2, + FTU_INSTANCE_3, + FTU_INSTANCE_4, + FTU_INSTANCE_5, + FTU_INSTANCE_6, + FTU_INSTANCE_7, +} FTU_InstanceType; + +/** + * @brief The channel index of the FTU peripheral + * + */ +typedef enum +{ + FTU_CHANNEL_0 = 0U, + FTU_CHANNEL_1, + FTU_CHANNEL_2, + FTU_CHANNEL_3, + FTU_CHANNEL_4, + FTU_CHANNEL_5, + FTU_CHANNEL_6, + FTU_CHANNEL_7 +} FTU_ChannelType; + +/** + * @brief The clock source of FTU peripheral + * + */ +typedef enum +{ + FTU_NO_CLK = 0U, /*!< No clock selected */ + FTU_INTERNAL_CLK = 1U, /*!< FTU input clock */ + FTU_EXTERNAL_CLK0 = 3U, /*!< External pin 0 input clock */ + FTU_EXTERNAL_CLK1 = 4U, /*!< External pin 1 input clock */ + FTU_EXTERNAL_CLK2 = 5U /*!< External pin 2 input clock */ +} FTU_ClkSrcType; + +/** + * @brief The channel operation of output compare mode + * + */ +typedef enum +{ + FTU_OUTPUT_TOGGLE_PIN = 0U, /*!< Toggle Output on match */ + FTU_OUTPUT_CLEAR_PIN, /*!< Clear Output on match */ + FTU_OUTPUT_SET_PIN /*!< Set Output on match */ +} FTU_OutputComparePinModeType; + +/** + * @brief The initial level of the output compare channel + * + */ +typedef enum +{ + FTU_OUTPUT_CMP_INIT_LOW = 0U, /*!< The initial level is low */ + FTU_OUTPUT_CMP_INIT_HIGH, /*!< The initial level is high */ +} FTU_OutputCompareInitLevelType; + +/** + * @brief The channel operation of PWM mode + * + */ +typedef enum +{ + FTU_PWM_HIGH_TRUE_PULSE = 0U, /*!< High-true pulses in PWM */ + FTU_PWM_LOW_TRUE_PULSE, /*!< Low-true pulses in PWM */ +} FTU_PwmPinModeType; + +/** + * @brief PWM Aligned Mode + * + */ +typedef enum +{ + FTU_EDGE_ALIGNED_PWM = 0u, /*!< Edge-Aligned PWM */ + FTU_CENTER_ALIGNED_PWM /*!< Center-Aligned PWM */ +}FTU_PwmAlignedType; + +/** + * @brief The measurement is single or continuous + * + */ +typedef enum +{ + FTU_MEASURE_SINGLE_MODE = 0u, /*!< Single mode */ + FTU_MEASURE_CONTINUOUS_MODE /*!< Continuous mode */ +} FTU_MeasureContModeType; + +/** + * @brief Timing of start measurement + * + */ +typedef enum +{ + FTU_MEASURE_START_AFTER_EDGE = 0u, /*!< The channel starts measuring after the first edge is detected */ + FTU_MEASURE_START_IMMEDIATELY /*!< The measurement starts immediately after activating the channel */ +}FTU_MeasureStartModeType; + +/** + * @brief The reload point flag of FTU peripheral + * + */ +typedef enum +{ + FTU_RELOAD_POINT_CNTMAX = 1u, /*!< Maximum Loading Point */ + FTU_RELOAD_POINT_CNTMIN = (1u << 1), /*!< Minimum Loading Point */ + FTU_RELOAD_POINT_CHANNEL_0 = (1u << 2), /*!< Channel 0 match is included as a reload opportunity */ + FTU_RELOAD_POINT_CHANNEL_1 = (1u << 3), /*!< Channel 1 match is included as a reload opportunity */ + FTU_RELOAD_POINT_CHANNEL_2 = (1u << 4), /*!< Channel 2 match is included as a reload opportunity */ + FTU_RELOAD_POINT_CHANNEL_3 = (1u << 5), /*!< Channel 3 match is included as a reload opportunity */ + FTU_RELOAD_POINT_CHANNEL_4 = (1u << 6), /*!< Channel 4 match is included as a reload opportunity */ + FTU_RELOAD_POINT_CHANNEL_5 = (1u << 7), /*!< Channel 5 match is included as a reload opportunity */ + FTU_RELOAD_POINT_CHANNEL_6 = (1u << 8), /*!< Channel 6 match is included as a reload opportunity */ + FTU_RELOAD_POINT_CHANNEL_7 = (1u << 9), /*!< Channel 7 match is included as a reload opportunity */ +} FTU_ReloadPointCfgType; + +/** + * @brief The synchronization flag of FTU peripheral + * + */ +typedef enum +{ + FTU_SYNC_FLAG_FTUEN = 1u, /*!< FTU Enable */ + FTU_SYNC_FLAG_LDOK = (1u << 1), /*!< Load Enable */ + FTU_SYNC_FLAG_CNTINC = (1u << 2), /*!< CNTIN Register Synchronization */ + FTU_SYNC_FLAG_PWMSYNC = (1u << 3), /*!< Synchronization Mode: Selects which triggers can be used + by MOD, CV, OUTMASK, and FTU counter synchronization. */ + FTU_SYNC_FLAG_REINIT = (1u << 4), /*!< FTU Counter re-initialization by Synchronization */ + FTU_SYNC_FLAG_SYNCHOM = (1u << 5), /*!< Selects when the OUTMASK register is updated with the + value of its buffer */ + FTU_SYNC_FLAG_SYNCEN01 = (1u << 6), /*!< synchronization of registers C(0)V and C(1)V. */ + FTU_SYNC_FLAG_SYNCEN23 = (1u << 7), /*!< synchronization of registers C(2)V and C(3)V. */ + FTU_SYNC_FLAG_SYNCEN45 = (1u << 8), /*!< synchronization of registers C(4)V and C(5)V. */ + FTU_SYNC_FLAG_SYNCEN67 = (1u << 9), /*!< synchronization of registers C(6)V and C(7)V. */ + FTU_SYNC_FLAG_HW_TRIG0 = (1u << 10), /*!< hardware trigger 0 to the synchronization */ + FTU_SYNC_FLAG_HW_TRIG1 = (1u << 11), /*!< hardware trigger 1 to the synchronization */ + FTU_SYNC_FLAG_HW_TRIG2 = (1u << 12), /*!< hardware trigger 2 to the synchronization */ +} FTU_SyncFlagType; + +/** + * @brief The interrupt enable/disable mask of FTU peripheral + * + */ +typedef enum +{ + FTU_INTR_MASK_CHANNEL_0 = 1u, /*!< interrupt mask of channel 0 */ + FTU_INTR_MASK_CHANNEL_1 = (1u << 1), /*!< interrupt mask of channel 1 */ + FTU_INTR_MASK_CHANNEL_2 = (1u << 2), /*!< interrupt mask of channel 2 */ + FTU_INTR_MASK_CHANNEL_3 = (1u << 3), /*!< interrupt mask of channel 3 */ + FTU_INTR_MASK_CHANNEL_4 = (1u << 4), /*!< interrupt mask of channel 4 */ + FTU_INTR_MASK_CHANNEL_5 = (1u << 5), /*!< interrupt mask of channel 5 */ + FTU_INTR_MASK_CHANNEL_6 = (1u << 6), /*!< interrupt mask of channel 6 */ + FTU_INTR_MASK_CHANNEL_7 = (1u << 7), /*!< interrupt mask of channel 7 */ + FTU_INTR_MASK_OVERFLOW = (1u << 8), /*!< interrupt mask of overflow */ + FTU_INTR_MASK_FAULT = (1u << 9), /*!< interrupt mask of fault */ + FTU_INTR_MASK_RELOAD_POINT = (1u << 10), /*!< interrupt mask of reload point */ +} FTU_IntrMaskType; + +/** + * @brief The fault control enable/disable mask for channels + * + */ +typedef enum +{ + FTU_FAULT_FOR_CHANNEL01 = 1u, /*!< fault control for channel 0 and channel 1 */ + FTU_FAULT_FOR_CHANNEL23 = (1u << 1), /*!< fault control for channel 2 and channel 3 */ + FTU_FAULT_FOR_CHANNEL45 = (1u << 2), /*!< fault control for channel 4 and channel 5 */ + FTU_FAULT_FOR_CHANNEL67 = (1u << 3), /*!< fault control for channel 6 and channel 7 */ +} FTU_FaultChannelEnableType; + +/** + * @brief the fault input polarity + * + */ +typedef enum +{ + FTU_FAULT_POL_ACTIVE_HIGH = 0u, /*!< The fault input polarity is active high. + 1 at the fault input indicates a fault */ + FTU_FAULT_POL_ACTIVE_LOW = 1u, /*!< The fault input polarity is active low. + 0 at the fault input indicates a fault */ +}FTU_FaultPolActiveType; + +/** + * @brief the output trigger mask + * + */ +typedef enum +{ + FTU_TRIG_OUTPUT_MASK_CHANNEL_0_MATCH = 1u, /*!< Enables/Disables the channel 0 match trigger */ + FTU_TRIG_OUTPUT_MASK_CHANNEL_1_MATCH = (1u << 1), /*!< Enables/Disables the channel 1 match trigger */ + FTU_TRIG_OUTPUT_MASK_CHANNEL_2_MATCH = (1u << 2), /*!< Enables/Disables the channel 2 match trigger */ + FTU_TRIG_OUTPUT_MASK_CHANNEL_3_MATCH = (1u << 3), /*!< Enables/Disables the channel 3 match trigger */ + FTU_TRIG_OUTPUT_MASK_CHANNEL_4_MATCH = (1u << 4), /*!< Enables/Disables the channel 4 match trigger */ + FTU_TRIG_OUTPUT_MASK_CHANNEL_5_MATCH = (1u << 5), /*!< Enables/Disables the channel 5 match trigger */ + FTU_TRIG_OUTPUT_MASK_CHANNEL_6_MATCH = (1u << 6), /*!< Enables/Disables the channel 6 match trigger */ + FTU_TRIG_OUTPUT_MASK_CHANNEL_7_MATCH = (1u << 7), /*!< Enables/Disables the channel 7 match trigger */ + FTU_TRIG_OUTPUT_MASK_ALL_CHANNEL_MATCH = (0xFFu), /*!< Enables/Disables all channel match trigger */ + FTU_TRIG_OUTPUT_MASK_RELOAD = (1u << 8), /*!< Enables/Disables reload trigger */ +}FTU_TriggerOutputMaskType; + +/** @brief Ftu input capture mode */ +typedef enum +{ + FTU_INPUT_RISING_EDGE = 0U, /*!< capture on rising edge only */ + FTU_INPUT_FALLING_EDGE, /*!< capture on falling edge only */ + FTU_INPUT_BOTH_EDGE /*!< capture on rising or falling edge */ +} FTU_InputCapturePinModeType; + +/** @brief Ftu Global Time Base instance start mask */ +typedef enum +{ + FTU_GTB_INSTANCE_START_FTU0 = 1u, /*!< FTU0 GTB start */ + FTU_GTB_INSTANCE_START_FTU1 = (1u << 1), /*!< FTU1 GTB start */ + FTU_GTB_INSTANCE_START_FTU2 = (1u << 2), /*!< FTU2 GTB start */ + FTU_GTB_INSTANCE_START_FTU3 = (1u << 3), /*!< FTU3 GTB start */ + FTU_GTB_INSTANCE_START_FTU4 = (1u << 4), /*!< FTU4 GTB start */ + FTU_GTB_INSTANCE_START_FTU5 = (1u << 5), /*!< FTU5 GTB start */ + FTU_GTB_INSTANCE_START_FTU6 = (1u << 6), /*!< FTU6 GTB start */ + FTU_GTB_INSTANCE_START_FTU7 = (1u << 7), /*!< FTU7 GTB start */ +} FTU_GlobalTimeBaseStartInstanceType; + +/** @brief Ftu Global Time Base start mask */ +typedef enum +{ + FTU_GTB_START_AT_ONCE = 1u, /*!< GTB start at once */ + FTU_GTB_START_AT_TSTMP1_MOD0 = (1u << 1), /*!< GTB start at modulate timer 0 of TSTMP1 */ + FTU_GTB_START_AT_TSTMP1_MOD1 = (1u << 2), /*!< GTB start at modulate timer 1 of TSTMP1 */ + FTU_GTB_START_AT_TSTMP1_MOD2 = (1u << 3), /*!< GTB start at modulate timer 2 of TSTMP1 */ + FTU_GTB_START_AT_TSTMP1_MOD3 = (1u << 4), /*!< GTB start at modulate timer 3 of TSTMP1 */ +} FTU_GlobalTimeBaseStartType; + +/** @brief FTU signal measurement mode type */ +typedef enum +{ + FTU_SIGNAL_MEASURE_HIGH_TIME = 0u, /*!< Measurement high time */ + FTU_SIGNAL_MEASURE_LOW_TIME = 1u, /*!< Measurement low time */ + FTU_SIGNAL_MEASURE_PERIOD_RISING_EDGE = 2u, /*!< Measurement period of rising edge */ + FTU_SIGNAL_MEASURE_PERIOD_FALLING_EDGE = 3u /*!< Measurement period of falling edge */ +} FTU_SignalMeasureModeType; + +/** @brief FTU signal measurement configuration type */ +typedef struct +{ + uint8_t u8Channel; /*!< selected FTU channel */ + FTU_SignalMeasureModeType eMeasureMode; /*!< signal measurement mode type */ + FTU_MeasureContModeType eContinuouslyMode; /*!< The measurement is single or continuous */ + FTU_MeasureStartModeType eStartMode; /*!< Timing of start measurement */ +} FTU_SignalMeasureType; + +/** @brief FTU signal measurement result time */ +typedef struct +{ + uint32_t u32StartTime; /*!< start time of measured signal */ + uint32_t u32EndTime; /*!< end time of measured signal */ +} FTU_SignalMeasureValueType; + +/** @brief Expect edge number result time */ +typedef struct +{ + uint32_t u32FirstEdgeTime; /*!< first edge time of measured signal */ + uint32_t u32LastEdgeTime; /*!< last edge time of measured signal */ +} FTU_ExpectEdgeNumberResultType; + +/** @brief FTU edge number measurement configuration type */ +typedef struct +{ + uint8_t u8Channel; /*!< selected FTU channel */ + FTU_InputCapturePinModeType eEdgeMode; /*!< input capture mode */ + FTU_MeasureContModeType eContinuouslyMode; /*!< The measurement is single or continuous */ + uint32_t u32StartWindow; /*!< start-point window */ + uint32_t u32EndWindow; /*!< end-point window */ +} FTU_EdgeNumberMeasureType; + +/** @brief FTU expect edge number measurement configuration type */ +typedef struct +{ + uint8_t u8Channel; /*!< selected FTU channel */ + FTU_InputCapturePinModeType eEdgeMode; /*!< input capture mode */ + uint8_t u8ExpectEdgeNumber; /*!< Expected number of edges */ + FTU_MeasureContModeType eContinuouslyMode; /*!< The measurement is single or continuous */ +} FTU_ExpectEdgeNumberMeasureType; + +/** + * @brief The configuration option for the FTU interrupt + * + */ +typedef struct +{ + uint32_t u32InterruptMask; /*!< interrupt enable mask */ + FTU_ChannelCallBackType pChannelCallback; /*!< channel interrupt callback */ + FTU_FaultCallBackType pFaultCallback; /*!< fault interrupt callback */ + FTU_InterruptCallBackType pOverflowCallback; /*!< overflow interrupt callback */ + FTU_InterruptCallBackType pReloadPointCallback; /*!< reload point interrupt callback */ +} FTU_InterruptType; + +/** + * @brief The configuration for the Pwm channel + * + */ +typedef struct +{ + uint8_t u8Channel; /*!< selected FTU channel */ + FTU_PwmPinModeType ePinMode; /*!< pwm mode */ + uint32_t u32PwmDuty; /*!< pwm duty (timer ticks) */ + uint32_t u32PhaseShift; /*!< pwm phase shift (timer ticks)*/ + bool bLinkMode; /*!< pwm channel link mode enable, channel num must be even,and the linked channel is current_channel+1*/ + bool bLinkChannelComplement; /*!< pwm link channel output complement */ + bool bDeadtimeEnable; /*!< Deadtime Enable */ + uint32_t u32ChannelDeadtime; /*!< The separated deadtime (source clock ticks) */ +} FTU_PwmChannelType; + +/** + * @brief The configuration option for the Pwm Mode + * + */ +typedef struct +{ + uint32_t u32PwmPeriod; /*!< pwm period (timer ticks) */ + uint32_t u32PublicDeadtime; /*!< pwm deadtime (source clock ticks) */ + FTU_PwmAlignedType eAlignedMode; /*!< pwm Aligned Mode */ + uint32_t u32ChannelCount; /*!< channel count of the Ftu instance */ + FTU_PwmChannelType *pPwmChannels; /*!< point to the pwm channel */ +} FTU_PwmModeType; + +/** + * @brief The configuration option for the output compare mode + * + */ +typedef struct +{ + uint8_t u8Channel; /*!< selected FTU channel */ + FTU_OutputComparePinModeType eOutputMode; /*!< ouput compare mode */ + uint32_t u32CompareValue; /*!< output compare value (timer ticks) */ + FTU_OutputCompareInitLevelType eInitLevel; /*!< the initial level of the channel */ +} FTU_OutputCompareModeType; + +/** + * @brief The configuration option for the time counter mode + * + */ +typedef struct +{ + uint32_t u32CounterValue; /*!< counter overflow value (timer ticks) */ + uint32_t u32InitialValue; /*!< counter initial value (timer ticks) */ +} FTU_CounterModeType; + +/** + * @brief The basic configuration option for the FTU peripheral + * + */ +typedef struct +{ + FTU_PrescalerType ePrescaler; /*!< Ftu prescaler */ + FTU_ClkSrcType eClkSrc; /*!< Ftu clock source */ + FTU_FilterPrescalerType eFliterPrescaler; /*!< Select the prescaler of the FTU filter */ + uint32_t u32OverflowValue; /*!< Ftu modulo value */ + uint16_t u16ReloadPoints; /*!< Ftu Synchronization points to update the buffered registers.Multiple + update modes can be used by providing an OR'ed list of options + available in enumeration ::FTU_ReloadPointCfgType. */ + uint8_t u8ReloadFreq; /*!< Frequency of the Reload Opportunities. Range is 0-31, */ + uint16_t u16SyncFlag; /*!< Ftu Synchronization flags to config the Synchronization and update of + the buffered registers. Multiple update modes can be used by + providing an OR'ed list of options available in + enumeration ::FTU_SyncFlagType. */ + FTU_TrigModeType eHwTrigMode; /*!< hardware trigger mode */ + FTU_DebugModeType eDbgMode; /*!< Ftu debug mode */ + FTU_UpDownDisableType eUpDownDisable; /*!< Disable channel match trigger/interrupt when count-up/down in CPWM/QUAD mode */ + bool bGtbEnable; /*!< Global Time Base Enable */ +} FTU_CommonType; + +/** + * @brief The configuration option for initializing FTU fault + * + */ +typedef struct +{ + FTU_FaultModeType eFaultMode; /*!< fault control mode */ + uint8_t u8FilterValue; /*!< selects the filter value for the fault inputs */ + uint8_t u8FaultChannelEnable; /*!< fault control for channel */ + uint8_t u8FaultDisableDelay0; /*!< Fault Disable Channel Output Delay Value 0 (timer ticks) */ + uint8_t u8FaultDisableDelay1; /*!< Fault Disable Channel Output Delay Value 1 (timer ticks) */ +} FTU_FaultInitType; + +/** + * @brief The configuration option for enabling a FTU fault + * + */ +typedef struct +{ + uint8_t u8FaultIndex; /*!< fault index */ + FTU_FaultPolActiveType eFaultPol; /*!< the fault input active polarity */ + bool bFaultFilterEnable; /*!< whether to enable fault input glitch filter*/ +} FTU_FaultControlType; + +/** + * @brief The configuration option for a input capture channel + * + */ +typedef struct +{ + uint8_t u8Channel; /*!< selected FTU channel */ + FTU_InputCapturePinModeType eInputMode; /*!< input capture mode */ + uint8_t u8FilterValue; /*!< selects the filter value for the channel input */ +} FTU_InputChannelType; + +/** + * @brief The configuration option for the quadrature decoder mode + * + */ +typedef struct +{ + FTU_QuadratureModeType eQuadMode; /*!< selects the encoding mode used in the Quadrature Decoder mode */ + FTU_QuadratureDirectionType eQuadDirection; /*!< indicates the counting direction */ + FTU_TimerOverflowDirectionType eOveflowDirection; /*!< Indicates if the TOF bit was set on the top or the bottom of counting */ + uint8_t u8PhaFilterVal; /*!< The filter value for the phase A input */ + uint8_t u8PhbFilterVal; /*!< The filter value for the phase B input */ + bool bPhaInverted; /*!< whether to inverted polarity of phase A input */ + bool bPhbInverted; /*!< whether to inverted polarity of phase B input */ + uint16_t u16TopValue; /*!< the top value of counting */ + uint16_t u16BottomValue; /*!< the bottom value of counting */ +} FTU_QuadratureInitType; + +/** + * @brief Initialize FTU basic configuration + * + * @param eInstance the selected FTU instance + * @param pCommonStruct the basic configurations of the FTU instance + * @return FTU_StatusType whether the operation is successfully + */ +FTU_StatusType FTU_CommonInit(const FTU_InstanceType eInstance, const FTU_CommonType *const pCommonStruct); + +/** + * @brief Fills in the FTU configuration structure with the default settings. + * + * @param pCommonStruct Pointer to the user configuration structure + */ +void FTU_GetDefaultInitCfg(FTU_CommonType *pCommonStruct); + +/** + * @brief Configure FTU to counter mode + * + * @param eInstance the selected FTU instance + * @param pCounterStruct the configurations of the counter mode + * @return FTU_StatusType whether the operation is successfully + * @note This function will stop timer + */ +FTU_StatusType FTU_CounterModeInit(const FTU_InstanceType eInstance, + const FTU_CounterModeType *const pCounterStruct); + + +/** + * @brief Configure FTU to output compare mode + * + * @param eInstance the selected FTU instance + * @param pOutputModeStruct the configurations of the output compare mode + * @return FTU_StatusType whether the operation is successfully + * @note This function will stop timer + */ +FTU_StatusType FTU_OutputCompareModeInit(const FTU_InstanceType eInstance, + const FTU_OutputCompareModeType *const pOutputModeStruct); + +/** + * @brief Configure Configure FTU to PWM mode + * + * @param eInstance the selected FTU instance + * @param pPwmModeStruct the configurations of the PWM mode + * @return FTU_StatusType whether the operation is successfully + * @note This function will stop timer + */ +FTU_StatusType FTU_PwmModeInit(const FTU_InstanceType eInstance, const FTU_PwmModeType *const pPwmModeStruct); + +/** + * @brief Update the duty cycle of the FTU instance + * + * @param eInstance the selected FTU instance + * @param u8Channel the selected FTU channel + * @param u32Duty duty cycle of the PWM mode + * @return FTU_StatusType whether the operation is successfully + */ +FTU_StatusType FTU_PwmUpdateDuty(const FTU_InstanceType eInstance, uint8_t u8Channel, uint32_t u32Duty); + +/** + * @brief Ftu initialize interrupt function + * + * @param eInstance the selected FTU instance + * @param pIntStruct the configurations of the interrupt + * @return FTU_StatusType whether the operation is successfully + */ +FTU_StatusType FTU_InterruptInit(const FTU_InstanceType eInstance, const FTU_InterruptType *const pIntStruct); + +/** + * @brief Enable FTU interrupt + * + * @param eInstance the selected FTU instance + * @param u32InterruptMask interrupt enable mask + * @return FTU_StatusType whether the operation is successfully + */ +FTU_StatusType FTU_EnableInterrupt(const FTU_InstanceType eInstance, uint32_t u32InterruptMask); + +/** + * @brief Enable FTU interrupt + * + * @param eInstance the selected FTU instance + * @param u32InterruptMask interrupt disable mask + * @return FTU_StatusType whether the operation is successfully + */ +FTU_StatusType FTU_DisableInterrupt(const FTU_InstanceType eInstance, uint32_t u32InterruptMask); +/** + * @brief Start the FTU instance + * + * @param eInstance the selected FTU instance + * @return FTU_StatusType whether the operation is successfully + */ +FTU_StatusType FTU_StartTimer(const FTU_InstanceType eInstance); +/** + * @brief Stop the FTU global time base + * + * @param u32InstanceMask The selected FTU, each bit represents an instance + */ +void FTU_StopGlobalTimeBase(uint32_t u32InstanceMask); +/** + * @brief Start the FTU global time base + * + * @param u32InstanceMask The selected FTU, each bit represents an instance + * @param u32StartMask Start time, refer to FTU_GlobalTimeBaseStartType + */ +void FTU_StartGlobalTimeBase(uint32_t u32InstanceMask, uint32_t u32StartMask); +/** + * @brief Stop the FTU instance + * + * @param eInstance the selected FTU instance + * @return FTU_StatusType whether the operation is successfully + */ +FTU_StatusType FTU_StopTimer(const FTU_InstanceType eInstance); + +/** + * @brief De-initialize the FTU instance + * + * @param eInstance the selected FTU instance + * @return FTU_StatusType whether the operation is successfully + */ +FTU_StatusType FTU_DeInit(const FTU_InstanceType eInstance); + +/** + * @brief initialize fault input of the selected Ftu instance + * + * @param eInstance the selected FTU instance + * @param pFaultInit the fault configurations of the FTU instance + * @return FTU_StatusType whether the operation is successfully + */ +FTU_StatusType FTU_FaultInit(const FTU_InstanceType eInstance, const FTU_FaultInitType *const pFaultInit); + +/** + * @brief Enable a fault input + * + * @param eInstance the selected FTU instance + * @param pFaultCtrl configurations of the fault input + * @return FTU_StatusType whether the operation is successfully + */ +FTU_StatusType FTU_FaultEnable(const FTU_InstanceType eInstance, const FTU_FaultControlType *const pFaultCtrl); + +/** + * @brief Select fault disable channel output delay value + * + * @param eInstance the selected FTU instance + * @param u8Channel FTU channel number, range is 0-7. + * @param eDelaySelection Fault disable channel output delay value selection. + * @return FTU_StatusType whether the operation is successfully + */ +FTU_StatusType FTU_FaultSelectDelayValue(const FTU_InstanceType eInstance, uint8_t u8Channel, FTU_FaultDisableDelayType eDelaySelection); +/** + * @brief Get Edge number counter + * + * @param eInstance the selected FTU instance + * @param u8Channel FTU channel number. + * @return uint8_t Edge number counter + */ +uint8_t FTU_GetEdgeNumberCount(const FTU_InstanceType eInstance, uint8_t u8Channel); +/** + * @brief Initialize a Edge Number Measurement channel + * + * @param eInstance the selected FTU instance + * @param pEdgeNumMeasure measurement configuration. + * @return FTU_StatusType whether the operation is successfully + */ +FTU_StatusType FTU_EdgeNumberMeasureChannelInit(const FTU_InstanceType eInstance, FTU_EdgeNumberMeasureType *pEdgeNumMeasure); +/** + * @brief Initialize a signal measure channel + * + * @param eInstance the selected FTU instance + * @param pMeasure measurement configuration. + * @return FTU_StatusType whether the operation is successfully + */ +FTU_StatusType FTU_SignalMeasureChannelInit(const FTU_InstanceType eInstance, FTU_SignalMeasureType *pMeasure); +/** + * @brief Re-start measurement when in single mode + * + * @param eInstance the selected FTU instance + * @param u8Channel FTU channel number, range is 0-7. + * @return FTU_StatusType whether the operation is successfully + */ +FTU_StatusType FTU_SignalMeasureChannelSingle(const FTU_InstanceType eInstance, uint8_t u8Channel); +/** + * @brief Get the measurement result of the channel + * + * @param eInstance the selected FTU instance + * @param u8Channel FTU channel number, range is 0-7. + * @param pResult point to the result buffer. + * @return FTU_StatusType whether the operation is successfully + */ +FTU_StatusType FTU_GetSignaMeasureResult(const FTU_InstanceType eInstance, uint8_t u8Channel, FTU_SignalMeasureValueType *pResult); +/** + * @brief Disable a fault input + * + * @param eInstance the selected FTU instance + * @param u32FaultIndex index of the fault input + * @return FTU_StatusType whether the operation is successfully + */ +FTU_StatusType FTU_FaultDisable(const FTU_InstanceType eInstance, uint32_t u32FaultIndex); + +/** + * @brief Clear the fault flag of the FTU instance + * + * @param eInstance the selected FTU instance + * @param u32FaultFlag flag to clear + * @return FTU_StatusType whether the operation is successfully + */ +FTU_StatusType FTU_ClearFault(const FTU_InstanceType eInstance, uint32_t u32FaultFlag); + +/** + * @brief Get the fault flag of the FTU instance + * + * @param eInstance the selected FTU instance + * @return uint32_t the fault flag of the selected Ftu instance + */ +uint32_t FTU_GetFaultFlag(const FTU_InstanceType eInstance); + +/** + * @brief initialize a input capture channel of the selected Ftu instance + * + * @param eInstance the selected FTU instance + * @param pInputChannel configurations of the input capture channel + * @return FTU_StatusType whether the operation is successfully + */ +FTU_StatusType FTU_InputCaptureChannelInit(const FTU_InstanceType eInstance, + const FTU_InputChannelType *const pInputChannel); +/** + * @brief enable the synchronization of the selected FTU + * + * @param eInstance the selected FTU instance + * @param u16ReloadPoints The synchronization flag + * @return FTU_StatusType whether the operation is successfully + */ +FTU_StatusType FTU_EnableSync(const FTU_InstanceType eInstance, uint16_t u16SyncFlag); +/** + * @brief disable the synchronization of the selected FTU + * + * @param eInstance the selected FTU instance + * @param u16SyncFlag The synchronization flag + * @return FTU_StatusType whether the operation is successfully + */ +FTU_StatusType FTU_DisableSync(const FTU_InstanceType eInstance, uint16_t u16SyncFlag); +/** + * @brief Enable the output trigger of the selected FTU instance + * + * @param eInstance the selected FTU instance + * @param u32TriggerOutputMask the output trigger mask + * @return FTU_StatusType whether the operation is successfully + */ +FTU_StatusType FTU_EnableTriggerOutput(const FTU_InstanceType eInstance, uint32_t u32TriggerOutputMask); +/** + * @brief Disable the output trigger of the selected FTU instance + * + * @param eInstance the selected FTU instance + * @param u32TriggerOutputMask the output trigger mask + * @return FTU_StatusType whether the operation is successfully + */ +FTU_StatusType FTU_DisableTriggerOutput(const FTU_InstanceType eInstance, uint32_t u32TriggerOutputMask); +/** + * @brief initialize the quadrature decoder mode + * + * @param eInstance the selected FTU instance + * @param pQuadInit configurations of the quadrature decoder + * @return FTU_StatusType whether the operation is successfully + */ +FTU_StatusType FTU_QuadratureModeInit(const FTU_InstanceType eInstance, + const FTU_QuadratureInitType *const pQuadInit); +/** + * @brief Enable the reload points of the selected FTU instance + * + * @param eInstance the selected FTU instance + * @param u16ReloadPoints The reload points flag + * @return FTU_StatusType whether the operation is successfully + */ +FTU_StatusType FTU_EnableReloadPoints(const FTU_InstanceType eInstance, uint16_t u16ReloadPoints); +/** + * @brief Disable the reload points of the selected FTU instance + * + * @param eInstance the selected FTU instance + * @param u16ReloadPoints The reload points flag + * @return FTU_StatusType whether the operation is successfully + */ +FTU_StatusType FTU_DisableReloadPoints(const FTU_InstanceType eInstance, uint16_t u16ReloadPoints); + +/** + * @brief Enable ftu channel DMA + * + * @param eInstance the selected FTU instance + * @param u32DmaMask The dma channel mask. + * @return FTU_StatusType whether the operation is successfully + */ +FTU_StatusType FTU_EnableChannelDma(const FTU_InstanceType eInstance, uint32_t u32DmaMask); +/** + * @brief Get the expect edge number result of the channel + * + * @param eInstance the selected FTU instance + * @param u8Channel FTU channel number, range is 0-7. + * @param pResult point to the result buffer. + * @return FTU_StatusType whether the operation is successfully + */ +FTU_StatusType FTU_GetExpectEdgeNumberResult(const FTU_InstanceType eInstance, uint8_t u8Channel, FTU_ExpectEdgeNumberResultType *pResult); +/** + * @brief Initialize a Expect Edge Number Measurement channel + * + * @param eInstance the selected FTU instance + * @param pExpectEdgeNumMeasure measurement configuration. + * @return FTU_StatusType whether the operation is successfully + */ +FTU_StatusType FTU_ExpectEdgeNumberMeasureChannelInit(const FTU_InstanceType eInstance, FTU_ExpectEdgeNumberMeasureType *pExpectEdgeNumMeasure); +/** + * @brief Get the measurement result of the channel + * + * @param eInstance the selected FTU instance + * @param u8Channel FTU channel number, range is 0-7. + * @param pResult point to the result buffer. + * @return FTU_StatusType whether the operation is successfully + */ +FTU_StatusType FTU_GetSignalMeasureResult(const FTU_InstanceType eInstance, uint8_t u8Channel, FTU_SignalMeasureValueType *pResult); +/** + * @brief Interrupt IRQ handle of FTU instance + * + * @param eInstance the selected FTU instance + */ +void FTUn_IRQHandler(const FTU_InstanceType eInstance); +/** @}*/ /* fc7xxx_driver_ftu */ +#if defined(__cplusplus) +} +#endif +#endif diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_gpio.h b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_gpio.h new file mode 100644 index 0000000..9e92846 --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_gpio.h @@ -0,0 +1,145 @@ +/** + * @file fc7xxx_driver_gpio.h + * @author Flagchip + * @brief FC7xxx GPIO driver type definition and API + * @version 0.1.0 + * @date 2023-2-14 + * + * @copyright Copyright (c) 2023 Flagchip Semiconductors Co., Ltd. + * + */ +/******************************************************************************** +* Revision History: +* +* Version Date Initials CR# Descriptions +* --------- ---------- ------------ ---------- --------------- +* 0.1.0 2022/12/31 Flagchip071 N/A First version for FC7240 +********************************************************************************/ +#ifndef DRIVER_GPIO_H_ +#define DRIVER_GPIO_H_ +#include "HwA_gpio.h" + +/** + * @addtogroup fc7xxx_driver_port + * @{ + */ + +/********* global define ************/ + +#define GPIO_MAX_PORT_PINS 32 + +#define GPIO_PIN_0 ((uint32_t)0x00000001) /**< GPIO Pin 0 select */ +#define GPIO_PIN_1 ((uint32_t)0x00000002) /**< GPIO Pin 1 select */ +#define GPIO_PIN_2 ((uint32_t)0x00000004) /**< GPIO Pin 2 select */ +#define GPIO_PIN_3 ((uint32_t)0x00000008) /**< GPIO Pin 3 select */ +#define GPIO_PIN_4 ((uint32_t)0x00000010) /**< GPIO Pin 4 select */ +#define GPIO_PIN_5 ((uint32_t)0x00000020) /**< GPIO Pin 5 select */ +#define GPIO_PIN_6 ((uint32_t)0x00000040) /**< GPIO Pin 6 select */ +#define GPIO_PIN_7 ((uint32_t)0x00000080) /**< GPIO Pin 7 select */ +#define GPIO_PIN_8 ((uint32_t)0x00000100) /**< GPIO Pin 8 select */ +#define GPIO_PIN_9 ((uint32_t)0x00000200) /**< GPIO Pin 9 select */ +#define GPIO_PIN_10 ((uint32_t)0x00000400) /**< GPIO Pin 10 select */ +#define GPIO_PIN_11 ((uint32_t)0x00000800) /**< GPIO Pin 11 select */ +#define GPIO_PIN_12 ((uint32_t)0x00001000) /**< GPIO Pin 12 select */ +#define GPIO_PIN_13 ((uint32_t)0x00002000) /**< GPIO Pin 13 select */ +#define GPIO_PIN_14 ((uint32_t)0x00004000) /**< GPIO Pin 14 select */ +#define GPIO_PIN_15 ((uint32_t)0x00008000) /**< GPIO Pin 15 select */ +#define GPIO_PIN_16 ((uint32_t)0x00010000) /**< GPIO Pin 16 select */ +#define GPIO_PIN_17 ((uint32_t)0x00020000) /**< GPIO Pin 17 select */ +#define GPIO_PIN_18 ((uint32_t)0x00040000) /**< GPIO Pin 18 select */ +#define GPIO_PIN_19 ((uint32_t)0x00080000) /**< GPIO Pin 19 select */ +#define GPIO_PIN_20 ((uint32_t)0x00100000) /**< GPIO Pin 20 select */ +#define GPIO_PIN_21 ((uint32_t)0x00200000) /**< GPIO Pin 21 select */ +#define GPIO_PIN_22 ((uint32_t)0x00400000) /**< GPIO Pin 22 select */ +#define GPIO_PIN_23 ((uint32_t)0x00800000) /**< GPIO Pin 23 select */ +#define GPIO_PIN_24 ((uint32_t)0x01000000) /**< GPIO Pin 24 select */ +#define GPIO_PIN_25 ((uint32_t)0x02000000) /**< GPIO Pin 25 select */ +#define GPIO_PIN_26 ((uint32_t)0x04000000) /**< GPIO Pin 26 select */ +#define GPIO_PIN_27 ((uint32_t)0x08000000) /**< GPIO Pin 27 select */ +#define GPIO_PIN_28 ((uint32_t)0x10000000) /**< GPIO Pin 28 select */ +#define GPIO_PIN_29 ((uint32_t)0x20000000) /**< GPIO Pin 29 select */ +#define GPIO_PIN_30 ((uint32_t)0x40000000) /**< GPIO Pin 30 select */ +#define GPIO_PIN_31 ((uint32_t)0x80000000) /**< GPIO Pin 31 select */ + +/************************************global typedef ***************************************/ + +/** @brief GPIO return structure */ +typedef enum +{ + GPIO_STATUS_SUCCESS = 0U, + GPIO_STATUS_PARAM_INVALID = 1U +} GPIO_StatusType; + +/** @brief GPIO instance number */ +typedef enum +{ + GPIO_A = 0U, + GPIO_B, + GPIO_C, + GPIO_D, + GPIO_E +} GPIO_InstanceType; + +/** @brief GPIO direction */ +typedef enum +{ + GPIO_OUT = 0U, /* GPIO pin directon is output */ + GPIO_IN = 1U, /* GPIO pin directon is input */ + GPIO_ZERO = 2U /* GPIO pin directon is input disable */ +} GPIO_PinDirectionType; + +typedef struct +{ + uint32_t u32GpioPins; + GPIO_PinDirectionType ePinDirection; + GPIO_PinLevelType ePinLevel; +}GPIO_InitType; + +/************************************global typedef ***************************************/ + +/** + * @brief Initialize GPIO. + * + * @param eGpio GPIO instance + * @param pInitStruct Initialization structure of GPIO. + */ +GPIO_StatusType GPIO_InitPins(const GPIO_InstanceType eGpio, const GPIO_InitType *const pInitStruct); + +/** + * @brief Initialize GPIO. + * + * @param eGpio GPIO instance + * @param u32Pins The bit of u32Pins indicate the pin number of this GPIO. + */ +GPIO_StatusType GPIO_Deinit(const GPIO_InstanceType eGpio, const uint32_t u32Pins); + +/** + * @brief Read level of input port pins. + * + * @param ePort Port instance for GPIO functionality + * @param u32Pins The bit of u32Pins indicate the pin number of this Port. + * @return Pins level + */ +uint32_t GPIO_ReadPins(const GPIO_InstanceType ePort, const uint32_t u32Pins); + +/** + * @brief Write gpio level to u32Pins. + * + * @param ePort Port instance for GPIO functionality + * @param u32Pins The bit of u32Pins indicate the pin number of this Port. + * @param eOutput Output level enumeration + * @return Port return type. + */ +GPIO_StatusType GPIO_WritePins(const GPIO_InstanceType ePort, const uint32_t u32Pins, const GPIO_PinLevelType eOutput); + +/** + * @brief Toggle gpio api + * + * @param ePort ePort Port instance for GPIO functionality + * @param u32Pins The bit of u32Pins indicate the pin number of this Port. + * @return Port return type. + */ +GPIO_StatusType GPIO_Toggle(const GPIO_InstanceType ePort, const uint32_t u32Pins); + + +#endif /* end of DRIVER_GPIO_H_ */ diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_hsm.h b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_hsm.h new file mode 100644 index 0000000..249d1dd --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_hsm.h @@ -0,0 +1,3277 @@ +/** + * @file fc7xxx_driver_hsm.h + * @author Flagchip0103 + * @brief FC7xxx HSM driver type definition and API + * @version 0.1.0 + * @date 2023-12-20 + * + * @copyright Copyright (c) 2022 Flagchip Semiconductors Co., Ltd. + * + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2023-12-20 Flagchip0103 N/A First version for FC7240 + ******************************************************************************** */ + +#ifndef DRIVER_HSM_H_ +#define DRIVER_HSM_H_ + +#include "device_header.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +/** + * @addtogroup fc7xxx_driver_hsm + * @{ + */ + + +/** + * @brief Status returned by HSM SDK CM7 side APIs + * + */ +typedef enum +{ + HSM_STATUS_SUCCESS = 0U, /*!< return this when HSM API execute successfully */ + HSM_STATUS_PARAM_ERR, /*!< return this when parameter error */ + HSM_STATUS_AGAIN, /*!< return this when need more API call to continue process */ + HSM_STATUS_FINISH, /*!< return this when the process is finish */ +} HSM_StatusType; + + +/** + * @name definitions for HSM_MailboxApiRetType + * + */ +/**@{*/ +/** + * @brief success status (HSM_MailboxApiRetType) returned by HSM subsystem APIs + * + */ +#define MAILBOXAPI_RET_SUCCESS (0u) + +/** + * @brief error status (HSM_MailboxApiRetType) returned by HSM subsystem APIs + * + */ +#define MAILBOXAPI_RET_ERROR (1u) + +/** + * @brief failure status (HSM_MailboxApiRetType) returned by HSM subsystem APIs + * + */ +#define MAILBOXAPI_RET_FAIL (2u) + +/** + * @brief verify pass status (HSM_MailboxApiRetType) returned by HSM subsystem APIs + * + */ +#define MAILBOXAPI_RET_PASS (3u) + +/** + * @brief function not support status (HSM_MailboxApiRetType) returned by HSM subsystem APIs + * + */ +#define MAILBOXAPI_RET_NOT_SUPPORT (4u) + +/** + * @brief hardware error status (HSM_MailboxApiRetType) returned by HSM subsystem APIs + * + */ +#define MAILBOXAPI_RET_HW_ERROR (5u) + +/** + * @brief have no permission status (HSM_MailboxApiRetType) returned by HSM subsystem APIs + * + */ +#define MAILBOXAPI_RET_NO_PRIVILEGES (6u) + +/** + * @brief parameters error status (HSM_MailboxApiRetType) returned by HSM subsystem APIs + * + */ +#define MAILBOXAPI_RET_PARAMETER_ERROR (7u) + +/** + * @brief authority error status (HSM_MailboxApiRetType) returned by HSM subsystem APIs + * + */ +#define MAILBOXAPI_RET_AUTHORITY_ERROR (8u) + +/** + * @brief hardware busy status (HSM_MailboxApiRetType) returned by HSM subsystem APIs + * + */ +#define MAILBOXAPI_RET_BUSY (9u) + +/** + * @brief flash ecc error status (HSM_MailboxApiRetType) returned by HSM subsystem APIs + * + */ +#define MAILBOXAPI_RET_ECC_ERR (10u) + +/** + * @brief time expire error status (HSM_MailboxApiRetType) returned by HSM subsystem APIs + * + */ +#define MAILBOXAPI_RET_TIMEOUIT (11u) + +/** + * @brief status type definition returned by HSM subsystem APIs + * + */ +typedef uint32_t HSM_MailboxApiRetType; +/**@}*/ + + +/** + * @brief HSM 4bytes unit data format for HSM_DataFormatType + * for example, if data is 0x000102030405060708090a0b0c0d0e0f, use this format, should be divided as following. + * 0x00010203, 0x04050607, 0x08090a0b, 0x0c0d0e0f + */ +#define HSM_DATA_FORMAT_4B 0u + +/** + * @brief HSM 1byte unit data format for HSM_DataFormatType + * for example, if data is 0x000102030405060708090a0b0c0d0e0f, use this format, should be divided as following. + * 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f + */ +#define HSM_DATA_FORMAT_1B 1u + +/** + * @brief HSM data format + * refer to HSM_DATA_FORMAT_4B, HSM_DATA_FORMAT_1B + */ +typedef uint32_t HSM_DataFormatType; + + +/** + * @name Type definition for HSM Isr/Poll mode + * + */ +/**@{*/ + +typedef struct +{ + uint32_t u32Cmd; /*!< current command id to HSM core via mailbox */ + uint32_t u32Addr; /*!< current parameter address to HSM core via mailbox */ +} HSM_CmdType; + + +/** + * @name definitions for HSM_BoolType + * + */ +/**@{*/ +/** + * @brief Boolean false value definition for type HSM_BoolType used by HSM + * + */ +#define HSM_FALSE (0u) + +/** + * @brief Boolean true value definition for type HSM_BoolType used by HSM + * + */ +#define HSM_TRUE (1u) + +/** + * @brief Boolean type for HSM + * + */ +typedef uint32_t HSM_BoolType; +/**@}*/ + + +/* ------------------------------------------------------------------------------- */ +/** + * @brief the true random count return by the API + * + */ +#define HSM_TRNG_RAND_U32_CNT (16u) +/* ------------------------------------------------------------------------------- */ +/** + * @brief the true random source_0 definition for type HSMCom_TrueRandType.u32RandSrcType + * + */ +#define HSM_TRNG_SRC_0 (0u) +/* ------------------------------------------------------------------------------- */ +/** + * @brief the true random source_1 definition for type HSMCom_TrueRandType.u32RandSrcType + * + */ +#define HSM_TRNG_SRC_1 (1u) +/* ------------------------------------------------------------------------------- */ +/** + * @brief the true XOR random source_1 definition for type HSMCom_TrueRandType.u32RandSrcType + * + */ +#define HSM_TRNG_SRC_XOR (2u) +/* ------------------------------------------------------------------------------- */ +/** + * @brief the true any random source_1 definition for type HSMCom_TrueRandType.u32RandSrcType + * + */ +#define HSM_TRNG_SRC_ANY (3u) +/* ------------------------------------------------------------------------------- */ +/** + * @brief the pseudorandom source definition for type HSMCom_TrueRandType.u32RandSrcType + * + */ +#define HSM_DRNG_SRC (4u) +typedef uint32_t HSM_RndSrcType; +/** + * @brief the true random information passed to HSM core by mailbox + * + */ +typedef struct +{ + HSM_MailboxApiRetType u32HSMStatusRet; /*!< HSM core write return status value in this */ + uint32_t u32Timeout; /*!< current command timeout tick count, tick refer to the HSM bus clock */ + uint32_t (*aRandom)[HSM_TRNG_RAND_U32_CNT]; /*!< the buffer address, HSM core will write random data to this buffer */ + HSM_RndSrcType u32RandSrc; /*!< which random source will be selected */ +} HSMCom_TrueRandType; + +/* ------------------------------------------------------------------------------- */ + + +/** + * @name definitions for HSM_HashAlgType + * + */ +/**@{*/ +/** + * @brief MD5 algorithm value for type "HSM_HashAlgType" + * + */ +#define HSM_HASH_MD5 (0U) + +/** + * @brief SHA160 algorithm value for type "HSM_HashAlgType" + * + */ +#define HSM_HASH_SHA160 (1U) + +/** + * @brief SHA224 algorithm value for type "HSM_HashAlgType" + * + */ +#define HSM_HASH_SHA224 (2U) + +/** + * @brief SHA256 algorithm value for type "HSM_HashAlgType" + * + */ +#define HSM_HASH_SHA256 (3U) + +/** + * @brief SHA384 algorithm value for type "HSM_HashAlgType" + * + */ +#define HSM_HASH_SHA384 (4U) + +/** + * @brief SHA512 algorithm value for type "HSM_HashAlgType" + * + */ +#define HSM_HASH_SHA512 (5U) + +/** + * @brief SHA512_224 algorithm value for type "HSM_HashAlgType" + * + */ +#define HSM_HASH_SHA512_224 (6U) + +/** + * @brief SHA512_256 algorithm value for type "HSM_HashAlgType" + * + */ +#define HSM_HASH_SHA512_256 (7U) + +/** + * @brief SM3 algorithm value for type "HSM_HashAlgType" + * + */ +#define HSM_HASH_SM3 (8U) + +/** + * @brief type definition for HASH algorithm + * refer to HSM_HASH_MD5,HSM_HASH_SHA160,HSM_HASH_SHA224,HSM_HASH_SHA256,HSM_HASH_SHA384,HSM_HASH_SHA512,HSM_HASH_SHA512_224,HSM_HASH_SHA512_256,HSM_HASH_SM3 + */ +typedef uint32_t HSM_HashAlgType; +/**@}*/ + + +/** + * @name definitions for HSM_ShaAlgType + * + */ +/**@{*/ +/** + * @brief SHA160 algorithm value for type "HSM_ShaAlgType" + * @note it's the so-called SHA1 + */ +#define HSM_SHA_160 (1U) + +/** + * @brief SHA224 algorithm value for type "HSM_ShaAlgType" + * @note it's the so-called SHA2-224 + */ +#define HSM_SHA_224 (2U) + +/** + * @brief SHA256 algorithm value for type "HSM_ShaAlgType" + * @note it's the so-called SHA2-256 + */ +#define HSM_SHA_256 (3U) + +/** + * @brief SHA384 algorithm value for type "HSM_ShaAlgType" + * @note it's the so-called SHA2-384 + */ +#define HSM_SHA_384 (4U) + +/** + * @brief SHA512 algorithm value for type "HSM_ShaAlgType" + * @note it's the so-called SHA2-512 + */ +#define HSM_SHA_512 (5U) + +/** + * @brief SHA512/224 algorithm value for type "HSM_ShaAlgType" + * @note it's the so-called SHA2-512/224 + */ +#define HSM_SHA_512_224 (6U) + +/** + * @brief SHA512/256 algorithm value for type "HSM_ShaAlgType" + * @note it's the so-called SHA2-512/256 + */ +#define HSM_SHA_512_256 (7U) + +/** + * @brief type definition for SHA algorithm + * refer to HSM_SHA_160,HSM_SHA_224,HSM_SHA_256,HSM_SHA_384,HSM_SHA_512,HSM_SHA_512_224,HSM_SHA_512_256 + */ +typedef uint32_t HSM_ShaAlgType; +/**@}*/ + + +/** + * @name definitions for HSM_HfamMacType + * + */ +/**@{*/ +/** + * @brief SMAC mode value for type "HSM_HfamMacType" + * + */ +#define HSM_HFAM_MAC_SMAC (0U) + +/** + * @brief HMAC mode value for type "HSM_HfamMacType" + * + */ +#define HSM_HFAM_MAC_HMAC (1U) + +/** + * @brief SM3/MD5/SHA can generate MAC, use this to select the type of MAC + * SMAC refer to HSM_HFAM_MAC_SMAC + * HMAC refer to HSM_HFAM_MAC_HMAC + */ +typedef uint32_t HSM_HfamMacType; +/**@}*/ + + +/** + * @brief SHA/MD5/SM3 context information used by driver when call specific API + * + */ +typedef struct +{ + HSM_BoolType bGenerateMacEn; /*!< whether generate MAC */ + HSM_HfamMacType eMacType; /*!< if enable generating MAC, this should configure */ + uint32_t *pKeyData; /*!< key to generate MAC, if enable generating MAC, this should configure */ + uint32_t u32KeyByteCnt; /*!< the byte count of key data */ + uint32_t u32GenerateMacByteCnt; /*!< the byte count of MAC data output */ + + uint32_t u32InputDataByteCnt; /*!< the byte count of input data */ + const uint32_t *pInputData; /*!< point to the input data */ +} HSM_SmsCfgType; /* sms is short for sha/md5/sm3 */ + +/** + * @brief SHA context information used by driver when call specific API + * + */ +typedef HSM_SmsCfgType HSM_ShaCtxType; + +/** + * @brief type definition for driver to store information + * + */ +typedef struct +{ + uint32_t aResult[0x10]; /*!< store the sha result, max size 0x10 is for SHA512 */ + uint32_t u32ResultU32Cnt; /*!< store the result uint32_t count, it's set by driver */ +} HSM_ShaResultBufType; + +/** + * @brief SHA information used by driver when call specific API + * + */ +typedef struct +{ + HSM_ShaAlgType eAlg; /*!< select sha algorithm type */ + HSM_ShaCtxType tCfg; /*!< sha algorithm parameter set by user */ + HSM_ShaResultBufType *pResult; /*!< point to the memory that HSM core to write result */ +} HSM_ShaType; + +typedef struct +{ + HSM_MailboxApiRetType u32HSMStatusRet; /*!< HSM core write return status value in this */ + uint32_t u32Timeout; /*!< current command timeout tick count, tick refer to the HSM bus clock */ + HSM_ShaType tCfg; /*!< sha algorithm parameter set by user */ +} HSMCom_ShaType; + +/** + * @brief SHA information used by driver when call specific API + * + */ +typedef struct +{ + HSM_ShaAlgType eAlg; /*!< select sha algorithm type */ + HSM_ShaCtxType tCfg; /*!< sha algorithm parameter set by user */ + uint8_t *pResult; /*!< point to the memory that HSM core to write result */ + HSM_DataFormatType eInputFmt; /*!< input data organized format,uint8_t array or uint32_t array */ + HSM_DataFormatType eOutputFmt; /*!< output data organized format,uint8_t array or uint32_t array */ +} HSM_Sha2Type; + +typedef struct +{ + HSM_MailboxApiRetType u32HSMStatusRet; /*!< HSM core write return status value in this */ + uint32_t u32Timeout; /*!< current command timeout Millisecond count, max 916000ms, if set to 0, means 1000ms */ + HSM_Sha2Type tCfg; /*!< sha algorithm parameter set by user */ +} HSMCom_Sha2Type; + +typedef struct +{ + HSM_ShaAlgType eAlg; /*!< select sha algorithm type */ + HSM_ShaCtxType tCfg; /*!< sha algorithm parameter set by user */ + uint32_t (*pResult)[18]; /*!< point to the memory that HSM core to write result */ +} HSM_ScatterHashType; + +typedef struct +{ + HSM_MailboxApiRetType u32HSMStatusRet; /*!< HSM core write return status value in this */ + uint32_t u32Timeout; /*!< current command timeout Millisecond count, max 916000ms, if set to 0, means 1000ms */ + HSM_ScatterHashType tCfg; /*!< sha algorithm parameter set by user */ +} HSMCom_ScatterHashType; +/* ------------------------------------------------------------------------------- */ +typedef struct { + uint32_t u32KeyType; + uint32_t u32KeySel; + uint32_t *pKeyData; +} HSM_AesmKeyCfgType; + +typedef struct { + HSM_AesmKeyCfgType *pKeyCfg; + uint32_t u32KeyCfgEn; + uint32_t u32AesMode; + uint32_t u32AesAs; + uint32_t u32AesEncDecrypt; + uint32_t u32EngSel; + uint32_t u32AhbEn; + uint32_t u32IcvEn; + uint32_t u32DataLen; + uint32_t u32IcvLen; + uint32_t u32AadLen; + uint32_t *pInput; + uint32_t *pOutput; + uint32_t *pIvData; + uint32_t u32DbgWait; + uint32_t u32IvLen; +} HSM_AesmHwEntryCfgType; + +typedef struct { + HSM_AesmHwEntryCfgType tCfg; + HSM_AesmKeyCfgType tKeyCfg; + uint32_t (*pCtx)[16]; +} HSM_AesmRawApiType; + +typedef struct +{ + HSM_MailboxApiRetType u32HSMStatusRet; /*!< HSM core write return status value in this */ + uint32_t u32Timeout; /*!< current command timeout Millisecond count, max 916000ms, if set to 0, means 1000ms */ + uint32_t u32UserKeyId; + HSM_AesmRawApiType tCfg; /*!< algorithm parameter set by user */ +} HSMCom_AesmRawApiType; + +/* ------------------------------------------------------------------------------- */ +typedef struct { + uint32_t u32Flags; + uint32_t *pKeyData; + uint32_t *pMacOut; + uint32_t u32MacOutBufSz; + uint32_t *aData[8]; + uint32_t aDataSize[8]; +} HSM_ScatterMacType; + +typedef struct +{ + HSM_MailboxApiRetType u32HSMStatusRet; /*!< HSM core write return status value in this */ + uint32_t u32Timeout; /*!< current command timeout Millisecond count, max 916000ms, if set to 0, means 1000ms */ + uint32_t u32UserKeyId; + HSM_ScatterMacType tCfg; /*!< algorithm parameter set by user */ +} HSMCom_ScatterMacType; + + +/* ------------------------------------------------------------------------------- */ +/** + * @name definitions for HSM_DrvEccCurvePrmIndexType + * + */ +/**@{*/ +/** + * @brief ECC curve NIST SECP224R1 value for type "HSM_DrvEccCurvePrmIndexType" + * + */ +#define HSM_DRV_ECC_CURVE_PRM_IDX_SECP224R1 (0U) + +/** + * @brief ECC curve NIST SECP256R1 value for type "HSM_DrvEccCurvePrmIndexType" + * + */ +#define HSM_DRV_ECC_CURVE_PRM_IDX_SECP256R1 (1U) + +/** + * @brief ECC curve NIST SECP384R1 value for type "HSM_DrvEccCurvePrmIndexType" + * + */ +#define HSM_DRV_ECC_CURVE_PRM_IDX_SECP384R1 (2U) + +/** + * @brief ECC curve NIST SECP521R1 value for type "HSM_DrvEccCurvePrmIndexType" + * + */ +#define HSM_DRV_ECC_CURVE_PRM_IDX_SECP521R1 (3U) + +/** + * @brief ECC curve NIST SECP224R1_FIX value for type "HSM_DrvEccCurvePrmIndexType" + * + */ +#define HSM_DRV_ECC_CURVE_PRM_IDX_SECP224R1_FIX (4U) + + +/** + * @brief max count of ECC curve supported for type "HSM_DrvEccCurvePrmIndexType" + * + */ +#define HSM_DRV_ECC_CURVE_PRM_IDX_MAX (5U) + +/** + * @brief type definition for ECC curve data that defined by NIST + * + */ +typedef uint32_t HSM_DrvEccCurvePrmIndexType; +/**@}*/ + +/** + * @brief ECC curve information used by driver when call specific API + * + */ +typedef struct +{ + const uint32_t *pP; /*!< ecc curve modulus */ + const uint32_t *pN; /*!< ecc curve order; size; the count of all possible EC points */ + const uint32_t *pA; /*!< the constant "a" in y^2 = x^3 + a*x + b (mod p) */ + const uint32_t *pB; /*!< the constant "b" in y^2 = x^3 + a*x + b (mod p) */ + const uint32_t *pGx; /*!< x of the curve generator point G {x, y} */ + const uint32_t *pGy; /*!< y of the curve generator point G {x, y} */ +} HSM_DrvEccCurveParamType; + +/** + * @brief ECC sign information used by driver when call specific API + * + */ +typedef struct +{ + uint32_t u32ByteCount; /*!< all the data size, it should contains all N data */ + HSM_DrvEccCurveParamType tCurve; /*!< ecc curve parameters */ + const uint32_t *pPrivateKey; /*!< private key */ + const uint32_t *pHashData; /*!< hash of the data to verify */ + + /* the following the sign output */ + uint32_t *pR; /*!< driver internal use this buffer to store the sign result R of the data to sign */ + uint32_t *pS; /*!< driver internal use this buffer to store the sign result S of the data to sign */ +} HSM_EccSignType; + +typedef struct +{ + HSM_MailboxApiRetType u32HSMStatusRet; /*!< HSM core write return status value in this */ + uint32_t u32Timeout; /*!< current command timeout tick count, tick refer to the HSM bus clock */ + uint32_t u32UserKeyID_PrivateKey; /*!< 0 means use key from HSM internal key space, otherwise would load key with KEYID from key space */ + uint32_t u32BitCnt; /*!< ECC parameter N bit count */ + HSM_DrvEccCurvePrmIndexType u32EccCurve; /*!< select hsm rom internal ecc curve parameters, if use user's self curve, set it to HSM_DRV_ECC_CURVE_PRM_IDX_MAX */ + HSM_EccSignType tCfg; /*!< ecc sign parameters */ +} HSMCom_EccSignType; + +/* ------------------------------------------------------------------------------- */ +/** + * @brief ECC verify information used by driver when call specific API + * + */ +typedef struct +{ + uint32_t u32DataByteCnt; /*!< the byte count of all ecc curve parameter */ + HSM_DrvEccCurveParamType tCurve; /*!< ecc curve parameters */ + const uint32_t *pkG_x; /*!< public key axis x */ + const uint32_t *pkG_y; /*!< public key axis y */ + const uint32_t *pHashData; /*!< hash of the data to verify */ + const uint32_t *pR; /*!< the sign result R of the data to verify */ + const uint32_t *pS; /*!< the sign result S of the data to verify */ +} HSM_EccVerifyType; +typedef struct +{ + HSM_MailboxApiRetType u32HSMStatusRet; /*!< HSM core write return status value in this */ + uint32_t u32Timeout; /*!< current command timeout tick count, tick refer to the HSM bus clock */ + uint32_t u32UserKeyID_PublicKey; /*!< 0 means don't use key from HSM internal key space, otherwise would load key with KEYID from HSM */ + uint32_t u32BitCnt; /*!< ECC parameter N bit count */ + HSM_DrvEccCurvePrmIndexType u32EccCurve; /*!< select hsm rom internal ecc curve parameters, if use user's self curve, set it to HSM_DRV_ECC_CURVE_PRM_IDX_MAX */ + HSM_EccVerifyType tCfg; /*!< ecc verify parameters */ +} HSMCom_EccVerifyType; + +/* ------------------------------------------------------------------------------- */ +/** + * @brief SM2 key pair generation information used by driver when call specific API + * + */ +typedef struct +{ + uint32_t (*pPrivateKey)[8]; /*!< private key */ + uint32_t (*pPublicKey_X)[8]; /*!< the public key X */ + uint32_t (*pPublicKey_Y)[8]; /*!< the public key Y */ +} HSM_Sm2GenKeyPairType; + +typedef struct +{ + HSM_MailboxApiRetType u32HSMStatusRet; /*!< HSM core write return status value in this */ + uint32_t u32Timeout; /*!< current command timeout tick count, tick refer to the HSM bus clock */ + HSM_Sm2GenKeyPairType tCfg; /*!< sm2 generate key pair parameters */ +} HSMCom_Sm2GenKeyPairType; + +/* ------------------------------------------------------------------------------- */ +/** + * @brief SM2 encrypt information used by driver when call specific API + * + */ +typedef struct +{ + uint32_t u32SM2InputByteCnt; /*!< the length should be <= 32bytes */ + uint32_t *pSM2OutputByteCnt; /*!< driver internal will set output byte count in the memory this pointer point to */ + uint32_t *pInputData; /*!< length should be more than u32SM2InputByteCnt, and must be 4bytes align */ + uint32_t (*pPublicKey_x)[8]; /*!< public key axis x data */ + uint32_t (*pPublicKey_y)[8]; /*!< public key axis y data */ + uint32_t *pOutputData; /*!< length should be more than u32SM2InputByteCnt+97, and must be 4bytes align */ +} HSM_Sm2EncryptType; + +typedef struct +{ + HSM_MailboxApiRetType u32HSMStatusRet; /*!< HSM core write return status value in this */ + uint32_t u32Timeout; /*!< current command timeout tick count, tick refer to the HSM bus clock */ + uint32_t u32UserKeyID_PublicKey; /*!< 0 means don't use key from HSM internal key space, otherwise would load key with KEYID from HSM */ + HSM_Sm2EncryptType tCfg; /*!< sm2 encrypt parameters */ +} HSMCom_Sm2EncryptType; + +/* ------------------------------------------------------------------------------- */ +/** + * @brief SM2 decrypt information used by driver when call specific API + * + */ +typedef struct +{ + uint32_t u32SM2InputByteCnt; /*!< the length should be <= 129bytes */ + uint32_t *pSM2OutputByteCnt; /*!< driver internal will set output byte count in the memory this pointer point to */ + uint32_t *pInputData; /*!< length should be more than u32SM2InputByteCnt, and must be 4bytes align */ + uint32_t (*pPrivateKey)[8]; /*!< private key */ + uint32_t *pOutputData; /*!< length should be more than u32SM2InputByteCnt-97, and must be 4bytes align */ +} HSM_Sm2DecryptType; + +typedef struct +{ + HSM_MailboxApiRetType u32HSMStatusRet; /*!< HSM core write return status value in this */ + uint32_t u32Timeout; /*!< current command timeout tick count, tick refer to the HSM bus clock */ + uint32_t u32UserKeyID_PrivateKey; /*!< 0 means don't use key from HSM internal key space, otherwise would load key with KEYID from HSM */ + HSM_Sm2DecryptType tCfg; +} HSMCom_Sm2DecryptType; + +/* ------------------------------------------------------------------------------- */ +/** + * @brief SM2 sign information used by driver when call specific API + * + */ +typedef struct +{ + HSM_BoolType bUseDefaultID; /*!< TRUE means use default ID. FALSE means use specific ID with "pInputData_ID" and "u32SM2InputIDByteCnt" params. */ + HSM_BoolType bHashInput; /*!< TRUE means process hash message. FALSE means process raw M message */ + uint32_t u32SM2InputMByteCnt; /*!< the length should be <= 32bytes */ + uint32_t u32SM2InputIDByteCnt; /*!< the length should be <= 32bytes note: If "bUseDefaultID" is FALSE, would use this specific ID length with byte unit. */ + uint32_t *pInputData_ID; /*!< note: If "bUseDefaultID" is FALSE, would use this specific ID. length should be more than u32SM2InputIDByteCnt, and must be 4bytes align */ + uint32_t *pInputData_MOrHash; /*!< length should be more than u32SM2InputMOrHashByteCnt, and must be 4bytes align */ + uint32_t (*pPrivateKey)[8]; /*!< private key */ + uint32_t (*pPublicKey_X)[8]; /*!< If bHashInput is false, the pointer must be not NULL */ + uint32_t (*pPublicKey_Y)[8]; /*!< If bHashInput is false, the pointer must be not NULL */ + uint32_t (*pOutputData_R)[8]; /*!< sign result R */ + uint32_t (*pOutputData_S)[8]; /*!< sign result S */ +} HSM_Sm2SignType; + +typedef struct +{ + HSM_MailboxApiRetType u32HSMStatusRet; /*!< HSM core write return status value in this */ + uint32_t u32Timeout; /*!< current command timeout tick count, tick refer to the HSM bus clock */ + uint32_t u32UserKeyID_PublicKey; /*!< 0 means don't use key from HSM internal key space, otherwise would load key with KEYID from HSM */ + uint32_t u32UserKeyID_PrivateKey; /*!< 0 means don't use key from HSM internal key space, otherwise would load key with KEYID from HSM */ + HSM_Sm2SignType tCfg; +} HSMCom_Sm2SignType; + +/* ------------------------------------------------------------------------------- */ +/** + * @brief SM2 verify information used by driver when call specific API + * + */ +typedef struct +{ + HSM_BoolType bUseDefaultID; /*!< TRUE means use default ID. FALSE means use specific ID with "pInputData_ID" and "u32SM2InputIDByteCnt" params. */ + HSM_BoolType bHashInput; /*!< TRUE means process hash message. FALSE means process raw M message */ + uint32_t u32SM2InputMByteCnt; /*!< the length should be <= 32bytes */ + uint32_t u32SM2InputIDByteCnt; /*!< the length should be <= 32bytes note: If "bUseDefaultID" is FALSE, would use this specific ID length with byte unit. */ + uint32_t *pInputData_MOrHash; /*!< length should be more than u32SM2InputMOrHashByteCnt, and must be 4bytes align */ + uint32_t *pInputData_ID; /*!< note: If "bUseDefaultID" is FALSE, would use this specific ID. length should be more than u32SM2InputIDByteCnt, and must be 4bytes align */ + uint32_t (*pInputData_R)[8]; /*!< the sign result R */ + uint32_t (*pInputData_S)[8]; /*!< the sign result S */ + uint32_t (*pPublicKey_X)[8]; /*!< the public key X */ + uint32_t (*pPublicKey_Y)[8]; /*!< the public key Y */ +} HSM_Sm2VerifyType; + +typedef struct +{ + HSM_MailboxApiRetType u32HSMStatusRet; /*!< HSM core write return status value in this */ + uint32_t u32Timeout; /*!< current command timeout tick count, tick refer to the HSM bus clock */ + uint32_t u32UserKeyID_PublicKey; /*!< 0 means don't use key from HSM internal key space, otherwise would load key with KEYID from HSM */ + HSM_Sm2VerifyType tCfg; /*!< sm2 verify parameters */ +} HSMCom_Sm2VerifyType; + +/* ------------------------------------------------------------------------------- */ +/** + * @brief SM2 ZA generation information used by driver when call specific API + * + */ +typedef struct +{ + HSM_BoolType bUseDefaultID; /*!< TRUE means use default ID. FALSE means use specific ID with "pInputData_ID" and "u32SM2InputIDByteCnt" params. */ + uint32_t u32SM2InputIDByteCnt;/*!< the length should be <= 32bytes note: If "bUseDefaultID" is FALSE, would use this specific ID length with byte unit.*/ + uint32_t (*pPublicKey_X)[8]; + uint32_t (*pPublicKey_Y)[8]; + uint32_t *pInputData_ID; /*!< note: If "bUseDefaultID" is FALSE, would use this specific ID. length should be more than u32SM2InputIDByteCnt, and must be 4bytes align */ + uint32_t (*pOutputData_Za)[8]; /*!< Length is 32bytes, SM3 always output 256bit */ +} HSM_Sm2GenZaType; + +typedef struct +{ + HSM_MailboxApiRetType u32HSMStatusRet; /*!< HSM core write return status value in this */ + uint32_t u32Timeout; /*!< current command timeout tick count, tick refer to the HSM bus clock */ + uint32_t u32UserKeyID_PublicKey; /*!< 0 means don't use key from HSM internal key space, otherwise would load key with KEYID from HSM */ + HSM_Sm2GenZaType tCfg; +} HSMCom_Sm2GenZaType; +/* ------------------------------------------------------------------------------- */ +/** + * @brief SM2 HASH generation information used by driver when call specific API + * + */ +typedef struct +{ + uint32_t u32InputDataByteCnt; /*!< input data byte count */ + uint32_t *pInputData_ZaAndM; /*!< note: it should be ZA||M, the length should be more than u32InputDataByteCnt, and must be 4bytes align */ + uint32_t (*pOutputData_Hash)[8]; /*!< Length is 32bytes, SM3 always output 256bit */ +} HSM_Sm2GenHashType; + +typedef struct +{ + HSM_MailboxApiRetType u32HSMStatusRet; /*!< HSM core write return status value in this */ + uint32_t u32Timeout; /*!< current command timeout tick count, tick refer to the HSM bus clock */ + HSM_Sm2GenHashType tCfg; +} HSMCom_Sm2GenHashType; +/* ------------------------------------------------------------------------------- */ +/** + * @name definitions for HSM_Sm4KeyType + * + */ +/**@{*/ +/** + * @brief vendor key value for type "HSM_Sm4KeyType" + * + * HSM hardware support accessing the SM4 key stored in nvr flash directly, + * chip user should program the key in flash already. + * This way don't need software read data and write it to some place, + * hardware will read the data itself automatically. + */ +#define HSM_SM4_KEY_CHIP_VENDOR_IFR (0U) /* key has existed in Flash IFR, it provided by chip, not changeable */ + +/** + * @brief driver user's new key value for type "HSM_Sm4KeyType" + * + * HSM use the key passed by driver API user. + */ +#define HSM_SM4_KEY_NEW (1U) /* user should provide the new key */ +typedef uint32_t HSM_Sm4KeyType; +/**@}*/ + +/** + * @name definitions for HSM_Sm4EnDecryptAlgType + * + */ +/**@{*/ +/** + * @brief SM4 CTR mode value for type "HSM_Sm4EnDecryptAlgType" + * + */ +#define HSM_SM4_CTR (0U) + +/** + * @brief SM4 CBC mode value for type "HSM_Sm4EnDecryptAlgType" + * + */ +#define HSM_SM4_CBC (1U) + +/** + * @brief SM4 ECB mode value for type "HSM_Sm4EnDecryptAlgType" + * + */ +#define HSM_SM4_ECB (2U) + +/** + * @brief SM4 CFB mode value for type "HSM_Sm4EnDecryptAlgType" + * + */ +#define HSM_SM4_CFB (3U) + +/** + * @brief SM4 OFB mode value for type "HSM_Sm4EnDecryptAlgType" + * + */ +#define HSM_SM4_OFB (4U) + +/** + * @brief type definition for SM4 encrypt/decrypt mode + * + * HSM support CTR/CBC/ECB/CFB/OFB mode, driver api use this to select the encrypt/decrypt mode. + */ +typedef uint32_t HSM_Sm4EnDecryptAlgType; +/**@}*/ + +/** + * @brief SM4 encrypt/decrypt information used by driver when call specific API + * + */ +typedef struct +{ + HSM_Sm4KeyType eUseKeyType; /*!< the key source:vendor key programmed in nvr flash or new key in software */ + const uint32_t (*pKeyAddr)[4]; /*!< when eUseKeyType is HSM_SM4_KEY_NEW, this MUST configure */ + HSM_Sm4EnDecryptAlgType eSm4Alg; /*!< SM4 encrypt/decrypt mode */ + + const uint32_t *pDataInput; /*!< address should align with 4bytes */ + uint32_t u32InputByteCnt; /*!< 128bit(16Bytes) align */ + uint32_t *pDataOutput; /*!< address should align with 4bytes */ + uint32_t u32OutputMemSize; /*!< the output data buffer "pDataOutput" size, should >= "u32InputByteCnt" */ + + uint32_t (*pIvData)[4]; /*!< 128bit(16Bytes) iv(initialization vector) data array, ECB not need configure this */ +} HSM_Sm4EnDecryptType; + +typedef struct +{ + HSM_MailboxApiRetType u32HSMStatusRet; /*!< HSM core write return status value in this */ + uint32_t u32Timeout; /*!< current command timeout tick count, tick refer to the HSM bus clock */ + uint32_t u32UserKeyID; /*!< 0 means don't use key from HSM internal key space, otherwise would load key with KEYID from HSM */ + HSM_Sm4EnDecryptType tCfg; +} HSMCom_Sm4EnDecryptType; + +typedef HSMCom_Sm4EnDecryptType HSMCom_Sm4DecryptType; + +typedef HSMCom_Sm4EnDecryptType HSMCom_Sm4EncryptType; + +typedef struct { + HSMCom_Sm4EncryptType *pParam; + uint32_t u32Remain; +} HSMWrap_Sm4EncryptType; +/* ------------------------------------------------------------------------------- */ +/** + * @brief ECC encrypt information used by driver when call specific API + * + */ +typedef struct +{ + uint32_t u32ByteCount; /*!< all the data size, it should contains all N data */ + + const uint32_t *pCoeffi_A; /*!< the constant "a" in y^2 = x^3 + a*x + b (mod p), all data 8 bytes aligned */ + const uint32_t *pCoeffi_B; /*!< the constant "b" in y^2 = x^3 + a*x + b (mod p) */ + const uint32_t *pP; /*!< ecc curve modulus */ + const uint32_t *pN; /*!< ecc curve order; size; the count of all possible EC points */ + const uint32_t *pOtherSidePublicKey_x; /*!< decrypt side's public key axis x data */ + const uint32_t *pOtherSidePublicKey_y; /*!< decrypt side's public key axis y data */ + const uint32_t *pPrivateKey; /*!< encrypt side private key */ + const uint32_t *pPlainData; /*!< data to be encrypted, its byte count should be same as u32ByteCount */ + + uint32_t *pEncryedData; /*!< driver internal write the result to this buffer */ +} HSM_EccEasyEncryType; + +typedef struct +{ + HSM_MailboxApiRetType u32HSMStatusRet; /*!< HSM core write return status value in this */ + uint32_t u32Timeout; /*!< current command timeout tick count, tick refer to the HSM bus clock */ + uint32_t u32UserKeyID_PrivateKey;/*!< 0 means don't use key from HSM internal key space, otherwise would load key with KEYID from HSM */ + uint32_t u32UserKeyID_PublicKey; /*!< 0 means don't use key from HSM internal key space, otherwise would load key with KEYID from HSM */ + uint32_t u32BitCnt; + HSM_DrvEccCurvePrmIndexType u32EccCurve; + HSM_EccEasyEncryType tCfg; +} HSMCom_EccEasyEncryType; + +/* ------------------------------------------------------------------------------- */ +/** + * @brief ECC decrypt information used by driver when call specific API + * + */ +typedef struct +{ + uint32_t u32ByteCount; /*!< all the data size, it should contains all N data */ + const uint32_t *pCoeffi_A; /*!< the constant "a" in y^2 = x^3 + a*x + b (mod p), all data 8 bytes aligned */ + const uint32_t *pCoeffi_B; /*!< the constant "b" in y^2 = x^3 + a*x + b (mod p) */ + const uint32_t *pP; /*!< ecc curve modulus */ + const uint32_t *pN; /*!< ecc curve order; size; the count of all possible EC points */ + const uint32_t *pOtherSidePublicKey_x; /*!< encrypt side's public key axis x data */ + const uint32_t *pOtherSidePublicKey_y; /*!< encrypt side's public key axis y data */ + const uint32_t *pPrivateKey; /*!< decrypt side private key */ + const uint32_t *pEncryedData; /*!< data to be decrypted, its byte count should be same as u32ByteCount */ + uint32_t *pPlainData; /*!< driver internal write the result to this buffer */ +} HSM_EccEasyDecryType; + +typedef struct +{ + HSM_MailboxApiRetType u32HSMStatusRet; /*!< HSM core write return status value in this */ + uint32_t u32Timeout; /*!< current command timeout tick count, tick refer to the HSM bus clock */ + uint32_t u32UserKeyID_PrivateKey; /*!< 0 means don't use key from HSM internal key space, otherwise would load key with KEYID from HSM */ + uint32_t u32UserKeyID_PublicKey; /*!< 0 means don't use key from HSM internal key space, otherwise would load key with KEYID from HSM */ + uint32_t u32BitCnt; + HSM_DrvEccCurvePrmIndexType u32EccCurve; + HSM_EccEasyDecryType tCfg; +} HSMCom_EccEasyDecryType; +/* ------------------------------------------------------------------------------- */ +/** + * @brief ECC generate key pair information used by driver when call specific API + * + */ +typedef struct +{ + uint32_t u32ByteCount; /*!< all the data size, it should contains all N data */ + HSM_DrvEccCurveParamType tEccParam; + uint32_t *pPrivateKey; /*!< decrypt side private key */ + uint32_t *pPublicKey_x; /*!< encrypt side's public key axis x data */ + uint32_t *pPublicKey_y; /*!< encrypt side's public key axis y data */ +} HSM_EccKeyPairGenType; + +typedef struct +{ + HSM_MailboxApiRetType u32HSMStatusRet; /*!< HSM core write return status value in this */ + uint32_t u32Timeout; /*!< current command timeout tick count, tick refer to the HSM bus clock */ + uint32_t u32Bitcnt; /*!< 0 means don't use key from HSM internal key space, otherwise would load key with KEYID from HSM */ + HSM_DrvEccCurvePrmIndexType u32EccCurve; + HSM_EccKeyPairGenType tCfg; +} HSMCom_EccKeyPairGenType; +/* ------------------------------------------------------------------------------- */ + + +#define HSM_ECC_CALC_PADD 0xFC73F800 +#define HSM_ECC_CALC_PDBL 0xFC73F801 +#define HSM_ECC_CALC_PMUL 0xFC73F802 +#define HSM_ECC_CALC_PCHK 0xFC73F803 + +/** + * @brief ECC point calclulate used by driver when call specific API + * + */ +typedef struct +{ + uint32_t u32ByteCount; /*!< all the data size, it should contains all N data */ + const uint32_t *pCoeffi_A; /*!< address should align with 4bytes, the constant "a" in y^2 = x^3 + a*x + b (mod p), all data 8 bytes aligned */ + const uint32_t *pCoeffi_B; /*!< address should align with 4bytes, the constant "b" in y^2 = x^3 + a*x + b (mod p) */ + const uint32_t *pP; /*!< address should align with 4bytes, ecc curve modulus */ + const uint32_t *pN; /*!< address should align with 4bytes, ecc curve order; size; the count of all possible EC points */ + const uint32_t *pP1x; /*!< address should align with 4bytes, encrypt side's public key axis x data */ + const uint32_t *pP1y; /*!< address should align with 4bytes, encrypt side's public key axis y data */ + const uint32_t *pE; /*!< address should align with 4bytes, decrypt side private key */ + const uint32_t *pP2x; /*!< address should align with 4bytes, data to be decrypted, its byte count should be same as u32ByteCount */ + uint32_t *pResultx; /*!< address should align with 4bytes, driver internal write the result to this buffer */ + uint32_t u32CalcType; + const uint32_t *pP2y; + uint32_t *pResulty; +} HSM_EccCalcType; + +typedef struct +{ + HSM_MailboxApiRetType u32HSMStatusRet; /*!< HSM core write return status value in this */ + uint32_t u32Timeout; /*!< current command timeout Millisecond count, max 916000ms, if set to 0, means 1000ms */ + uint32_t u32UserKeyID_E; /*!< 0 means don't use key from HSM internal key space, otherwise would load key with KEYID from HSM */ + uint32_t u32UserKeyID_P1; /*!< 0 means don't use key from HSM internal key space, otherwise would load key with KEYID from HSM */ + uint32_t u32BitCnt; /*!< ecc encrypt data bit count */ + HSM_DrvEccCurvePrmIndexType u32EccCurve; /*!< ecc curve */ + HSM_EccCalcType tCfg; /*!< ecc decrypt parameters */ +} HSMCom_EccCalcType; +/* ------------------------------------------------------------------------------- */ + +#define HSM_COM_REQUEST_AUTH_DATA_U32_CNT 8 +typedef struct +{ + HSM_MailboxApiRetType u32HSMStatusRet; /*!< HSM core write return status value in this */ + uint32_t u32Timeout; /*!< current command timeout tick count, tick refer to the HSM bus clock */ + uint32_t (*pData)[HSM_COM_REQUEST_AUTH_DATA_U32_CNT]; +} HSMCom_RequestAuthType; +/* ------------------------------------------------------------------------------- */ +#define AUTH_CHECK_DATA_BYTE_CNT 32 +typedef struct +{ + HSM_MailboxApiRetType u32HSMStatusRet; /*!< HSM core write return status value in this */ + uint32_t u32Timeout; /*!< current command timeout tick count, tick refer to the HSM bus clock */ + const uint32_t *pkG_x; + const uint32_t *pkG_y; + const uint32_t *pR; + const uint32_t *pS; + //For user code verify function + const uint32_t *pData; + uint32_t u32DataLength; +} HSMCom_LifeCycleChangeType; +/* ------------------------------------------------------------------------------- */ +typedef struct +{ + HSM_MailboxApiRetType u32HSMStatusRet; /*!< HSM core write return status value in this */ + uint32_t u32Timeout; /*!< current command timeout tick count, tick refer to the HSM bus clock */ + uint32_t u32MailboxChannel; +} HSMCom_CancelJobType; +/* ------------------------------------------------------------------------------- */ +/** + * @name definitions for HSMCom_FirmwareLoadStatus + * + */ +/**@{*/ +/** + * @brief no firmware detected in flash status + * + */ +#define HSMCOM_FIRMWARE_LOAD_NONE (0u) + +/** + * @brief status value represents firmware is loading now + * + */ +#define HSMCOM_FIRMWARE_LOADING (1u) + +/** + * @brief status value represents firmware waiting user to trigger load in CM7 side + * + */ +#define HSMCOM_FIRMWARE_NEED_USER_LOAD (2u) + +/** + * @brief status value represents firmware is loaded successfully + * + */ +#define HSMCOM_FIRMWARE_LOAD_OK (3u) + +/** + * @brief status value represents firmware load fail + * + */ +#define HSMCOM_FIRMWARE_LOAD_FAIL (4u) + +typedef uint32_t HSMCom_FirmwareLoadStatus; +/**@}*/ + +typedef struct +{ + HSM_MailboxApiRetType u32HSMStatusRet; /*!< HSM core write return status value in this */ + uint32_t u32Timeout; /*!< current command timeout tick count, tick refer to the HSM bus clock */ + uint32_t u32Rng0CtrlAndNotFlag; // conf val, only ft mode, other mode REPO_COMMIT_ID + uint32_t u32Rng0CtrlOrFlag; // conf val,only ft mode, other mode REPO_BUILD_DATA + uint32_t u32FirmVersion; /*!< firmware version */ + uint32_t u32Rng1CtrlOrFlag; /*< FIX to 0x4d6f0000 */ + uint32_t u32BusClk; /*!< the hsm bus clock */ + uint32_t u32EntropyDelay0; + uint32_t u32FreqMax0; + uint32_t u32EntropyDelay1; + uint32_t u32FreqMax1; + HSMCom_FirmwareLoadStatus u32FirmwareLoadStatus; /*!< the status of loading firmware, IF >= 4 FAIL */ +} HSMCom_SelfTestType; +/* ------------------------------------------------------------------------------- */ + +#define HSMCOM_NVR_OTP_START_ADDR 0x04400400 +#define HSMCOM_NVR_OTP_END_ADDR 0x04401fff + +typedef struct +{ + HSM_MailboxApiRetType u32HSMStatusRet; /*!< HSM core write return status value in this */ + uint32_t u32Timeout; /*!< current command timeout tick count, tick refer to the HSM bus clock */ + uint32_t u32Addr; // 0x04400400 - 0x04401fff, 16bytes align + uint32_t aData[4]; +} HSMCom_NvrOtpType; +/* ------------------------------------------------------------------------------- */ +/** + * @name definitions for KeyManager_BoolType + * + */ +/**@{*/ +#define KEYMANAGER_FALSE (0u) +#define KEYMANAGER_TRUE (1u) +typedef uint32_t KeyManager_BoolType; +/**@}*/ + +/** + * @name definitions for KEYMANAGER_KeyExportType + * + */ +/**@{*/ +#define KEYMANAGER_KEY_EXPORT_FORBIRD (0u) +#define KEYMANAGER_KEY_EXPORT_PLAIN (1u) +#define KEYMANAGER_KEY_EXPORT_CIPHER (2u) +#define KEYMANAGER_KEY_EXPORT_MAX (3u) +typedef uint32_t KEYMANAGER_KeyExportType; +/**@}*/ + +/** + * @name definitions for KeyManager_UserKeyEnDecryType + * + */ +/**@{*/ +#define KEYMANAGER_ENDECRY_NONE (0u)/* For plain key, no need to encrypt or decrypt. */ +#define KEYMANAGER_ENDECRY_AES256 (1u) +#define KEYMANAGER_ENDECRY_SM4 (2u) +#define KEYMANAGER_ENDECRY_MAX (3u) +typedef uint32_t KeyManager_UserKeyEnDecryType; +/**@}*/ + +/** + * @name definitions for KeyManager_UserKeyTypeType + * + */ +/**@{*/ +#define KEYMANAGER_USER_KEY_TYPE_NONE (0u)//not configure the key type, HSM shall not check if the key type is matched with de/encrypt ALG. +#define KEYMANAGER_USER_KEY_TYPE_AES (1u) +#define KEYMANAGER_USER_KEY_TYPE_SM4 (2u) +#define KEYMANAGER_USER_KEY_TYPE_ECC_PRIVATE (3u) +#define KEYMANAGER_USER_KEY_TYPE_ECC_PUBLIC (4u) +#define KEYMANAGER_USER_KEY_TYPE_SM2_PRIVATE (5u) +#define KEYMANAGER_USER_KEY_TYPE_SM2_PUBLIC (6u) +#define KEYMANAGER_USER_KEY_TYPE_RSA_E (7u) +#define KEYMANAGER_USER_KEY_TYPE_RSA_N (8u) +#define KEYMANAGER_USER_KEY_TYPE_XMAC (9u) +#define KEYMANAGER_USER_KEY_TYPE_CMAC (10u) +#define KEYMANAGER_USER_KEY_TYPE_CCM (11u) +#define KEYMANAGER_USER_KEY_TYPE_GCM (12u) +typedef uint32_t KeyManager_UserKeyTypeType; +/**@}*/ + +/** + * @name definitions for KEYMANAGER_EnDecryAlgType + * + */ +/**@{*/ + +#define KEYMANAGER_ENDECRY_ALG_CTR (0u) +#define KEYMANAGER_ENDECRY_ALG_CBC (1u) +#define KEYMANAGER_ENDECRY_ALG_ECB (2u) +#define KEYMANAGER_ENDECRY_ALG_CFB (3u) +#define KEYMANAGER_ENDECRY_ALG_OFB (4u) +#define KEYMANAGER_ENDECRY_ALG_MAX (5u) + +typedef uint32_t KEYMANAGER_EnDecryAlgType; +/**@}*/ + +typedef struct +{ + uint32_t *pDataAddr; + uint32_t *pDataLength; + uint32_t u32KeyID; + KeyManager_UserKeyEnDecryType eEncryType; //indicate if the key exported is need to be encrypted + //if the key exported need to be encrypted, below Param need to configure + uint32_t u32EncryKeyID; //0 means use USRK as encrykey, otherwise load decrykey with KEYID from hsm key space + KEYMANAGER_EnDecryAlgType eAlgType; + uint32_t (*pIV)[4]; + uint32_t *pCiperKeyLength; +} KeyManager_ExportUserKeyType; + +typedef struct +{ + KeyManager_BoolType bStoreInFlash; //true means store the key in flash, false means store the key in ram + KEYMANAGER_KeyExportType eExportType; + uint32_t *pDataAddr; //the address of key imported + uint32_t u32DataLength; // the length of key imported + uint32_t *pKeyID; + KeyManager_UserKeyEnDecryType eDecryType; //indicate if the key imported is plain + //if the key imported is encrypted, below Param need to configure + uint32_t u32DecryKeyID; //0 means use USRK as decrykey, otherwise load decrykey with KEYID from hsm key space + KeyManager_UserKeyTypeType eUserKeyType; + KEYMANAGER_EnDecryAlgType eAlgType; + uint32_t (*pIV)[4]; +} KeyManager_ImportUserKeyType; + +#define KEYMANAGER_GEN_KEYPAIR_SM2 (0u) +#define KEYMANAGER_GEN_KEYPAIR_ECC (1u) +#define KEYMANAGER_GEN_KEYPAIR_MAX (2u) +typedef uint32_t KeyManager_GeNKeyPairType; + +typedef struct +{ + KeyManager_GeNKeyPairType eKeyPairType; + KEYMANAGER_KeyExportType eExportType; + KeyManager_BoolType bStoreInFlash; + uint32_t *pPrivateKeyID; + uint32_t *pPublicKeyID; +} KeyManager_GenAsymmetricUserKeyType; + +typedef struct +{ + KEYMANAGER_KeyExportType eExportType; + KeyManager_BoolType bStoreInFlash; + uint32_t u32KeyLength; + uint32_t *pKeyID; +} KeyManager_GenSymmetricUserKeyType; + +typedef struct +{ + union{ + KeyManager_GenAsymmetricUserKeyType tGenKeyPairCfg; + KeyManager_GenSymmetricUserKeyType tGenKeyCfg; + }; + HSM_DrvEccCurveParamType tEccParam; //only for generate ECC key pair + uint32_t u32EccBitLength; //only for generate ECC key pair + HSM_BoolType bGenSymmetricKey; + HSM_DrvEccCurvePrmIndexType u32EccCurve; +} HSMCom_GenUserKeyType; + +typedef struct +{ + HSM_MailboxApiRetType u32HSMStatusRet; /*!< HSM core write return status value in this */ + uint32_t u32Timeout; /*!< current command timeout tick count, tick refer to the HSM bus clock */ + union + { + uint32_t u32RevokeUserKeyID;/* For revoke UserKey function*/ + KeyManager_ImportUserKeyType tImportUserKeyCfg;/* For import User Key function*/ + KeyManager_ExportUserKeyType tExportUserKeyCfg;/* For export user key function */ + HSMCom_GenUserKeyType tGenUserKeyCfg;/* For generate key pair function */ + }; +} HSMCom_UserKeyManageType; +/* ------------------------------------------------------------------------------- */ +typedef struct +{ + //For Key Flash Space + KeyManager_BoolType bCriticalError; + KeyManager_BoolType bKMLackKeyHeadSpace; + KeyManager_BoolType bKMLackKeyDataSpace; + uint32_t u32KeyHeadRestSpace; //The unit is number + uint32_t u32KeyDataRestSpace; //The unit is page + uint32_t u32InvalidKeyCounter; + //For Key ram space + uint32_t u32KeyRamSpaceUsed; +} KeyManager_SpaceStatusType; + +typedef struct +{ + HSM_MailboxApiRetType u32HSMStatusRet; /*!< HSM core write return status value in this */ + uint32_t u32Timeout; /*!< current command timeout tick count, tick refer to the HSM bus clock */ + KeyManager_SpaceStatusType *pKMSpaceStatus; +} HSMCom_KeySpaceStatusType; +/* ------------------------------------------------------------------------------- */ + +/** + * @name definitions for HSM_AesKeyType + * + */ +/**@{*/ + +/** + * @brief vendor key value for type "HSM_AesKeyType" + * + * HSM hardware support accessing the aes key stored in nvr flash directly, + * chip user should program the key in flash already. + * This way don't need software read data and write it to some place, + * hardware will read the data itself automatically. + */ +#define HSM_AES_KEY_CHIP_VENDOR_IFR (0U) /* key has existed in Flash IFR, it provided by chip hardware, not changeable */ + +/** + * @brief driver user's new key value for type "HSM_AesKeyType" + * + * HSM use the key passed by driver API user. + */ +#define HSM_AES_KEY_NEW (1U) /* user should provide the new key */ + +/** + * @brief type definition for the key source + * + * key from the nvr refer to HSM_AES_KEY_CHIP_VENDOR_IFR + * key from driver user's parameters refer to HSM_AES_KEY_NEW + */ +typedef uint32_t HSM_AesKeyType; +/**@}*/ + +/** + * @name definitions for HSM_AesKeyBitCntType + * + */ +/**@{*/ + +/** + * @brief AES128 key type value for type "HSM_AesKeyBitCntType" + * + */ +#define HSM_AES_KEY128 (0U) + +/** + * @brief AES192 key type value for type "HSM_AesKeyBitCntType" + * + */ +#define HSM_AES_KEY192 (1U) + +/** + * @brief AES256 key type value for type "HSM_AesKeyBitCntType" + * + */ +#define HSM_AES_KEY256 (2U) + +/** + * @brief type definition for AES key + * + * HSM support AES128/192/256, driver api use this to select the algorithm. + */ +typedef uint32_t HSM_AesKeyBitCntType; +/**@}*/ + + +/** + * @brief key information used by AES when use one key in software + * + */ +typedef struct +{ + HSM_AesKeyBitCntType eKeyType; /*!< the key bit count, which determine the AES algorithm type */ + const uint32_t *pKeyAddr; /*!< the key data pointer, the address should 4bytes align, the buffer array should declared by uint32_t */ +} HSM_AesNewKeyInfType; + +/** + * @brief key information used by AES when use one key in nvr flash + * + */ +typedef struct +{ + HSM_AesKeyBitCntType eKeyType; /*!< the key bit count, which determine the AES algorithm type */ +} HSM_AesVendorKeyInfType; + +/** + * @name definitions for HSM_AesEnDecryptAlgType + * + */ +/**@{*/ + +/** + * @brief AES CTR mode value for type "HSM_AesEnDecryptAlgType" + * + */ +#define HSM_AES_CTR (0U) + +/** + * @brief AES CBC mode value for type "HSM_AesEnDecryptAlgType" + * + */ +#define HSM_AES_CBC (1U) + +/** + * @brief AES ECB mode value for type "HSM_AesEnDecryptAlgType" + * + */ +#define HSM_AES_ECB (2U) + +/** + * @brief AES CFB mode value for type "HSM_AesEnDecryptAlgType" + * + */ +#define HSM_AES_CFB (3U) + +/** + * @brief AES OFB mode value for type "HSM_AesEnDecryptAlgType" + * + */ +#define HSM_AES_OFB (4U) + +/** + * @brief type definition for AES encrypt/decrypt mode + * + * HSM support CTR/CBC/ECB/CFB/OFB mode, driver api use this to select the encrypt/decrypt mode. + */ +typedef uint32_t HSM_AesEnDecryptAlgType; +/**@}*/ + +/** + * @brief AES encrypt/decrypt information used by driver when call specific API + * + */ +typedef struct +{ + HSM_AesKeyType eUseKeyType; /*!< the key source:vendor key programmed in nvr flash or new key in software */ + HSM_AesNewKeyInfType tNewKeyInf; /*!< when eUseKeyType is HSM_AES_KEY_NEW, this MUST configure */ + HSM_AesVendorKeyInfType tVendorKeyInf; /*!< when eUseKeyType is HSM_AES_KEY_CHIP_VENDOR_IFR, this MUST configure */ + HSM_AesEnDecryptAlgType eAesAlg; /*!< encrypt/decrypt mode */ + + const uint32_t *pDataInput; /*!< address should align with 4bytes */ + uint32_t u32InputByteCnt; /*!< 128bit(16Bytes) align */ + uint32_t *pDataOutput; /*!< address should align with 4bytes */ + uint32_t u32OutputMemSize; /*!< the output data buffer "pDataOutput" size, should >= "u32InputByteCnt" */ + + uint32_t (*pIvData)[4]; /*!< 128bit(16Bytes) iv(initialization vector) data array, ECB not need configure this */ + +} HSM_AesEnDecryptType; + +/** + * @brief Flexiable AES zero padding type for type "HSM_FlexAesPadType" + * if input data is not aligned with 16bytes, this configuration will make append byte data 0 to keep 16bytes align. + */ +#define HSM_FLEXAES_PAD_ZERO 0u + +/** + * @brief Flexiable AES PKCS7 padding type for type "HSM_FlexAesPadType" + * if input data is not aligned with 16bytes, this configuration will make append bytes by PKCS7 method to keep 16bytes align. + */ +#define HSM_FLEXAES_PAD_PKCS7 1u + +/** + * @brief Flexiable AES padding type definition + * if use zero padding, refer to HSM_FLEXAES_PAD_ZERO, after decrypt, user should remove the zero manually + * if use PKCS7 padding, refer to HSM_FLEXAES_PAD_PKCS7 + */ +typedef uint32_t HSM_FlexAesPadType; + +/* ------------------------------------------------------------------------------- */ +/** + * @brief AES hardware backend for AES for type "HSM_AesBackendType" + * + */ +#define HSM_AES_BACKEND_AES 0u + +/** + * @brief SM4 hardware backend for AES for type "HSM_AesBackendType" + * + */ +#define HSM_AES_BACKEND_SM4 1u + +/** + * @brief type definition for GCM's hardware backend + * AES backend refer to HSM_AES_BACKEND_AES + * SM4 backend refer to HSM_GCM_BACKEND_SM4 + */ +typedef uint32_t HSM_AesBackendType; + +/** + * @brief Flex AES encrypt/decrypt information used by driver when call specific API + * + */ +typedef struct +{ + HSM_AesKeyType eUseKeyType; /*!< the key source:vendor key programmed in nvr flash or new key in software */ + HSM_AesNewKeyInfType tNewKeyInf; /*!< when eUseKeyType is HSM_AES_KEY_NEW, this MUST configure */ + HSM_AesVendorKeyInfType tVendorKeyInf; /*!< when eUseKeyType is HSM_AES_KEY_CHIP_VENDOR_IFR, this MUST configure */ + HSM_AesEnDecryptAlgType eAesAlg; /*!< encrypt/decrypt mode */ + + const uint32_t *pDataInput; /*!< address should align with 4bytes */ + uint32_t u32InputByteCnt; /*!< 128bit(16Bytes) align */ + uint32_t *pDataOutput; /*!< address should align with 4bytes */ + uint32_t u32OutputMemSize; /*!< the output data buffer "pDataOutput" size, should >= "u32InputByteCnt" */ + + uint32_t (*pIvData)[4]; /*!< address should align with 4bytes, 128bit(16Bytes) iv(initialization vector) data array, ECB not need configure this */ + + uint32_t *pGenerateOutByteCnt; /*!< point to the uint32_t variable to store the result byte count, can't be NULL */ + + HSM_FlexAesPadType epad; + HSM_DataFormatType eInputFmt; + HSM_DataFormatType eOutputFmt; + HSM_AesBackendType eBackend; +} HSM_FlexAesEnDecryptType; + +/** + * @brief AES decrypt information used by driver when call specific API + * + */ +typedef HSM_AesEnDecryptType HSM_AesEncryptType; +typedef struct +{ + HSM_MailboxApiRetType u32HSMStatusRet; /*!< HSM core write return status value in this */ + uint32_t u32Timeout; /*!< current command timeout tick count, tick refer to the HSM bus clock */ + uint32_t u32UserKeyID; /*!< 0 means don't use key from HSM internal key space, otherwise would load key with KEYID from HSM */ + HSM_AesEncryptType tCfg; /*!< aes parameters */ +} HSMCom_AesEncryptType; +/* ------------------------------------------------------------------------------- */ +/** + * @brief AES encrypt information used by driver when call specific API + * + */ +typedef HSM_AesEnDecryptType HSM_AesDecryptType; + +typedef struct +{ + HSM_MailboxApiRetType u32HSMStatusRet; /*!< HSM core write return status value in this */ + uint32_t u32Timeout; /*!< current command timeout tick count, tick refer to the HSM bus clock */ + uint32_t u32UserKeyID; /*!< 0 means don't use key from HSM internal key space, otherwise would load key with KEYID from HSM */ + HSM_AesDecryptType tCfg; /*!< AES decrypt parameters */ +} HSMCom_AesDecryptType; +/* ------------------------------------------------------------------------------- */ + +/** + * @brief Flex AES decrypt information used by driver when call specific API + * + */ +typedef HSM_FlexAesEnDecryptType HSM_FlexAesEncryptType; +typedef struct +{ + HSM_MailboxApiRetType u32HSMStatusRet; /*!< HSM core write return status value in this */ + uint32_t u32Timeout; /*!< current command timeout Millisecond count, max 916000ms, if set to 0, means 1000ms */ + uint32_t u32UserKeyID; /*!< 0 means don't use key from HSM internal key space, otherwise would load key with KEYID from HSM */ + HSM_FlexAesEncryptType tCfg; /*!< aes parameters */ +} HSMCom_FlexAesEncryptType; +/* ------------------------------------------------------------------------------- */ +/** + * @brief AES encrypt information used by driver when call specific API + * + */ +typedef HSM_FlexAesEnDecryptType HSM_FlexAesDecryptType; + +typedef struct +{ + HSM_MailboxApiRetType u32HSMStatusRet; /*!< HSM core write return status value in this */ + uint32_t u32Timeout; /*!< current command timeout Millisecond count, max 916000ms, if set to 0, means 1000ms */ + uint32_t u32UserKeyID; /*!< 0 means don't use key from HSM internal key space, otherwise would load key with KEYID from HSM */ + HSM_FlexAesDecryptType tCfg; /*!< AES decrypt parameters */ +} HSMCom_FlexAesDecryptType; +/* ------------------------------------------------------------------------------- */ + +/** + * @brief CMAC/XMAC information used by driver when call specific API + * + */ + +#define HSM_XCMAC_BACKEND_AES 0u +#define HSM_XCMAC_BACKEND_SM4 1u + +typedef uint32_t HSM_XCMAC_BackendType; + +typedef struct +{ + HSM_AesKeyType eUseKeyType; /*!< fix to HSM_AES_KEY_NEW */ + HSM_AesNewKeyInfType tNewKeyInf; /*!< when eUseKeyType is HSM_AES_KEY_NEW, this MUST configure */ + HSM_AesVendorKeyInfType tVendorKeyInf; /*!< when eUseKeyType is HSM_AES_KEY_CHIP_VENDOR_IFR, this MUST configure */ + uint32_t u32GenMacByteCnt; /*!< XCMAC API generate MAC data, it's "u32GenMacByteCnt" size ICV data */ + HSM_BoolType bCheckMacEn; /*!< if enable this check, user should place the data after the input data, hsm will check the generated data and it, if fail, hsm generate a interrupt, and if user get hw status, will get a error status */ + const uint32_t *pDataInput; /*!< address should align with 4bytes */ + uint32_t u32InputByteCnt; /*!< 128bit(16Bytes) align */ + uint32_t *pDataOutput; /*!< address should align with 4bytes */ + uint32_t u32OutputMemSize; /*!< 4bytes align, the output data buffer "pDataOutput" size, should >= "u32GenMacByteCnt" */ +} HSM_XCMacType; + +/** + * @brief CMAC information used by driver when call specific API + * + */ +typedef HSM_XCMacType HSM_CMacType; + + +typedef struct +{ + HSM_MailboxApiRetType u32HSMStatusRet; /*!< HSM core write return status value in this */ + uint32_t u32Timeout; /*!< current command timeout tick count, tick refer to the HSM bus clock */ + uint32_t u32UserKeyID; /*!< 0 means don't use key from HSM internal key space, otherwise would load key with KEYID from HSM */ + HSM_CMacType tCfg; /*!< CMAC parameters */ +} HSMCom_CMacType; + +typedef struct +{ + HSM_AesKeyType eUseKeyType; /*!< fix to HSM_AES_KEY_NEW */ + HSM_AesNewKeyInfType tNewKeyInf; /*!< when eUseKeyType is HSM_AES_KEY_NEW, this MUST configure */ + HSM_AesVendorKeyInfType tVendorKeyInf; /*!< when eUseKeyType is HSM_AES_KEY_CHIP_VENDOR_IFR, this MUST configure */ + uint32_t u32GenMacByteCnt; /*!< XCMAC API generate MAC data, it's "u32GenMacByteCnt" size ICV data */ + HSM_BoolType bCheckMacEn; /*!< if enable this check, user should place the data after the input data, hsm will check the generated data and it, if fail, hsm generate a interrupt, and if user get hw status, will get a error status */ + const uint32_t *pDataInput; /*!< address should align with 4bytes */ + uint32_t u32InputByteCnt; /*!< 128bit(16Bytes) align */ + uint32_t *pDataOutput; /*!< address should align with 4bytes */ + uint32_t u32OutputMemSize; /*!< 4bytes align, the output data buffer "pDataOutput" size, should >= "u32GenMacByteCnt" */ + + HSM_XCMAC_BackendType eBackend; + HSM_DataFormatType eInputFmt; + HSM_DataFormatType eOutputFmt; +} HSM_XCMacExType; + +typedef HSM_XCMacExType HSM_CMacExType; +typedef struct +{ + HSM_MailboxApiRetType u32HSMStatusRet; /*!< HSM core write return status value in this */ + uint32_t u32Timeout; /*!< current command timeout tick count, tick refer to the HSM bus clock */ + uint32_t u32UserKeyID; /*!< 0 means don't use key from HSM internal key space, otherwise would load key with KEYID from HSM */ + HSM_CMacExType tCfg; /*!< CMAC parameters */ +} HSMCom_CMacExType; + + +/* ------------------------------------------------------------------------------- */ +/** + * @brief XMAC information used by driver when call specific API + * + */ +typedef HSM_XCMacType HSM_XMacType; +typedef struct +{ + HSM_MailboxApiRetType u32HSMStatusRet; /*!< HSM core write return status value in this */ + uint32_t u32Timeout; /*!< current command timeout tick count, tick refer to the HSM bus clock */ + uint32_t u32UserKeyID; /*!< 0 means don't use key from HSM internal key space, otherwise would load key with KEYID from HSM */ + HSM_XMacType tCfg; /*!< XMAC parameter */ +} HSMCom_XMacType; + +typedef HSM_XCMacExType HSM_XMacExType; +typedef struct +{ + HSM_MailboxApiRetType u32HSMStatusRet; /*!< HSM core write return status value in this */ + uint32_t u32Timeout; /*!< current command timeout tick count, tick refer to the HSM bus clock */ + uint32_t u32UserKeyID; /*!< 0 means don't use key from HSM internal key space, otherwise would load key with KEYID from HSM */ + HSM_XMacExType tCfg; /*!< XMAC parameter */ +} HSMCom_XMacExType; + +/* ------------------------------------------------------------------------------- */ +/** + * @brief AES hardware backend for CCM for type "HSM_CcmBackendType" + * + */ +#define HSM_CCM_BACKEND_AES 0u + +/** + * @brief SM4 hardware backend for CCM for type "HSM_CcmBackendType" + * + */ +#define HSM_CCM_BACKEND_SM4 1u + +/** + * @brief type definition for CCM's hardware backend + * AES backend refer to HSM_CCM_BACKEND_AES + * SM4 backend refer to HSM_CCM_BACKEND_SM4 + */ +typedef uint32_t HSM_CcmBackendType; + + +/** + * @brief CCM Encrypt information used by driver when call specific API + * + */ +typedef struct +{ + HSM_AesKeyType eUseKeyType; /*!< the key source:vendor key programmed in nvr flash or new key in software */ + HSM_AesNewKeyInfType tNewKeyInf; /*!< when eUseKeyType is HSM_AES_KEY_NEW, this MUST configure */ + HSM_AesVendorKeyInfType tVendorKeyInf; /*!< when eUseKeyType is HSM_AES_KEY_CHIP_VENDOR_IFR, this MUST configure */ + uint32_t *pAllData; /*!< address should align with 4bytes, place AAD data(16bytes align) first, then input data */ + uint32_t u32AadByteCnt; /*!< the byte count contain the 2bytes in the head, it's the valid data size, not after aligned, 128bit(16Bytes) align, if not, only the aligned data treat as AAD, the left AAD bytes will be treated as input data */ + uint32_t u32InputByteCnt; /*!< 128bit(16Bytes) align, ONLY represent data */ + uint32_t u32GenMacByteCnt; /*!< output mac size */ + uint32_t *pDataOutput; /*!< address should align with 4bytes */ + uint32_t u32OutputMemSize; /*!< the output data buffer "pDataOutput" size, should >= "u32InputByteCnt" */ + uint32_t (*pIvData)[8]; /*!< iv data, consist of 16bytes B0 data, and 16bytes CTR, MUST configure */ + uint32_t (*pMacOut)[4]; /*!< HSM generated MAC data */ + uint32_t (*pEmacOut)[4]; /*!< HSM generated encrypted MAC data */ +} HSM_CcmEncryptType; + +typedef struct +{ + HSM_MailboxApiRetType u32HSMStatusRet; /*!< HSM core write return status value in this */ + uint32_t u32Timeout; /*!< current command timeout tick count, tick refer to the HSM bus clock */ + uint32_t u32UserKeyID; /*!< 0 means don't use key from HSM internal key space, otherwise would load key with KEYID from HSM */ + HSM_CcmEncryptType tCfg; /*!< CCM encrypt parameters */ +} HSMCom_CcmEncryptType; + +typedef struct +{ + HSM_AesKeyType eUseKeyType; /*!< the key source:vendor key programmed in nvr flash or new key in software */ + HSM_AesNewKeyInfType tNewKeyInf; /*!< when eUseKeyType is HSM_AES_KEY_NEW, this MUST configure */ + HSM_AesVendorKeyInfType tVendorKeyInf; /*!< when eUseKeyType is HSM_AES_KEY_CHIP_VENDOR_IFR, this MUST configure */ + uint32_t *pAllData; /*!< address should align with 4bytes, place AAD data(16bytes align) first, then input data */ + uint32_t u32AadByteCnt; /*!< the byte count contain the 2bytes in the head, it's the valid data size, not after aligned, 128bit(16Bytes) align, if not, only the aligned data treat as AAD, the left AAD bytes will be treated as input data */ + uint32_t u32InputByteCnt; /*!< 128bit(16Bytes) align, ONLY represent data */ + uint32_t u32GenMacByteCnt; /*!< output mac size */ + uint32_t *pDataOutput; /*!< address should align with 4bytes */ + uint32_t u32OutputMemSize; /*!< the output data buffer "pDataOutput" size, should >= "u32InputByteCnt" */ + uint32_t (*pIvData)[8]; /*!< iv data, consist of 16bytes B0 data, and 16bytes CTR, MUST configure */ + uint32_t (*pMacOut)[4]; /*!< HSM generated MAC data */ + uint32_t (*pEmacOut)[4]; /*!< HSM generated encrypted MAC data */ + HSM_CcmBackendType eBackend; +} HSM_CcmEncryptExType; + +typedef struct +{ + HSM_MailboxApiRetType u32HSMStatusRet; /*!< HSM core write return status value in this */ + uint32_t u32Timeout; /*!< current command timeout tick count, tick refer to the HSM bus clock */ + uint32_t u32UserKeyID; /*!< 0 means don't use key from HSM internal key space, otherwise would load key with KEYID from HSM */ + HSM_CcmEncryptExType tCfg; /*!< CCM encrypt parameters */ +} HSMCom_CcmEncryptExType; + +/* ------------------------------------------------------------------------------- */ +/** + * @brief CCM Decrypt information used by driver when call specific API + * + */ +typedef struct +{ + HSM_AesKeyType eUseKeyType; /*!< the key source:vendor key programmed in nvr flash or new key in software */ + HSM_AesNewKeyInfType tNewKeyInf; /*!< when eUseKeyType is HSM_AES_KEY_NEW, this MUST configure */ + HSM_AesVendorKeyInfType tVendorKeyInf; /*!< when eUseKeyType is HSM_AES_KEY_CHIP_VENDOR_IFR, this MUST configure */ + uint32_t *pAllData; /*!< address should align with 4bytes, place AAD data(if exist, 16bytes align) first, then input data, then MAC data(if exist) */ + uint32_t u32AadByteCnt; /*!< 128bit(16Bytes) align, if not, only the aligned data treat as AAD, the left AAD bytes will be treated as input data */ + uint32_t u32InputByteCnt; /*!< 128bit(16Bytes) align */ + HSM_BoolType bCheckMacEn; /*!< check the MAC data in input or not */ + uint32_t u32MacByteCnt; /*!< 128bit(16Bytes) align */ + uint32_t *pDataOutput; /*!< point to the buffer that store the result */ + uint32_t u32OutputMemSize; /*!< the output data buffer "pDataOutput" size, should >= "u32InputByteCnt" */ + uint32_t (*pIvData)[8]; /*!< iv data, consist of 16bytes B0 data, and 16bytes CTR, MUST configure */ +} HSM_CcmDecryptType; + +typedef struct +{ + HSM_MailboxApiRetType u32HSMStatusRet; /*!< HSM core write return status value in this */ + uint32_t u32Timeout; /*!< current command timeout tick count, tick refer to the HSM bus clock */ + uint32_t u32UserKeyID; /*!< 0 means don't use key from HSM internal key space, otherwise would load key with KEYID from HSM */ + HSM_CcmDecryptType tCfg; /*!< CCM decrypt parameter */ +} HSMCom_CcmDecryptType; + +typedef struct +{ + HSM_AesKeyType eUseKeyType; /*!< the key source:vendor key programmed in nvr flash or new key in software */ + HSM_AesNewKeyInfType tNewKeyInf; /*!< when eUseKeyType is HSM_AES_KEY_NEW, this MUST configure */ + HSM_AesVendorKeyInfType tVendorKeyInf; /*!< when eUseKeyType is HSM_AES_KEY_CHIP_VENDOR_IFR, this MUST configure */ + uint32_t *pAllData; /*!< address should align with 4bytes, place AAD data(if exist, 16bytes align) first, then input data, then MAC data(if exist) */ + uint32_t u32AadByteCnt; /*!< 128bit(16Bytes) align, if not, only the aligned data treat as AAD, the left AAD bytes will be treated as input data */ + uint32_t u32InputByteCnt; /*!< 128bit(16Bytes) align */ + HSM_BoolType bCheckMacEn; /*!< check the MAC data in input or not */ + uint32_t u32MacByteCnt; /*!< 128bit(16Bytes) align */ + uint32_t *pDataOutput; /*!< point to the buffer that store the result */ + uint32_t u32OutputMemSize; /*!< the output data buffer "pDataOutput" size, should >= "u32InputByteCnt" */ + uint32_t (*pIvData)[8]; /*!< iv data, consist of 16bytes B0 data, and 16bytes CTR, MUST configure */ + HSM_CcmBackendType eBackend; +} HSM_CcmDecryptExType; + +typedef struct +{ + HSM_MailboxApiRetType u32HSMStatusRet; /*!< HSM core write return status value in this */ + uint32_t u32Timeout; /*!< current command timeout tick count, tick refer to the HSM bus clock */ + uint32_t u32UserKeyID; /*!< 0 means don't use key from HSM internal key space, otherwise would load key with KEYID from HSM */ + HSM_CcmDecryptExType tCfg; /*!< CCM decrypt parameter */ +} HSMCom_CcmDecryptExType; + +/* ------------------------------------------------------------------------------- */ +/** + * @brief AES hardware backend for GCM for type "HSM_GcmBackendType" + * + */ +#define HSM_GCM_BACKEND_AES 0u + +/** + * @brief SM4 hardware backend for GCM for type "HSM_GcmBackendType" + * + */ +#define HSM_GCM_BACKEND_SM4 1u + +/** + * @brief type definition for GCM's hardware backend + * AES backend refer to HSM_GCM_BACKEND_AES + * SM4 backend refer to HSM_GCM_BACKEND_SM4 + */ +typedef uint32_t HSM_GcmBackendType; + +/** + * @brief GCM Encrypt information used by driver when call specific API + * + */ +typedef struct +{ + HSM_AesKeyType eUseKeyType; /*!< the key source:vendor key programmed in nvr flash or new key in software */ + HSM_AesNewKeyInfType tNewKeyInf; /*!< when eUseKeyType is HSM_AES_KEY_NEW, this MUST configure */ + HSM_AesVendorKeyInfType tVendorKeyInf; /*!< when eUseKeyType is HSM_AES_KEY_CHIP_VENDOR_IFR, this MUST configure */ + uint32_t *pAllData; /*!< address should align with 4bytes, place IV data first, then AAD data(16bytes align), then input data */ + uint32_t u32IvDataByteCnt; /*!< 64bit(8Bytes) align, if not, only the aligned data treat as IV, the left IV bytes will be treated as AAD data */ + uint32_t u32AadByteCnt; /*!< 64bit(8Bytes) align, if not, only the aligned data treat as AAD, the left AAD bytes will be treated as input data */ + uint32_t u32InputByteCnt; /*!< 128bit(16Bytes) align */ + uint32_t u32GenMacByteCnt; /*!< set the MAC result byte count */ + uint32_t *pDataOutput; /*!< address should align with 4bytes */ + uint32_t u32OutputMemSize; /*!< the output data buffer "pDataOutput" size, should >= "u32InputByteCnt" */ + uint32_t (*pMacOut)[4]; /*!< buffer address, this buffer store the result */ +} HSM_GcmEncryptType; + +typedef struct +{ + HSM_MailboxApiRetType u32HSMStatusRet; /*!< HSM core write return status value in this */ + uint32_t u32Timeout; /*!< current command timeout tick count, tick refer to the HSM bus clock */ + uint32_t u32UserKeyID; /*!< 0 means don't use key from HSM internal key space, otherwise would load key with KEYID from HSM */ + HSM_GcmEncryptType tCfg; /*!< GCM parameters */ +} HSMCom_GcmEncryptType; + +/** + * @brief GCM Encrypt information used by driver when call specific API + * + */ +typedef struct +{ + HSM_AesKeyType eUseKeyType; /*!< the key source:vendor key programmed in nvr flash or new key in software */ + HSM_AesNewKeyInfType tNewKeyInf; /*!< when eUseKeyType is HSM_AES_KEY_NEW, this MUST configure */ + HSM_AesVendorKeyInfType tVendorKeyInf; /*!< when eUseKeyType is HSM_AES_KEY_CHIP_VENDOR_IFR, this MUST configure */ + uint32_t *pAllData; /*!< address should align with 4bytes, place IV data first, then AAD data(16bytes align), then input data */ + uint32_t u32IvDataByteCnt; /*!< 64bit(8Bytes) align, if not, only the aligned data treat as IV, the left IV bytes will be treated as AAD data */ + uint32_t u32AadByteCnt; /*!< 64bit(8Bytes) align, if not, only the aligned data treat as AAD, the left AAD bytes will be treated as input data */ + uint32_t u32InputByteCnt; /*!< 128bit(16Bytes) align */ + uint32_t u32GenMacByteCnt; /*!< set the MAC result byte count */ + uint32_t *pDataOutput; /*!< address should align with 4bytes */ + uint32_t u32OutputMemSize; /*!< the output data buffer "pDataOutput" size, should >= "u32InputByteCnt" */ + uint32_t (*pMacOut)[4]; /*!< buffer address, this buffer store the result */ + HSM_GcmBackendType eBackend; +} HSM_GcmEncryptExType; + +typedef struct +{ + HSM_MailboxApiRetType u32HSMStatusRet; /*!< HSM core write return status value in this */ + uint32_t u32Timeout; /*!< current command timeout tick count, tick refer to the HSM bus clock */ + uint32_t u32UserKeyID; /*!< 0 means don't use key from HSM internal key space, otherwise would load key with KEYID from HSM */ + HSM_GcmEncryptExType tCfg; /*!< GCM parameters */ +} HSMCom_GcmEncryptExType; + +/* ------------------------------------------------------------------------------- */ +/** + * @brief GCM Decrypt information used by driver when call specific API + * + */ +typedef struct +{ + HSM_AesKeyType eUseKeyType; /*!< the key source:vendor key programmed in nvr flash or new key in software */ + HSM_AesNewKeyInfType tNewKeyInf; /*!< when eUseKeyType is HSM_AES_KEY_NEW, this MUST configure */ + HSM_AesVendorKeyInfType tVendorKeyInf; /*!< when eUseKeyType is HSM_AES_KEY_CHIP_VENDOR_IFR, this MUST configure */ + uint32_t *pAllData; /*!< address should align with 4bytes, place IV data first, then AAD data(if exist, 16bytes align), then input data, then MAC data(if exist) */ + uint32_t u32IvDataByteCnt; /*!< 64bit(8Bytes) align, if not, only the aligned data treat as IV, the left IV bytes will be treated as AAD data */ + uint32_t u32AadByteCnt; /*!< 64bit(8Bytes) align, if not, only the aligned data treat as AAD, the left AAD bytes will be treated as input data */ + uint32_t u32InputByteCnt; /*!< 128bit(16Bytes) align */ + HSM_BoolType bCheckMacEn; /*!< check the MAC data in input or not */ + uint32_t u32MacByteCnt; /*!< 128bit(16Bytes) align */ + uint32_t *pDataOutput; /*!< point to the buffer that store the result */ + uint32_t u32OutputMemSize; /*!< the output data buffer "pDataOutput" size, should >= "u32InputByteCnt" */ +} HSM_GcmDecryptType; + +typedef struct +{ + HSM_MailboxApiRetType u32HSMStatusRet; /*!< HSM core write return status value in this */ + uint32_t u32Timeout; /*!< current command timeout tick count, tick refer to the HSM bus clock */ + uint32_t u32UserKeyID; /*!< 0 means don't use key from HSM internal key space, otherwise would load key with KEYID from HSM */ + HSM_GcmDecryptType tCfg; /*!< GCM decrypt parameter */ +} HSMCom_GcmDecryptType; + +/** + * @brief GCM Decrypt information used by driver when call specific API + * + */ +typedef struct +{ + HSM_AesKeyType eUseKeyType; /*!< the key source:vendor key programmed in nvr flash or new key in software */ + HSM_AesNewKeyInfType tNewKeyInf; /*!< when eUseKeyType is HSM_AES_KEY_NEW, this MUST configure */ + HSM_AesVendorKeyInfType tVendorKeyInf; /*!< when eUseKeyType is HSM_AES_KEY_CHIP_VENDOR_IFR, this MUST configure */ + uint32_t *pAllData; /*!< address should align with 4bytes, place IV data first, then AAD data(if exist, 16bytes align), then input data, then MAC data(if exist) */ + uint32_t u32IvDataByteCnt; /*!< 64bit(8Bytes) align, if not, only the aligned data treat as IV, the left IV bytes will be treated as AAD data */ + uint32_t u32AadByteCnt; /*!< 64bit(8Bytes) align, if not, only the aligned data treat as AAD, the left AAD bytes will be treated as input data */ + uint32_t u32InputByteCnt; /*!< 128bit(16Bytes) align */ + HSM_BoolType bCheckMacEn; /*!< check the MAC data in input or not */ + uint32_t u32MacByteCnt; /*!< 128bit(16Bytes) align */ + uint32_t *pDataOutput; /*!< point to the buffer that store the result */ + uint32_t u32OutputMemSize; /*!< the output data buffer "pDataOutput" size, should >= "u32InputByteCnt" */ + HSM_GcmBackendType eBackend; +} HSM_GcmDecryptExType; + +typedef struct +{ + HSM_MailboxApiRetType u32HSMStatusRet; /*!< HSM core write return status value in this */ + uint32_t u32Timeout; /*!< current command timeout tick count, tick refer to the HSM bus clock */ + uint32_t u32UserKeyID; /*!< 0 means don't use key from HSM internal key space, otherwise would load key with KEYID from HSM */ + HSM_GcmDecryptExType tCfg; /*!< GCM decrypt parameter */ +} HSMCom_GcmDecryptExType; + +/* ------------------------------------------------------------------------------- */ +/** + * @brief MD5 context information used by driver when call specific API + * + */ +typedef HSM_SmsCfgType HSM_Md5CtxType; +/** + * @brief MD5 information used by driver when call specific API + * + */ +typedef struct +{ + HSM_Md5CtxType tCfg; /*!< MD5 algorithm parameter set by user */ + uint32_t (*pRet)[4]; /*!< point to the memory that driver to store result */ + HSM_DataFormatType eIntputFmt; + HSM_DataFormatType eOutputFmt; +} HSM_Md5Type; + +typedef struct +{ + HSM_MailboxApiRetType u32HSMStatusRet; /*!< HSM core write return status value in this */ + uint32_t u32Timeout; /*!< current command timeout tick count, tick refer to the HSM bus clock */ + HSM_Md5Type tCfg; +} HSMCom_Md5Type; +/* ------------------------------------------------------------------------------- */ +/** + * @brief SM3 context information used by driver when call specific API + * + */ +typedef HSM_SmsCfgType HSM_Sm3CtxType; +/** + * @brief SM3 information used by driver when call specific API + * + */ +typedef struct +{ + HSM_Sm3CtxType tCfg; /*!< sm3 algorithm parameter set by user */ + uint32_t (*pRet)[8]; /*!< point to the memory that driver to store result */ + HSM_DataFormatType eIntputFmt; + HSM_DataFormatType eOutputFmt; +} HSM_Sm3Type; + +typedef struct +{ + HSM_MailboxApiRetType u32HSMStatusRet; /*!< HSM core write return status value in this */ + uint32_t u32Timeout; /*!< current command timeout tick count, tick refer to the HSM bus clock */ + HSM_Sm3Type tCfg; +} HSMCom_Sm3Type; + +/* ------------------------------------------------------------------------------- */ +#define HSMCOM_MONOTOIC_COUNTER_FLEX_REG_CNT 8 +typedef struct +{ + HSM_MailboxApiRetType u32HSMStatusRet; /*!< HSM core write return status value in this */ + uint32_t u32Timeout; /*!< current command timeout tick count, tick refer to the HSM bus clock */ + uint32_t u32MonotonicIndex; // 0-13 + uint32_t u32CurrentValue; + uint32_t (*u32ExtraValue)[HSMCOM_MONOTOIC_COUNTER_FLEX_REG_CNT - 1]; + uint32_t (*u32ExtraAdd)[HSMCOM_MONOTOIC_COUNTER_FLEX_REG_CNT]; +} HSMCom_MonCountType; +/* ------------------------------------------------------------------------------- */ +/** + * @brief RSA information used by driver when call specific API + * + */ +typedef struct +{ + uint32_t *pInputData; /*!< input data, if not 64bytes align, the last uint64_t's high byte left to patch 0 to align */ + uint32_t u32InputDataByteCount; /*!< the byte count of input data */ + uint32_t *pKey_E; /*!< input key E data for "A = (input data)^E mod N", if not 64bytes align, the last uint64_t's high byte left to patch 0 to align */ + uint32_t u32Key_E_ByteCount; /*!< the byte count of key E */ + uint32_t *pKey_N; /*!< input key N data for "A = (input data)^E mod N", if not 64bytes align, the last uint64_t's high byte left to patch 0 to align */ + uint32_t u32Key_N_ByteCount; /*!< hw will get the actual key data bit count according to the non-zero bit count, it means key not generate by multiply 2 */ + uint32_t *pResult; /*!< output buffer, the buffer size should >= "u32Key_N_ByteCount" */ + uint32_t u32ResultBufByteCnt; /*!< the result buffer size */ +} HSM_RsaType; + +typedef struct +{ + HSM_MailboxApiRetType u32HSMStatusRet; /*!< HSM core write return status value in this */ + uint32_t u32Timeout; /*!< current command timeout tick count, tick refer to the HSM bus clock */ + uint32_t u32UserKeyID_KEY_E; //0 means don't load key from HSM, otherwise would load key with KEYID from HSM + uint32_t u32UserKeyID_KEY_N; //0 means don't load key from HSM, otherwise would load key with KEYID from HSM + uint32_t u32RsaBitCnt; + HSM_RsaType tCfg; +} HSMCom_RsaType; +/* ------------------------------------------------------------------------------- */ +#define HSM_BIGNUMBER_CALC_A_ADD_B 0xFC730002 +#define HSM_BIGNUMBER_CALC_A_SUB_B 0xFC730003 +#define HSM_BIGNUMBER_CALC_B_SUB_A 0xFC730004 +#define HSM_BIGNUMBER_CALC_A_MUL_B 0xFC730005 +#define HSM_BIGNUMBER_CALC_A_EXP_E 0xFC730006 +#define HSM_BIGNUMBER_CALC_A_RED_N 0xFC730007 +#define HSM_BIGNUMBER_CALC_A_INV 0xFC730008 + +/** + * @brief RSA information used by driver when call specific API + * + */ +typedef struct +{ + uint32_t *pA; /*!< address is 4bytes aligned, input data, if not 64bytes align, the last uint64_t's high byte left to patch 0 to align */ + uint32_t u32AByteCount; /*!< the byte count of input data */ + uint32_t *pE; /*!< address is 4bytes aligned, input key E data for "A = (input data)^E mod N", if not 64bytes align, the last uint64_t's high byte left to patch 0 to align */ + uint32_t u32EByteCount; /*!< the byte count of key E */ + uint32_t *pN; /*!< address is 4bytes aligned, input key N data for "A = (input data)^E mod N", if not 64bytes align, the last uint64_t's high byte left to patch 0 to align */ + uint32_t u32NByteCount; /*!< hw will get the actual key data bit count according to the non-zero bit count, it means key not generate by multiply 2 */ + uint32_t *pResult; /*!< address is 4bytes aligned, output buffer, the buffer size should >= "u32Key_N_ByteCount" */ + uint32_t u32ResultBufByteCnt; /*!< the result buffer size */ + uint32_t u32CalcType; + uint32_t *pB; + uint32_t u32BByteCount; +} HSM_BigNumberCalcType; + +typedef struct +{ + HSM_MailboxApiRetType u32HSMStatusRet; /*!< HSM core write return status value in this */ + uint32_t u32Timeout; /*!< current command timeout Millisecond count, max 916000ms, if set to 0, means 1000ms */ + uint32_t u32UserKeyID_KEY_E; /*!< means don't load key from HSM, otherwise would load key with KEYID from HSM */ + uint32_t u32UserKeyID_KEY_N; /*!< means don't load key from HSM, otherwise would load key with KEYID from HSM */ + uint32_t u32BitCnt; /*!< the bit count of numbers used of N */ + HSM_BigNumberCalcType tCfg; /*!< RSA parameters */ +} HSMCom_BigNumberCalcType; +/* ------------------------------------------------------------------------------- */ + + +typedef struct +{ + HSM_MailboxApiRetType u32HSMStatusRet; /*!< HSM core write return status value in this */ + uint32_t u32Timeout; /*!< current command timeout Millisecond count, max 916000ms, if set to 0, means 1000ms */ +} HSMCom_LoadFirmwareType; + +/* ------------------------------------------------------------------------------- */ + +typedef HSMCom_LoadFirmwareType HSMCom_BasicType; + +/* #define AUTH_CHECK_DATA_BYTE_CNT 32 */ + +typedef struct { + uint32_t u32HSMStatusRet; + uint32_t u32Timeout; + const uint32_t *pkG_x; /*!< address should align with 4bytes */ + const uint32_t *pkG_y; /*!< address should align with 4bytes */ + const uint32_t *pR; /*!< address should align with 4bytes */ + const uint32_t *pS; /*!< address should align with 4bytes */ + //For user code verify function + const uint32_t *pData; /*!< address should align with 4bytes */ + uint32_t u32DataLength; +} HSMCom_AuthCheckType; + +typedef struct { + HSM_BoolType bStoreInFlash; + HSM_BoolType bUseDefaultID; //TRUE means use default ID. FALSE means use specific ID with "pInputData_ID" and "u32SM2InputIDByteCnt" params. + uint32_t u32SM2InputIDByteCnt;//the length should be <= 32bytes note: If "bUseDefaultID" is FALSE, would use this specific ID length with byte unit. + uint32_t *pInputData_ID; //note: If "bUseDefaultID" is FALSE, would use this specific ID. length should be more than u32SM2InputIDByteCnt, and must be 4bytes align + uint32_t (*pRaPublicKey_X)[8]; + uint32_t (*pRaPublicKey_Y)[8]; + uint32_t (*pPaPublicKey_X)[8]; + uint32_t (*pPaPublicKey_Y)[8]; + uint32_t (*pPublicKey_X)[8]; + uint32_t (*pPublicKey_Y)[8]; + uint32_t (*PrivateKey)[8]; + uint32_t (*pRbPublicKey_X)[8]; + uint32_t (*pRbPublicKey_Y)[8]; + uint32_t *pOutputKeyID; +}HSM_SmDHType; + +typedef struct { + uint32_t u32HSMStatusRet; + uint32_t u32Timeout; + HSM_SmDHType tCfg; +} HSMCom_SmDHType; + +typedef struct { + uint32_t u32ByteCount; /*!< all the data size, it should contains all N data */ + HSM_DrvEccCurveParamType tCurve; + const uint32_t *pASidePublicKey_x; /*!< A side's public key axis x data */ + const uint32_t *pASidePublicKey_y; /*!< A side's public key axis y data */ + const uint32_t *pBSidePrivateKey; /*!< B side private key */ + /* Below is output data */ + uint32_t *pBSidePublicKey_x; /*!< B side's public key axis x data */ + uint32_t *pBSidePublicKey_y; /*!< B side's public key axis y data */ + uint32_t *pSharedPublicKey_x; + uint32_t *pSharedPublicKey_y; +}HSM_ECDHType; + +typedef struct { + uint32_t u32HSMStatusRet; + uint32_t u32Timeout; + uint32_t u32UserKeyID_BSidePrivateKey; //0 means don't load key from HSM, otherwise would load key with KEYID from HSM + uint32_t u32UserKeyID_BSidePublicKey; //0 means don't load key from HSM, otherwise would load key with KEYID from HSM + uint32_t u32BitCnt; + HSM_DrvEccCurvePrmIndexType u32EccCurve; + HSM_ECDHType tCfg; +} HSMCom_ECDHType; + +typedef struct { + uint32_t *pInputKey_a; /*!< input private key b data, if not 64bytes align, the last uint64_t's high byte left to patch 0 to align */ + uint32_t u32Key_a_ByteCount; /*!< the byte count of key b */ + uint32_t *pInputKey_B; /*!< input public key A data, if not 64bytes align, the last uint64_t's high byte left to patch 0 to align */ + uint32_t u32Key_B_ByteCount; /*!< the byte count of key A */ + uint32_t *pPublicParam_g; /*!< Param g data for "A = g^a mod p", if not 64bytes align, the last uint64_t's high byte left to patch 0 to align */ + uint32_t u32PublicParam_g_ByteCount; /*!< the byte count of param g */ + uint32_t *pPublicParam_p; /*!< Param p data for "A = g^a mod p", if not 64bytes align, the last uint64_t's high byte left to patch 0 to align */ + uint32_t u32PublicParam_p_ByteCount; /*!< the byte count of param p */ + uint32_t *pOutputKey_A; /*!< output public key B data, if not 64bytes align, the last uint64_t's high byte left to patch 0 to align */ + uint32_t *pOutputKey_S; +} HSM_RsaDHType; + +typedef struct { + uint32_t u32HSMStatusRet; + uint32_t u32Timeout; + uint32_t u32UserKeyID_a; //0 means don't load key from HSM, otherwise would load key with KEYID from HSM + uint32_t u32UserKeyID_B; //0 means don't load key from HSM, otherwise would load key with KEYID from HSM + HSM_RsaDHType tCfg; +} HSMCom_RsaDHType; + +typedef struct { + HSM_HashAlgType eHashAlg; + uint32_t u32Counter; + uint32_t u32dkLen; + uint32_t u32PasswordByteLength; + const uint32_t *pPassword; + uint32_t u32SaltByteLength; + const uint32_t *pSalt; + uint32_t *pKdfOutput; +} HSM_PBKDF2Type; + +/** + * @brief RSA SSA input data is the raw message for HSM_RsaSsaInputType + * + */ +#define HSM_RSA_SSA_INPUT_RAW_MESSAGE 0u + +/** + * @brief RSA SSA input data is the hash value of raw message for HSM_RsaSsaInputType + * + */ +#define HSM_RSA_SSA_INPUT_HASH_DATA 1u + +/** + * @brief type definition for rsa ssa input data type + * refer to HSM_RSA_SSA_INPUT_RAW_MESSAGE, HSM_RSA_SSA_INPUT_HASH_DATA + */ +typedef uint32_t HSM_RsaSsaInputType; + + +/** + * @brief RSA PSS signature information used by driver when call specific API + * + */ +typedef struct { + HSM_BoolType bUsePseudoRand; + HSM_HashAlgType eMgfHashType; + HSM_DataFormatType eInputFmt; /*!< input data organized format, uint8_t array, or uint32_t array */ + HSM_DataFormatType eOutputFmt; /*!< output data organized format, uint8_t array, or uint32_t array */ + uint32_t u32EmBitCnt; /* RFC8017 require set it to (N's bit count - 1).the em data bit count, it MUST < N's bit count */ + HSM_HashAlgType eHashType; /*!< the hash type used by signature */ + HSM_RsaSsaInputType eInputType; /*!< input data type, may raw input message, or the hash data of raw message */ + const uint8_t *pInputData; /*!< input data */ + uint32_t u32InputDataByteCount; /*!< the byte count of input data */ + const uint8_t *pPrivateKey; /*!< private key, input key E data for "A = (input data)^E mod N" */ + uint32_t u32PrivateKeyByteCnt; /*!< the byte count of key E */ + HSM_BoolType bUseInputSaltData; /*!< use input salt data or not, , suggest set to HSM_FALSE to use internal random data */ + const uint8_t *pSalt; /*!< input salt data, , suggest set to NULL. if use hsm internal random data, just set it to NULL */ + uint32_t u32SaltByteCount; /*!< the byte count of salt data, it must > 0, suggest use hash length, for example, if eHashType is HSM_SHA_256, set this to 256/8=32bytes */ + const uint8_t *pKeyN; /*!< input key N data for "A = (input data)^E mod N" */ + uint32_t u32KeyNByteCount; /*!< key N's data byte count */ + uint8_t *pResult; /*!< output buffer, the buffer size should >= "u32KeyNByteCount" */ + uint32_t u32ResultBufByteCnt; /*!< the result buffer size */ + uint32_t *pResultByteCnt; /*!< the result data byte count */ +} HSM_RsaSsaPssSignType; + +typedef struct { + uint32_t u32HSMStatusRet; + uint32_t u32Timeout; + uint32_t u32UserKeyID_KEY_E; + uint32_t u32UserKeyID_KEY_N; + uint32_t u32RsaBitCnt; + HSM_RsaSsaPssSignType tCfg; +}HSMCom_RsaSsaPssSignType; + +/** + * @brief RSA PSS signature verify information used by driver when call specific API + * + */ +typedef struct { + uint32_t u32EmBitCnt; /* RFC8017 require set it to (N's bit count - 1). the em data bit count, it MUST < N's bit count, should keep same with the signature generate configuration */ + HSM_HashAlgType eMgfHashType; + HSM_HashAlgType eHashType; /*!< the hash type used by signature */ + uint32_t u32SaltByteCount; /*!< the byte count of salt data, it must > 0, suggest use hash length, for example, if eHashType is HSM_SHA_256, set this to 256/8=32bytes */ + HSM_DataFormatType eInputDataFmt; /*!< input data(raw message or hash data) organized format, uint8_t array, or uint32_t array */ + HSM_RsaSsaInputType eInputType; /*!< input data type, may raw input message, or the hash data of raw message */ + const uint8_t *pInputData; /*!< input data */ + uint32_t u32InputDataByteCount; /*!< the byte count of input data, when the eInputType is HSM_RSA_SSA_INPUT_RAW_MESSAGE */ + HSM_DataFormatType eSignDataFmt; /*!< Signature/Public key/N input data organized format, uint8_t array, or uint32_t array */ + const uint8_t *pSignData; /*!< input signature data */ + uint32_t u32SignDataByteCount; /*!< the byte count of signature data, it must > 0 */ + HSM_DataFormatType ePublicKeyDataFmt; + const uint8_t *pPublicKey; /*!< public key, input key E data for "A = (input data)^E mod N" */ + uint32_t u32PublicKeyByteCnt; /*!< the byte count of key E */ + HSM_DataFormatType eKeyNDataFmt; + const uint8_t *pKeyN; /*!< input key N data for "A = (input data)^E mod N" */ + uint32_t u32KeyNByteCount; /*!< key N data byte count */ +} HSM_RsaSsaPssVerifyType; + +typedef struct { + uint32_t u32HSMStatusRet; + uint32_t u32Timeout; + uint32_t u32UserKeyID_KEY_E; + uint32_t u32UserKeyID_KEY_N; + uint32_t u32RsaBitCnt; + HSM_RsaSsaPssVerifyType tCfg; +}HSMCom_RsaSsaPssVerifyType; + +/** + * @brief RSA PKCS1 V1.5 signature information used by driver when call specific API + * + */ +typedef struct { + HSM_DataFormatType eInputFmt; /*!< input data organized format, uint8_t array, or uint32_t array */ + HSM_DataFormatType eOutputFmt; /*!< output data organized format, uint8_t array, or uint32_t array */ + uint32_t u32EmByteCnt; /* RFC8017 require set it to N'byte count, equal to u32KeyNByteCount. the em data byte count, itx8 MUST < N's bit count, should keep same with the signature generate configuration */ + HSM_HashAlgType eHashType; /*!< the hash type used by signature */ + const uint8_t *pInputData; /*!< input data */ + uint32_t u32InputDataByteCount; /*!< the byte count of input data */ + const uint8_t *pPrivateKey; /*!< private key, input key E data for "A = (input data)^E mod N" */ + uint32_t u32PrivateKeyByteCnt; /*!< the byte count of key E */ + HSM_BoolType bUseInputDer; /*!< set to HSM_TRUE when RFC8017 not support some hash algorithm, for example SM3 Hash type, DER encoding of the DigestInfo value, if use hsm internal data, just set it to HSM_FALSE */ + const uint8_t *pDer; /*!< when bUseInputDer is HSM_TRUE, this field point to the DER encoding of the DigestInfo value, others, ignore */ + uint32_t u32DerByteCount; /*!< when bUseInputDer is HSM_TRUE, this field represent the byte count of DER data, if bUseInputDer is HSM_FALSE, ignore this field */ + const uint8_t *pKeyN; /*!< input key N data for "A = (input data)^E mod N" */ + uint32_t u32KeyNByteCount; /*!< key N's data byte count */ + uint8_t *pResult; /*!< output buffer, the buffer size should >= "u32KeyNByteCount" */ + uint32_t u32ResultBufByteCnt; /*!< the result buffer size */ + uint32_t *pResultByteCnt; /*!< the result data byte count */ +} HSM_RsaSsaPkcs1V15SignType; + +typedef struct { + uint32_t u32HSMStatusRet; + uint32_t u32Timeout; + uint32_t u32UserKeyID_KEY_E; + uint32_t u32UserKeyID_KEY_N; + uint32_t u32RsaBitCnt; + HSM_RsaSsaPkcs1V15SignType tCfg; +}HSMCom_RsaSsaPkcs1V15SignType; + +/** + * @brief RSA PKCS1 V1.5 signature verify information used by driver when call specific API + * + */ +typedef struct { + HSM_DataFormatType eInputFmt; /*!< input data organized format, uint8_t array, or uint32_t array */ + uint32_t u32EmByteCnt; /* RFC8017 require set it to N'byte count, equal to u32KeyNByteCount. the em data byte count, itx8 MUST < N's bit count, should keep same with the signature generate configuration */ + HSM_HashAlgType eHashType; /*!< the hash type used by signature */ + const uint8_t *pInputData; /*!< input data */ + uint32_t u32InputDataByteCount; /*!< the byte count of input data */ + const uint8_t *pSignData; /*!< input signature data */ + uint32_t u32SignDataByteCount; /*!< the byte count of signature data, it must > 0 */ + const uint8_t *pPublicKey; /*!< public key, input key E data for "A = (input data)^E mod N" */ + uint32_t u32PublicKeyByteCnt; /*!< the byte count of key E */ + HSM_BoolType bUseInputDer; /*!< set to HSM_TRUE when RFC8017 not support some hash algorithm, for example SM3 Hash type, DER encoding of the DigestInfo value, if use hsm internal data, just set it to HSM_FALSE */ + const uint8_t *pDer; /*!< when bUseInputDer is HSM_TRUE, this field point to the DER encoding of the DigestInfo value, others, ignore */ + uint32_t u32DerByteCount; /*!< when bUseInputDer is HSM_TRUE, this field represent the byte count of DER data, if bUseInputDer is HSM_FALSE, ignore this field */ + const uint8_t *pKeyN; /*!< input key N data for "A = (input data)^E mod N" */ + uint32_t u32KeyNByteCount; /*!< key N's data byte count */ +} HSM_RsaSsaPkcs1V15VerifyType; + +typedef struct { + uint32_t u32HSMStatusRet; + uint32_t u32Timeout; + uint32_t u32UserKeyID_KEY_E; + uint32_t u32UserKeyID_KEY_N; + uint32_t u32RsaBitCnt; + HSM_RsaSsaPkcs1V15VerifyType tCfg; +}HSMCom_RsaSsaPkcs1V15VerifyType; + +typedef struct { + + HSM_BoolType bUsePseudoRand; + const uint8_t *pInputData; /*!< input data */ + uint32_t u32InputDataByteCount; + HSM_DataFormatType eInputDataFmt; + const uint8_t *pKeyE; + uint32_t u32KeyEByteCount; + HSM_DataFormatType eKeyEFmt; + const uint8_t *pKeyN; + uint32_t u32KeyNByteCount; + HSM_DataFormatType eKeyNFmt; + uint8_t *pResult; + uint32_t u32ResultBufByteCnt; + HSM_DataFormatType eOutputFmt; + uint32_t *pResultByteCnt; +} HSM_RsaEsPkcs1V15EnDecryptType; + +typedef struct { + uint32_t u32HSMStatusRet; + uint32_t u32Timeout; + uint32_t u32UserKeyID_KEY_E; + uint32_t u32UserKeyID_KEY_N; + uint32_t u32RsaBitCnt; + HSM_RsaEsPkcs1V15EnDecryptType tCfg; +}HSMCom_RsaEsPkcs1V15EnDecryptType; + +typedef HSMCom_RsaEsPkcs1V15EnDecryptType HSMCom_RsaEsPkcs1V15EncryptType; + +typedef HSMCom_RsaEsPkcs1V15EnDecryptType HSMCom_RsaEsPkcs1V15DecryptType; + +typedef struct { + HSM_BoolType bUsePseudoRand; + HSM_HashAlgType eHashType; /*!< the hash type used by signature */ + HSM_HashAlgType eMgfHashType; + const uint8_t *pLabel; /*!< input data */ + uint32_t u32LabelByteCount; + HSM_DataFormatType eLabelFmt; + const uint8_t *pInputData; /*!< input data */ + uint32_t u32InputDataByteCount; + HSM_DataFormatType eInputDataFmt; + const uint8_t *pKeyE; + uint32_t u32KeyEByteCount; + HSM_DataFormatType eKeyEFmt; + const uint8_t *pKeyN; + uint32_t u32KeyNByteCount; + HSM_DataFormatType eKeyNFmt; + uint8_t *pResult; + uint32_t u32ResultBufByteCnt; + HSM_DataFormatType eOutputFmt; + uint32_t *pResultByteCnt; +} HSM_RsaEsOaepEnDecryptType; + +typedef struct { + uint32_t u32HSMStatusRet; + uint32_t u32Timeout; + uint32_t u32UserKeyID_KEY_E; + uint32_t u32UserKeyID_KEY_N; + uint32_t u32RsaBitCnt; + HSM_RsaEsOaepEnDecryptType tCfg; +}HSMCom_RsaEsOaepEnDecryptType; + + +typedef HSMCom_RsaEsOaepEnDecryptType HSMCom_RsaEsOaepEncryptType; + +typedef HSMCom_RsaEsOaepEnDecryptType HSMCom_RsaEsOaepDecryptType; + + +typedef struct { + uint32_t u32HSMStatusRet; + uint32_t u32Timeout; + uint32_t u32UserKeyID_Password; //0 means don't load key from HSM, otherwise would load key with KEYID from HSM + HSM_PBKDF2Type tCfg; +} HSMCom_Pbkdf2Type; + +typedef struct { + uint32_t u32Counter; + uint32_t u32dkLen; + uint32_t u32PasswordByteLength; + const uint32_t *pPassword; + uint32_t u32SaltByteLength; + const uint32_t *pSalt; + uint32_t *pKdfOutput; +} HSM_GMPBKDFType; + +typedef struct { + uint32_t u32HSMStatusRet; + uint32_t u32Timeout; + uint32_t u32UserKeyID_Password; //0 means don't load key from HSM, otherwise would load key with KEYID from HSM + HSM_GMPBKDFType tCfg; +} HSMCom_GMpbkdfType; +/* ------------------------------------------------------------------------------- */ + +/**@}*/ + + +/** + * @name API declaration for HSM + * + */ +/**@{*/ + +/** + * @brief Get the true random data + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pRandom the array address to store the result + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_TrueRandGetSrc0(HSM_CmdType *pCmd, const HSMCom_TrueRandType*pCfg); + + +/** + * @brief Get the true random data + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pRandom the array address to store the result + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_TrueRandGetSrc1(HSM_CmdType *pCmd, const HSMCom_TrueRandType*pCfg); + + +/** + * @brief Get the true random data + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pRandom the array address to store the result + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_TrueRandGetSrcXor(HSM_CmdType *pCmd, const HSMCom_TrueRandType*pCfg); + + +/** + * @brief Get the true random data + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pRandom the array address to store the result + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_TrueRandGet(HSM_CmdType *pCmd, const HSMCom_TrueRandType*pCfg); + + +/** + * @brief Get the pseudo random data + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pRandom the array address to store the result + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_PseudoRandGet(HSM_CmdType *pCmd, const HSMCom_TrueRandType*pCfg); + + +/** + * @brief SHA + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg SHA parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_Sha(HSM_CmdType *pCmd, const HSMCom_ShaType *pCfg); + + +/** + * @brief SHAEx + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg SHA parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_ShaEx(HSM_CmdType *pCmd, const HSMCom_Sha2Type *pCfg); + + +/** + * @brief Md5Ex + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg MD5 parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_Md5Ex(HSM_CmdType *pCmd, const HSMCom_Md5Type *pCfg); + + +/** + * @brief Sm3Ex + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg SM3 parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_Sm3Ex(HSM_CmdType *pCmd, const HSMCom_Sm3Type *pCfg); + + +/** + * @brief HashEx Init + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg HashEx parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY when driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_HashInitEx(HSM_CmdType *pCmd, const HSMCom_ShaType *pCfg); + + +/** + * @brief HashEx Update + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg HashEx parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY when driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_HashUpdateEx(HSM_CmdType *pCmd, const HSMCom_ShaType *pCfg); + + +/** + * @brief HashEx Finally + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg HashEx parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY when driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_HashFinallyEx(HSM_CmdType *pCmd, const HSMCom_ShaType *pCfg); + + +/** + * @brief Scatter Hash Init + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg scatter hash parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY when driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_ScatterHashInit(HSM_CmdType *pCmd, const HSMCom_ScatterHashType *pCfg); + + +/** + * @brief Scatter Hash Update + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg scatter hash parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY when driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_ScatterHashUpdate(HSM_CmdType *pCmd, const HSMCom_ScatterHashType *pCfg); + + +/** + * @brief Scatter Hash Finally + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg scatter hash parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY when driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_ScatterHashFinally(HSM_CmdType *pCmd, const HSMCom_ScatterHashType *pCfg); + +/** + * @brief ECC Sign + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg ECC sign parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_EccSign(HSM_CmdType *pCmd, const HSMCom_EccSignType *pCfg); + + +/** + * @brief EccPointCalc + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg EccPointCalc parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_EccPointCalc(HSM_CmdType *pCmd, const HSMCom_EccCalcType *pCfg); + + +/** + * @brief ECC Verify + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg ECC verify parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_EccVerify(HSM_CmdType *pCmd, const HSMCom_EccVerifyType *pCfg); + + +/** + * @brief ECC key pair generate + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg ECC key pair parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_EccGenKeyPair(HSM_CmdType *pCmd, const HSMCom_EccKeyPairGenType *pCfg); + + +/** + * @brief SM2 key pair generate + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg SM2 key pair parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_Sm2GenKeyPair(HSM_CmdType *pCmd, const HSMCom_Sm2GenKeyPairType *pCfg); + + +/** + * @brief SM2 encrypt + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg SM2 encrypt parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_Sm2Encry(HSM_CmdType *pCmd, const HSMCom_Sm2EncryptType *pCfg); + + +/** + * @brief SM2 decrypt + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg SM2 decrypt parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_Sm2Decry(HSM_CmdType *pCmd, const HSMCom_Sm2DecryptType *pCfg); + + +/** + * @brief SM2 sign + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg SM2 sign parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_Sm2Sign(HSM_CmdType *pCmd, const HSMCom_Sm2SignType *pCfg); + + +/** + * @brief SM2 verify + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg SM2 verify parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_Sm2Verify(HSM_CmdType *pCmd, const HSMCom_Sm2VerifyType *pCfg); + + +/** + * @brief SM2 ZA + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg SM2 ZA parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_Sm2GenZa(HSM_CmdType *pCmd, const HSMCom_Sm2GenZaType *pCfg); + + +/** + * @brief SM2 Hash generate + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg SM2 HASH parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_Sm2GenHash(HSM_CmdType *pCmd, const HSMCom_Sm2GenHashType *pCfg); + + +/** + * @brief SM4 encrypt + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg SM4 encrypt parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_Sm4Encrypt(HSM_CmdType *pCmd, const HSMCom_Sm4EncryptType *pCfg); + + +/** + * @brief SM4 decrypt + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg SM4 decrypt parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_Sm4Decrypt(HSM_CmdType *pCmd, const HSMCom_Sm4DecryptType *pCfg); + + +/** + * @brief ECC easy encrypt + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg ECC encrypt parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_EccEasyEncry(HSM_CmdType *pCmd, const HSMCom_EccEasyEncryType *pCfg); + + +/** + * @brief ECC easy decrypt + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg ECC decrypt parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_EccEasyDecry(HSM_CmdType *pCmd, const HSMCom_EccEasyDecryType *pCfg); + + +/** + * @brief RequestAuthorization + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg ECC decrypt parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_RequestAuthorization(HSM_CmdType *pCmd, const HSMCom_RequestAuthType *pCfg); + + +/** + * @brief TakeEffect + * + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_TakeEffect(HSM_CmdType *pCmd); + + +/** + * @brief OemDevEnter + * + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_OemDevEnter(HSM_CmdType *pCmd); + + +/** + * @brief HSM_OemPdtEnter + * + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_OemPdtEnter(HSM_CmdType *pCmd); + +/** + * @brief HSM_InFieldEnter + * + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_InFieldEnter(HSM_CmdType *pCmd); + + +/** + * @brief CancelJob + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_CancelJob(HSM_CmdType *pCmd, const HSMCom_CancelJobType *pCfg); + + +/** + * @brief SelfTest + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg self test parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_SelfTest(HSM_CmdType *pCmd, const HSMCom_SelfTestType *pCfg); + + +/** + * @brief NvrOtpProgram + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_NvrOtpProgram(HSM_CmdType *pCmd, const HSMCom_NvrOtpType *pCfg); + + +/** + * @brief NvrOtpRead + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_NvrOtpRead(HSM_CmdType *pCmd, const HSMCom_NvrOtpType *pCfg); + + +/** + * @brief Revoke UserKey + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg UserKeyManage parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_UserKeyRevoke(HSM_CmdType *pCmd, const HSMCom_UserKeyManageType *pCfg); + + +/** + * @brief Revoke Umrk0 + * + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_RevokeUmrk0(HSM_CmdType *pCmd); + + +/** + * @brief Revoke Umrk1 + * + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_RevokeUmrk1(HSM_CmdType *pCmd); + + +/** + * @brief Revoke Umrk2 + * + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_RevokeUmrk2(HSM_CmdType *pCmd); + + +/** + * @brief Revoke Umrk3 + * + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_RevokeUmrk3(HSM_CmdType *pCmd); + + +/** + * @brief UserKeyImport + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_UserKeyImport(HSM_CmdType *pCmd, const HSMCom_UserKeyManageType *pCfg); + + +/** + * @brief UserKeyExport + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_UserKeyExport(HSM_CmdType *pCmd, const HSMCom_UserKeyManageType *pCfg); + + +/** + * @brief Generate User Key + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_UserKeyGen(HSM_CmdType *pCmd, const HSMCom_UserKeyManageType *pCfg); + + +/** + * @brief Generate Usrk + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_GenUsrk(HSM_CmdType *pCmd,const HSMCom_RsaType *pCfg); + + +/** + * @brief Erase Key in Flash + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_EraseKeyFlash(HSM_CmdType *pCmd, HSMCom_BasicType *pCfg); + + +/** + * @brief Enable Ram Key Copy + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_EnableKeyRamCopy(HSM_CmdType *pCmd, const HSMCom_UserKeyManageType *pCfg); + + +/** + * @brief Disable Ram Key Copy + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_DisableKeyRamCopy(HSM_CmdType *pCmd, const HSMCom_UserKeyManageType *pCfg); + + +/** + * @brief GetKeySpaceStatus + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg ECC decrypt parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_GetKeySpaceStatus(HSM_CmdType *pCmd, const HSMCom_KeySpaceStatusType *pCfg); + + +/** + * @brief TidyUpKeySpace + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg ECC decrypt parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_TidyUpKeySpace(HSM_CmdType *pCmd, const HSMCom_KeySpaceStatusType *pCfg); + + +/** + * @brief AES encrypt + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg AES encrypt parameters. + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_AesEncrypt(HSM_CmdType *pCmd, const HSMCom_AesEncryptType *pCfg); + + +/** + * @brief AES decrypt + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg AES decrypt parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. Others, some error occur. + */ +HSM_StatusType HSM_AesDecrypt(HSM_CmdType *pCmd, const HSMCom_AesDecryptType *pCfg); + + +/** + * @brief AES FlexEncrypt + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg AES encrypt parameters. + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_Aes_FlexEncrypt(HSM_CmdType *pCmd, const HSMCom_FlexAesEncryptType *pCfg); + + +/** + * @brief AES FlexDecrypt + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg AES decrypt parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. Others, some error occur. + */ +HSM_StatusType HSM_Aes_FlexDecrypt(HSM_CmdType *pCmd, const HSMCom_FlexAesDecryptType *pCfg); + + +/** + * @brief CMAC + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg CMAC parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY when driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_CMac(HSM_CmdType *pCmd, const HSMCom_CMacType *pCfg); + + +/** + * @brief CmacAesm + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY when driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_CmacAesm(HSM_CmdType *pCmd, const HSMCom_AesmRawApiType *pCfg); + + +/** + * @brief CmacEx + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg CMAC parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY when driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_CmacEx(HSM_CmdType *pCmd, const HSMCom_CMacExType *pCfg); + + +/** + * @brief Scatter Cmac + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg CMAC parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY when driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_CmacScatter(HSM_CmdType *pCmd, const HSMCom_ScatterMacType *pCfg); + + +/** + * @brief XMAC + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg XMAC parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY when driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_XMac(HSM_CmdType *pCmd, const HSMCom_XMacType *pCfg); + + +/** + * @brief XMacEx + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg XMAC parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY when driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_XMacEx(HSM_CmdType *pCmd, const HSMCom_XMacExType *pCfg); + + +/** + * @brief CCM encrypt + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg CCM encrypt parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY when driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_CcmEncry(HSM_CmdType *pCmd, const HSMCom_CcmEncryptType *pCfg); + + +/** + * @brief CCM decrypt + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg CCM decrypt parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY when driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_CcmDecry(HSM_CmdType *pCmd, const HSMCom_CcmDecryptType *pCfg); + + +/** + * @brief CcmEncryEx + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg Ccm encrypt parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY when driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_CcmEncryEx(HSM_CmdType *pCmd, const HSMCom_CcmEncryptExType *pCfg); + + +/** + * @brief CcmDecryEx + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg Ccm decrypt parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY when driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_CcmDecryEx(HSM_CmdType *pCmd, const HSMCom_CcmDecryptExType *pCfg); + + +/** + * @brief GCM encrypt + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg GCM encrypt parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY when driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_GcmEncry(HSM_CmdType *pCmd, const HSMCom_GcmEncryptType *pCfg); + + +/** + * @brief GCM decrypt + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg GCM decrypt parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY when driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_GcmDecry(HSM_CmdType *pCmd, const HSMCom_GcmDecryptType *pCfg); + + + +/** + * @brief GcmEncryEx + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg Gcm encrypt parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY when driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_GcmEncryEx(HSM_CmdType *pCmd, const HSMCom_GcmEncryptExType *pCfg); + + +/** + * @brief GcmDecryEx + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg Gcm decrypt parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY when driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_GcmDecryEx(HSM_CmdType *pCmd, const HSMCom_GcmDecryptExType *pCfg); + +/** + * @brief MD5 + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg MD5 parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_Md5(HSM_CmdType *pCmd, const HSMCom_Md5Type *pCfg); + + +/** + * @brief SM3 + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg SM3 parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_Sm3(HSM_CmdType *pCmd, const HSMCom_Sm3Type *pCfg); + + +/** + * @brief Increase Monotonic Counter + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg MonotonicCounter parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_MonotonicCounterIncrease(HSM_CmdType *pCmd, const HSMCom_MonCountType *pCfg); + + +/** + * @brief Read Monotonic Counter + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg MonotonicCounter parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_MonotonicCounterRead(HSM_CmdType *pCmd, const HSMCom_MonCountType *pCfg); + + +/** + * @brief Set Monotonic Counter Value + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg MonotonicCounter parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_MonotonicCounterSetValue(HSM_CmdType *pCmd, const HSMCom_MonCountType *pCfg); + + +/** + * @brief Read All Flex Counters + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg MonotonicCounter parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_MonotonicReadAllFlexCounters(HSM_CmdType *pCmd, const HSMCom_MonCountType *pCfg); + + +/** + * @brief Set Single Config + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg MonotonicCounter parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_MonotonicCounterSetSingleCfg(HSM_CmdType *pCmd, const HSMCom_MonCountType *pCfg); + + +/** + * @brief Get Single Config + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg MonotonicCounter parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_MonotonicCounterGetSingleCfg(HSM_CmdType *pCmd, const HSMCom_MonCountType *pCfg); + + +/** + * @brief Increase Monotonic Counter 2 + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg MonotonicCounter parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_MonotonicIncreaseCounter2(HSM_CmdType *pCmd, const HSMCom_MonCountType *pCfg); + + +/** + * @brief Read Monotonic Counter 2 + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg MonotonicCounter parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_MonotonicReadCounter2(HSM_CmdType *pCmd, const HSMCom_MonCountType *pCfg); + + +/** + * @brief Increase Monotonic Counter when equal + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg MonotonicCounter parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY When driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_MonotonicIncCountWhenEqu(HSM_CmdType *pCmd, const HSMCom_MonCountType *pCfg); + + +/** + * @brief LoadFirmware + * + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. Others, some error occur. + */ +HSM_StatusType HSM_LoadFirmware(HSM_CmdType *pCmd); + + +/** + * @brief RSA + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg RSA parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. Others, some error occur. + */ +HSM_StatusType HSM_Rsa(HSM_CmdType *pCmd, const HSMCom_RsaType *pCfg); + + +/** + * @brief RSA PSS Sign + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg RSA Sign parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY when driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_RSA_SSA_PSS_Sign(HSM_CmdType *pCmd, const HSMCom_RsaSsaPssSignType *pCfg); + + +/** + * @brief RSA PSS Verify + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg RSA Verify parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY when driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_RSA_SSA_PSS_Verify(HSM_CmdType *pCmd, const HSMCom_RsaSsaPssVerifyType *pCfg); + + +/** + * @brief RSA ES_PKCS1V15 Encrypt + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg RSA encrypt parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY when driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_RSA_SSA_ES_PKCS1V15_Encrypt(HSM_CmdType *pCmd, const HSMCom_RsaEsPkcs1V15EncryptType *pCfg); + + +/** + * @brief RSA ES_PKCS1V15 Decrypt + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg RSA decrypt parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY when driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_RSA_SSA_ES_PKCS1V15_Decrypt(HSM_CmdType *pCmd, const HSMCom_RsaEsPkcs1V15DecryptType *pCfg); + + +/** + * @brief RSA ES_PKCS1V15 Verify + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg RSA Verify parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY when driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_RSA_SSA_ES_PKCS1V15_Verify(HSM_CmdType *pCmd, const HSMCom_RsaSsaPkcs1V15VerifyType *pCfg); + + +/** + * @brief RSA ES PKCS1V15 Sign + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg RSA Verify parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY when driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_RSA_SSA_ES_PKCS1V15_Sign(HSM_CmdType *pCmd, const HSMCom_RsaSsaPkcs1V15SignType *pCfg); + + +/** + * @brief RSA ES OAEP Encrypt + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg RSA encrypt parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY when driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_RSA_SSA_ES_OAEP_Encrypt(HSM_CmdType *pCmd, const HSMCom_RsaEsOaepEncryptType *pCfg); + + +/** + * @brief RSA ES OAEP Decrypt + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg RSA decrypt parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY when driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_RSA_SSA_ES_OAEP_Decrypt(HSM_CmdType *pCmd, const HSMCom_RsaEsOaepDecryptType *pCfg); + + +/** + * @brief BigNumberCalc + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY when driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_BigNumberCalc(HSM_CmdType *pCmd, const HSMCom_BigNumberCalcType *pCfg); + + +/** + * @brief SMDH + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY when driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_SMDH(HSM_CmdType *pCmd, HSMCom_SmDHType *pCfg); + + +/** + * @brief ECDH + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY when driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_ECDH(HSM_CmdType *pCmd, HSMCom_ECDHType *pCfg); + + +/** + * @brief DH + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY when driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_DH(HSM_CmdType *pCmd, HSMCom_RsaDHType *pCfg); + + +/** + * @brief PBKDF2 + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY when driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_PBKDF2(HSM_CmdType *pCmd, HSMCom_Pbkdf2Type *pCfg); + + +/** + * @brief GMPBKDF + * @param pCmd point to the struct variable used to configure the mailbox information send to HSM core + * @param pCfg parameters for trigger the process + * @return HSM_StatusType HSM_STATUS_SUCCESS when succeed. HSM_STATUS_BUSY when driver is busy. Others, some error occur. + */ +HSM_StatusType HSM_GMPBKDF(HSM_CmdType *pCmd, HSMCom_GMpbkdfType *pCfg); + + +/**@}*/ + +/** @}*/ /* fc7xxx_driver_hsm */ + +#if defined(__cplusplus) +} +#endif + +#endif /* end of DRIVER_HSM_H_ */ diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_intm.h b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_intm.h new file mode 100644 index 0000000..b5280e4 --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_intm.h @@ -0,0 +1,137 @@ +/** + * @file fc7xxx_driver_intm.h + * @author Flagchip + * @brief FC7240 INTM driver type definition and API + * @version 0.1.0 + * @date 2024-01-10 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-01-10 Flagchip084 N/A FC7240 release version + ******************************************************************************** */ + +#ifndef _DRIVER_INTM_H_ +#define _DRIVER_INTM_H_ + +#include "HwA_intm.h" + +typedef enum +{ + INTM_INSTANCE_0 = 0U, + INTM_INSTANCE_MAX = 1u +} INTM_InstanceType; + +typedef enum +{ + INTM_IRQ_MONITOR_0 = 0U, + INTM_IRQ_MONITOR_1 = 1U, + INTM_IRQ_MONITOR_MAX = 2U +} INTM_IrqMonitorType; + +typedef enum +{ + INTM_RETURN_OK = 0x00U, /*!< The INTM operation is succeeded */ + INTM_RETURN_E_NOT_OK = 0x01U, /*!< The INTM operation is failed */ + INTM_RETURN_E_ALREADY_INIT = 0x02U, /*!< The INTM has been initialized. */ + INTM_RETURN_E_UNINIT = 0x03U, /*!< The INTM is not initialized */ + INTM_RETURN_E_PARAM = 0x04U /*!< The INTM parameter is incorrect or out of range. */ +} INTM_ReturnType; + +typedef enum +{ + INTM_INTERRUPT_MODE_ACTIVE = 0x00U, /*!< INTM is configured as active mode */ + INTM_INTERRUPT_MODE_INACTIVE /*!< INTM is configured as inactive mode */ +} INTM_InterruptModeType; + +/** + * @brief INTM Channel ISR callback function prototype + * + */ +typedef void (*INTM_ISRCallbackType)(void); + +typedef struct +{ + INTM_InterruptModeType eMode; /*!< INTM active mode */ + bool bEnReset; /*!< Enable Reset */ + bool bEnInterrupt; /*!< Enable Interrupt */ + uint32_t u32SrcDelayCnt; /*!< Enable Interrupt */ + uint16_t u16IrqNumber; /*!< Monitored interrupt number */ + INTM_ISRCallbackType pIntmIsrCallback; /*!< INTM interrupt callback. */ +} INTM_InitType; + +/** + * @brief Init the INTM. + * @param eInstance INTM instance. + * @param eIrqMonitorIndex Monitor index. + * @param pInitCfg Init Configuration. + * @return INTM_ReturnType INTM Status. + */ +INTM_ReturnType INTM_Init(INTM_InstanceType eInstance, INTM_IrqMonitorType eIrqMonitorIndex, INTM_InitType *pInitCfg); + +/** + * @brief Enable INTM. + * + * @param eInstance INTM instance. + * @param bEnable Enable INTM. + * @return INTM_ReturnType INTM Status. + */ +INTM_ReturnType INTM_enable(INTM_InstanceType eInstance, bool bEnable); + +/** + * @brief Start INTM inactive mode. + * @param eInstance INTM instance. + * @param eIrqMonitorIndex Monitor index. + * @return INTM_ReturnType INTM Status. + */ +INTM_ReturnType INTM_StartInactiveMode(INTM_InstanceType eInstance, INTM_IrqMonitorType eIrqMonitorIndex); + +/** + * @brief + * @param eInstance INTM instance. + * @param eIrqMonitorIndex Monitor index. + * @return INTM_ReturnType INTM Status. + */ +INTM_ReturnType INTM_StopInactiveMode(INTM_InstanceType eInstance, INTM_IrqMonitorType eIrqMonitorIndex); + +/** + * @brief Write the interrupt acknowledge. + * + * @param eInstance INTM instance. + * @param u16IrqNumber Interrupt nunmber. + * @return INTM_ReturnType INTM Status. + */ +INTM_ReturnType INTM_SetAcknowledge(INTM_InstanceType eInstance, uint16_t u16IrqNumber); + +/** + * @brief Return counter value. + * + * @param eInstance INTM instance. + * @param eIrqMonitorIndex Monitor index. + * @return Counter value. + */ +uint32_t INTM_GetCounterValue(INTM_InstanceType eInstance, INTM_IrqMonitorType eIrqMonitorIndex); + +/** + * @brief Clear the interrupt flag. + * + * @param eInstance INTM instance. + * @param eIrqMonitorIndex Monitor index. + */ +INTM_ReturnType INTM_ClearIntFlag(INTM_InstanceType eInstance, INTM_IrqMonitorType eIrqMonitorIndex); + +/** + * @brief Get the timeout flag. Return true if INTM_TMR value has exceeded the INTM_LATR value. + * + * @param eInstance INTM instance. + * @param eIrqMonitorIndex Monitor index. + * @return Timeout flag. + */ +bool INTM_GetTimeoutStatus(INTM_InstanceType eInstance, INTM_IrqMonitorType eIrqMonitorIndex); + +#endif /* end of _DRIVER_INTM_H_ */ diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_ism.h b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_ism.h new file mode 100644 index 0000000..4867328 --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_ism.h @@ -0,0 +1,249 @@ +/** + * @file fc7xxx_driver_ism.h + * @author Flagchip084 + * @brief FC7xxx ISM driver type definition and API + * @version 0.2.0 + * @date 2023-02-13 + * + * @copyright Copyright (c) 2023 Flagchip Semiconductors Co., Ltd. + * + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2022-11-18 Flagchip084 N/A First version for FC7xxx + * 0.2.0 2023-02-13 Flagchip084 N/A FC7xxx release version + ******************************************************************************** */ + +#ifndef _DRIVER_FC7XXX_DRIVER_ISM_H_ +#define _DRIVER_FC7XXX_DRIVER_ISM_H_ +#include "device_header.h" +#include "HwA_ism.h" +/** + * @addtogroup fc7xxx_driver_ism + * @{ + */ + +#define ISM_ECM_CHANNEL(x) (1<<(x)) +#define ISM_LAM_CHANNEL(x) (1<<(x)) +#define ISM_FPC_CHANNEL(x) (1<<(x)) + +typedef enum +{ + ISM_INSTANCE_0 = 0U, /*!< ISM instance 0 is selected. */ +} ISM_InstanceType; + +typedef enum +{ + FPC_RISING_GLITCH_DETECTED = 0x01U, /*!< PFC Rising Glitch Detected. */ + FPC_FALLING_GLITCH_DETECTED = 0x02U /*!< PFC Falling Glitch Detected. */ +} FPC_GlitchDetectType; + +/** + * @brief ISM Channel ISR callback function prototype + * + */ +typedef void (*ISM_EventISRCallbackType)(const uint16_t u16LamStatus, const uint8_t u8EcmStatus); + +/** + * @brief FPC Channel Glitch dectection ISR callback function prototype + * + */ +typedef void (*FPC_ISRCallbackType)(const uint32_t u32Status); + +/** + * @brief LAM Channel Overflow ISR callback function prototype + * + */ +typedef void (*LAM_ISRCallbackType)(void); + +typedef struct +{ + + bool bIntEnable; + ISM_EventISRCallbackType pEventIsrCallback; +} ISM_InitCfgType; + +typedef struct +{ + bool bGlitchIntEnable; + ISM_FPC_EdgeDetectModeType eFallingDetectMode; + ISM_FPC_EdgeDelayModeType eFallingDelayNode; + ISM_FPC_EdgeDetectModeType eRisingDetectMode; + ISM_FPC_EdgeDelayModeType eRisingDelayNode; + uint16_t u32ThresholdValue; + FPC_ISRCallbackType pFpcIsrCallback; +} ISM_FpcCfgType; + +typedef struct +{ + bool bOvflIntEnable; + uint8_t u8SrcSel; + uint8_t u8MonSel; + ISM_LAM_InvertEventWindowType eInvWin; + ISM_LAM_EventWindowEdgeType eWinEdgSel; + ISM_LAM_EventWindowSelectType eEvtWinSel; + ISM_LAM_RunModeSelectType eRunMode; + ISM_LAM_MonitorSourceType eMonSrcSel; + ISM_LAM_InvertMonitorType eInvMon; + ISM_LAM_InvertReferenceType eInvRef; + uint32_t u32EvtCntThreshold; + LAM_ISRCallbackType pLamOverFlowIsrCallback; +} ISM_LamCfgType; + +/** + * @brief Init the ISM. + * + * @param pInitConfig ISMInstance initial configuration. + */ +void ISM_Init(const ISM_InitCfgType *pInitConfig); + +/** + * @brief Get the channels mask of ECM that has event happened. + * + * @return Channels mask. + */ +uint8_t ISM_GetEcmEventHappenedChannels(void); + +/** + * @brief Get the channels mask of LAM that has event happened. + * + * @return Channels mask. + */ +uint16_t ISM_GetLamEventHappenedChannels(void); + +/** + * @brief Clear the channels status of ECM that has event happened. + * + * @param u8Channels Channels mask. + */ +void ISM_ClearEcmEventHappenedChannels(uint8_t u8Channels); + +/** + * @brief Clear the channels status of LAM that has event happened. + * + * @param u16Channels Channels mask. + */ +void ISM_ClearLamEventHappenedChannels(uint16_t u16Channels); + +/** + * @brief Enable or disable ISM. + * + * @param bEnable Enable value. + */ +void ISM_Enable(bool bEnable); + +/** + * @brief Enable or disable ISM interrupt. + * + * @param bEnable Enable value. + */ +void ISM_InterruptEnable(bool bEnable); + +/** + * @brief ENable LAM overflow interrupt. + * + * @param u8LamIndex LAM index. + * @param bEnable Enable value. + */ +void ISM_LamOverflowInterruptEnable(uint8_t u8LamIndex, bool bEnable); + +/** + * @brief Enable LAM Channel. + * + * @param u8LamIndex LAM index. + * @param bEnable Enable value. + */ +void ISM_LamEnable(uint8_t u8LamIndex, bool bEnable); + +/** + * @brief Config the LAM channel. + * + * @param u8LamIndex LAM index. + * @param pConfig LAM configuration. + */ +void ISM_LamConfig(uint8_t u8LamIndex, const ISM_LamCfgType *pConfig); + +/** + * @brief Enable FPC glitch interrupt. + * + * @param u8FpcIndex FPC index. + * @param bEnable Enable value. + */ +void ISM_FpcGlitchInterruptEnable(uint8_t u8FpcIndex, bool bEnable); + +/** + * @brief Enable FPC channel. + * + * @param u8FpcIndex FPC index. + * @param bEnable Enable value. + */ +void ISM_FpcEnable(uint8_t u8FpcIndex, bool bEnable); + +/** + * @brief Config the FPC channel. + * + * @param u8FpcIndex FPC index. + * @param pConfig FPC configuration. + */ +void ISM_FpcConfig(uint8_t u8FpcIndex, const ISM_FpcCfgType *pConfig); + +/** + * @brief Enable ECM system event + * + * @param u32Channels Channel masks. + * @param bEnable Enable value. + */ +void ISM_EnableEcmSystemEvent(uint32_t u32Channels, bool bEnable); + +/** + * @brief Enable LAM system event + * + * @param u32Channels Channel masks. + * @param bEnable Enable value. + */ +void ISM_EnableLamSystemEvent(uint32_t u32Channels, bool bEnable); + +/** + * @brief Enable LAM system event + * + * @param u32LamIndex Lam channel index. + * @param u32EcmIndex Ecm channel index. + * @param u8EventCount Threshold of the ECM channel counter value. + */ +void ISM_EcmEventConfig(uint8_t u32LamIndex, uint8_t u32EcmIndex, uint8_t u8EventCount); + +/** + * @brief Clears the value of the LAM counter. + * + * @param u32LamIndex Lam channel index. + */ +void ISM_ClearLamStatusCounter(uint8_t u8LamIndex); + +/** + * @brief Gets the value of the LAM counter when a LAM event is triggered. + * + * @param u32LamIndex Lam channel index. + * @return Counter value. + */ +uint32_t ISM_GetLamStatusCounter(uint8_t u8LamIndex); + +/** + * @brief Clears LAM Timer Overflow Flag. + * + * @param u32LamIndex Lam channel index. + */ +void ISM_ClearLamStatusOvfl(uint8_t u8LamIndex); + +/** + * @brief Gets LAM Timer Overflow Flag. + * + * @param u32LamIndex Lam channel index. + * @return Overflow flag. + */ +bool ISM_GetLamStatusOvfl(uint8_t u8LamIndex); + +/** @}*/ /* fc7xxx_driver_ism. */ +#endif diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_lin.h b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_lin.h new file mode 100644 index 0000000..107ba23 --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_lin.h @@ -0,0 +1,427 @@ +/** + * @file fc7xxx_driver_lin.h + * @author Flagchip0122 + * @brief FC7xxx LIN driver type definition and API + * @version 0.1.0 + * @date 2023-12-26 + * + * @copyright Copyright (c) 2023 Flagchip Semiconductors Co., Ltd. + * + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2023-12-26 Flagchip0122 N/A First version for FC7xxx + ******************************************************************************** */ + +#ifndef _DRIVER_FC4XXX_DRIVER_LIN_H_ +#define _DRIVER_FC4XXX_DRIVER_LIN_H_ + +#include "HwA_fcuart.h" +#include "device_header.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +/** + * @addtogroup fc4xxx_driver_lin + * @{ + */ + +/** + * @brief LIN status type use in API. + */ +typedef enum +{ + LIN_STATUS_SUCCESS = 0x00U, /*!< API execute successfully */ + LIN_STATUS_ERROR, /*!< API excute error */ + LIN_STATUS_BUSY, /*!< currently instance busy. */ + LIN_STATUS_TIMEOUT, /*!< timeout status */ + LIN_STATUS_PARAM_ERROR, /*!< Parameter error. */ + LIN_STATUS_NOT_INIT, /*!< LIN node has not been initialized. */ + LIN_STATUS_USEED, /*!< LIN node has not been initialized. */ + LIN_STATUS_NOT_START, /*!< LIN node has not been started. */ + LIN_STATUS_UNSUPPORTED, /*!< unsupport status */ +} LIN_StatusType; + +/** + * @brief LIN node type use in API, master or slave. + */ +typedef enum +{ + LIN_NODE_MASTER, /*!< LIN Master node. */ + LIN_NODE_SLAVE, /*!< LIN slave node. */ +} LIN_NodeType; + +/** + * @brief A callback function to get the interval time value in nanoseconds. + */ +typedef uint32_t (*lin_get_interval_time_t)(uint32_t *nanoSeconds); + +/** + * @brief Structure for LIN hardware configurations. + */ +typedef struct +{ + LIN_NodeType nodeMode; /*!< Node mode as Master node or Slave node. 0: slave 1: master */ + uint32_t baudRate; /*!< baudrate configurations for LIN protocol. */ + uint32_t clockSrcFreq; /*!< LIN instance clock source frequency. */ + lin_get_interval_time_t getIntervalTimeValueCallback; /*!< Callback function to get time interval in nanoseconds */ + uint8_t *classicPID; /*!< List of PIDs use classic checksum */ + uint8_t numOfClassicPID; /*!< Number of PIDs use classic checksum */ +} lin_config_t; + +/** + * @brief Types for an event related Identifier. + */ +typedef enum +{ + LIN_NO_EVENT = 0x00U, /*!< No event occurred. */ + LIN_WAKEUP_SIGNAL, /*!< Wakeup signal */ + LIN_BAUDRATE_ADJUSTED, /*!< Baudrate was adjusted in slave autobaud mode. */ + LIN_RECV_BREAK_FIELD_OK, /*!< Break Field was received */ + LIN_SYNC_OK, /*!< Sync field is correct */ + LIN_SYNC_ERROR, /*!< Sync field is incorrect */ + LIN_PID_OK, /*!< PID receive correct */ + LIN_PID_ERROR, /*!< PID receive incorrect */ + LIN_FRAME_ERROR, /*!< Frame receive error */ + LIN_READBACK_ERROR, /*!< Readback words are incorrect */ + LIN_CHECKSUM_ERROR, /*!< Checksum byte error */ + LIN_TX_COMPLETED, /*!< TX data completed */ + LIN_RX_COMPLETED, /*!< rx data completed */ + LIN_RX_OVERRUN, /*!< RX overflow occurred */ + LIN_TIMEOUT, /*!< RX overflow occurred */ +} lin_event_id_t; + +/*! + * @brief Define type for an enumerating LIN Node state. + */ +typedef enum +{ + LIN_NODE_STATE_UNINIT = 0x00U, /*!< LIN hardware uninitialized state */ + LIN_NODE_STATE_SLEEP_MODE, /*!< LIN node in sleep mode state */ + LIN_NODE_STATE_IDLE, /*!< LIN node in idle state */ + LIN_NODE_STATE_SEND_BREAK_FIELD, /*!< LIN node in send break field state */ + LIN_NODE_STATE_RECV_SYNC, /*!< LIN node in receive the synchronization byte state */ + LIN_NODE_STATE_SEND_PID, /*!< LIN node in rend PID state */ + LIN_NODE_STATE_RECV_PID, /*!< LIN node in receive PID state */ + LIN_NODE_STATE_RECV_DATA, /*!< LIN node in receive data state */ + LIN_NODE_STATE_RECV_DATA_COMPLETED, /*!< LIN node in receive data completed state */ + LIN_NODE_STATE_SEND_DATA, /*!< LIN node in send data state */ + LIN_NODE_STATE_SEND_DATA_COMPLETED /*!< LIN node in send data completed state */ +} lin_node_state_t; + +/*! + * @brief LIN Driver callback function type + */ +typedef void (*lin_callback_t)(uint8_t u8LinIndex, void *linState); + +/*! + * @brief Runtime state of the LIN driver. + * + * Note that the caller provides memory for the driver state structures during + * initialization because the driver does not statically allocate memory. + * Implements : lin_state_t_Class + */ +typedef struct +{ + const uint8_t *txBuff; /*!< The buffer of data being sent. */ + uint8_t *rxBuff; /*!< The buffer of received data. */ + uint8_t cntByte; /*!< To count number of bytes already transmitted or received. */ + volatile uint8_t txSize; /*!< The remaining number of bytes to be transmitted. */ + volatile uint8_t rxSize; /*!< The remaining number of bytes to be received. */ + uint8_t checkSum; /*!< Checksum byte. */ + volatile bool isTxBusy; /*!< True if the LIN interface is transmitting frame data. */ + volatile bool isRxBusy; /*!< True if the LIN interface is receiving frame data. */ + volatile bool isBusBusy; /*!< True if there are data, frame headers being transferred on bus */ + volatile bool isTxBlocking; /*!< True if transmit is blocking transaction. */ + volatile bool isRxBlocking; /*!< True if receive is blocking transaction. */ + lin_callback_t Callback; /*!< Callback function to invoke after receiving a byte or transmitting a byte. */ + uint8_t currentId; /*!< Current ID */ + uint8_t currentPid; /*!< Current PID */ + volatile lin_event_id_t currentEventId; /*!< Current ID Event */ + volatile lin_node_state_t currentNodeState; /*!< Current Node state */ + volatile uint32_t timeoutCounter; /*!< Value of the timeout counter */ + volatile bool timeoutCounterFlag; /*!< Timeout counter flag */ +} lin_xfer_state_t; + +/**@}*/ +/** + * @name API declaration for LIN driver. + * + */ +/**@{*/ + +/** + * @brief Init the LIN instance for LIN network. This API will help initialize the FCUART to expect state, + * but will nots start the TX&RX function, if users want to start the LIN protocol transfer, please + * call the function LIN_DrvStart() after this API is called. + * + * @param u8LinIndex LIN hardware instance, 0U... + * @param pConfig Configuration for LIN hardware, must not be null. + * @return operation status: + * - LIN_STATUS_SUCCESS : operation is successfully. + * - LIN_STATUS_USEED : The instance has been used, user should use another instance or de-initialize this instance firstly. + * - LIN_STATUS_ERROR : the baudrate has not been set successfully. + */ +LIN_StatusType LIN_DrvInit(uint8_t u8LinIndex, lin_config_t *pConfig); + +/** + * @brief De-Init the LIN instance used by LIN network. + * This API will help disable the fcuart interrupts and stop the TX/RX transfer. + * + * @return operation status: + * - LIN_STATUS_SUCCESS : operation is successfully. + * - LIN_STATUS_NOT_INIT : The instance has not been initialized. + */ +LIN_StatusType LIN_DrvDeInit(uint8_t u8LinIndex); + +/** + * @brief Help users get the default configuration of LIN node. users should provide the configuration structure + * in app code, and transfer the ptr address to driver code. uses can also set this parameters in the application code + * as designed. + * + * @param u8NodeMode LIN node mode select, 0 for slave mode and 1 for master mode. + * @param pConfig default configuration for LIN node, must not be null. + */ +void LIN_DrvGetDefaultConfig(LIN_NodeType eNodeMode, lin_config_t *pConfig); + +/** + * @brief Start LIN node transfer, this API should be called after LIN hardware has been initialized, and must + * be called before starting a LIN node transfer. Users should provide a tansfer structure for storing the + * transfer state, ant LIN node state changed will be stored to this xfer state. + * + * @param u8LinIndex LIN hardware instance, 0U... + * @param pXferState Transfer state structure which will help store the trasnfer state. + * @return operation status: + * - LIN_STATUS_SUCCESS : operation is successfully. + * - LIN_STATUS_PARAM_ERROR: the parameter setting maybe not correct, maybe instance has bot been initialized. + */ +LIN_StatusType LIN_DrvStart(uint8_t u8LinIndex, lin_xfer_state_t *pXferState); + +/** + * @brief This function will help install callback function that used by application code. + * users can handle some needed operations in driver code or get some important states. + * or uses can also setting this in transfer state structure. + * + * @param u8LinIndex LIN hardware instance, 0U... + * @param callback user's callbak function that need be called in driver code. + * @return operation status: + * - LIN_STATUS_SUCCESS : operation is successfully. + * - LIN_STATUS_NOT_INIT : The instance required has bot been initialized. + */ +LIN_StatusType LIN_DrvInstallUserCallback(uint8_t u8LinIndex, lin_callback_t callback); + +/** + * @brief This function will help users send a header in master node which will help start a new + * frame transfer. please do not used this API will LIN instance is configured as slave node. + * This API will make a parity ID, and only send a break field to the protocol, all the other + * filed like sync filed and pid byte will be handled in FCUART IRQHandler. more details can + * refer to IRQ routine. + * + * @param u8LinIndex LIN hardware instance, 0U... + * @param u8Id The ID data that useds need to send in header. + * @return operation status: + * - LIN_STATUS_SUCCESS : operation is successfully. + * - LIN_STATUS_NOT_INIT : Instance required has not been intialized. + * - LIN_STATUS_UNSUPPORTED : Current node is slave not, could not send header to protocol. + * - LIN_STATUS_BUSY : Bus busy which means node is sending or receiving another frame. + */ +LIN_StatusType LIN_DrvSendHeader(uint8_t u8LinIndex, uint8_t u8Id); + +/** + * @brief This API will help users send a frame data through LIN protocol, and will return only when + * all frame data has been sent to the protocol, or while timeout occurred, so please configure + * the u32TimeOut parameter as needed. And currentlyt this API has not implement the OS feature, + * so do not call this API in interrupt routine, otherwise, routine maybe halted by this API. + * + * @param u8LinIndex LIN hardware instance, 0U... + * @param pTxBuf TX buffer whihc will be sent to protocol, MUST NOT BE NULL. + * @param u8Length bytes lengths in TX buffer. + * @param u32TimeOut Timeout value, 0 indicates timeout feature is not used, in unit of millieconds. + * @return operation status: + * - LIN_STATUS_SUCCESS : operation is successfully. + * - LIN_STATUS_NOT_INIT : Instance required has not been initialized. + * - LIN_STATUS_BUSY : Bus busy, node is transfer state. + */ +LIN_StatusType LIN_DrvSendFrameBlocking(uint8_t u8LinIndex, uint8_t *pTxBuf, uint8_t u8Length, uint32_t u32TimeOut); + +/** + * @brief This API will help users send a frame data through LIN protocol, this API will return immediately. + * data will be stored in txbuffer, users can check the transmit status while data is sending. + * + * @param u8LinIndex LIN hardware instance, 0U... + * @param pTxBuf TX buffer whihc will be sent to protocol, MUST NOT BE NULL. + * @param u8Length bytes lengths in TX buffer. + * @param u32TimeOut Timeout value, 0 indicates timeout feature is not used, in unit of millieconds. + * @return operation status: + * - LIN_STATUS_SUCCESS : operation is successfully. + * - LIN_STATUS_NOT_INIT : Instance required has not been initialized. + * - LIN_STATUS_BUSY : Bus busy, node is transfer state. + */ +LIN_StatusType LIN_DrvSendFrameNonBlocking(uint8_t u8LinIndex, uint8_t *pTxBuf, uint8_t u8Length); + +/** + * @brief This API will help users get the LIN transfer status while data is sending. and will also + * help user get remainning byte in transfer still need sending in buffer. + * + * @param u8LinIndex LIN hardware instance, 0U... + * @param pRemainBytes Address to be stored the remain byte value, should not be NULL. + * @return operation status: + * - LIN_STATUS_TIMEOUT : node transfer timeout occurred. + * - LIN_STATUS_SUCCESS : transfer complete. + * - LIN_STATUS_BUSY : transfer is going + */ +LIN_StatusType LIN_DrvGetTransmitStatus(uint8_t u8LinIndex, uint8_t *pRemainBytes); + +/** + * @brief This API will help users receive frame data through LIN protocol, this API will return only when + * all frame data has been received from the protocol, or while timeout occurred, so please configure + * the u32TimeOut parameter as needed. And currently, this API has not implement the OS feature, + * so do not call this API in interrupt routine, otherwise, routine maybe halted by this API. + * + * @param u8LinIndex LIN hardware instance, 0U... + * @param pRxBuf RX buffer which will be received from protocol, MUST not be NULL. + * @param u8Length bytes lengths should be received. + * @param u32TimeOut Timeout value, 0 indicates timeout feature is not used, in millieconds. + * @return operation status: + * - LIN_STATUS_SUCCESS : operation is successfully. + * - LIN_STATUS_NOT_INIT : Instance has not been initialized + * - LIN_STATUS_BUSY : Bus in busy state, need wait bus idle. + * - LIN_STATUS_TIMEOUT : Timeout occurred, data received may not successful. + */ +LIN_StatusType LIN_DrvReceiveFrameBlocking(uint8_t u8LinIndex, uint8_t *pRxBuf, uint8_t u8Length, uint32_t u32TimeOut); + +/** + * @brief This API will help users received frame data through LIN protocol, this API will return immediately. + * data will be stored in rxbuffer, users can check the receive status while using this API. + * + * @param u8LinIndex LIN hardware instance, 0U... + * @param pRxBuf RX buffer which will be received from protocol, MUST not be NULL. + * @param u8Length bytes lengths should be received. + * @param u32TimeOut Timeout value, 0 indicates timeout feature is not used, in millieconds. + * @return operation status: + * - LIN_STATUS_SUCCESS : operation is successfully. + * - LIN_STATUS_NOT_INIT : Instance has not been initialized + * - LIN_STATUS_BUSY : Bus in busy state, need wait bus idle. + * - LIN_STATUS_TIMEOUT : Timeout occurred, data received may not successful. + */ +LIN_StatusType LIN_DrvReceiveFrameNonBlocking(uint8_t u8LinIndex, uint8_t *pRxBuf, uint8_t u8Length); + +/** + * @brief This API will help users get the LIN transfer status while data is receiving. and will also + * help user get remainning byte in transfer still need receiving in buffer. + * + * @param u8LinIndex LIN hardware instance, 0U... + * @param pRemainBytes Address to be stored the remain byte value, should not be NULL. + * @return operation status: + * - LIN_STATUS_SUCCESS : operation is successfully. + * - others are not successfully. + */ +LIN_StatusType LIN_DrvGetReceiveStatus(uint8_t u8LinIndex, uint8_t *pRemainBytes); + +/** + * @brief Abort transfer both sending or receiving data, actually, call this APU will enter IDLE state. + * will stop end and receive even data transfer is on going. + * + * @param u8LinIndex LIN hardware instance, 0U... + * @return operation status: + * - LIN_STATUS_SUCCESS : operation is successfully. + */ +LIN_StatusType LIN_DrvAbortTransfer(uint8_t u8LinIndex); + +/** + * @brief This API should be called while no data is transferring, once this API is called, node will + * enter sleep mode, TX/RX and interrupts will also be disabled, and node will wait a wakeup signal + * on the protocol. This API will enable receive active interrupt, once a wakeup signal triggered, + * routine will entern uart IRQHandler to handle this case, and then wakeup the LIN node. + * + * @param u8LinIndex LIN hardware instance, 0U... + * @return operation status: + * - LIN_STATUS_SUCCESS : operation is successfully. + */ +LIN_StatusType LIN_DrvGoToSleepMode(uint8_t u8LinIndex); + +/** + * @brief THis API will help confgure the mode into IDLE state. In IDLE state, node will enable receive interrupt and break + * field detect interrupt, slave node will wait the break field from master node, master node will prepare to send a + * new break filed to start a new frame. + * + * @param u8LinIndex LIN hardware instance, 0U... + * @return operation status: + * - LIN_STATUS_SUCCESS : operation is successfully. + */ +LIN_StatusType LIN_DrvGoToIdleMode(uint8_t u8LinIndex); + +/** + * @brief Sending a wakeup signal to the protocol, all LIN network nodes receive this signal will + * wakeup from sleep mode. Actually, the master will send a character which will cause a 150us + * larger active level to the protocol. while receiving this signal, LIN node will wake up + * from sleep mode. + * + * @param u8LinIndex LIN hardware instance, 0U... + * @return operation status: + * - LIN_STATUS_SUCCESS : operation is successfully. + * - LIN_STATUS_NOT_INIT : Instance required is not initialized. + * - LIN_STATUS_BUSY :LIN node state is not correct, need update state firstly. + */ +LIN_StatusType LIN_DrvSendWakeupSignal(uint8_t u8LinIndex); + +/** + * @brief Get the LIN node state. + * + * @param u8LinIndex LIN hardware instance, 0U... + * @return the node current state, refer to @lin_node_state_t + */ +lin_node_state_t LIN_DrvGetNodeState(uint8_t u8LinIndex); + +/** + * @brief This API should be called by user's application code, and the timeout periods should be 500ms once. + * Better to provide a timer IRQhandler to call this APIs 500ms onces. + * + * @param u8LinIndex LIN hardware instance, 0U... + * @return operation status: + * - LIN_STATUS_SUCCESS : operation is successfully. + * - others are not successfully. + */ +LIN_StatusType LIN_DrvTimeOutService(uint8_t u8LinIndex); + +/** + * @brief This API will help users set the timeout counter with one API, users should use this feature with LIN_DrvTimeOutService() + * called every fixed time. + * + * @param u8LinIndex LIN hardware instance, 0U... + * @param u32TimeOutValue Timeout value. + * @return operation status: + * - LIN_STATUS_SUCCESS : operation is successfully. + * - LIN_STATUS_NOT_INIT : Instance required is not initialized. + */ +LIN_StatusType LIN_DrvSetTimeOutCounter(uint8_t u8LinIndex, uint32_t u32TimeOutValue); + +/** + * @brief This API will help users get the Node timeout flag status. + * + * @param u8LinIndex LIN hardware instance, 0U... + * @return true for timeout occurred, false indicate no timeout. + */ +bool LIN_DrvGetTimeOutFlag(uint8_t u8LinIndex); + +/** + * @brief This is LIN IRQ routine code, uses should call this in the FCUART IRQhandler code. please must implement + * the feature in application code. + * + * @param u8LinIndex LIN hardware instance, 0U... + */ +void LIN_DrvIRQHandler(uint8_t u8LinIndex); + +/**@}*/ + +/** @}*/ /* fc4xxx_driver_lin */ +#if defined(__cplusplus) +} +#endif + +#endif /* _DRIVER_FC4XXX_DRIVER_LIN_H_ */ diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_lu.h b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_lu.h new file mode 100644 index 0000000..6b7166c --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_lu.h @@ -0,0 +1,138 @@ +/** + * @file fc7xxx_driver_lu.h + * @author Flagchip0103 + * @brief FC7xxx LU driver header file + * @version 0.1.0 + * @date 2023-12-19 + * + * @copyright Copyright (c) 2023 Flagchip Semiconductors Co., Ltd. + * + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2023-12-19 Flagchip0103 N/A First version for FC7240 + ******************************************************************************** */ + +#ifndef _DRIVER_FC4XXX_DRIVER_LU_H_ +#define _DRIVER_FC4XXX_DRIVER_LU_H_ +#include "HwA_lu.h" +/** + * @addtogroup fc7xxx_driver_lu + * @{ + */ + +#define LU_AOI_IN_N_CFG_N(AoiIn, AoiInN, InNCfgNType) ((((uint32_t)(InNType) & 0x3U) << (((uint32_t)3U - (uint32_t)(AoiInN)) << 3U)) << (((uint32_t)3U - (uint32_t)(AoiIn)) << 3U)) +#define LU_AOI_IN_N_CFG_N_MASK(AoiIn, AoiInN) (((uint32_t)0x3U << (((uint32_t)3U - (uint32_t)(AoiInN)) << 3U)) << (((uint32_t)3U - (uint32_t)(AoiIn)) << 3U)) + +#define LU_AOI_IN_CFG(AoiInN, CfgNType) ((((uint32_t)(CfgNType) & 0x3U) << (((uint32_t)3U - (uint32_t)(AoiInN)) << 1U))) +#define LU_AOI_IN_CFG_MASK(AoiInN) ((((uint32_t)0x3U) << (((uint32_t)3U - (uint32_t)(AoiInN)) << 1U))) + +#define LU_AOI_IN_N_CFG(AoiIn, InNType) ((((uint32_t)(InNType) & 0xFFU) << (((uint32_t)3U - (uint32_t)(AoiIn)) << 3U))) +#define LU_AOI_IN_N_CFG_MASK(AoiIn) ((((uint32_t)0xFFU) << (((uint32_t)3U - (uint32_t)(AoiIn)) << 3U))) + +#define LU_SYNC_CONTROL_INPUT_N(InputN, value) ((uint32_t)(value) << (InputN)) + +/** @brief LU return structure */ +typedef enum +{ + LU_STATUS_SUCCESS = 0U, + LU_STATUS_PARAM_INVALID = 1U +} LU_StatusType; + +/** @brief LU IN type */ +typedef enum +{ + LU_AOI_IN_0 = 0U, + LU_AOI_IN_1, + LU_AOI_IN_2, + LU_AOI_IN_3, +} LU_AoiInType; + +/** @brief LU IN(n) configuration type */ +typedef enum +{ + LU_AOI_IN_N_A = 0U, + LU_AOI_IN_N_B, + LU_AOI_IN_N_C, + LU_AOI_IN_N_D +} LU_AoiInNType; + +/** @brief LU IN(n) configuration */ +typedef enum +{ + FORCE_ITEM_AS_ZERO = 0U, /**< force item as logic zero */ + PASS_THROUGH_ITEM, /**< pass through item */ + COMPLEMENT_ITEM, /**< complement item */ + FORCE_ITEM_AS_ONE /**< force item as logic one */ +} LU_InModeType; + +/** @brief LU output initialization value */ +typedef enum +{ + LU_OUTPUT_INIT_ZERO = 0U, + LU_OUTPUT_INIT_ONE, + LU_OUTPUT_INIT_DISABLE +} LU_OutputInitValueType; + +/** @brief LU IN(n) configuration register type */ +typedef struct +{ + LU_InModeType eInNACfg; /**< AOI IN(n) A configuration */ + LU_InModeType eInNBCfg; /**< AOI IN(n) B configuration */ + LU_InModeType eInNCCfg; /**< AOI IN(n) C configuration */ + LU_InModeType eInNDCfg; /**< AOI IN(n) D configuration */ +} LU_InConfigType; + +/** @brief LU AOI IN(n) configuration type */ +typedef struct +{ + LU_InConfigType tIn0Config; /**< AOI IN0 configuration */ + LU_InConfigType tIn1Config; /**< AOI IN1 configuration */ + LU_InConfigType tIn2Config; /**< AOI IN2 configuration */ + LU_InConfigType tIn3Config; /**< AOI IN3 configuration */ +} LU_AoiConfigType; + +/** @brief LU LG inputs synchronous control */ +typedef struct +{ + bool bInputNA; /**< LU IN(n) A sync control */ + bool bInputNB; /**< LU IN(n) B sync control */ + bool bInputNC; /**< LU IN(n) C sync control */ + bool bInputND; /**< LU IN(n) D sync control */ +} LU_InputsSyncCtrlType; + +/** @brief LU initialization type */ +typedef struct +{ + LU_LgType eLgNum; /**< LG number */ + LU_AoiConfigType tAoi0Config; /**< aoi0 configuration */ + LU_AoiConfigType tAoi1Config; /**< aoi1 configuration */ + LU_InputsSyncCtrlType tSyncCtrl; /**< inputs sync control, when set, would sync input product with bus clock */ + LU_BypassModeType eAoiMode; /**< AOI mode */ + LU_ConfigModeType eFFMode; /**< flip-flop mode */ + LU_OutputInitValueType eFFInitValue; /**< flip-flop initial value */ + LU_InputNType eFbMode; /**< feedback override control in JKFF mode */ + uint8_t u8Aoi0FiltCnt; /**< aoi0 input filter sample count */ + uint8_t u8Aoi0Period; /**< aoi0 input filter sample period */ + uint8_t u8Aoi1FiltCnt; /**< aoi1 input filter sample count */ + uint8_t u8Aoi1Period; /**< aoi1 input filter sample period */ +} LU_InitType; + +/* global functions */ +/** + * @brief Initialize LU instance + * @param pInitStruct LU initialization structure + * @return LU return type + */ +LU_StatusType LU_Init(const LU_InitType *const pInitStruct); + +/** + * @brief De-initialize LU instance + */ +void LU_Deinit(void); + +/** @}*/ /* fc7xxx_driver_lu */ +#endif diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_mam.h b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_mam.h new file mode 100644 index 0000000..9f1a303 --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_mam.h @@ -0,0 +1,109 @@ +/** + * @file fc7xxx_driver_mam.h + * @author Flagchip + * @brief FC7xxx MAM driver type definition and API + * @version 0.2.0 + * @date 2023-02-08 + * + * @copyright Copyright (c) 2023 Flagchip Semiconductors Co., Ltd. + * + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2023-02-08 Flagchip095 N/A First version for FC7240 + ******************************************************************************** */ +#ifndef _DRIVER_FC7XXX_DRIVER_MAM_H_ +#define _DRIVER_FC7XXX_DRIVER_MAM_H_ + +#include "device_header.h" +#include "HwA_mam.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +/** + * @brief The master index of the mam peripheral + * + */ +typedef enum { + MAM_MASTER_CPU0_AXIM = 0, + MAM_MASTER_CPU0_AHBP, + MAM_MASTER_DMA0, + MAM_MASTER_HSM, + MAM_MASTER_NUM +} MAM_Master_Type; + +/** + * @brief The mam index + * + */ +typedef enum { + NVM_MAM0 = 0, + RAM_MAM1, + PERIPHERAL_MAM2 +} MAM_Index_Type; + + +/** + * @brief the MAM slave information + * + */ +typedef struct +{ + uint8_t error; + uint32_t block_num; +} MAM_Inf_Type; + + +typedef enum { + FORBID_READ_ACCESS = 1, + FORBID_WRITE_ACCESS = 2, + FORBID_EXECUTE_ACCESS = 4, + FORBID_USER_ACCESS = 8 +} MAM_Forbid_Access_Type; + +/** + * @brief The function of software reset to MAM + * + * @param number mam index + */ +void MAM_Reset(MAM_Index_Type idx); + +/** + * @brief The function to enable MAM watch dog + * + * @param1 Master The master index + * + * @param2 u32Addr The input address + */ +uint8_t MAM_Enable_Wdg(MAM_Master_Type Master,uint32_t u32Addr); + +/** + * @brief The function to disable MAM watch dog + * + * @param1 Master The master index + * + * @param2 u32Addr The input address + */ +uint8_t MAM_Disable_Wdg(MAM_Master_Type Master,uint32_t u32Addr); + +/** + * @brief The function to config MAM + * + * @param1 Master The master index + * + * @param2 u32Addr The input address + * + * @param3 u32Val The value to set + */ +uint8_t MAM_Config(MAM_Master_Type Master, uint32_t u32Addr, uint32_t u32Val); + +#if defined(__cplusplus) +} +#endif + +#endif /* end of DRIVER_UART_H_ */ diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_mb.h b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_mb.h new file mode 100644 index 0000000..12b55e4 --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_mb.h @@ -0,0 +1,201 @@ +/** + * @file fc7xxx_driver_mb.h + * @author Flagchip070 + * @brief FC7xxx Mailbox driver type definition and API + * @version 0.1.0 + * @date 2022-11-15 + * + * @copyright Copyright (c) 2022 Flagchip Semiconductors Co., Ltd. + * + * @details + */ +/******************************************************************************** +* Revision History: +* +* Version Date Initials CR# Descriptions +* --------- ---------- ------------ ---------- --------------- +* 0.1.0 2022-11-15 Flagchip070 N/A First version for FC7300 +********************************************************************************/ + +#ifndef _DRIVER_fc7xxx_driver_mb_H_ +#define _DRIVER_fc7xxx_driver_mb_H_ + +#include "device_header.h" +#include "HwA_mb.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +/** + * @addtogroup fc7xxx_driver_mb + * @{ + */ + + +/** + * @brief Mailbox channel bit flag of security information + * + */ +#define MB_CHANNEL_STATUS_SECURE 2u + +/** + * @brief Mailbox channel bit flag of processing information + * + */ +#define MB_CHANNEL_STATUS_PRIVILEGED 1u + +/** + * @name Mailbox channel bit mask + * @brief Bit of channel indicate channel number + * + * @{ + */ +#define MB_CHANNEL_MASK_NONE 0u +#define MB_CHANNEL_MASK_ALL 0xFFFFu +#define MB_CHANNEL_MASK(ch) ((uint32_t)(1ul << (ch))) +/** @}*/ + +/** + * @brief Mailbox has not initialized, the core index will be MB_NOT_INIT + * + */ + +#define MB_NOT_INIT 0xFFFFFFFFu +/** + * @brief Mailbox operation return values + * + */ +typedef enum { + MB_STATUS_SUCCESS = 0u, /*!< The Mailbox operation is success */ + MB_STATUS_FAILED, /*!< The Mailbox operation is failed */ + MB_STATUS_PARAM_ERROR, /*!< The Mailbox operation is failed because of parameter error*/ + MB_STATUS_ALREADY_INITED, /*!< The Mailbox operation is failed because of + Mailbox has already initialized*/ + MB_STATUS_UNINIT, /*!< The Mailbox operation is failed because of + Mailbox has not initialized*/ + MB_STATUS_LOCKED, /*!< The Mailbox channel is locked */ + MB_STATUS_NO_REQUEST, /*!< No valid requests */ +} MB_StatusType; + +/** + * @brief Configuration of a Mailbox request + * + */ +typedef struct +{ + uint8_t u8Channel; /*!< The selected Mailbox channel */ + uint8_t u8RequestMask; /*!< The mask for issuing requests */ + uint8_t u8DoneMasterIndex; /*!< The master ID of the core that generates a done event */ + uint8_t u8DoneMask; /*!< The mask for the done events */ + uint8_t u8AutoReleaseFlag; /*!< Automatically clear the channel lock enable bit */ + uint8_t u8Reserved[3]; + uint32_t aData[2]; /*!< Sending data */ +} MB_RequestType; + +/** + * @brief Configuration of a receiving request + * + */ +typedef struct +{ + uint8_t u8Channel; /*!< The selected Mailbox channel */ + uint8_t u8MasterCoreIndex; /*!< Buffer to store the master core index */ + uint8_t u8ChannelStatus; /*!< Buffer to store the security information + and processing mode of the channel*/ + uint8_t u8Reserved; + uint32_t aData[2]; /*!< Buffer to store the receiving data */ +} MB_ReceiveType; + +/** + * @brief Configuration of the Mailbox + * + */ +typedef struct +{ + uint32_t u32EventMask; /*!< Mask for the request events and done events */ + uint32_t u32IntrMask; /*!< Mask for enable the interrupts */ + void (*pRequestCallback)(MB_ReceiveType *pReceive); /*!< Callback of the request events */ + void (*pDoneCallback)(uint32_t u32ChannelMask); /*!< Callback of the done events */ +} MB_InitType; + +/** + * @brief Initialize the Mailbox + * + * @param pInitConfig the configurations of the Mailbox + * @return MB_StatusType whether the operation is successfully + */ +MB_StatusType MB_Init(const MB_InitType *pInitConfig); +/** + * @brief De-initialize the Mailbox + * + * @return MB_StatusType whether the operation is successfully + */ +MB_StatusType MB_DeInit(void); +/** + * @brief Attempt to acquire a Mailbox channel + * + * @param u32Channel the selected Mailbox channel + * @return MB_StatusType whether the operation is successfully + */ +MB_StatusType MB_LockChannel(uint32_t u32Channel); +/** + * @brief Release a Mailbox channel + * + * @param u32Channel the selected Mailbox channel + * @return MB_StatusType whether the operation is successfully + */ +MB_StatusType MB_ReleaseChannel(uint32_t u32Channel); +/** + * @brief Get the index of the core + * + * @return uint32_t index of the core + */ +uint32_t MB_GetCoreIndex(void); +/** + * @brief Launching a Mailbox request + * + * @param pRequest Configuration of the request + * @return MB_StatusType whether the operation is successfully + */ +MB_StatusType MB_SendRequest(MB_RequestType *pRequest); +/** + * @brief Attempt to receive a request from the selected channel + * + * @param pReceive Configuration of the receiving request + * @return MB_StatusType whether the operation is successfully + */ +MB_StatusType MB_ReceiveChannel(MB_ReceiveType *pReceive); +/** + * @brief Software clears channel lock + * + * @param u32Channel the selected Mailbox channel + * @return MB_StatusType whether the operation is successfully + */ +MB_StatusType MB_UnlockChannel(uint32_t u32Channel); +/** + * @brief Polling the done event of all channels + * + * @param u32PollMask mask of the done event + * @param pDoneMask buffer to store the done events + * @return MB_StatusType whether the operation is successfully + */ +MB_StatusType MB_PollDone(uint32_t u32PollMask, uint32_t *pDoneMask); +/** + * @brief Issue a done event to the selected channel + * + * @param u32Channel the selected Mailbox channel + * @param u32DoneMask The mask for issuing done + * @return MB_StatusType whether the operation is successfully + */ +MB_StatusType MB_DoneChannel(uint32_t u32Channel, uint32_t u32DoneMask); +/** + * @brief Interrupt IRQ handle of Mailbox + * + */ +void MB_IRQProcess(void); +/** @}*/ /* fc7xxx_driver_mb */ +#if defined(__cplusplus) +} +#endif +#endif diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_mpu.h b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_mpu.h new file mode 100644 index 0000000..7937cf7 --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_mpu.h @@ -0,0 +1,242 @@ +/** + * @file fc7xxx_driver_mpu.h + * @author Flagchip085 + * @brief FC7xxx MPU driver type definition and API + * @version 0.1.0 + * @date 2024-01-12 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + * @details The MPU only checks the CPU master access to CTCM and DTCM memory. When access denied, it will cause MemManage Interrupt. + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-01-12 Flagchip085 N/A First version for FC7240 + ******************************************************************************** */ +#ifndef _DRIVER_FC7XXX_DRIVER_MPU_H_ +#define _DRIVER_FC7XXX_DRIVER_MPU_H_ + +#include "HwA_mpu.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +/** + * @addtogroup fc7xxx_driver_mpu + * @{ + */ + +/** + * @brief Status enumeration used by Flagchip MPU Driver + * + */ +typedef enum { + MPU_STATUS_SUCCESS = 0, /*!< MPU API execute successfully */ + MPU_STATUS_ERROR, /*!< Some error occur in MPU API */ +} MPU_StatusType; + +/** + * @brief + * + */ +typedef enum { + MPU_EN_HFNMI_PRIVDEF_NONE = 0U, /*!< disables use of the default memory map. Any memory access to a location not covered by any enabled region causes a fault, + MPU is disabled during hard fault, NMI, and FAULTMASK handlers */ + MPU_EN_HARDFAULT_NMI = 1, /*!< Enables the operation of MPU during hard fault, NMI, and FAULTMASK handlers */ + MPU_EN_PRIVILEGED_DEFAULT = 2, /*!< enables use of the default memory map as a background region for privileged software accesses. + When enabled, the background region acts as if it is region number -1. + Any region that is defined and enabled has priority over this default map. */ + MPU_EN_HFNMI_PRIVDEF = 3, /*!< same with MPU_EN_HARDFAULT_NMI | MPU_EN_PRIVILEGED_DEFAULT */ +} MPU_EnableOptionType; + +/** + * @brief Enable Status for Sub-region configuration + * + */ +typedef enum { + MPU_REGION_SRD_ENABLE_SUBREGION = 0, /*!< sub-region is enabled */ + MPU_REGION_SRD_DISABLE_SUBREGION = 1, /*!< sub-region is not enabled */ +} MPU_RegionSubDisableType; + +/** + * @brief Configure the code in the region whether can be execute + * + */ +typedef enum { + MPU_REGION_XN_EXECUTE_ENABLE = 0x0, + MPU_REGION_XN_EXECUTE_DISABLE = 0x1 +} MPU_RegionExecuteNeverType; + +/** + * @brief region Shareable configuration + * + */ +typedef enum { + MPU_REGION_S_DISABLE = 0, + MPU_REGION_S_ENABLE = 1 +} MPU_RegionShareableType; + +/** + * @brief Region Cacheable configuration + * + */ +typedef enum { + MPU_REGION_C_DISABLE = 0, + MPU_REGION_C_ENABLE = 1 +} MPU_RegionCacheableType; + +/** + * @brief Region Bufferable configuration + * + */ +typedef enum { + MPU_REGION_B_DISABLE = 0, + MPU_REGION_B_ENABLE = 1 +} MPU_RegionBufferableType; + +/** + * @brief Region Type Extend Level configuration + * + */ +typedef enum { + MPU_REGION_TEX_LEVEL_0 = 0, + MPU_REGION_TEX_LEVEL_1 = 1, + MPU_REGION_TEX_LEVEL_2 = 2 +} MPU_RegionTypeExtLevelType; + +/** + * @brief Region size enumeration for enabling MPU region + * + */ +typedef enum { + MPU_REGION_SIZE_32B = 0x04, + MPU_REGION_SIZE_64B = 0x05, + MPU_REGION_SIZE_128B = 0x06, + MPU_REGION_SIZE_256B = 0x07, + MPU_REGION_SIZE_512B = 0x08, + MPU_REGION_SIZE_1KB = 0x09, + MPU_REGION_SIZE_2KB = 0x0A, + MPU_REGION_SIZE_4KB = 0x0B, + MPU_REGION_SIZE_8KB = 0x0C, + MPU_REGION_SIZE_16KB = 0x0D, + MPU_REGION_SIZE_32KB = 0x0E, + MPU_REGION_SIZE_64KB = 0x0F, + MPU_REGION_SIZE_128KB = 0x10, + MPU_REGION_SIZE_256KB = 0x11, + MPU_REGION_SIZE_512KB = 0x12, + MPU_REGION_SIZE_1MB = 0x13, + MPU_REGION_SIZE_2MB = 0x14, + MPU_REGION_SIZE_4MB = 0x15, + MPU_REGION_SIZE_8MB = 0x16, + MPU_REGION_SIZE_16MB = 0x17, + MPU_REGION_SIZE_32MB = 0x18, + MPU_REGION_SIZE_64MB = 0x19, + MPU_REGION_SIZE_128MB = 0x1A, + MPU_REGION_SIZE_256MB = 0x1B, + MPU_REGION_SIZE_512MB = 0x1C, + MPU_REGION_SIZE_1GB = 0x1D, + MPU_REGION_SIZE_2GB = 0x1E, + MPU_REGION_SIZE_4GB = 0x1F +} MPU_RegionSizeType; + +/** + * @brief MPU Permission Enumeration + * + */ +typedef enum { + MPU_REGION_AP_NO_ACCESS = 0x00, /*!< Any access generates a permission fault */ + MPU_REGION_AP_PRIV_RW = 0x01, /*!< Privileged access only, unprivileged no access */ + MPU_REGION_AP_PRIV_RW_URO = 0x02, /*!< Any unprivileged write generates a permission fault */ + MPU_REGION_AP_FULL_ACCESS = 0x03, /*!< Full access */ + MPU_REGION_AP_PRIV_RO = 0x05, /*!< Privileged read-only, unprivileged no access */ + MPU_REGION_AP_PRIV_RO_URO = 0x06 /*!< Privileged and unprivileged read-only */ +} MPU_RegionAccessPermissionType; + + +typedef enum { + MPU_REGION_NUMBER_0 = 0x0, /*!< lowest priority */ + MPU_REGION_NUMBER_1 = 0x1, + MPU_REGION_NUMBER_2 = 0x2, + MPU_REGION_NUMBER_3 = 0x3, + MPU_REGION_NUMBER_4 = 0x4, + MPU_REGION_NUMBER_5 = 0x5, + MPU_REGION_NUMBER_6 = 0x6, + MPU_REGION_NUMBER_7 = 0x7, + MPU_REGION_NUMBER_8 = 0x8, + MPU_REGION_NUMBER_9 = 0x9, + MPU_REGION_NUMBER_10 = 0xA, + MPU_REGION_NUMBER_11 = 0xB, + MPU_REGION_NUMBER_12 = 0xC, + MPU_REGION_NUMBER_13 = 0xD, + MPU_REGION_NUMBER_14 = 0xE, + MPU_REGION_NUMBER_15 = 0xF /*!< highest priority */ +} MPU_RegionNumberType; + + +typedef struct { + uint32_t u32BaseAddr; /*!< the start address of region, the least significant 5 bits should be 0 */ + MPU_RegionSizeType eRegionSize; /*!< region size */ + MPU_RegionAccessPermissionType eAccessPermission; /*!< region access permission */ + MPU_RegionExecuteNeverType eExecuteNever; /*!< region data can be execute or not */ + MPU_RegionTypeExtLevelType eTypeExtLevel; /*!< region type extend level */ + MPU_RegionShareableType eShareable; /*!< region shareable */ + MPU_RegionCacheableType eCacheable; /*!< region cacheable */ + MPU_RegionBufferableType eBufferable; /*!< region bufferable */ + MPU_RegionSubDisableType eSubRegionDis_0; /*!< sub-region 0 disable or not */ + MPU_RegionSubDisableType eSubRegionDis_1; /*!< sub-region 1 disable or not */ + MPU_RegionSubDisableType eSubRegionDis_2; /*!< sub-region 2 disable or not */ + MPU_RegionSubDisableType eSubRegionDis_3; /*!< sub-region 3 disable or not */ + MPU_RegionSubDisableType eSubRegionDis_4; /*!< sub-region 4 disable or not */ + MPU_RegionSubDisableType eSubRegionDis_5; /*!< sub-region 5 disable or not */ + MPU_RegionSubDisableType eSubRegionDis_6; /*!< sub-region 6 disable or not */ + MPU_RegionSubDisableType eSubRegionDis_7; /*!< sub-region 7 disable or not */ +} MPU_RegionConfigurationType; + + +/** + * @brief Check the MPU exist or not + * + * @return MPU_StatusType if exist return MPU_STATUS_SUCCESS, others not exist + */ +MPU_StatusType MPU_CheckExist(void); + +/** + * @brief Enable the MPU + * + * @param eOption Enable Options + */ +void MPU_Enable(MPU_EnableOptionType eOption); + +/** + * @brief Disable MPU + * + */ +void MPU_Disable(void); + +/** + * @brief Disable region + * + * @param eRegion Region index + * @return MPU_StatusType MPU_STATUS_SUCCESS when disable successfully, others fail + */ +MPU_StatusType MPU_RegionDisable(MPU_RegionNumberType eRegion); + +/** + * @brief Enable region + * + * @param eRegion Region index + * @param pConfig Region Configuration Parameter + * @return MPU_StatusType MPU_STATUS_SUCCESS when disable successfully, others fail + */ +MPU_StatusType MPU_RegionEnable(MPU_RegionNumberType eRegion, const MPU_RegionConfigurationType *pConfig); + + +/** @} */ /* fc7xxx_driver_mpu */ +#if defined(__cplusplus) +} +#endif +#endif /* _DRIVER_FC7XXX_DRIVER_MPU_H_ */ diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_msc.h b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_msc.h new file mode 100644 index 0000000..cc96c5d --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_msc.h @@ -0,0 +1,402 @@ +/** + * @file fc7xxx_driver_msc.h + * @author Flagchip + * @brief FC7240 MSC driver type definition and API + * @version 0.1.0 + * @date 2024-01-10 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-01-10 Flagchip084 N/A FC7240 release version + ******************************************************************************** */ + +#ifndef _DRIVER_FC7XXX_DRIVER_MSC_H_ +#define _DRIVER_FC7XXX_DRIVER_MSC_H_ +#include "device_header.h" +#include "HwA_msc.h" +/** + * @addtogroup fc7xxx_driver_msc + * @{ +. */ + +typedef enum +{ + MSC_RETURN_OK = 0x00U, /*!< The SENT operation is succeeded */ + MSC_RETURN_E_NOT_OK = 0x01U, /*!< The SENT operation is failed */ + MSC_RETURN_E_PARAM = 0x04U, /*!< The SENT parameter is incorrect or out of range. */ +} MSC_ReturnType; + +typedef enum +{ + MSC_RDR0 = 0x0U, + MSC_RDR1 = 0x1U, + MSC_RDR2 = 0x2U, + MSC_RDR3 = 0x3U, + MSC_RDRx_COUNT = 0x4U +} MSC_RDRxIndexType; + +typedef enum +{ + MSC_INSTANCE_0 = 0U, /*!< MSC instance 0 is selected. */ + MSC_INSTANCE_1 = 1U /*!< MSC instance 1 is selected. */ +} MSC_InstanceType; + +typedef enum +{ + MSC_RFIE_DISABLE = 0x0U, /*!< Interrupt generation disabled. */ + MSC_RFIE_MODE1 = 0x1U, /*!< The interrupt is generated when data is received and written into the RDRx. */ + MSC_RFIE_MODE2 = 0x2U, /*!< The interrupt is generated when received data is not equal to 0. */ + MSC_RFIE_MODE3 = 0x3U /*!< The interrupt is generated when data is received and written into register RDR3. */ +} MSC_RFIEModeType; + +typedef enum +{ + MSC_DFIE_DISABLE = 0x0U, /*!< Disable. */ + MSC_DFIE_MODE1 = 0x1U, /*!< Interrupt is generated when the last data bit has been shifted. */ + MSC_DFIE_MODE2 = 0x2U /*!< Interrupt is generated when the first data bit has been shifted. */ +} MSC_DFIEModeType; + +/** + * @brief MSC Channel ISR callback function prototype + * + */ +typedef void (*MSC_ISRCallbackType)(const MSC_InstanceType eInstance); + +/** @brief MSC interrupt configure structure. */ +typedef struct +{ + bool bCFIntEnable; /*!< MSC_INCR[CFIE] bit, interrupt enable, if this bit asserted, command frame can lead the interrupt. */ + bool bTFIntEnable; /*!< MSC_INCR[TFIE] bit, interrupt enable, if this bit asserted, time frame can lead the interrupt. */ + MSC_RFIEModeType eRFIEMode; /*!< Interrupt mode of RFIE. */ + MSC_DFIEModeType eDFIEMode; /*!< Interrupt mode of DFIE. */ + bool bTOIntEnable; /*!< Enable the interrupt of timeout. */ + uint16_t u16TimeoutValue; /*!< Timeout value of timeout interrupt. */ + MSC_ISRCallbackType pReceiveFrameISRCallback; /*!< Receive frame ISR callback. */ + MSC_ISRCallbackType pTimeFrameISRCallback; /*!< Time Frame ISR callback. */ + MSC_ISRCallbackType pCommandFrameISRCallback; /*!< Command Frame ISR callback. */ + MSC_ISRCallbackType pDataFrameISRCallback; /*!< Data Frame ISR callback. */ + MSC_ISRCallbackType pReceiveTimeOutISRCallback; /*!< Data Frame ISR callback. */ +} MSC_InterruptCfgType; + +typedef enum +{ + MSC_SDI_SEL_SDI0 = 0x0U, /*!< SDI0 input is selected for SDI. */ + MSC_SDI_SEL_SDI1 = 0x1U, /*!< SDI1 input is selected for SDI. */ + MSC_SDI_SEL_SDI2 = 0x2U, /*!< SDI2 input is selected for SDI. */ + MSC_SDI_SEL_SDI3 = 0x3U, /*!< SDI3 input is selected for SDI. */ + MSC_SDI_SEL_SDI4 = 0x4U, /*!< SDI4 input is selected for SDI. */ + MSC_SDI_SEL_SDI5 = 0x5U, /*!< SDI5 input is selected for SDI. */ + MSC_SDI_SEL_SDI6 = 0x6U, /*!< SDI6 input is selected for SDI. */ + MSC_SDI_SEL_SDI7 = 0x7U /*!< SDI7 input is selected for SDI. */ +} MSC_SDISelectionType; + +typedef enum +{ + MSC_ENC_SEL_EN0 = 0x0U, /*!< EN0 is selected for ENC. */ + MSC_ENC_SEL_EN1 = 0x1U, /*!< EN1 is selected for ENC. */ + MSC_ENC_SEL_EN2 = 0x2U, /*!< EN2 is selected for ENC. */ + MSC_ENC_SEL_EN3 = 0x3U /*!< EN3 is selected for ENC. */ +} MSC_ENCSelectionType; + +typedef enum +{ + MSC_ENH_SEL_EN0 = 0x0U, /*!< EN0 is selected for ENH. */ + MSC_ENH_SEL_EN1 = 0x1U, /*!< EN1 is selected for ENH. */ + MSC_ENH_SEL_EN2 = 0x2U, /*!< EN2 is selected for ENH. */ + MSC_ENH_SEL_EN3 = 0x3U /*!< EN3 is selected for ENH. */ +} MSC_ENHSelectionType; + +typedef enum +{ + MSC_ENL_SEL_EN0 = 0x0U, /*!< EN0 is selected for ENL. */ + MSC_ENL_SEL_EN1 = 0x1U, /*!< EN1 is selected for ENL. */ + MSC_ENL_SEL_EN2 = 0x2U, /*!< EN2 is selected for ENL. */ + MSC_ENL_SEL_EN3 = 0x3U /*!< EN3 is selected for ENL. */ +} MSC_ENLSelectionType; + +typedef enum +{ + MSC_EN_SELECTION_0 = 0x00, /*!< EN0 is selected for ENX. */ + MSC_EN_SELECTION_1 = 0x01, /*!< EN1 is selected for ENX. */ + MSC_EN_SELECTION_2 = 0x02, /*!< EN2 is selected for ENX. */ + MSC_EN_SELECTION_3 = 0x03, /*!< EN3 is selected for ENX. */ +} Msc_ENxActiveType; + +typedef enum +{ + MSC_ENC = 0x00, + MSC_ENL = 0x01, + MSC_ENH = 0x02, +} Msc_ENxType; + +typedef enum +{ + MSC_FLC_ACTIVE_ON_FRAMES = 0x0U, /*!< FCL is actived only during the active phases of frames. */ + MSC_FLC_ALWAYS_ACTIVE = 0x1U /*!< FCL is always active whether or not a downstream frame is transmitted currently.. */ +} MSC_FCLControlType; + +typedef enum +{ + MSC_INPUT_IDENTICAL = 0x0U, /*!< SDI and SI signal polarities are identical. */ + MSC_INPUT_INVERTED = 0x1U /*!< SDI and SI signal polarities are inverted. */ +} MSC_InputPolarityType; + +typedef enum +{ + MSC_ENX_IDENTICAL = 0x0U, /*!< Enx and ENL, ENH, ENC signal polarities are identical (high active). */ + MSC_ENX_INVERTED = 0x1U /*!< ENx and ENL, ENH, ENC signal polarities are inverted (low active). */ +} MSC_ENxPolarityType; + +typedef enum +{ + MSC_SO_IDENTICAL = 0x0U, /*!< SOP and SO signal polarity is identical. */ + MSC_SO_INVERTED = 0x1U /*!< SOP and SO signal polarity is inverted. */ +} MSC_SOPolarityType; + +typedef enum +{ + MSC_FLC_IDENTICAL = 0x0U, /*!< FCLP and FCL polarity is identical. */ + MSC_FLC_INVERTED = 0x1U /*!< FCLP and FCL polarity is inverted. */ +} MSC_FCLpolarityType; + +typedef struct +{ + MSC_SDISelectionType eSDIsel; /*!< SDI seletion. */ + MSC_ENCSelectionType eENCSel; /*!< ENC seletion. */ + MSC_ENHSelectionType eENHSel; /*!< ENH seletion. */ + MSC_ENLSelectionType eENLSel; /*!< ENL seletion. */ + MSC_FCLControlType eFclCtrl; /*!< FCL Control. */ + MSC_InputPolarityType eSDIPol; /*!< SDI Polarity. */ + MSC_ENxPolarityType eENXPol; /*!< ENX Polarity. */ + MSC_SOPolarityType eSOPPol; /*!< SO Polarity. */ + MSC_FCLpolarityType eFCLPPol; /*!< FCL Polarity. */ +} MSC_IOControlInitType; + +typedef enum +{ + MSC_TRANS_SOURCE_DATA_REG = 0x0U, /*!< SSL[x] is taken from TCDAR.DL[x]. */ + MSC_TRANS_SOURCE_ALTIN = 0x2U, /*!< SSL[x] is taken from the ALTINL input line x. */ + MSC_TRANS_SOURCE_ALTIN_INV = 0x3U, /*!< SSL[x] is taken from the ALTINL input line x in inverted state. */ +} MSC_TransSourceType; + +typedef enum +{ + MSC_TRIGGER_MODE = 0x00U, /*!< Trigger work mode. */ + MSC_REPETITION_MODE = 0x01U /*!< Repetition work mode. */ +} MSC_WorkModeType; + +typedef enum +{ + MSC_EVEN_PARITY = 0x00U, /*!< Reception even parity. */ + MSC_ODD_PARITY = 0x01U /*!< Reception odd parity. */ +} MSC_ParityType; + +typedef enum +{ + MSC_RECEIVE_DISABLED = 0x00U, /*!< Receiving channel is disabled. */ + MSC_BAUDRATE_FMSC_DIV4 = 0x01U, /*!< Baud rate=fmsc/4. */ + MSC_BAUDRATE_FMSC_DIV8 = 0x02U, /*!< Baud rate=fmsc/8. */ + MSC_BAUDRATE_FMSC_DIV16 = 0x03U, /*!< Baud rate=fmsc/16. */ + MSC_BAUDRATE_FMSC_DIV32 = 0x04U, /*!< Baud rate=fmsc/32. */ + MSC_BAUDRATE_FMSC_DIV64 = 0x05U, /*!< Baud rate=fmsc/64. */ + MSC_BAUDRATE_FMSC_DIV128 = 0x06U, /*!< Baud rate=fmsc/128. */ + MSC_BAUDRATE_FMSC_DIV256 = 0x07U /*!< Baud rate=fmsc/256. */ +} MSC_ReceiveBaudRateType; + +typedef enum +{ + MSC_FRAME_12_BIT = 0x00U, /*!< 12-bit frame selected. */ + MSC_FRAME_16_BIT = 0x01U /*!< 16-bit frame selected. */ +} MSC_ReceiveFrameType; + +typedef struct +{ + uint8_t u8PassiveLength; /*!< Frame Passive length. */ + uint8_t u8PTFNumber; /*!< The number of passive time frames that are inserted in repetition mode between two data frames. */ + MSC_WorkModeType eWorkMode; /*!< MSC work mode. */ + uint8_t u8CommandBitLength; /*!< Bit length of command frame. */ + bool bSelSRH; /*!< Select SRH. */ + uint8_t u8SRHDataBitLength; /*!< Bit length of SRH. */ + bool bSelSRL; /*!< Select SRL. */ + uint8_t u8SRLDataBitLength; /*!< Bit length of SRL. */ + bool bDelayControl; /*!< Hardware Receive Interrupt Delay Control. */ + MSC_ParityType eParity; /*!< Parity mode. */ + MSC_ReceiveBaudRateType eBaudRate; /*!< Baudrate. */ + MSC_ReceiveFrameType eRsvFrameType; /*!< Frame type. */ +} MSC_InitCfgType; + +/** + * @brief Init the MSC. + * + * @param eInstance MSCInstance. + * @param pInitConfig MSCInstance initial configuration. + */ +MSC_ReturnType MSC_init(const MSC_InstanceType eInstance, const MSC_InitCfgType *pInitConfig); + +/** + * @brief Init the MSC interrupt. + * + * @param eInstance MSCInstance. + * @param pInteruptConfig MSCInstance interrupt configuration. + */ +void MSC_initInterrupt(const MSC_InstanceType eInstance, const MSC_InterruptCfgType *pInteruptConfig); + +/** + * @brief Select the transmitting sources. + * + * @param eInstance MSCInstance. + * @param u32SourceMask Transmitting sources. + * @param eSourceType Transmitting sources type. + */ +void MSC_SelTranmittingSource(const MSC_InstanceType eInstance, uint32_t u32SourceMask, MSC_TransSourceType eSourceType); + +/** + * @brief Set Emergency load value. + * + * @param eInstance MSCInstance. + * @param u32Value Emergency load value. + */ +void MSC_SetEmergencyLoad(const MSC_InstanceType eInstance, uint32_t u32Value); + +/** + * @brief Configure the MSC IO control. + * + * @param eInstance MSCInstance. + * @param pIOConfig MSC IO control configuration. + */ +void MSC_SetIOControl(const MSC_InstanceType eInstance, const MSC_IOControlInitType *pIOConfig); + +/** + * @brief Enable MSC. + * + * @param eInstance MSCInstance. + */ +void MSC_Enable(const MSC_InstanceType eInstance); + +/** + * @brief Disable MSC. + * + * @param eInstance MSCInstance. + */ +void MSC_Disable(const MSC_InstanceType eInstance); + +/** + * @brief MSC set data frame. + * + * @param eInstance MSCInstance. + * @param u32Data Data to be sent. + */ +void MSC_SetDataFrame(const MSC_InstanceType eInstance, uint32_t u32Data); + +/** + * @brief MSC send data frame. + * + * @param eInstance MSCInstance. + */ +void MSC_SendDataFrame(const MSC_InstanceType eInstance); + +/** + * @brief MSC send command frame. + * + * @param eInstance MSCInstance. + * @param u32Command command to be sent. + */ +void MSC_SendCommandFrame(const MSC_InstanceType eInstance, uint32_t u32Command); + +/** + * @brief Get the msc received data address. + * + * @param eInstance MSCInstance. + * @param eIndex Receive data register index. + * @return uint8_t Receiverd data address. + */ +uint8_t MSC_GetReceivedFrameAddr(const MSC_InstanceType eInstance, MSC_RDRxIndexType eIndex); + +/** + * @brief Get the msc received data. + * + * @param eInstance MSCInstance. + * @param eIndex Receive data register index. + * @param pData Received data value. + * @return MSC_ReceiveStatusType Status of getting received data. + */ +MSC_ReceiveStatusType MSC_GetReceivedFrame(const MSC_InstanceType eInstance, MSC_RDRxIndexType eIndex, uint8_t *pData); + +/** + * @brief Get the msc interrupt status. + * + * @param eInstance MSCInstance. + * @return uint32_t Interrupt status. + */ +uint32_t MSC_GetInterruptStatus(const MSC_InstanceType eInstance); + +/** + * @brief Get the msc interrupt status. + * + * @param eInstance MSCInstance. + * @param bEnable Enable transmit channel. + */ +void MSC_EnableTrasmit(const MSC_InstanceType eInstance, bool bEnable); + +/** + * @brief Enable the msc data frame interrupt. + * + * @param eInstance MSCInstance. + */ +void MSC_EnableDataFrameInterrupt(const MSC_InstanceType eInstance, bool bEnable); + +/** + * @brief Enable the msc command frame interrupt. + * + * @param eInstance MSCInstance. + */ +void MSC_EnableCommandFrameInterrupt(const MSC_InstanceType eInstance, bool bEnable); + +/** + * @brief Enable the msc time frame interrupt. + * + * @param eInstance MSCInstance. + */ +void MSC_EnableTimeFrameInterrupt(const MSC_InstanceType eInstance, bool bEnable); + +/** + * @brief Enable the msc receive interrupt. + * + * @param eInstance MSCInstance. + */ +void MSC_EnableReceiveInterrupt(const MSC_InstanceType eInstance, bool bEnable); + +/** + * @brief Enable the msc timeout interrupt. + * + * @param eInstance MSCInstance. + */ +void MSC_EnableTimeoutInterrupt(const MSC_InstanceType eInstance, bool bEnable); + +/** + * @brief Switch ENC/ENH/ENL active EN selection. + * @param eInstance MSCInstance. + * @param eEnx ENC/ENH/ENL. + * @param eENn ENX selection. + * @param u32TimeoutLoops Wait timeout if transmission is busy. + * @return + */ +MSC_ReturnType Msc_SwitchENXChannel(const MSC_InstanceType eInstance, Msc_ENxType eEnx, Msc_ENxActiveType eENn, uint32_t u32TimeoutLoops); + +/** + * @brief Switch the SDI Channel. + * @param eInstance MSCInstance. + * @param eSDIChannel SDI channel. + * @param u32TimeoutLoops Wait timeout if receiving is busy. + * @return + */ +MSC_ReturnType Msc_SwitchSDIChannel(const MSC_InstanceType eInstance, MSC_SDISelectionType eSDIChannel, uint32_t u32TimeoutLoops); + +/** @}*/ /* fc7xxx_driver_msc. */ +#endif diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_overlay.h b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_overlay.h new file mode 100644 index 0000000..d6921f6 --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_overlay.h @@ -0,0 +1,172 @@ +/** + * @file fc7xxx_driver_overlay.h + * @author Flagchip + * @brief FC7xxx overlay driver type definition and API + * @version 0.1.0 + * @date 2023-12-25 + * + * @copyright Copyright (c) 2023 Flagchip Semiconductors Co., Ltd. + * + */ + +/******************************************************************************** +* Revision History: +* +* Version Date Initials CR# Descriptions +* --------- ---------- ------------ ---------- --------------- +* 0.1.0 2023-12-25 Flagchip0038 N/A First version for FC7240 +********************************************************************************/ + +#ifndef _DRIVER_FC7XXX_DRIVER_OVERLAY_H_ +#define _DRIVER_FC7XXX_DRIVER_OVERLAY_H_ +#include "HwA_overlay.h" + +/** + * @addtogroup fc7xxx_driver_overlay + * @{ + */ + + +/** + * @brief Overlay Error Information + * + */ +typedef enum +{ + OVERLAY_ERROR_OK, /**< no error */ + OVERLAY_ERROR_ADDR, /**< error address */ + OVERLAY_ERROR_SIZE, /**< error size */ + OVERLAY_ERROR_FLAG, /**< error flag */ +} OVERLAY_ErrorType; + + +/** + * @brief Overlay Region parameters + * + */ +typedef struct +{ + uint32_t aOverlayRegionEn[OVERLYA_REGION_CNT]; /**< Overlay region enable array */ + uint32_t aOverlayRegionSrc[OVERLYA_REGION_CNT]; /**< Overlay region source array, pflash */ + uint32_t aOverlayRegionDst[OVERLYA_REGION_CNT]; /**< Overlay region destination array, sram */ + OVERLAY_OverlaySizeType aOverlayRegionSize[OVERLYA_REGION_CNT]; /**< Overlay region size array */ +}OVERLAY_OverlayRegionInitType; + +/** + * @brief FAR parameter + * + */ +typedef struct +{ + uint32_t u32FAREn; /**< Overlay region enable array */ + uint32_t u32FARDst; /**< Overlay region destination array, pflash, source always is 0x08000000 */ + uint32_t u32FARSize; /**< Overlay region size array, must align to 64KB */ +}OVERLAY_FARInitType; + + +/** + * @brief Error Info + * + */ +typedef struct +{ + uint8_t bError_FAR_SIZE_INTR; /**< bit 17, The FAR of size value is invalid */ + uint8_t bError_FAR_DST_OVERFLOW_INTR; /**< bit 16, FAR of destination region is overflow with size */ + uint8_t bError_FAR_DST_NO_FLASH_INTR; /**< bit 15, FAR of destination address is not flash */ + uint8_t bError_REGION2_D_CROS_INTR; /**< bit 14, The range of region 2 destination address is crossed with other region */ + uint8_t bError_REGION2_S_CROS_INTR; /**< bit 13, The range of region 2 source address is crossed with other region */ + uint8_t bError_REGION2_SIZE_INTR; /**< bit 12, The region 2 of size value is invalid */ + uint8_t bError_REGION2_DST_INTR; /**< bit 11, The region 2 of destination address is not aligned with size */ + uint8_t bError_REGION2_SRC_INTR; /**< bit 10, The region 2 of source address is not aligned with size */ + uint8_t bError_REGION1_D_CROS_INTR; /**< bit 9, The range of region 1 destination address is crossed with other region */ + uint8_t bError_REGION1_S_CROS_INTR; /**< bit 8, The range of region 1 source address is crossed with other region */ + uint8_t bError_REGION1_SIZE_INTR; /**< bit 7, The region 1 of size value is invalid */ + uint8_t bError_REGION1_DST_INTR; /**< bit 6, The region 1 of destination address is not aligned with size */ + uint8_t bError_REGION1_SRC_INTR; /**< bit 5, The region 1 of source address is not aligned with size */ + uint8_t bError_REGION0_D_CROS_INTR; /**< bit 4, The range of region 0 destination address is crossed with other region */ + uint8_t bError_REGION0_S_CROS_INTR; /**< bit 3, The range of region 0 source address is crossed with other region */ + uint8_t bError_REGION0_SIZE_INTR; /**< bit 2, The region 0 of size value is invalid */ + uint8_t bError_REGION0_DST_INTR; /**< bit 1, The region 0 of destination address is not aligned with size */ + uint8_t bError_REGION0_SRC_INTR; /**< bit 0, The region 0 of source address is not aligned with size */ +}OVERLAY_ErrorInfoType; + + +/** Overlay Setting Error callback type */ +typedef void (*OVERLAY_ErrorCallback_Type)(OVERLAY_ErrorInfoType u16ErrorFlag); + + +/** + * @brief Interrupt Parameter + * + */ +typedef struct +{ + uint32_t bEnableInterrupt; /**< Enable interrupt, 0 is disable, 1 is enable */ + OVERLAY_ErrorCallback_Type pCallBack; /**< Callback function for error interrupt */ +}OVERLAY_InterruptType; + + +/** + * @brief Overlay region initial function + * + * @param pOverlayInitCfg initial parameters + * @return ERROR_OK is ok, others are not ok + */ +OVERLAY_ErrorType OVERLAY_RegionInit(OVERLAY_OverlayRegionInitType *pOverlayInitCfg); + +/** + * @brief De-Init Overlay Region + * + * @return ERROR_OK is ok, others are not ok + */ +OVERLAY_ErrorType OVERLAY_RegionDeInit(void); + +/** + * @brief Far initial function + * + * @param pFarInitCfg initial parameters + * @return ERROR_OK is ok, others are not ok + */ +OVERLAY_ErrorType OVERLAY_FARInit(OVERLAY_FARInitType *pFarInitCfg); + +/** + * @brief De-Init FAR Region + * + * @return ERROR_OK is ok, others are not ok + */ +OVERLAY_ErrorType OVERLAY_FARDeInit(void); + +/** + * @brief Enable or Disable Interrupt + * + * @param pInterruptCfg interrupt config parameter + */ +void OVERLAY_SetInterrupt(OVERLAY_InterruptType *pInterruptCfg); + +/** + * @brief Get Error Info + * + * @param pErrorInfo error info point + */ +void OVERLAY_GetErrorInfo(OVERLAY_ErrorInfoType *pErrorInfo); + +/** + * @brief Clear Error Info + * + * @param pErrorInfo error info point + */ +void OVERLAY_ClrErrorInfo(OVERLAY_ErrorInfoType *pErrorInfo); + +/** + * @brief Call Me in Overlay Error interrupt handler + * + */ +void OVERLAY_ErrorInterruptRoutine(void); + + +/** @}*/ /* fc7xxx_driver_overlay */ + + +#endif + + diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_pcc.h b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_pcc.h new file mode 100644 index 0000000..40aaf5f --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_pcc.h @@ -0,0 +1,157 @@ +/** + * @file fc7xxx_driver_pcc.h + * @author Flagchip085 + * @brief FC7xxx PCC driver type definition and API + * @version 0.1.0 + * @date 2024-01-12 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-01-12 Flagchip085 N/A First version for FC7240 + ******************************************************************************** */ +#ifndef _DRIVER_FC7XXX_DRIVER_PCC_H_ +#define _DRIVER_FC7XXX_DRIVER_PCC_H_ +#include "HwA_pcc.h" +/** + * @addtogroup fc7xxx_driver_pcc + * @{ + */ + + +#define PCC_MUX_MAX_NUMBER 8U + +/** @brief PCC clock list */ +typedef enum +{ + PCC_CLK_DMA0 = 0U, + PCC_CLK_DMAMUX0, + PCC_CLK_ROMC, + PCC_CLK_ERM0, + PCC_CLK_EIM0, + PCC_CLK_INTM0, + PCC_CLK_ISM0, + PCC_CLK_WDOG0, + PCC_CLK_TRGSEL0, + PCC_CLK_TRGSEL1, + PCC_CLK_TRGSEL2, + PCC_CLK_TRGSEL3, + PCC_CLK_CRC0, + PCC_CLK_CORDIC, + PCC_CLK_TSTMP0, + PCC_CLK_TSTMP1, + PCC_CLK_FCPIT0, + PCC_CLK_AONTIMER0, + PCC_CLK_RTC, + PCC_CLK_CMU0, + PCC_CLK_CMU1, + PCC_CLK_CMU2, + PCC_CLK_CMU3, + PCC_CLK_CMU4, + PCC_CLK_PTIMER0, + PCC_CLK_PTIMER1, + PCC_CLK_ADC0, + PCC_CLK_ADC1, + PCC_CLK_WKU0, + PCC_CLK_CMP0, + PCC_CLK_CMP1, + PCC_CLK_TMU0, + PCC_CLK_SENT0, + PCC_CLK_MB0, + PCC_CLK_FTU0, + PCC_CLK_FTU1, + PCC_CLK_FTU2, + PCC_CLK_FTU3, + PCC_CLK_FCSPI0, + PCC_CLK_FCSPI1, + PCC_CLK_FCSPI2, + PCC_CLK_FCIIC0, + PCC_CLK_FCUART0, + PCC_CLK_FCUART1, + PCC_CLK_FCUART2, + PCC_CLK_FCUART3, + PCC_CLK_LU0, + PCC_CLK_FREQM, + PCC_CLK_STCU, + PCC_CLK_FLEXCAN0, + PCC_CLK_FLEXCAN1, + PCC_CLK_WDOG1, + PCC_CLK_TRGSEL4, + PCC_CLK_TRGSEL5, + PCC_CLK_FCSPI3, + PCC_CLK_FCSPI4, + PCC_CLK_FCSPI5, + PCC_CLK_FTU4, + PCC_CLK_FTU5, + PCC_CLK_FTU6, + PCC_CLK_FTU7, + PCC_CLK_FCIIC1, + PCC_CLK_FCUART4, + PCC_CLK_FCUART5, + PCC_CLK_FCUART6, + PCC_CLK_FCUART7, + PCC_CLK_MSC0, + PCC_CLK_FLEXCAN2, + PCC_CLK_FLEXCAN3, + PCC_END_OF_CLOCKS +} PCC_ClkSrcType; + +/** + * @brief Pcc clock status +*/ +typedef enum +{ + PCC_STATUS_SUCCESS = 0U, + PCC_STATUS_CLOCK_INVALID = 1U, + PCC_STATUS_CONFIGURED_NOT_SUPPORT = 1U, +} PCC_StatusType; + +/** + * @brief define the PCC module initialization structure. + */ +typedef struct +{ + PCC_ClkSrcType eClockName; /*!< Peripheral clock */ + bool bEn; /*!< Peripheral clock enable or disable */ + PCC_ClkGateSrcType eClkSrc; /*!< Peripheral function clock source select */ + PCC_ClkDivType eDivider; /*!< Peripheral clock divider value */ +} PCC_CtrlType; + +/** + * @brief get PCC function clock status and value. + * + * @param pcc_ClkSrcType eClockName: used for choose PCC clock source to query. + * @return uint32_t Pcc function clock frequency, if PCC is not enable or do not have clock mux configuration, + * the function will return 0 + */ +uint32_t PCC_GetPccFunctionClock(const PCC_ClkSrcType eClockName); + +/** + * @brief get PCC interface clock status and value. + * + * @param pcc_ClkSrcType eClockName: used for choose PCC clock source to query. + */ +uint32_t PCC_GetPccInterfaceClock(const PCC_ClkSrcType eClockName); + +/** + * @brief set PCC one peripheral clock configuration. + * + * @param PCC_CtrlType* pConfig: the PCC initialize value point set by user. + * @return PCC_StatusType pcc function status + */ +PCC_StatusType PCC_SetPcc(const PCC_CtrlType *const pConfig); + +/** + * @brief Generate peripheral reset + * + */ +void PCC_GenPeripheralReset(const PCC_ClkSrcType eClockName); + + +/** @}*/ /* fc7xxx_driver_pcc */ +#endif diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_pmc.h b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_pmc.h new file mode 100644 index 0000000..57542e8 --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_pmc.h @@ -0,0 +1,181 @@ +/* @file fc7xxx_driver_pmc.h +* @author Flagchip032 +* @brief FC7xxx PMC driver type definition and API +* @version 0.1.0 +* @date 2022-11-21 +* +* @copyright Copyright (c) 2022 Flagchip Semiconductors Co., Ltd. +* +*/ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials Descriptions + * --------- ---------- ------------ --------------- + * 0.1.0 2022-11-21 Flagchip032 First version for FC7xxx + ******************************************************************************** */ +#ifndef _DRIVER_FC7XXX_DRIVER_PMC_H_ +#define _DRIVER_FC7XXX_DRIVER_PMC_H_ +#include "HwA_pmc.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +/** + * @addtogroup fc7xxx_driver_pmc + * @{ + */ + +/***************** typedef *********************/ +/** + * @brief PMC voltage flags. + * + */ +typedef enum +{ + PMC_HVD5V_FLAG = PMC_LVSCR_HVD5V_FLAG_MASK, /**< interrupt flag on V5 domain in FPM */ + PMC_HVD2P5V_FLAG = PMC_LVSCR_HVD2P5V_FLAG_MASK, /**< interrupt flag on V25 domain in FPM */ + PMC_HVD1P1V_FLAG = PMC_LVSCR_HVD1P1V_FLAG_MASK, /**< interrupt flag on V11 domain in FPM */ + PMC_LVD5V_FLAG = PMC_LVSCR_LVD5V_FLAG_MASK, /**< interrupt flag on V5 domain in FPM */ + PMC_LVD1P5V_FLAG = PMC_LVSCR_LVD1P5V_FLAG_MASK, /**< interrupt flag on V15 domain in FPM */ + PMC_HVD1P5V_FLAG = PMC_LVSCR_HVD1P5V_FLAG_MASK, /**< interrupt flag on V15 domain in FPM */ + PMC_LVR5V_FPM_FLAG = PMC_LVSCR_LVR5V_FPM_FLAG_MASK, /**< Low voltage reset flag of V5 domain in FPM */ + PMC_LVR5V_RPM_FLAG = PMC_LVSCR_LVR5V_RPM_FLAG_MASK, /**< Low voltage reset flag of V5 domain in RPM */ + PMC_LVR2P5V_FPM_FLAG = PMC_LVSCR_LVR2P5V_FPM_FLAG_MASK, /**< Low voltage reset flag of V25 domain in FPM */ + PMC_LVR2P5V_RPM_FLAG = PMC_LVSCR_LVR2P5V_RPM_FLAG_MASK, /**< Low voltage reset flag of V25 domain in RPM */ + PMC_LVR1P1V_FPM_FLAG = PMC_LVSCR_LVR1P1V_FPM_FLAG_MASK, /**< Low voltage reset flag of V11 domain in FPM */ + PMC_LVR1P1V_RPM_FLAG = PMC_LVSCR_LVR1P1V_RPM_FLAG_MASK, /**< Low voltage reset flag of V11 domain in RPM */ + PMC_POR_FLAG = PMC_LVSCR_POR_FLAG_MASK /**< POR flag */ +} PMC_FlagType; + +/** + * @brief PMC voltage status. + * + */ +typedef enum +{ + PMC_HVD5V_STATUS = PMC_LVSCR_HVD5V_STATUS_MASK, /**< HVD5V status on V5 domain in FPM */ + PMC_HVD2P5V_STATUS = PMC_LVSCR_HVD2P5V_STATUS_MASK, /**< HVD25 status on V25 domain in FPM */ + PMC_HVD1P1V_STATUS = PMC_LVSCR_HVD1P1V_STATUS_MASK, /**< HVD11 status on V11 domain in FPM */ + PMC_LVD5V_STATUS = PMC_LVSCR_LVD5V_STATUS_MASK, /**< LVD5V status on V5 domain in FPM */ + PMC_LVD1P5V_STATUS = PMC_LVSCR_LVD1P5V_STATUS_MASK, /**< LVD1P5V status on V15 domain in FPM */ + PMC_HVD1P5V_STATUS = PMC_LVSCR_HVD1P5V_STATUS_MASK, /**< HVD1P5V status on V15 domain in FPM */ + PMC_V15_LDO_STATUS = PMC_LVSCR_V15_STATUS(0U), /**< V15 is working on internal V15 LDO */ + PMC_V15_ON_BOARD_NPN_STATUS = PMC_LVSCR_V15_STATUS(1U), /**< V15 is working on internal V15 controller with on board NPN */ + PMC_V15_DRIVEN_BY_EXTERNAL_STATUS = PMC_LVSCR_V15_STATUS(2U) /**< V15 is driven by external driver such as on board DCDC, V15_CFG PAD is driven high */ +} PMC_StatusType; + +typedef void (*PMC_VolIntCallbackType)(void); + +/** @brief Pmc control type */ +typedef struct +{ + boolean bLvdIntEn; /**< bit9, low voltage detect interrupt enable */ + boolean bHvdIntEn; /**< bit8, high voltage detect interrupt enable */ + boolean b5VBMonEn; /**< bit6, VDD5V_B LVR monitor enable during RPM */ + boolean bV15CtrlEn; /**< bit5, V15 controller with on board NPN enable */ + boolean bV15AutoswEn; /**< bit4, V15 auto switch enable */ + boolean bRpmV25En; /**< bit3, V25 domain enable during RPM */ + PMC_VolIntCallbackType pIsrNotify; /**< interrupt notification */ +} PMC_CtrlType; + +/***************** macro *********************/ +/**< All flags of LVCSR MSASK */ +#define PMC_LVCSR_ALLFLAG_MASK (uint32_t)(PMC_LVSCR_HVD5V_FLAG_MASK|\ + PMC_LVSCR_HVD2P5V_FLAG_MASK|\ + PMC_LVSCR_HVD1P1V_FLAG_MASK|\ + PMC_LVSCR_LVD5V_FLAG_MASK|\ + PMC_LVSCR_LVD1P5V_FLAG_MASK|\ + PMC_LVSCR_HVD1P5V_FLAG_MASK|\ + PMC_LVSCR_LVR5V_FPM_FLAG_MASK|\ + PMC_LVSCR_LVR5V_RPM_FLAG_MASK|\ + PMC_LVSCR_LVR2P5V_FPM_FLAG_MASK|\ + PMC_LVSCR_LVR2P5V_RPM_FLAG_MASK|\ + PMC_LVSCR_LVR1P1V_FPM_FLAG_MASK|\ + PMC_LVSCR_LVR1P1V_RPM_FLAG_MASK|\ + PMC_LVSCR_POR_FLAG_MASK) + +#define PMC_LVCSR_ALLSTATUS_MASK (uint32_t)(PMC_LVSCR_HVD5V_STATUS_MASK|\ + PMC_LVSCR_HVD2P5V_STATUS_MASK|\ + PMC_LVSCR_HVD1P1V_STATUS_MASK|\ + PMC_LVSCR_LVD5V_STATUS_MASK|\ + PMC_LVSCR_LVD1P5V_STATUS_MASK|\ + PMC_LVSCR_HVD1P5V_STATUS_MASK|\ + PMC_LVSCR_V15_STATUS_MASK) + + + + + + +/***************** API *********************/ +/** + * @brief Get LVCSRRegister Value + * + * @return uint32_t LVCSRRegister Value + */ +uint32_t PMC_GetLVCSRRegister(void); +/** + * @brief Get All voltage flag + * + * @return uint32_t All voltage flag + */ +uint32_t PMC_GetAllVolFlag(void); + +/** + * @brief Get specific voltage flag + * + * @param eFlag Voltage flag + * @return boolean If return true, the specific voltage flag is 0, otherwise, the flag is 1. + */ +boolean PMC_GetSpecificVolFlag(const PMC_FlagType eFlag); + +/** + * @brief Clear all voltage flag + * + */ +void PMC_ClearAllVolFlag(void); + +/** + * @brief Clear specific voltage flag + * + * @param eFlag Voltage flag + */ +void PMC_ClearSpecificVolFlag(const PMC_FlagType eFlag); + +/** + * @brief Get All voltage status + * + * @return uint32_t All voltage status + */ +uint32_t PMC_GetAllVolStatus(void); + +/** + * @brief Get specific voltage status + * + * @param eStatus Specific voltage status + * @return boolean If return true, the specific voltage status is 0, otherwise, the status is 1. + */ +boolean PMC_GetSpecificVolStatus(const PMC_StatusType eStatus); + +/** + * @brief Configure Voltage + * + * @param pCtrl Configuration of voltage + */ +void PMC_ConfigVoltage(const PMC_CtrlType *const pCtrl); + +/** + * @brief Clear all PMC register + * + */ +void PMC_Deinit(void); + + +#if defined(__cplusplus) +} +#endif +/** @}*/ /* fc7xxx_driver_pmc */ +#endif diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_port.h b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_port.h new file mode 100644 index 0000000..d384331 --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_port.h @@ -0,0 +1,239 @@ +/** + * @file fc7xxx_driver_port.h + * @author Flagchip + * @brief FC7xxx PORT driver type definition and API + * @version 0.1.0 + * @date 2023-2-14 + * + * @copyright Copyright (c) 2023 Flagchip Semiconductors Co., Ltd. + * + * @details + */ +/******************************************************************************** +* Revision History: +* +* Version Date Initials CR# Descriptions +* --------- ---------- ------------ ---------- --------------- +* 0.1.0 2022/12/31 Flagchip0121 N/A First version for FC7240 +********************************************************************************/ +#ifndef _DRIVER_FC7XXX_DRIVER_PORT_H_ +#define _DRIVER_FC7XXX_DRIVER_PORT_H_ +#include "HwA_port.h" +#include +/** + * @addtogroup fc7xxx_driver_port + * @{ + */ + +/********* global define ************/ +/** @brief Max number of Port */ +#define MAX_PORT_NUM 5U + +/** @brief Max number of Port Pin */ +#define PORT_PIN_NUM_MAX (uint32_t)(MAX_PORT_NUM*PORT_PCR_COUNT) + +/** @brief number of Port Pin */ +#define PORT_PIN_NUM(port,pin) (((uint32_t)(port) << 5U)+(uint32_t)(pin)) + +#define PORT_PIN_0 ((uint32_t)0x00000001) /**< PORT Pin 0 select */ +#define PORT_PIN_1 ((uint32_t)0x00000002) /**< PORT Pin 1 select */ +#define PORT_PIN_2 ((uint32_t)0x00000004) /**< PORT Pin 2 select */ +#define PORT_PIN_3 ((uint32_t)0x00000008) /**< PORT Pin 3 select */ +#define PORT_PIN_4 ((uint32_t)0x00000010) /**< PORT Pin 4 select */ +#define PORT_PIN_5 ((uint32_t)0x00000020) /**< PORT Pin 5 select */ +#define PORT_PIN_6 ((uint32_t)0x00000040) /**< PORT Pin 6 select */ +#define PORT_PIN_7 ((uint32_t)0x00000080) /**< PORT Pin 7 select */ +#define PORT_PIN_8 ((uint32_t)0x00000100) /**< PORT Pin 8 select */ +#define PORT_PIN_9 ((uint32_t)0x00000200) /**< PORT Pin 9 select */ +#define PORT_PIN_10 ((uint32_t)0x00000400) /**< PORT Pin 10 select */ +#define PORT_PIN_11 ((uint32_t)0x00000800) /**< PORT Pin 11 select */ +#define PORT_PIN_12 ((uint32_t)0x00001000) /**< PORT Pin 12 select */ +#define PORT_PIN_13 ((uint32_t)0x00002000) /**< PORT Pin 13 select */ +#define PORT_PIN_14 ((uint32_t)0x00004000) /**< PORT Pin 14 select */ +#define PORT_PIN_15 ((uint32_t)0x00008000) /**< PORT Pin 15 select */ +#define PORT_PIN_16 ((uint32_t)0x00010000) /**< PORT Pin 16 select */ +#define PORT_PIN_17 ((uint32_t)0x00020000) /**< PORT Pin 17 select */ +#define PORT_PIN_18 ((uint32_t)0x00040000) /**< PORT Pin 18 select */ +#define PORT_PIN_19 ((uint32_t)0x00080000) /**< PORT Pin 19 select */ +#define PORT_PIN_20 ((uint32_t)0x00100000) /**< PORT Pin 20 select */ +#define PORT_PIN_21 ((uint32_t)0x00200000) /**< PORT Pin 21 select */ +#define PORT_PIN_22 ((uint32_t)0x00400000) /**< PORT Pin 22 select */ +#define PORT_PIN_23 ((uint32_t)0x00800000) /**< PORT Pin 23 select */ +#define PORT_PIN_24 ((uint32_t)0x01000000) /**< PORT Pin 24 select */ +#define PORT_PIN_25 ((uint32_t)0x02000000) /**< PORT Pin 25 select */ +#define PORT_PIN_26 ((uint32_t)0x04000000) /**< PORT Pin 26 select */ +#define PORT_PIN_27 ((uint32_t)0x08000000) /**< PORT Pin 27 select */ +#define PORT_PIN_28 ((uint32_t)0x10000000) /**< PORT Pin 28 select */ +#define PORT_PIN_29 ((uint32_t)0x20000000) /**< PORT Pin 29 select */ +#define PORT_PIN_30 ((uint32_t)0x40000000) /**< PORT Pin 30 select */ +#define PORT_PIN_31 ((uint32_t)0x80000000) /**< PORT Pin 31 select */ + +#define PORT_DWP_CPU0_ALLOWED ((uint32_t)0x00000001) /**< Only CPU0 is allowed to write PCR and GPIO register corresponding to this pin. */ +#define PORT_DWP_DMA0_ALLOWED ((uint32_t)0x00000008) /**< Only DMA0 is allowed to write PCR and GPIO register corresponding to this pin. */ +#define PORT_DWP_FlexCore_ALLOWED ((uint32_t)0x00000010) /**< Only DMA1 is allowed to write PCR and GPIO register corresponding to this pin. */ + +/** @brief Port Alternate 0 Mode */ +#define PORT_ALT0_FUNC_MODE ((Port_PinModeType)0) +/** @brief Port GPIO Mode */ +#define PORT_GPIO_MODE ((Port_PinModeType)1) +/** @brief Port Alternate 2 Mode */ +#define PORT_ALT2_FUNC_MODE ((Port_PinModeType)2) +/** @brief Port Alternate 3 Mode */ +#define PORT_ALT3_FUNC_MODE ((Port_PinModeType)3) +/** @brief Port Alternate 4 Mode */ +#define PORT_ALT4_FUNC_MODE ((Port_PinModeType)4) +/** @brief Port Alternate 5 Mode */ +#define PORT_ALT5_FUNC_MODE ((Port_PinModeType)5) +/** @brief Port Alternate 6 Mode */ +#define PORT_ALT6_FUNC_MODE ((Port_PinModeType)6) +/** @brief Port Alternate 7 Mode */ +#define PORT_ALT7_FUNC_MODE ((Port_PinModeType)7) + + +/********* global typedef ************/ +/** @brief Port return structure */ +typedef enum +{ + PORT_STATUS_SUCCESS = 0U, + PORT_STATUS_PARAM_INVALID = 1U +} PORT_StatusType; + +/** @brief Port instance number */ +typedef enum +{ + PORT_A = 0U, + PORT_B, + PORT_C, + PORT_D, + PORT_E +} PORT_InstanceType; + +typedef enum +{ + PORT_TRIGGER_DISABLE = 0U, + PORT_TRIGGER_INPUT_CONSISTENT_WITH_PAD = 1U, + PORT_TRIGGER_INPUT_OPPOSITE_WITH_PAD = 2U +} PORT_TriggerInputType; + +/** @brief Port interrupt notification type */ +typedef void (*PORT_PinInterruptCallBackType)(void); + +/** @brief Port initialization structure */ +typedef struct +{ + uint32_t u32PortPins; /**< Port pin, 0~31 bit indicates the pin 0~31 */ + Port_PinMuxType uPortPinMux; /**< Port pin mode */ + PORT_TriggerInputType eTriggrtMode; /**< Port trigger mode */ + bool bPullEn; /**< whether to pull the port pin */ + PORT_PullStatusType ePullSel; /**< pull status, pull up or pull down */ + bool bDrvStrength0En; /**< whether to enable pad drive strength 0 , only hs PAD used */ + bool bDrvStrength1En; /**< whether to enable pad drive strength 1, only uhs PAD used */ + bool u8PassiveFilterEn; /**< whether to use passive filter, please refer to reference manual for details */ +} PORT_InitType; + +/** @brief Port interrupt configuration structure */ +typedef struct +{ + uint32_t u32PortPins; /**< Port pin, 0~31 bit indicates the pin 0~31 */ + PORT_IntConfigType ePortIsrMode; /**< Port interrupt mode */ + PORT_PinInterruptCallBackType pIsrNotify; /**< Port interrupt notification pointer */ +} PORT_InterruptType; + +/** @brief Port digital filter configuration structure */ +typedef struct +{ + uint32_t u32PortPinsEn; /**< Port pin, 0~31 bit indicates the pin 0~31 */ + PORT_DigitalFilterClkSrcType eClkSrc; /**< Port clock source */ + uint8_t u8FilterLength; /**< digital filter length, the range is :0~31 */ +} PORT_DigitalFilterType; + + +/********* global API ************/ +/** + * @brief Initialize port pins + * + * @param ePort Port instance + * @param pInitStruct Initialization structure of port + * @return Port return type. + */ +PORT_StatusType PORT_InitPins(const PORT_InstanceType ePort, const PORT_InitType *const pInitStruct); + +/** + * @brief De-initialize the Port instance + * + * @param ePort Port instance enumeration + * @param u32Pins The bit of u32Pins indicate the Pin number of this Port. + * @return Port return type. + */ +PORT_StatusType PORT_Deinit(const PORT_InstanceType ePort, const uint32_t u32Pins); + +/** + * @brief Enable interrupt function of port + * + * @param ePort Port instance enumeration + * @param pIntStruct Interrupt structure of port. + * @return Port return type. + */ +PORT_StatusType PORT_InitInterrupt(const PORT_InstanceType ePort, const PORT_InterruptType *const pIntStruct); + +/** + * @brief Enable interrupt function of port + * + * @param ePort Port instance enumeration + * @param u32Pins The bit of u32Pins indicate the Pin number of this Port. + * @return Port return type. + */ +PORT_StatusType PORT_EnableInterrupt(const PORT_InstanceType ePort, const uint32_t u32Pins); + +/** + * @brief Disable interrupt function of port + * + * @param ePort Port instance enumeration + * @param u32Pins The bit of u32Pins indicate the Pin number of this Port. + * @return Port return type. + */ +PORT_StatusType PORT_DisableInterrupt(const PORT_InstanceType ePort, const uint32_t u32Pins); + +PORT_StatusType PORT_SetPinsDmaReqMode(const PORT_InstanceType ePort, const uint32_t u32Pins, const PORT_DMAReqType eDMAReqMode); +/** + * @brief Initialize digital filter for Port instance + * + * @param ePort Port instance enumeration + * @param pDFStruct Digital filter initialization structure of port + * @return Port return type. + */ +PORT_StatusType PORT_InitDigitalFilterPort(const PORT_InstanceType ePort, + const PORT_DigitalFilterType *pDFStruct); + +/** + * @brief De-initialize digital filter for Port instance + * + * @param ePort Port instance enumeration + * @return Port return type. + */ +PORT_StatusType PORT_DeinitDigitalFilterPort(const PORT_InstanceType ePort); + +/** + * @brief Enable the digital filter function for the specific pin. + * + * @param ePort Port instance enumeration + * @param u32Pins The bit of u32Pins indicate the Pin number of this Port. + * @return Port return type. + */ +PORT_StatusType PORT_EnableDigitalFilterPin(const PORT_InstanceType ePort, const uint32_t u32Pins); + +/** + * @brief Disable the digital filter function for the specific pin. + * + * @param ePort Port instance enumeration + * @param u32Pins The bit of u32Pins indicate the Pin number of this Port. + * @return Port return type. + */ +PORT_StatusType PORT_DisableDigitalFilterPin(const PORT_InstanceType ePort, const uint32_t u32Pins); + + + +/** @}*/ /* fc7xxx_driver_port */ + +#endif + diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_ptimer.h b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_ptimer.h new file mode 100644 index 0000000..5196609 --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_ptimer.h @@ -0,0 +1,226 @@ +/** + * @file fc7xxx_driver_ptimer.h + * @author Flagchip0126 + * @brief FC7xxx PTIMER driver type definition and API + * @version 0.1.0 + * @date 2024-01-15 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-01-15 Flagchip0126 N/A First version for FC7240 + ******************************************************************************** */ + +#ifndef _DRIVER_FC7XXX_DRIVER_PTIMER_H_ +#define _DRIVER_FC7XXX_DRIVER_PTIMER_H_ +#include "device_header.h" +#include "HwA_ptimer.h" +#include "HwA_scm.h" + +#if defined(__cplusplus) +extern "C" { +#endif +/** + * @addtogroup fc7xxx_driver_ptimer + * @{ + */ + +/** + * @brief PTIMER interrupt callback function prototype + * + */ +typedef void (*PTIMER_InterruptCallbackType)(void); + +/** + * @brief PTIMER sequence error callback function prototype + * + */ +typedef void (*PTIMER_SeqErrorCallbackType)(uint8_t u8Channel); + +/** + * @brief The instance index of the PTIMER peripheral + * + */ +typedef enum +{ + PTIMER_INSTANCE_0 = 0U, + PTIMER_INSTANCE_1 = 1U +} PTIMER_InstanceType; + +/** + * @brief Ptimer instance initialization parameters + * + */ +typedef struct +{ + PTIMER_LoadValueModeType eLoadValueMode; /*!< Select the load mode */ + PTIMER_ClockPreDividerType eClkPreDiv; /*!< Select the prescaler divider */ + PTIMER_ClockPreDivMultiplyFactorType eClkPreMultFactor; /*!< Select multiplication factor for prescaler */ + PTIMER_TrgSrcType eTriggerInput; /*!< Select the trigger input source */ + bool bContinuousModeEnable; /*!< Enable the continuous mode */ + bool bDmaEnable; /*!< Enable the dma for timer */ +} PTIMER_InitType; + +/** + * @brief Ptimer interrupt configuration parameters + * + */ +typedef struct +{ + bool bDelayIntEnable; /*!< Enable the interrupt for timer */ + uint32_t u32IntDelayPeriodUs; /*!< The period in micro second */ + PTIMER_InterruptCallbackType pIntNotify; /*!< Ptimer interrupt callback function pointer */ + bool bSeqErrIntEnable; /*!< Enable PTIMER Sequence Error Interrupt */ + PTIMER_SeqErrorCallbackType pSeqErrorNotify; /*!< Ptimer sequence error callback function pointer */ +} PTIMER_InterruptType; + +/** + * @brief Ptimer channel configuration parameters + * + */ +typedef struct +{ + uint32_t u32DelayUs; /*!< Setting pre_trigger's delay in microsecond. */ + bool bPreTriggerEnable; /*!< Enable the pre_trigger. */ + bool bPreTriggerOutputEnable; /*!< Enable the pre_trigger output. */ + bool bPreTriggerBackToBackEnable; /*!< Enable the back to back mode for ADC pre_trigger. */ +} PTIMER_ChannelCfgType; + +/** + * @brief Ptimer pulse out configgurations + * + * When the Ptimer counter time reaches u32PulseOutDlyHighUs, the pulse-out goes high; + * When the Ptimer counter time reaches u32PulseOutDlyLowUs, the pulse-out goes low. + * + */ +typedef struct +{ + uint32_t u32PulseOutDlyHighUs; /*!< Microsecond delay for pulse out to output high */ + uint32_t u32PulseOutDlyLowUs; /*!< Microsecond delay for pulse out to output low */ +} PTIMER_PulseOutType; + +/** + * @brief Initialize the Ptimer instance + * + * @param eInstance the Ptimer instance to use + * @param pInitCfg the Ptimer initialization parameters + */ +void PTIMER_Init(const PTIMER_InstanceType eInstance, const PTIMER_InitType *const pInitCfg); + +/** + * @brief De-initialize the Ptimer instance + * Disable the Ptimer instance and reset the configurations to its reset values + * + * @param eInstance the Ptimer instance to use + */ +void PTIMER_DeInit(const PTIMER_InstanceType eInstance); + +/** + * @brief Initialize the Ptimer interrupt + * + * @note the interrupt delay value is buffered and will take effect only after called PTIMER_LoadValue() + * function. + * + * @param eInstance the Ptimer instance to configure + * @param pInterruptCfg the Ptimer initialization parameters + */ +void PTIMER_InitInterrupt(const PTIMER_InstanceType eInstance, + const PTIMER_InterruptType *const pInterruptCfg); + +/** + * @brief Initialize the Ptimer channels + * + * @note the channel delay value is buffered and will take effect only after called PTIMER_LoadValue() + * function. + * + * @param eInstance the Ptimer instance to use + * @param aChannelCfg the array of channels to config + * @param u8ChnNum the channel numbers in the channel array + */ +void PTIMER_InitChannel(const PTIMER_InstanceType eInstance, + const PTIMER_ChannelCfgType aChannelCfg[], const uint8_t u8ChnNum); + +/** + * @brief Set the Ptimer max counter period in microsecond + * When the Ptimer counter reaches the period, it will return to zero + * + * @note the period parameter is buffered and will take effect only after called PTIMER_LoadValue() + * function. + * + * @param eInstance the Ptimer instance to use + * @param u32PeriodUs the max counter period in microsecond + */ +void PTIMER_SetPeriod(const PTIMER_InstanceType eInstance, uint32_t u32PeriodUs); + +/** + * @brief Set the Ptimer pulse-out function + * + * @note the pulse-out delay values are buffered and will take effect only after called PTIMER_LoadValue() + * function. + * + * @param eInstance the Ptimer instance to use + * @param pPulseOutCfg the pulse-out configuration + */ +void PTIMER_SetPulseOut(const PTIMER_InstanceType eInstance, const PTIMER_PulseOutType *pPulseOutCfg); + +/** + * @brief Load the buffered values into register + * + * Some Ptimer registers are buffered and will only take effect after called + * this function + * + * @param eInstance the Ptimer instance to use + */ +void PTIMER_LoadValue(const PTIMER_InstanceType eInstance); + +/** + * @brief Enable the Ptimer instance + * + * @param eInstance the Ptimer instance to use + */ +void PTIMER_Enable(const PTIMER_InstanceType eInstance); + +/** + * @brief Disable the Ptimer instance + * + * @param eInstance the Ptimer instance to use + */ +void PTIMER_Disable(const PTIMER_InstanceType eInstance); + +/** + * @brief Enable the Ptimer pulse-out function + * + * @param eInstance the Ptimer instance to use + */ +void PTIMER_EnablePulseOut(const PTIMER_InstanceType eInstance); + +/** + * @brief Disable the Ptimer pulse-out function + * + * @param eInstance the Ptimer instance to use + */ +void PTIMER_DisablePulseOut(const PTIMER_InstanceType eInstance); + +void PTIMER_SelectInstance01BackToBackMode(SCM_PTimerLMSelType ePTimerLoopMode); + +/** + * @brief Generate the software trigger signal for the Ptimer instance + * + * If the Ptimer trigger source is selected as PTIMER_TRGSRC_SW, call this function + * will make the Ptimer instance to start. + * + * @param eInstance the Ptimer instance to use + */ +void PTIMER_GenerateSWTrigger(const PTIMER_InstanceType eInstance); + +/** @}*/ /* fc7xxx_driver_ptimer */ + +#if defined(__cplusplus) +} +#endif +#endif diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_rgm.h b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_rgm.h new file mode 100644 index 0000000..166438b --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_rgm.h @@ -0,0 +1,182 @@ +/** + * @file fc7xxx_driver_rgm.h + * @author Flagchip + * @brief FC7xxx RGM driver type definition and API + * @version 0.1.0 + * @date 2024-01-12 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + * @details + */ +/******************************************************************************** +* Revision History: +* +* Version Date Initials CR# Descriptions +* --------- ---------- ------------ ---------- --------------- +* 0.1.0 2024-01-12 Flagchip119 N/A First version for FC7240 +********************************************************************************/ +#ifndef _DRIVER_FC7XXX_DRIVER_RCM_H_ +#define _DRIVER_FC7XXX_DRIVER_RCM_H_ + +#include "HwA_rgm.h" + +/** + * @addtogroup fc7xxx_driver_rcgm + * @{ + */ + +/** @brief Get which core currently belongs to. */ +#define GET_CORE_NUM (*(uint32_t *)0xE0080004) + +/** @brief Rgm return type. */ +typedef enum +{ + RGM_STATUS_SUCCESS = 0U, + RGM_STATUS_PARAM_INVALID = 1U, + RGM_STATUS_COREID_INVALID = 2U +} RGM_StatusType; + +/** @brief Rgm reset pin filter clock type. */ +typedef enum +{ + RGM_RESET_FILTER_BUS_CLOCK = 0U, + RGM_RESET_FILTER_AON32K_CLOCK = 1U +} RGM_FilterClkSrc; + +/** @brief Rgm interrupt notification type */ +typedef void (*RGM_InterruptCallBackType)(uint32_t u32SRS); + +/** + * @brief This api can get RGM_SRS register that indicate the source of the most recent reset. + * + * @return RGM->RGM_SRS register, bit 0-15,29-31 corresponding to RGM_ResetEventType, refer to reference manual for details. + * @note Multiple flags can be set if multiple reset events occur at the same time + */ +uint32_t RGM_GetLastResetFLag(void); + +/** + * @brief This api can get RGM_SSRS register that indicate all reset sources since the last POR or LVD that have not been cleared by software. + * + * @returnRGM->RGM_SSRS register, bit 0-15,29-31 corresponding to RGM_ResetEventType, refer to reference manual for details. + */ +uint32_t RGM_GetAllResetFlag(void); + +/** + * @brief This api can clear reset flag of RGM_SSRS register which indicate all reset sources since the last POR or LVD that have not been cleared by software. + * + * @param eReset Enumeration of reset event flag + */ +void RGM_ClearResetFlagAfterPOR(const RGM_ResetEventType eReset); + +/** + * @brief This api can clear all reset flag of RGM_SSRS register which indicate all reset sources since the last POR or LVD that have not been cleared by software. + * + */ +void RGM_ClearAllResetFlagAfterPOR(void); + +/** + * @brief Enable reset pin filter + * + * @param eClk Reset pin filter clock source + * @param u8BusClockFilterWidth Bus clock filter width + * @param bLpClkEn select whether enable reset pin filter using AON32clock in low power mode + * @return RGM return type + * @note If use AON32K clock, A reset signal whose length is less than 2 AON32K clock periods will be filtered + */ +RGM_StatusType RGM_EnableResetFilter(RGM_FilterClkSrc eClk, uint8_t u8BusClockFilterWidth, bool bLpClkEn); + +/** + * @brief Disable reset pin filter + * + * @param eClk Reset pin filter clock source + * @param bLpClkEn select whether disable reset pin filter using AON32clock in low power mode + * @return RGM return type + */ +RGM_StatusType RGM_DisableResetFilter(RGM_FilterClkSrc eClk, bool bLpClkEn); + +/** + * @brief This api can enable interrupt before an system reset appear. + * + * @param eDelay Enumeration of delay cycles + * @param eResetInterrupt Reset event flag, like: RGM_INT_CLKERR0 | RGM_INT_FCSMU + * @return RGM return type + */ +RGM_StatusType RGM_EnableSystemResetInt(RGM_ResetDelayType eDelay, RGM_ResetIntMangerType eResetInterrupt); + +/** + * @brief This api can disable interrupt before an system reset appear. + * + * @param eResetInterrupt Reset event flag, like: RGM_INT_CLKERR0 | RGM_INT_FCSMU + * @param bClearDelay Whether to clear delay configuration + * @return RGM return type + */ +RGM_StatusType RGM_DisableSystemResetInt(RGM_ResetIntMangerType eResetInterrupt, bool bClearDelay); + +/** + * @brief Generate software reset through cotex-m register + * + */ +void RGM_GenerateSwReset(void); + +/** + * @brief This api can enable interrupt before an CPU0 core related reset appear. + * + * @param eCPU0Interrupt Reset event flag, like: RGM_CPU_INT_SWRST | RGM_CPU_INT_SYSRST + * @param pIsrNotify Interrupt function + * @return RGM return type + */ +RGM_StatusType RGM_EnableCPU0CoreResetInt(RGM_CPUIntMangerType eCPU0Interrupt,RGM_InterruptCallBackType pIsrNotify); + +/** + * @brief This api can disable interrupt before an CPU0 core related reset appear. + * + * @param eCPU0Interrupt Reset event flag, like: RGM_CPU_INT_SWRST | RGM_CPU_INT_SYSRST + * @return RGM return type + */ +RGM_StatusType RGM_DisableCPU0CoreResetInt(RGM_CPUIntMangerType eCPU0Interrupt); + +/** + * @brief Get the CPU0 exit reset flag + * + * @return RGM_CPU_OUT_RST_UNDER CPU0 is under reset + * @return RGM_CPU_OUT_RST_OUT CPU0 is out of reset + */ +RGM_CPUOutResetType RGM_GetCPU0OutResetFlag(void); + +/** + * @brief Generate a CPU0 software reset. + * + */ +void RGM_GenerateCPU0SwReset(void); + +/** + * @brief This api can get RGM_C0_SRS register that indicate the source of the most recent CPU0 reset. + * + * @return RGM->RGM_C0_SRS register, bit 0-20 corresponding to RGM_ResetEventType, refer to reference manual for details. + * @note Multiple flags can be set if multiple reset events occur at the same time + */ +uint32_t RGM_GetCPU0LastResetFLag(void); + +/** + * @brief This api can get RGM_C0_SSRS register that indicate all CPU0 reset sources since the last POR or LVD that have not been cleared by software. + * + * @returnRGM->RGM_C0_SSRS register, bit 0-20,29-31 corresponding to RGM_CPUResetEventType, refer to reference manual for details. + */ +uint32_t RGM_GetCPU0AllResetFlag(void); + +/** + * @brief This api can clear reset flag of RGM_C0_SSRS register which indicate CPU0 all reset sources since the last POR or LVD that have not been cleared by software. + * + * @param eReset Enumeration of reset event flag + */ +void RGM_ClearCPU0ResetFlagAfterPOR(const RGM_CPUResetEventType eReset); + +/** + * @brief This api can clear all reset flag of RGM_C0_SSRS register which indicate CPU0 all reset sources since the last POR or LVD that have not been cleared by software. + * + */ +void RGM_ClearCPU0AllResetFlagAfterPOR(void); + +/** @}*/ /* fc7xxx_driver_rgm */ +#endif /* end of _DRIVER_FC7XXX_DRIVER_RGM_H_ */ diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_rtc.h b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_rtc.h new file mode 100644 index 0000000..599a6f8 --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_rtc.h @@ -0,0 +1,152 @@ +/** + * @file fc7xxx_driver_rtc.h + * @author Flagchip + * @brief FC7xxx rtc driver type definition and API + * @version 0.1.0 + * @date 2024-01-10 + * + * @copyright Copyright (c) 2023 Flagchip Semiconductors Co., Ltd. + * + * @details + */ +/******************************************************************************** +* Revision History: +* +* Version Date Initials CR# Descriptions +* --------- ---------- ------------ ---------- --------------- +* 0.1.0 2024-01-10 Flagchip0076 N/A First version for FC7240 +********************************************************************************/ + + +#ifndef DRIVER_INCLUDE_FC7XXX_DRIVER_RTC_H_ +#define DRIVER_INCLUDE_FC7XXX_DRIVER_RTC_H_ + +#include"HwA_rtc.h" + + +/** + * @addtogroup fc7xxx_driver_rtc + * @{ + */ + +/** @brief Rtc return type. */ +typedef enum +{ + RTC_STATUS_SUCCESS = 0U, /**< rtc status is success */ + RTC_STATUS_PARAM_INVALID = 1U, /**< rtc status is failed because the param is invalid */ + RTC_STATUS_FUNCTION_ERROR = 2U, /**< rtc status is failed because the function is error */ + RTC_STATUS_CLOCK_INVALID = 3U /**< rtc status is failed because the clock is invalid */ +} RTC_StatusType; + +/** @brief Rtc mode */ +typedef enum +{ + RTC_ALARM_INT = 0U, /**< rtc interrupt mode is alarm */ + RTC_SECOND_INT = 1U, /**< rtc interrupt mode is second */ + RTC_OVERFLOW_INT = 2U /**< rtc interrupt mode is overflow */ +} RTC_IntEventType; + +/** @brief Rtc interrupt notification type */ +typedef void (*RTC_InterruptCallBackType)(void); + +/** @brief Rtc interrupt configuration type */ +typedef struct +{ + bool bAlarmIntEn; /**< whether enable rtc alarm interrupt */ + RTC_InterruptCallBackType pIsrAlarmNotify; /**< rtc alarm notification function pointer */ + bool bSecondIntEn; /**< whether to use the second interrupt */ + RTC_InterruptCallBackType pIsrSecondNotify; /**< second interrupt notification function pointer */ + bool bOverflowIntEn ; /**< overflow interrupt notification function pointer */ + RTC_InterruptCallBackType pIsrOverflowNotify; /**< overflow interrupt notification function pointer */ +} RTC_InterruptType; + +/** @brief Rtc initialization type */ +typedef struct +{ + uint32_t u32AlarmValue; /**< rtc alarm value */ + RTC_ClkoutSecIntFreqType eSecIntAndClkoutFreq; /**< Select the RTC Seconds interrupt and the RTC_CLKOUT prescaler output frequency */ + bool bStableClkoutFreq; /**< Select the RTC Seconds interrupt and the RTC_CLKOUT prescaler output frequency or RTC_CLKOUT is from the 32.768 kHz clock. */ +} RTC_InitType; + +/* global functions */ +/** + * @brief Initialize Rtc instance + * @param pInitStruct Rtc initialization structure + */ +void RTC_Init(const RTC_InitType *const pInitStruct); + +/** + * @brief Rtc set interrupt + * + * @param pIntStruct interrupt structure pointer + * @return Rtc return type + * @note this function will stop Rtc timer + */ +RTC_StatusType RTC_InitInterrupt(const RTC_InterruptType *const pIntStruct); + +/** + * @brief De-initialize Rtc instance + * + */ +void RTC_Deinit(void); + +/** + * @brief Rtc enable interrupt + * + * @param bAlarmIntEn whether enable alarm interrupt + * @param bSecondIntEn whether enable second interrupt + */ +void RTC_EnableInterrupt(const bool bAlarmIntEn, const bool bSecondIntEn, const bool bOverflowIntEn); + +/** + * @brief Rtc disable interrupt + * + * @param bAlarmIntEn whether disable alarm interrupt + * @param bSecondIntEn whether disable second interrupt + */ +void RTC_DisableInterrupt(const bool bAlarmIntEn, const bool bSecondIntEn, const bool boverflowIntEn); + +/** + * @brief Rtc start + * + */ +void RTC_Start(void); + +/** + * @brief Rtc stop + * + */ +void RTC_Stop(void); + +/** + * @brief Rtc alarm value + * + * @param u32AlarmValue Input value + */ +void RTC_UpdateAlarmValue(const uint32_t u32AlarmValue); + +/** + * @brief Get Rtc counter value + * + * @return Rtc counter value + */ +uint32_t RTC_GetTime(void); + +/** + * @brief Check RTC overflow flag + * + * @return Overflow flag + */ +bool RTC_CheckOverflowFlag(void); + + +/** + * @brief Set second counter value + * @param u32Value the second value. + * */ + +void RTC_SetSecondCounterValue(uint32_t u32Value); + + +/** @}*/ /* fc7xxx_driver_rtc */ +#endif /* DRIVER_INCLUDE_FC7XXX_DRIVER_RTC_H_ */ diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_scg.h b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_scg.h new file mode 100644 index 0000000..64bd5a1 --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_scg.h @@ -0,0 +1,459 @@ +/** + * @file fc7xxx_driver_scg.h + * @author Flagchip085 + * @brief FC7xxx SCG driver type definition and API + * @version 0.1.0 + * @date 2024-01-12 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-01-12 Flagchip085 N/A First version for FC7240 + ******************************************************************************** */ +#ifndef _DRIVER_FC7XXX_DRIVER_SCG_H_ +#define _DRIVER_FC7XXX_DRIVER_SCG_H_ +#include "HwA_scg.h" +#include "HwA_csc.h" +/** + * @addtogroup fc7xxx_driver_scg + * @{ + */ + +/** @brief clock list for internal clock tree */ +typedef enum +{ + /* Main clocks */ + SCG_CORE_CLK = 0U, /*!< Core clock */ + SCG_BUS_CLK = 1U, /*!< Bus clock */ + SCG_SLOW_CLK = 2U, /*!< Slow clock */ + + /* Other internal clocks used by peripherals. */ + SCG_FOSC_CLK = 3U, /*!< FOSC clock */ + SCG_FIRC_CLK = 4U, /*!< FIRC clock */ + SCG_PLL0_CLK = 5U, /*!< PLL0 clock */ + SCG_PLL1_CLK = 6U, /*!< PLL1 clock */ + SCG_SIRC_CLK = 7U, /*!< SIRC clock */ + SCG_SIRC32K_CLK = 8U, /*!< SIRC32K clock */ + SCG_SOSC_CLK = 9U, /*!< SOSC clock */ + SCG_SCG_CLKOUT_CLK = 10U, /*!< SCG CLK_OUT clock */ + SCG_SIRCDIVH_CLK = 11U, /*!< SIRCDIVH functional clock */ + SCG_SIRCDIVM_CLK = 12U, /*!< SIRCDIVM functional clock */ + SCG_SIRCDIVL_CLK = 13U, /*!< SIRCDIVL functional clock */ + SCG_FIRCDIVH_CLK = 14U, /*!< FIRCDIVH functional clock */ + SCG_FIRCDIVM_CLK = 15U, /*!< FIRCDIVM functional clock */ + SCG_FIRCDIVL_CLK = 16U, /*!< FIRCDIVL functional clock */ + SCG_FOSCDIVH_CLK = 17U, /*!< FOSCDIVH functional clock */ + SCG_FOSCDIVM_CLK = 18U, /*!< FOSCDIVM functional clock */ + SCG_FOSCDIVL_CLK = 19U, /*!< FOSCDIVL functional clock */ + SCG_PLL0DIVH_CLK = 20U, /*!< PLL0DIVH functional clock */ + SCG_PLL0DIVM_CLK = 21U, /*!< PLL0DIVM functional clock */ + SCG_PLL0DIVL_CLK = 22U, /*!< PLL0DIVL functional clock */ + SCG_PLL1DIVH_CLK = 23U, /*!< PLL1DIVH functional clock */ + SCG_PLL1DIVM_CLK = 24U, /*!< PLL1DIVM functional clock */ + SCG_PLL1DIVL_CLK = 25U, /*!< PLL1DIVL functional clock */ + SCG_NVMINIT_CLK = 26U, /*!< NVM initial clock source */ + SCG_CMU4REF_CLK = 27U, /*!< CMU4 reference clock */ + SCG_END_OF_CLOCKS = 28U /*!< End of SCG clocks */ +} SCG_ClkSrcType; + +/** + * @brief PLL clock type + */ +typedef enum +{ + SCG_PLL0 = 0U, /*!< PLL0 clock */ + SCG_PLL1 = 1U /*!< PLL1 clock */ +} SCG_PllClkType; + +/** + * @brief indicate the clock function status + * + */ +typedef enum +{ + SCG_STATUS_SUCCESS = 0U, /*!< function called success */ + SCG_STATUS_SEQUENCE_ERROR = 1U, /*!< function called report sequence error */ + SCG_STATUS_TIMEOUT = 2U, /*!< function called report timeout error */ + SCG_STATUS_IRC_ERROR = 3U, /*!< function called report internal clock error */ + SCG_STATUS_PARAM_ERROR = 4U /*!< function called report internal clock error */ +} SCG_StatusType; + +/** + * @brief indicate the CRC check result + * + */ +typedef enum +{ + SCG_CRC_CHECK_SUCCESS = 0U, /*!< CRC check success *//**< SCG_CRC_CHECK_SUCCESS */ + SCG_CRC_GEN_TIMEOUT = 1U, /*!< CRC Generate Timeout *//**< SCG_CRC_GEN_TIMEOUT */ + SCG_CRC_CHECK_FAILED = 2U /*!< CRC check failed */ /**< SCG_CRC_CHECK_FAILED */ +} SCG_CrcCheckResType; + +/** + * @brief SCG xxxIRC TRIMSRC type. +*/ +typedef enum +{ + SCG_IRC_TRIMSRC_RESERVE0 = 0U, /*!< Clock Trim source reserve0 */ + SCG_IRC_TRIMSRC_RESERVE1 = 1U, /*!< Clock Trim source reserve1 */ + SCG_IRC_TRIMSRC_FOSC = 2U, /*!< Clock Trim source FOSC */ + SCG_IRC_TRIMSRC_SOSC = 3U, /*!< Clock Trim source SOSC */ +} SCG_IrcTrimSrcType; + +/** + * @brief SCG_CCR [SCS] to Select system clock source + * + */ +typedef enum +{ + SCG_CLOCK_SRC_FOSC = 1U, /*!< System OSC. */ + SCG_CLOCK_SRC_SIRC = 2U, /*!< Slow IRC 12MHz. */ + SCG_CLOCK_SRC_FIRC = 3U, /*!< Fast IRC. */ + SCG_CLOCK_SRC_PLL0 = 6U, /*!< System PLL. */ + SCG_CLOCK_SRC_NONE = 255U /*!< MAX value. */ +} SCG_ClockSrcType; + +/** + * @brief SCG_CCR [DIVCORE ]/ SCG_CCR [DIVBUS ]/ SCG_CCR [DIVSLOW ] to Select system clock source. + * + */ +typedef enum +{ + SCG_CLOCK_DIV_BY1 = 0U, /*!< Divided by 1. */ + SCG_CLOCK_DIV_BY2 = 1U, /*!< Divided by 2. */ + SCG_CLOCK_DIV_BY3 = 2U, /*!< Divided by 3. */ + SCG_CLOCK_DIV_BY4 = 3U /*!< Divided by 4. */ +} SCG_ClockDivType; + +/** + * @brief SCG_ CLKOUTCFG [CLKOUTSEL] to Select system clock source. + */ +typedef enum +{ + SCG_CLOCKOUT_SRC_OFF = 0U, /*!< SCG OFF. */ + SCG_CLOCKOUT_SRC_FOSC = 1U, /*!< Fast OSC. */ + SCG_CLOCKOUT_SRC_SIRC = 2U, /*!< Slow IRC. */ + SCG_CLOCKOUT_SRC_FIRC = 3U, /*!< Fast IRC. */ + SCG_CLOCKOUT_SRC_SOSC = 4U, /*!< Slow OSC. */ + SCG_CLOCKOUT_SRC_PLL1 = 5U, /*!< System PLL1. */ + SCG_CLOCKOUT_SRC_PLL0 = 6U, /*!< System PLL0. */ + SCG_CLOCKOUT_SRC_SIRC32K = 7U, /*!< SIRC32K_CLK.*/ +} SCG_ClockoutSrcType; + +/** + * @brief NVM clock source enumeration + */ +typedef enum +{ + SCG_NVMCLK_SRC_SIRC = 30u, /*!< NVM source choose SIRC. */ + SCG_NVMCLK_SRC_FIRC = 31u /*!< NVM source choose FIRC. */ +} SCG_NvmClkSrcType; + +/** + * @brief CMU4 clock source enumeration + */ +typedef enum +{ + SCG_CMU4CLK_SRC_SIRC = 28u, /*!< NVM source choose SIRC. */ + SCG_CMU4CLK_SRC_FOSC = 29u /*!< NVM source choose FORC. */ +} SCG_Cmu4ClkSrcType; + +/** + * @brief SCG registers CRC trigger mode + */ +typedef enum +{ + SCG_CRC_SW_MODE = 0U, /*!< SCG registers CRC software mode. */ + SCG_CRC_TRIGGER_MODE = 1U /*!< SCG registers CRC trigger mode. */ +} SCG_CrcModeType; + +/** @brief [DIVL]/[DIVM]/[DIVH] bit field definition for SCG_SIRC/ SCG_FIRC/ SCG_FOSC/ SCG_PLL0 registers */ +typedef enum +{ + SCG_ASYNC_CLOCK_DISABLE = 0U, /*!< Clock output is disabled. */ + SCG_ASYNCCLOCKDIV_BY1 = 1U, /*!< Divided by 1. */ + SCG_ASYNCCLOCKDIV_BY2 = 2U, /*!< Divided by 2. */ + SCG_ASYNCCLOCKDIV_BY4 = 3U, /*!< Divided by 4. */ + SCG_ASYNCCLOCKDIV_BY8 = 4U, /*!< Divided by 8. */ + SCG_ASYNCCLOCKDIV_BY16 = 5U, /*!< Divided by 16. */ + SCG_ASYNCCLOCKDIV_BY32 = 6U, /*!< Divided by 32. */ + SCG_ASYNCCLOCKDIV_BY64 = 7U /*!< Divided by 64. */ +} SCG_AsyncClockDivType; + +/** @brief SCG_ PLLCFG[PREDIV] for PLL clock calculation. The pre-div value range is 0 ~ 31 */ +typedef uint8_t SCG_PllPredivType; + +/** @brief SCG_ PLLCFG[PSTDIV] for PLL clock calculation */ +typedef enum +{ + SCG_PLLPSTDIV_BY2 = 1U, + SCG_PLLPSTDIV_BY4 = 2U, + SCG_PLLPSTDIV_BY8 = 3U +} SCG_PllPstdivType; + +/** @brief SCG_ PLLCFG[SOURCE] to Select PLL clock source */ +typedef enum +{ + SCG_PLLSOURCE_FOSC = 0U, + SCG_PLLSOURCE_FIRC = 1U +} SCG_PllSourceType; + +/** @brief SCG_ PLLCFG [MULT] for PLL clock calculation. The mult value range is 96 ~ 512 */ +typedef uint16_t SCG_PllMultiplyType; + +/** @brief FOSC initial definition, include register SCG_FOSCCSR/SCG_FOSCDIV/SCG_FOSCCFG. */ +typedef struct +{ + bool bLock; /*!< SCG_FOSCCSR[LK] bit, Write to set the register can be written or not */ + bool bCm; /*!< SCG_FOSCCSR[CM] bit, Clock Monitor is enable */ + bool bCmre; /*!< SCG_FOSCCSR[CMRE] bit, Clock Monitor Reset Enable + 0 Generates interrupt, 1 Generates rese */ + bool bSten; /*!< SCG_FOSCCSR[STEN] bit, Clock Stop in Stop modes */ + bool bBypass; /*!< SCG_FOSCCFG[BYPASS] bit, Configures FOSC for bypassing the internal oscillator.*/ + SCG_AsyncClockDivType eDivH; /*!< SCG_FOSCDIV[DIVH] bit field definition, 0 means disable. */ + SCG_AsyncClockDivType eDivM; /*!< SCG_FOSCDIV[DIVM] bit field definition, 0 means disable. */ + SCG_AsyncClockDivType eDivL; /*!< SCG_FOSCDIV[DIVL] bit field definition, 0 means disable. */ +} SCG_FoscType; + +/** @brief SIRC initial definition, include register SCG_ SIRCCSR/ SCG_ SIRCDIV/ SCG_ SIRCTCCFG. */ +typedef struct +{ + bool bLock; /*!< SCG_SIRCCSR[LK] bit, Write to set the register can be written or not */ + bool bCm; /*!< SCG_SIRCCSR[CM] bit, SIRC Clock Monitor Enable */ + bool bTrEn; /*!< SCG_SIRCCSR[TREN] bit, IRC software trim enable (auto trim) */ + bool bLpen; /*!< SCG_SIRCCSR[LPEN] bit, Clock Stop Enable */ + bool bSten; /*!< SCG_SIRCCSR[STEN] bit, Clock Standby Enable */ + SCG_AsyncClockDivType eDivH; /*!< SCG_SIRCDIV[DIVH] bit field definition.*/ + SCG_AsyncClockDivType eDivM; /*!< SCG_SIRCDIV[DIVM] bit field definition.*/ + SCG_AsyncClockDivType eDivL; /*!< SCG_SIRCDIV[DIVL] bit field definition.*/ + uint8_t u8TrimSrc; /*!< SCG_SIRCTCFG[TRIMSRC] IRC clock auto trim reference clock source select.*/ +} SCG_SircType; + +typedef struct +{ + bool bLock; /*!< SIRC32KCSR[LK] bit, Write to set the register can be written or not */ +} SCG_Sirc32kType; + +/** @brief FIRC initial definition, include register SCG_ FIRCCSR/ SCG_ FIRCDIV/ SCG_ FIRCFG. */ +typedef struct +{ + bool bLock; /*!< SCG_FIRCCSR[LK] bit, Write to set the register can be written or not */ + bool bCm; /*!< SCG_FIRCCSR[CM] bit, FIRC Clock Monitor Enable */ + bool bTrEn; /*!< SCG_FIRCCSR[TREN] bit, IRC software trim enable (auto trim) */ + bool bSten; /*!< SCG_FIRCCSR[STEN] bit, Clock Standby Enable */ + SCG_AsyncClockDivType eDivH; /*!< SCG_FIRCDIV[DIVH] bit field definition.*/ + SCG_AsyncClockDivType eDivM; /*!< SCG_FIRCDIV[DIVM] bit field definition.*/ + SCG_AsyncClockDivType eDivL; /*!< SCG_FIRCDIV[DIVL] bit field definition.*/ + uint8_t u8TrimSrc; /*!< SCG_FIRCTCFG[TRIMSRC] IRC clock auto trim reference clock source select.*/ +} SCG_FircType; + +/** @brief SOSC definition, include register SCG_SOSCCFG. */ +typedef struct +{ + bool bLock; /*!< SCG_SOSCCSR[LK] bit, Write to set the register can be written or not.*/ + bool bBypass; /*!< SCG_SOSCCSR[BYPASS] bit, Configures SOSC for bypassing the internal oscillator.*/ + bool bCm; /*!< SCG_SOSCCSR[CM] bit,Clock Monitor enable.*/ + bool bCmre; /*!< SCG_SOSCCSR[CMRE] bit, 1:Clock Monitor Reset, 0: interrupt*/ +} SCG_SoscType; + +/** @brief PLL definition, include register SCG_PLLCSR/ SCG_PLLDIV/SCG_PLL0CFG. */ +typedef struct +{ + bool bLock; /*!< SCG_PLLCSR[LK] bit, Write to set the register can be written or not.*/ + bool bCm; /*!< SCG_PLLCSR[CM] bit,Clock Monitor enable.*/ + bool bCmre; /*!< SCG_PLLCSR[CMRE] bit, 1:Clock Monitor Reset, 0: interrupt*/ + bool bSten; /*!< SCG_PLLCSR[STEN] bit, Clock Standby Enable */ + SCG_AsyncClockDivType eDivH; /*!< SCG_PLLDIV[DIVH] bit field definition.*/ + SCG_AsyncClockDivType eDivM; /*!< SCG_PLLDIV[DIVM] bit field definition.*/ + SCG_AsyncClockDivType eDivL; /*!< SCG_PLLDIV[DIVL] bit field definition.*/ + SCG_PllPredivType u8Prediv; /*!< SCG_PLLCFG[PREDIV] bit field definition, the range is 0~31. [Pre-divider = u8Prediv + 1] */ + SCG_PllPstdivType ePstDiv; /*!< SCG_PLLCFG[PSTDIV] bit field definition. [Post Divider = (ePstDiv == 0 ? 2 : 2^ePstDiv)] */ + SCG_PllMultiplyType u16Mult; /*!< SCG_PLLCFG[MULT] bit field definition, this value need to be greater than 95. + [Multiplier = u16Mult + 1] */ + SCG_PllSourceType eSrc; /*!< SCG_PLLCFG[SOURCE] bit field definition.*/ +} SCG_PllType; + +/** @brief Current system clock definition, include register SCG_CCR. */ +typedef struct +{ + bool bSysClkMonitor; /*!< SCG_CCR[SYSCLK_CME], System Clock monitor bit.*/ + SCG_ClockSrcType eSrc; /*!< SCG_CCR[SCS], System Clock Source.*/ + SCG_ClockDivType eDivSlow; /*!< SCG_CCR[DIVSLOW], Slow Clock Divide Ratio.*/ + SCG_ClockDivType eDivBus; /*!< SCG_CCR[DIVBUS], Bus Clock Divide Ratio.*/ + SCG_ClockDivType eDivCore; /*!< SCG_CCR[DIVCORE], Core Clock Divide Ratio.*/ +} SCG_ClockCtrlType; + +/** + * @brief Enable SOSC + * + * @param pSoscConfig SOSC configuration + * @return SCG_StatusType Function status + */ +SCG_StatusType SCG_EnableSOSC(const SCG_SoscType *const pSoscConfig); + +/** + * @brief Disable SOSC + * + * @return SCG_StatusType Funtion status + */ +SCG_StatusType SCG_DisableSOSC(void); + +/** + * @brief Enable FOSC clock with input configuration + * + * @param pFoscConfig FOSC configuration + * @return SCG_StatusType function status + */ +SCG_StatusType SCG_EnableFOSC(const SCG_FoscType *const pFoscConfig); + +/** + * @brief Disable FOSC + * + * @return SCG_StatusType function status + */ +SCG_StatusType SCG_DisableFOSC(void); + +/** + * @brief Set SIRC configuration and configure SIRC DIV + * + * @param pSircConfig SIRC configuation + * @return SCG_StatusType function status + */ +SCG_StatusType SCG_SetSIRC(const SCG_SircType *const pSircConfig); + +/** + * @brief Disable SIRC DIV and clear DIV configuration + * + * @return SCG_StatusType function status + */ +SCG_StatusType SCG_ClearSIRC(void); + +/** + * @brief Enable SIRC32K + * + * @param pSirc32kConfig SIRC32K configuration + * @return SCG_StatusType function status + */ +SCG_StatusType SCG_EnableSIRC32K(const SCG_Sirc32kType *const pSirc32kConfig); + +/** + * @brief Disable SIRC32K + * + * @return SCG_StatusType function status + */ +SCG_StatusType SCG_DisableSIRC32K(void); + +/** + * @brief Enable FIRC + * + * @param pFircConfig FIRC configuration + * @return SCG_StatusType function status + */ +SCG_StatusType SCG_EnableFIRC(const SCG_FircType *const pFircConfig); + +/** + * @brief Disable FIRC + * + * @return SCG_StatusType function status + */ +SCG_StatusType SCG_DisableFIRC(void); + +/** + * @brief Enable PLL + * + * @param ePll PLL instance + * @param pPllConfig PLL configuration + * @return SCG_StatusType function status + */ +SCG_StatusType SCG_EnablePLL(const SCG_PllClkType ePll, const SCG_PllType *const pPllConfig); + +/** + * @brief Disable PLL + * + * @param ePll PLL instance + * @return SCG_StatusType function status + */ +SCG_StatusType SCG_DisablePLL(const SCG_PllClkType ePll); + +/** + * @brief Set system run time clock and related CORE/BUS/SLOW clock. + * + * @param pSysClkConfig pointer to the clockCtrlType structure data instance,which defined for system clock selection. + * @return SCG_StatusType function status + * SCG_STATUS_SUCCESS : clock source and dividers are valid,and switch system clock successfully + * SCG_STATUS_SEQUENCE_ERROR: new clock source is not enabled + * SCG_STATUS_PARAM_ERROR: the core bus slow divider are invalid + * SCG_STATUS_TIMEOUT: switch system clock procedure time out + */ +SCG_StatusType SCG_SetClkCtrl(const SCG_ClockCtrlType *const pSysClkConfig); + +/** + * @brief Get clock frequency + * + * @param eScgClockName Clock source type + * @return uint32_t frequency value + */ +uint32_t SCG_GetScgClockFreq(const SCG_ClkSrcType eScgClockName); + +/** + * @brief Select clock out source + * + * @param eClkoutSel clock out source + */ +void SCG_SetClkOut(const SCG_ClockoutSrcType eClkoutSel); + +/** + * @brief Select NVM clock source + * + * @param eNvmClkSrc NVM clock source + * @return uint32_t function status + */ +SCG_StatusType SCG_SetNvmClk(const SCG_NvmClkSrcType eNvmClkSrc); + +/** + * @brief Select CMU4 clock source + * + * @param eCmu4ClkSrc CMU4 clock source + * @return SCG_StatusType function status + */ +SCG_StatusType SCG_SetCmu4Clk(const SCG_Cmu4ClkSrcType eCmu4ClkSrc); + +/** + * @brief Generate the origion SCG register CRC result, and configure the SCG register CRC option. + * + * @param eMode The SCG register CRC trigger mode + * @return CRC configure status + * SCG_STATUS_SUCCESS : CRC configure successfully + * SCG_STATUS_TIMEOUT : CRC configure time out + */ +SCG_StatusType SCG_RegCrcConfig(SCG_CrcModeType eMode); + +/** + * @brief Trigger the SCG register CRC generation by software + * + */ +void SCG_RegCrcGenerate(void); + +/** + * @brief Trigger the SCG register CRC generation by software,and wait the CRC check result + * + * @return CRC check result + */ +SCG_CrcCheckResType SCG_RegCrcGenerateWaitResult(void); + +/** + * @brief Clock source De-init + * + * @return SCG_StatusType function status + */ +SCG_StatusType SCG_Deinit(void); + + + +/** @}*/ /* fc7xxx_driver_scg */ +#endif diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_scm.h b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_scm.h new file mode 100644 index 0000000..dd3c071 --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_scm.h @@ -0,0 +1,232 @@ +/** + * @file fc7xxx_driver_scm.h + * @author Flagchip085 + * @brief FC7xxx SCM driver type definition and API + * @version 0.1.0 + * @date 2024-01-12 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-01-12 Flagchip085 N/A First version for FC7240 + ******************************************************************************** */ + +#ifndef _DRIVER_SCM_H_ +#define _DRIVER_SCM_H_ + +#include "HwA_scm.h" +#include "HwA_csc.h" +#include "interrupt_manager.h" + +/********* Local typedef ************/ +/** + * @brief SCM return status + * + */ +typedef enum +{ + SCM_E_OK = 0U, /*!< Return ok */ + SCM_E_NOT_OK, /*!< Return not ok */ + SCM_E_PARAM, /*!< Return invalid parameters */ + SCM_E_LOCK, /*!< Return register has been locked */ + SCM_E_TIMEOUT, /*!< Return operation timeout */ + SCM_E_CRC /*!< Return CRC check failed */ +} SCM_RetStatusType; + +/** + * @brief CCMx type + * + */ +typedef enum +{ + SCM_CCM0 = 0U /*!< CCM0 */ +} SCM_CCM_Type; + +/** + * @brief Matrixx type + * + */ +typedef enum +{ + SCM_MatrixStatus_0 = 0U, /*!< Matrix status 0 */ + SCM_MatrixStatus_1, /*!< Matrix status 1 */ + SCM_MatrixStatus_2, /*!< Matrix status 2 */ + SCM_MatrixStatus_5, /*!< Matrix status 5 */ + SCM_MatrixStatus_6, /*!< Matrix status 6 */ + SCM_MatrixStatus_7, /*!< Matrix status 7 */ + SCM_MatrixStatus_ID /*!< Matrix ID status */ +} SCM_MatrixStatusType; + +/** + * @brief SCM registers CRC trigger mode + */ +typedef enum +{ + SCM_CRC_SW_MODE = 0U, /*!< SCM registers CRC software mode. */ + SCM_CRC_TRIGGER_MODE = 1U /*!< SCM registers CRC trigger mode. */ +} SCM_CrcModeType; + +/********* Local function ************/ +/** + * @brief Get unique identification for the chip, loaded from NVR. + * + * @param pUid Pointer to UID + * + */ +void SCM_GetChip_UID(uint32 *pUid); + +/** + * @brief Get CCMx status. + * + * @param eCCMType CCM type + * @param u32Value The or value of SCM_CCMxStatusType to select the status to get + * + */ +uint32_t SCM_GetStatus_CCMx(SCM_CCM_Type eCCMType, uint32_t u32Value); + +/** + * @brief Get matrix status. + * + * @param eMatrixType Matrix type + * @param u32Value selection to get + * + */ +uint32_t SCM_GetStatus_Matrix(SCM_MatrixStatusType eMatrixType, uint32_t u32Value); + +/** + * @brief Set cpu to control MAM ECC enable register 0. + * + * @param eCpuType Cpu to use + * @param bLockStatus Lock the cpu control settings + * + * @return Set operation success/failed + */ +SCM_RetStatusType SCM_SetCpuCtrl_MAMECCR0(const SCM_WPB_CpuType eCpuType, bool bLockStatus); + +/** + * @brief Set cpu to control MAM ECC enable register 1. + * + * @param eCpuType Cpu to use + * @param bLockStatus Lock the cpu control settings + * + * @return Set operation success/failed + */ +SCM_RetStatusType SCM_SetCpuCtrl_MAMECCR1(const SCM_WPB_CpuType eCpuType, bool bLockStatus); + +/** + * @brief Set cpu to control CPU0 ECC enable register. + * + * @param eCpuType Cpu to use + * @param bLockStatus Lock the cpu control settings + * + * @return Set operation success/failed + */ +SCM_RetStatusType SCM_SetCpuCtrl_CPU0ECCEN(const SCM_WPB_CpuType eCpuType, bool bLockStatus); + +/** + * @brief Set cpu to control SOCMISC register. + * + * @param eCpuType Cpu to use + * @param bLockStatus Lock the cpu control settings + * + * @return Set operation success/failed + */ +SCM_RetStatusType SCM_SetCpuCtrl_SOCMISC(const SCM_WPB_CpuType eCpuType, bool bLockStatus); + +/** + * @brief Set cpu to control Subsystem pcc register. + * + * @param eCpuType Cpu to use + * @param bLockStatus Lock the cpu control settings + * + * @return Set operation success/failed + */ +SCM_RetStatusType SCM_SetCpuCtrl_SUBSYS_PCC(const SCM_WPB_CpuType eCpuType, bool bLockStatus); + +/** + * @brief Set cpu to control master halt request register. + * + * @param eCpuType Cpu to use + * @param bLockStatus Lock the cpu control settings + * + * @return Set operation success/failed + */ +SCM_RetStatusType SCM_SetCpuCtrl_MASTER_HALT_REQ(const SCM_WPB_CpuType eCpuType, bool bLockStatus); + +/** + * @brief Set lock FTU_ROUTING register. + * + */ +void SCM_SetLock_FTU_ROUTING(void); + +/** + * @brief Set lock FTU_GTB register. + * + */ +void SCM_SetLock_FTU_GTB(void); + +/** + * @brief Set lock DEBUG_TRACE register. + * + */ +void SCM_SetLock_DEBUG_TRACE(void); + +/** + * @brief Set lock FLEXCAN_ROUTING register. + * + */ +void SCM_SetLock_FLEXCAN_ROUTING(void); + +/** + * @brief Set lock MSC0_ROUTING register. + * + */ +void SCM_SetLock_MSC0_ROUTING(void); + +/** + * @brief Set lock INT_ROUTER_NMI register. + * + */ +void SCM_SetLock_INT_ROUTER_NMI(void); + +/** + * @brief Set NMI interrupt router . + * + * @param eCpuType Cpu to use + * @param bEnable Enable/Disable + * @return Set operation success/failed + * SCM_E_OK: Set NMI interrupt router successfully + * SCM_E_PARAM: eCpuType invalid + */ +SCM_RetStatusType SCM_SetEnable_NMIIntRouter(const SCM_WPB_CpuType eCpuType, bool bEnable); + +/** + * @brief Generate the origion SCM register CRC result, and configure the SCM register CRC option. + * + * @param eMode The SCM register CRC trigger mode + * @return CRC configure status + * SCM_E_OK : CRC configure successfully + * SCM_E_TIMEOUT : CRC configure time out + */ +SCM_RetStatusType SCM_RegCrcConfig(SCM_CrcModeType eMode); + +/** + * @brief Trigger the SCM register CRC generation by software + * + */ +void SCM_RegCrcGenerate(void); + +/** + * @brief Trigger the SCM register CRC generation by software,and wait the CRC check result + * + * @return CRC check result + */ +SCM_RetStatusType SCM_RegCrcGenerateWaitResult(void); + + +#endif /* end of _DRIVER_SCM_H_ */ diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_scst.h b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_scst.h new file mode 100644 index 0000000..7a11c88 --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_scst.h @@ -0,0 +1,137 @@ +/** + * @file fc7xxx_driver_scst.h + * @author Flagchip + * @brief FC7xxx scst driver type definition and API + * @version 0.1.0 + * @date 2023-12-29 + * + * @copyright Copyright (c) 2023 Flagchip Semiconductors Co., Ltd. + * + */ +/********************************************************************************* +* Revision History: +* +* Version Date Initials CR# Descriptions +* --------- ---------- ------------ ---------- --------------- +* 0.1.0 2023-12-29 qxw074 N/A First version for FC7240 +******************************************************************************** */ + +#ifndef _DRIVER_FC7XXX_DRIVER_SCST_H_ +#define _DRIVER_FC7XXX_DRIVER_SCST_H_ + +#include "device_header.h" + +/** + * @addtogroup fc7xxx_driver_scst + * @{ + */ + +/** + * @brief typed of test result returned + * + */ +typedef enum +{ + M7ST_FaultInjectError, + M7ST_ErrorAluTest, + M7ST_ErrorAluMLATest, + M7ST_ErrorAluSHIFTTest, + M7ST_ErrorAluTes1t, + M7ST_ErrorAluTest2, + M7ST_ErrorAluTest3, + M7ST_ErrorAluTest4, + M7ST_ErrorAluTest5, + M7ST_ErrorAluTest6, + M7ST_ErrorRegbankTest1, + M7ST_ErrorRegbankTest2, + M7ST_ErrorRegbankTest3, + M7ST_ErrorRegbankTest4, + M7ST_ErrorRegbankTest5, + M7ST_ErrorRegbankTest6, + M7ST_ErrorLoadStoreTest1, + M7ST_ErrorLoadStoreTest2, + M7ST_ErrorLoadStoreTest3, + M7ST_ErrorLoadStoreTest4, + M7ST_ErrorLoadStoreTest5, + M7ST_ErrorLoadStoreTest6, + M7ST_ErrorSimdSatTest1, + M7ST_ErrorSimdSatTest2, + M7ST_ErrorSimdSatTest3, + M7ST_ErrorSimdSatTest4, + M7ST_ErrorMacTest1, + M7ST_ErrorMacTest2, + M7ST_ErrorFetchTest, + M7ST_ErrorStatusTest1, + M7ST_ErrorStatusTest2, + M7ST_ErrorBranchTest1, + M7ST_ErrorBranchTest2, + M7ST_ErrorIntSvcTest, + M7ST_ErrorIntBusFaultTest, + M7ST_ErrorIntHardFaultTest1, + M7ST_ErrorIntHardFaultTest2, + M7ST_ErrorIntUsageFaultTest, + M7ST_ErrorIntSystickTest, + M7ST_ErrorIntPendSvTest, + M7ST_ErrorIntMemFaultTest, + M7ST_ErrorIntMaskingTest, + M7ST_ErrorIntHandlerThreadsTest, + M7ST_ErrorIntNMIHfTest, + M7ST_ErrorIntTailChainTest, + M7ST_ErrorIntAluTest, + M7ST_ErrorIntBranchTest, + M7ST_ErrorIntStatusTest, + M7ST_ErrorM7ST_TestPass +} Type_M7ST_AtomicStatus; + +/** + * @brief typed of test index + * + */ +typedef enum +{ + M7ST_AluTest, + M7ST_AluMLATest, + M7ST_AluSHIFTTest, + M7ST_AluTes1t, + M7ST_AluTest2, + M7ST_AluTest3, + M7ST_AluTest4, + M7ST_AluTest5, + M7ST_AluTest6, + M7ST_RegbankTest1, + M7ST_RegbankTest2, + M7ST_RegbankTest3, + M7ST_RegbankTest4, + M7ST_RegbankTest5, + M7ST_RegbankTest6, + M7ST_LoadStoreTest1, + M7ST_LoadStoreTest2, + M7ST_LoadStoreTest3, + M7ST_LoadStoreTest4, + M7ST_LoadStoreTest5, + M7ST_LoadStoreTest6, + M7ST_SimdSatTest1, + M7ST_SimdSatTest2, + M7ST_SimdSatTest3, + M7ST_SimdSatTest4, + M7ST_MacTest1, + M7ST_MacTest2, + M7ST_FetchTest, + M7ST_StatusTest1, + M7ST_StatusTest2, + M7ST_BranchTest1, + M7ST_BranchTest2, + M7ST_RegressionTest +} SCST_TestIndexType; + +/** + * @brief This function is used to get the result of the executed test + * + * @param test_index is test number,0U..32U + * @param s_u32RamBase The first address of the 1k memory that the program needs to run + * @return M7ST_ErrorM7ST_TestPass is ok, others are not ok + */ +Type_M7ST_AtomicStatus SCST_ExecuteTest(SCST_TestIndexType test_index,uint32_t *s_u32RamBase); + +/** @}*/ /* fc7xxx_driver_scst */ +#endif diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_sec.h b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_sec.h new file mode 100644 index 0000000..9f842af --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_sec.h @@ -0,0 +1,371 @@ +/** + * @file fc7xxx_driver_sec.h + * @author Flagchip + * @brief FC7xxx sec driver type definition and API + * @version 0.2.0 + * @date 2023-2-7 + * + * @copyright Copyright (c) 2023 Flagchip Semiconductors Co., Ltd. + * + * @details + */ +/******************************************************************************** +* Revision History: +* +* Version Date Initials CR# Descriptions +* --------- ---------- ------------ ---------- --------------- +* 0.2.0 2023-2-7 Flagchip076 N/A First version for FC7300 +********************************************************************************/ + + +#ifndef _DRIVER_SEC_H_ +#define _DRIVER_SEC_H_ + +#include "HwA_sec.h" +#include "device_header.h" + +/** + * @addtogroup fc7xxx_driver_sec + * @{ + */ + +/** + * @brief Debug Re-Enable Key + * @note Only if four 32-bit writes match, it will set the DEN to 0x5 to enable + debug and unlock SEC registers. The key is up to the user to decide in advance. + * */ +typedef struct +{ + uint32_t Re_key0; /*!< The Debug Re-enable key 0*/ + uint32_t Re_key1; /*!< The Debug Re-enable key 1*/ + uint32_t Re_key2; /*!< The Debug Re-enable key 2*/ + uint32_t Re_key3; /*!< The Debug Re-enable key 3*/ + +} ReEnDebug_Keys; + +typedef enum +{ + SEC_STATUS_SUCCESS = 0U, /*!< SEC status success */ + SEC_STATUS_FAILED = 1U /*!< SEC status failed */ +}SEC_RetType; + +/** + * @brief NVR write and read Permissions. + * @*/ +typedef struct +{ + bool WritEn; /*!< The NVR write permission*/ + bool ReadEn; /*!< The NVR read permission*/ + bool EraseEn; /*!< The NVR Erase permission*/ +} NVR_Per; + +/** + * @brief Indicate the system state + * + * */ +typedef enum +{ + Securedstate = 0u, /*!< The system is in secured state*/ + UnSecuredstate = 1u /*!< The system is in no secured state*/ +} Systemstate; + +/** + * @brief Indicate the ISP instance + * + * */ +typedef enum +{ + ISP_FCUART1 = 0U, /*!< The ISP instance is FCUART1 */ + ISP_FCUART3 = 1U, /*!< The ISP instance is FCUART3 */ + ISP_FLEXCAN1 = 2U, /*!< The ISP instance is FLEXCAN1 */ + ISP_FLEXCAN5 = 3U /*!< The ISP instance is FLEXCAN3 */ +}Isp_Instance; + +/** + * @brief Indicate the FCUART Baud Rate for ISP + * + * */ +typedef enum +{ + ISP_FCUART_2MBPS =0u, /*!< the FCUART Baud Rate is 2Mbps*/ + ISP_FCUART_1MBPS =1u, /*!< the FCUART Baud Rate is 1Mbps*/ + ISP_FCUART_512KBPS =2u, /*!< the FCUART Baud Rate is 512kbps*/ + ISP_FCUART_115200BPS =3u, /*!< the FCUART Baud Rate is 115200bps*/ + ISP_FCUART_INVALID = 4u /*!< the ISP instance is not FCUART*/ +}FCUART_ISP_BAUDRATE; + +/** + * @brief Indicate the FLEXCAN Baud Rate for ISP + * + * */ +typedef enum +{ + ISP_FLEXCANFD_4MBPS =0u, /*!< the CANFD Baud Rate is 4Mbps*/ + ISP_FLEXCANFD_2MBPS =1u, /*!< the CANFD Baud Rate is 2Mbps*/ + ISP_FLEXCAN_1MBPS =2u, /*!< the CAN Baud Rate is 1Mbps*/ + ISP_FLEXCAN_500kBPS =3u, /*!< the FCUART Baud Rate is 500kbps*/ + ISP_FLEXCAN_INVALID = 4u /*!< the ISP instance is not FLEXCAN*/ +}FLEXCAN_ISP_BAUDRATE; + +/** + * @brief Indicate the ISP information. + * + * */ +typedef struct +{ + bool IspModeEn; /*!< true means - ISP mode is active.*/ + bool IspPinEn; /*!< true means - ISP pin is active.The associated pin defaults to internal pull up enabled.*/ + bool IspAuthEn; /*!<*true means - ISP Auth Enable. Only valid in secure boot. (Value loaded from NVR sector)*/ + Isp_Instance Ispinstance; /*!< the Isp instance*/ + FCUART_ISP_BAUDRATE Ispfcuartbaudrate; /*!< Indicate the FCUART Baud Rate for ISP*/ + FLEXCAN_ISP_BAUDRATE Ispflexcanbaudrate; /*!< Indicate the FLEXCAN Baud Rate for ISP*/ + +}SEC_IspInfo; + +/** + * @brief Indicate the fast boot speed. + * + * */ +typedef enum +{ + FASTBOOT_300MHZ = 0u, /*!< Select PLL0 as the core clock source; the core clock is 300MHz.*/ + FASTBOOT_96MHZ = 1u /*!< Select FIRC as the core clock source; the core clock is 96MHz.*/ +}FastBoot_Speed; + +/** + * @brief Indicate the OSC Frequency + * + * */ +typedef enum +{ + OSC_8MHZ = 0u, /*!SENT_CHN[echannel].CHN_DFD)) +#define SENT_GET_FAST_MSG_DMA_BYTELENGTH (12U) +#define SENT0_GET_SLOW_MSG_DMA_ADDR(echannel) (&(SENT->SENT_CHN[echannel].CHN_DSB3)) +#define SENT_GET_SLOW_MSG_DMA_BYTELENGTH (12U) + + /** + * @brief SENT operation return values + * + */ + typedef enum + { + SENT_RETURN_OK = 0x00U, /*!< The SENT operation is succeeded */ + SENT_RETURN_E_NOT_OK = 0x01U, /*!< The SENT operation is failed */ + SENT_RETURN_E_ALREADY_INIT = 0x02U, /*!< The SENT has been initialized. */ + SENT_RETURN_E_UNINIT = 0x03U, /*!< The SENT is not initialized */ + SENT_RETURN_E_PARAM = 0x04U, /*!< The SENT parameter is incorrect or out of range. */ + } + Sent_ReturnType; + + /** + * @brief SENT Channel index + * + */ + typedef enum + { + SENT_CHANNEL_0 = 0x00U, /*!< The SENT channel 0 */ + SENT_CHANNEL_1 = 0x01U, /*!< The SENT channel 1 */ + SENT_CHANNEL_2 = 0x02U, /*!< The SENT channel 2 */ + SENT_CHANNEL_3 = 0x03U, /*!< The SENT channel 3 */ + SENT_CHANNEL_MAX = SENT_CHANNEL_COUNT + } Sent_ChannelType; + + /** + * @brief SENT instance index + * + */ + typedef enum + { + SENT_INSTANCE_0 = 0x00U, /*!< The SENT channel 0 */ + SENT_INSTANCE_1 = 0x01U, /*!< The SENT channel 1 */ + SENT_INSTANCE_MAX = SENT_INSTANCE_COUNT + } Sent_InstanceType; + + /** + * @brief SENT nibble data mode control. Refer to SENT SAE J2716 2010 for detail protocol definition + * + */ + typedef enum + { + SENT_DATA_NIBBLE_MODE_A = 0x0U, /*!< Frame format A */ + SENT_DATA_NIBBLE_MODE_H1 = 0x1U, /*!< Frame format H1 */ + SENT_DATA_NIBBLE_MODE_H2 = 0x2U, /*!< Frame format H2 */ + SENT_DATA_NIBBLE_MODE_H3 = 0x3U, /*!< Frame format H3 */ + SENT_DATA_NIBBLE_MODE_H4 = 0x4U, /*!< Frame format H4 */ + SENT_DATA_NIBBLE_MODE_H5 = 0x5U, /*!< Frame format H5 */ + SENT_DATA_NIBBLE_MODE_H6 = 0x6U, /*!< Frame format H6 */ + SENT_DATA_NIBBLE_MODE_H7 = 0x7U /*!< Frame format H7 */ + } Sent_DataNibbleModeType; + + /** + * @brief SENT calibration valid type + * + */ + typedef enum + { + SENT_CALIBRATION_VALID_DISABLE = 0x0U, /*!< The successive calibration pulses diagnostic will be disabled */ + SENT_CALIBRATION_VALID_WITHIN_20 = 0x1U, /*!< The difference of received calibration pulse and receiver configuration is within 20%, the message is deemed to be valid */ + SENT_CALIBRATION_VALID_FROM_20_TO_25 = 0x2U, /*!< The difference of received calibration pulse and receiver configuration is more than 20% but less than 25%, the message is deemed to be valid */ + } Sent_CalibrationValidType; + + /** + * @brief SENT Successive calibration pulses diagnostic option + * + */ + typedef enum + { + SENT_CALIBRATION_PULSE_DIAG_OPTION2 = 0x0U, /*!< Option 2 i.e. Low Latency Option as per SAE Specification */ + SENT_CALIBRATION_PULSE_DIAG_OPTION1 = 0x1U, /*!< Option 1 i.e. Preferred but High Latency Option as per SAE Specification */ + } Sent_CalDiagOptionType; + + /** + * @brief Determines how long the bus idle flag will assert when SENT bus is idle + * + */ + typedef enum + { + SENT_IDLE_COUNT_FLAG_DISABLE = 0x0U, /*!< The bus idle flag will never assert */ + SENT_IDLE_COUNT_FLAG_254_TICKS = 0x1U, /*!< The bus is idle for more than 127*2 ticks, then the bus idle flag will assert */ + SENT_IDLE_COUNT_FLAG_508_TICKS = 0x2U, /*!< The bus is idle for more than 127*2 ticks, then the bus idle flag will assert */ + SENT_IDLE_COUNT_FLAG_1016_TICKS = 0x4U, /*!< The bus is idle for more than 127*2 ticks, then the bus idle flag will assert */ + SENT_IDLE_COUNT_FLAG_2032_TICKS = 0x8U, /*!< The bus is idle for more than 127*2 ticks, then the bus idle flag will assert */ + } Sent_IdleCountType; + + /** + * @brief SENT Slow message type. + * + */ + typedef enum + { + SENT_SERIAL_MESSAGE_SHORT = 0x0U, /*!< short serial data message */ + SENT_SERIAL_MESSAGE_ENHANCE_12DATA_8ID = 0x1U, /*!< enhanced serial data message with 12-bit data and 8-bit ID */ + SENT_SERIAL_MESSAGE_ENHANCE_16DATA_4ID = 0x2U, /*!< enhanced serial data message with 16-bit data and 4-bit ID */ + } Sent_SerialMessageType; + + /** + * @brief SENT trigger type in SPC mode + * + */ + typedef enum + { + SENT_SPC_SOFTWARE_TRIGGER = 0x0U, /*!< SPC pulse triggered by software method */ + SENT_SPC_EXTERNAL_TRIGGER = 0x1U, /*!< SPC pulse triggered by external trigger */ + } Sent_SpcTriggerType; + + /** + * @brief Select the tick base in SPC mode + * + */ + typedef enum + { + SENT_SPC_TICK_BASE_PRE_MSG = 0x0U, /*!< Previous received message tick base */ + SENT_SPC_TICK_BASE_CONFIGURED = 0x1U, /*!< SENT configured tick base */ + } Sent_SpcTickBaseType; + + /** + * @brief Sent global interrupt type. + * + */ + typedef enum + { + SENT_SLOW_MSG_DMA_UF_IT = 0U, /*!< Slow message dma read underflow interrupt enable. */ + SENT_FAST_MSG_DMA_DF_IT = 1U, /*!< Fast message dma read underflow interrupt enable. */ + SENT_FAST_MSG_READY_IT = 2U, /*!< Fast message ready interrupt enable. */ + SENT_SLOW_MSG_READY_IT = 3U, /*!< Slow message ready interrupt enable. */ + SENT_FAST_MSG_FIFO_OF_IT = 4U, /*!< Fast message FIFO overflow interrupt enable. */ + } Sent_GlobalInterruptType; + + /** + * @brief Structure to enable or disable the channel interrupts. + * + */ + typedef struct + { + bool bBusIdleITEn; /*!< Bus idle interrupt enable. */ + bool bSpcOverrunITEn; /*!< SPC overrun interrupt enable. */ + bool bCalResyncErrITEn; /*!< Continuous 2 sync/calibration pulse difference exceed 1.5625% error interrupt enable. */ + bool bCalFailITEn; /*!< Calibation 20% pass 25% fail interrupt enable. */ + bool bSlowMsgOFITEn; /*!< Slow message overflow interrupt enable. */ + bool bFastMsgOFITEn; /*!< Fast message overflow interrupt enable. */ + bool bNibbleValueErrITEn; /*!< Nibble value more than 15 or less than 0 error interrupt enable. */ + bool bPrePulseDiagErrITEn; /*!< Previous pulse diagnosis error interrupt enable. */ + bool bCalDiagErrITEn; /*!< Calibration diagnosis over 25% error interrupt enable. */ + bool bCalErrITEn; /*!< Sync/calibration pulse difference eceed 1.5625% error interrupt enable. */ + bool bSlowMsgCrcErrITEn; /*!< Slow message CRC check error interrupt enable. */ + bool bFastMsgCrcErrITEn; /*!< Fast message CRC check error interrupt enable. */ + bool bFallingEdgeNumErrITEn; /*!< Falling edge number error interrupt enable. */ + } Sent_ChannelInterruptType; + + /** + * @brief Structure for fast message buffer. + * + */ + typedef struct + { + uint8_t u8CRC; /*!< Receied fast message CRC data. */ + uint8_t u8SC; /*!< Fast message status communication nibble value. */ + uint32_t u32Timestamp; /*!< Fast message timestamp value. */ + uint32_t u32Data; /*!< Received fast message data nibble. */ + } Sent_FastMessageDataType; + + /** + * @brief Structure for slow message buffer. + * + */ + typedef struct + { + Sent_SerialMessageType eMsgType; /*!< Slow message type. */ + uint8_t u8CRC; /*!< Slow message crc data. */ + uint8_t u8ID; /*!< Slow message ID. */ + uint16_t u16Data; /*!< Slow message data. */ + uint32_t u32Timestamp; /*!< Slow message timestamp value. */ + } Sent_SlowMessageDataType; + + /** + * @brief SENT Global ISR callback function prototype + * + */ + typedef void (*SENT_GBISRCallbackType)(Sent_ChannelType eChannel, const Sent_GlobalInterruptType eInterrupt); + + /** + * @brief SENT Channel ISR callback function prototype + * + */ + typedef void (*SENT_CHISRCallbackType)(Sent_ChannelType eChannel, const uint32_t u32ChannelStatus); + + /** + * @brief structure to configure the SENT. + * + */ + typedef struct + { + uint8_t u8PreScaler; /**/ + STCU_SELFTEST_DONE = 0x01U, /***/ + STCU_SELFTEST_ABORT = 0x02U, /***/ + STCU_SELFTEST_LBIST_ERROR = 0x10U, /***/ + STCU_SELFTEST_MBIST_ERROR = 0x20U, /***/ + STCU_SELFTEST_TIMEOUT_ERROR = 0x40U, /***/ + STCU_SELFTEST_NVRLOAD_ERROR = 0x100U, /***/ + STCU_SELFTEST_SELFCHECK_ERROR = 0x200u /***/ +}STCU_SelfTestStatusType; + +/** @brief STCU interrupt flag */ +typedef enum +{ + STCU_INTERRUPT_FLAG_NONE = 0x00U, /***/ + STCU_INTERRUPT_FLAG_SIZE_ERR = 0x01U, /***/ + STCU_INTERRUPT_FLAG_SEQ_ERR = 0x02U, /***/ +}STCU_InterruptFlagType; + +/** @brief The items select for MBIST */ +typedef enum +{ + STCU_MBIST_SEL_NONE = 0x00U, /***/ + STCU_MBIST_SEL_SRAM = 0x01U, /***/ + STCU_MBIST_SEL_ITCM_CPU0 = 0x02U, /***/ + STCU_MBIST_SEL_DTCM0_CPU0 = 0x04U, /***/ + STCU_MBIST_SEL_DTCM1_CPU0 = 0x08U, /***/ + STCU_MBIST_SEL_CACHE_CPU0 = 0x10U, /***/ + STCU_MBIST_SEL_SUBSYS = 0x20U, /***/ + STCU_MBIST_SEL_SRAM_HSM = 0x40U, /***/ + STCU_MBIST_SEL_SRAM_DMACAN = 0x80U, /***/ + STCU_MBIST_SEL_ROM_HOST = 0x100U, /***/ + STCU_MBIST_SEL_ROM_HSM = 0x200U /***/ +}STCU_MbistSelType; + +/** @brief MBIST done status flag. */ +typedef enum +{ + STCU_MBIST_DONE_NONE = 0x00U, /***/ + STCU_MBIST_DONE_SRAM = 0x01U, /***/ + STCU_MBIST_DONE_ITCM_CPU0 = 0x02U, /***/ + STCU_MBIST_DONE_DTCM0_CPU0 = 0x04U, /***/ + STCU_MBIST_DONE_DTCM1_CPU0 = 0x08U, /***/ + STCU_MBIST_DONE_CACHE_CPU0 = 0x10U, /***/ + STCU_MBIST_DONE_SUBSYS = 0x20U, /***/ + STCU_MBIST_DONE_SRAM_HSM = 0x40U, /***/ + STCU_MBIST_DONE_SRAM_DMACAN = 0x80U, /***/ + STCU_MBIST_DONE_ROM_HOST = 0x100U, /***/ + STCU_MBIST_DONE_ROM_HSM = 0x200U /***/ +}STCU_MbistDoneType; + +/** @brief MBIST fail status flag. */ +typedef enum +{ + STCU_MBIST_FAIL_NONE = 0x00U, /***/ + STCU_MBIST_FAIL_SRAM = 0x01U, /***/ + STCU_MBIST_FAIL_ITCM_CPU0 = 0x02U, /***/ + STCU_MBIST_FAIL_DTCM0_CPU0 = 0x04U, /***/ + STCU_MBIST_FAIL_DTCM1_CPU0 = 0x08U, /***/ + STCU_MBIST_FAIL_CACHE_CPU0 = 0x10U, /***/ + STCU_MBIST_FAIL_SUBSYS = 0x20U, /***/ + STCU_MBIST_FAIL_SRAM_HSM = 0x40U, /***/ + STCU_MBIST_FAIL_SRAM_DMACAN = 0x80U, /***/ + STCU_MBIST_FAIL_ROM_HOST = 0x100U, /***/ + STCU_MBIST_FAIL_ROM_HSM = 0x200U /***/ +}STCU_MbistFailedType; + +/** @brief Hardware SRAM initialization mode. */ +typedef enum +{ + STCU_INIT_RAM_MODE_POR_OR_WAKEUP4STANDBY0 = 0U, /***/ + STCU_INIT_RAM_MODE_AFTER_WAKEUP4STANDBY1, /***/ + STCU_INIT_RAM_MODE_AFTER_WAKEUP4STANDBY2, /***/ + STCU_INIT_RAM_MODE_AFTER_WAKEUP4STANDBY3 /***/ +}STCU_InitRamModeType; + +/** @brief The items select for Hardware SRAM Initialization. */ +typedef enum +{ + STCU_INIT_RAM_TYPE_NONE = 0x00U, /***/ + STCU_INIT_RAM_TYPE_SRAM = 0x01U, /***/ + STCU_INIT_RAM_TYPE_ITCM_CPU0 = 0x02U, /***/ + STCU_INIT_RAM_TYPE_DTCM0_CPU0 = 0x04U, /***/ + STCU_INIT_RAM_TYPE_DTCM1_CPU0 = 0x08U, /***/ +}STCU_InitRamType; + +/** @brief Init Ram done status flag. */ +typedef enum +{ + STCU_INIT_RAM_DONE_TYPE_NONE = 0x00U, /***/ + STCU_INIT_RAM_DONE_TYPE_SRAM = 0x01U, /***/ + STCU_INIT_RAM_DONE_TYPE_ITCM_CPU0 = 0x02U, /***/ + STCU_INIT_RAM_DONE_TYPE_DTCM0_CPU0 = 0x04U, /***/ + STCU_INIT_RAM_DONE_TYPE_DTCM1_CPU0 = 0x08U, /***/ +}STCU_InitRamDoneType; + +/** @brief Init Ram status flag. */ +typedef enum +{ + STCU_HARDWARE_INIT_RAM_STATUS_NONE = 0U, /***/ + STCU_HARDWARE_INIT_RAM_STATUS_DONE = 1U, /***/ + STCU_HARDWARE_INIT_RAM_STATUS_BUSY = 2U, /***/ + STCU_HARDWARE_INIT_RAM_STATUS_ABORT = 4U /***/ +}STCU_HardwareInitRamStatusType; + +/** @brief LBIST status flag. */ +typedef enum +{ + STCU_LBIST_STATUS_NONE = 0U, /***/ + STCU_LBIST_STATUS_DONE = 1U, /***/ + STCU_LBIST_STATUS_FAILED = 2U /***/ +}STCU_LbistStatusType; + +/** @brief LBIST Clock Divider. */ +typedef enum +{ + STCU_LBIST_CLK_DIVIDER_BY_2 = 1U, /***/ + STCU_LBIST_CLK_DIVIDER_BY_3 = 2U, /***/ + STCU_LBIST_CLK_DIVIDER_BY_4 = 3U, /***/ +}STCU_LbistClkDivType; + +/** @brief clock source of self-test. */ +typedef enum +{ + STCU_CLK_SOURCE_FIRC = 0U, /***/ + STCU_CLK_SOURCE_PLL = 1U /***/ +}STCU_ClkSourceType; + +/** @brief Self-test Port Pull Selection. */ +typedef enum +{ + STCU_PORT_PULL_DISABLE = 0U, /***/ + STCU_PORT_PULL_DOWN, /***/ + STCU_PORT_PULL_UP /***/ +}STCU_PortPullModeType; + +/** @brief Stcu call back function type, the u32status should refer to "STCU_InterruptFlagType" */ +typedef void (*Stcu_IRQCallback)(uint32_t u32Status); + +typedef struct +{ + bool bLbistEn; /***/ + bool bMbistLPC; /***/ + bool bMbistEn; /***/ + bool bMbistFullTest; /***/ + bool bMbistSramInit; /***/ + bool bInterruptEn; /***/ + STCU_PortPullModeType ePortPullMode; /***/ + STCU_ClkSourceType eClkSource; /***/ + STCU_LbistClkDivType eLbistClkDivider; /***/ + uint16_t u16MaxTime; /***/ + uint32_t u32MbistSel; /***/ +}STCU_ConfigType; + + +typedef struct +{ + STCU_InitRamModeType eInitMode; /**< RAM Initial Mode */ + uint8_t bLockAfterEn; /**< Lock STCU after RAM Initial */ + uint32_t u32InitRamType; /**< RAM Type, DTCM, ITCM, SRAM, refer to "STCU_InitRamType" and use OR to combine them */ +}STCU_InitRamConfigType; + + +/** + * \brief Init the STCU module + * + * \param pConfig the configuration structure + */ +void STCU_Init(STCU_ConfigType *pConfig); + +/** + * \brief Trigger to start Software self test + * + */ +void STCU_StartSelfTest(void); + +/** + * \brief Check Software Trigger Self-test result + * + * \return refer to "STCU_SelfTestStatusType" enum. + */ +uint32_t STCU_CheckTriggerResult(void); + +/** + * \brief Initial RAM with hardware + * + * \param pConfig the configuration structure + */ +void STCU_StartRamInit(STCU_InitRamConfigType *pInitCfg); + +/** + * \brief Get status of RAM initialize action + * + * \return the status of ram initialize action, refer to "STCU_HardwareInitRamStatusType" + */ +uint32_t STCU_GetRamInitStatus(void); + +/** + * \brief Get if the LBIST test result is Fail + * + * \return true means LBIST fail. false means LBIST pass. + */ +bool STCU_GetLbistFailResult(void); +/** + * \brief Get each MBIST Fail result + * + * \return refer to "STCU_MbistFailedType" enum. + */ +uint32_t STCU_GetMbistFailResult(void); + +/** + * \brief Get each done status of SRAM initialize + * + * \return the done status of SRAM initialize action, refer to "STCU_InitRamDoneType" + */ +uint32_t STCU_GetRamInitDoneStatus(void); + +/** + * \brief Set the LBIST Pattern value and expected misr value. + * The two value should be load from NVR, but also can reconfigure by this API. + * The expected misr value is calculated from pattern, so please make sure this two value is right, or the LBST would fail. + * + * \param u16Pattern the LBIST Pattern value + * \param u16Pattern the LBIST expected misr value + */ +void STCU_LBIST_Set_Pattern_Misr(uint16_t u16Pattern, uint32_t u32ExpectedMisr); + +/** + * \brief Get LBIST actual MISR value, the value should be read and use DFT tool to decode it, if LBIST test resault is fail. + * + * \return the LBIST actual MISR value + */ +uint32_t STCU_GetLbistAcutalMisr(void); + +/** + * @brief STCU 0 interrupt handler + * + * @note This function should be called as/in STCU 0 interrupt handler + */ +void STCU0_IRQHandler(void); +#endif /* end of _DRIVER_STCU_H_ */ diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_systick.h b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_systick.h new file mode 100644 index 0000000..5517e64 --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_systick.h @@ -0,0 +1,28 @@ +#ifndef _DRIVER_CORE_SYSTICK_H_ +#define _DRIVER_CORE_SYSTICK_H_ + +#include "device_header.h" + + +/** + * \brief Config system tick + * + * \param u32ReloadVal reload value, val is decrease from reload value + * \return 0 is ok, and others are not ok + */ +uint8_t Core_SysTick_Config(uint32_t u32ReloadVal); + +void Core_SysTick_DeConfig(void); + +void Core_SysTick_SetValue(uint32_t u32Value); + +void Core_SysTick_ClearValue(void); + +uint32_t Core_SysTick_GetValue(void); + +void Core_SysTick_Enable(void); + +void Core_SysTick_Disable(void); + + +#endif /* end of _DRIVER_CORE0_SYSTICK_H_ */ diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_tmu.h b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_tmu.h new file mode 100644 index 0000000..711afec --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Inc/fc7xxx_driver_tmu.h @@ -0,0 +1,156 @@ +/** + * @file fc7xxx_driver_tmu.h + * @author Flagchip + * @brief FC7xxx TMU driver type definition and API + * @version 0.1.0 + * @date 2023-12-29 + * + * @copyright Copyright (c) 2023 Flagchip Semiconductors Co., Ltd. + * + */ +/********************************************************************************* +* Revision History: +* +* Version Date Initials CR# Descriptions +* --------- ---------- ------------ ---------- --------------- +* 0.1.0 2023-12-29 qxw074 N/A First version for FC7240 +******************************************************************************** */ + +#ifndef _DRIVER_FC7XXX_DRIVER_TMU_H_ +#define _DRIVER_FC7XXX_DRIVER_TMU_H_ +#include "device_header.h" +#include "HwA_tmu.h" + +#if defined(__cplusplus) +extern "C" { +#endif +/** + * @addtogroup fc7xxx_driver_tmu + * @{ + */ + +/** + * @brief The Flag-based temperature sensor over 150 Celsius callback function prototype + * + */ +typedef void (*TMU_TempOver150InterruptCallbackType)(void); + +/** + * @brief The Flag-based temperature sensor over 125 Celsius callback function prototype + * + */ +typedef void (*TMU_TempOver125InterruptCallbackType)(void); + +/** + * @brief The Flag-based temperature sensor ready callback function prototype + * + */ +typedef void (*TMU_TempFlagReadyInterruptCallbackType)(void); + +/** + * @brief The Voltage-based temperature sensor ready callback function prototype + * + */ +typedef void (*TMU_TempVoltageReadyInterruptCallbackType)(void); + +/** + * @brief TMU operation return values + * + */ +typedef enum +{ + TMU_STATUS_ERROR = 0x0U, /*!< The TMU operation is failed */ + TMU_STATUS_SUCCESS = 0x1U, /*!< The TMU operation is succeed */ + TMU_STATUS_TIMEOUT = 0x2U /*!< The TMU operation is failed because of time out */ +} TMU_StatusType; + +/** + * @brief Defines the temperature sensor configuration + * + * This structure is used to configure for Flag-based temperature sensor ane Voltage-based temperature sensor + * + * Implements : TMU_InitType + */ +typedef struct +{ + TMU_LockType eTempRegisterLockCon; /*!eResolution = ADC_RESOLUTION_12_BIT; /* 12 bit Resolution */ + pInitCfg->eAlign = ADC_ALIGN_RIGHT; /* Align right */ + pInitCfg->eTriggerMode = ADC_TRIGMODE_SW; /* Software trigger */ + pInitCfg->bWaitEnable = false; /* Disable wait conversion mode */ + pInitCfg->bSequenceGroupModeEnable = false; /* Disable sequence group mode */ + pInitCfg->eTrgLatchUnitPri = TRG_LATCH_UNIT_PRI_ROUND_ROBIN; /* Round Robin priority */ + pInitCfg->eClockDivider = ADC_CLOCK_DIV_1; /* Adc clock divided by 1 */ + pInitCfg->eSequenceMode = ADC_SEQMODE_SINGLE; /* Single sequence mode */ + pInitCfg->bAutoDis = false; /* Disable auto disable mode */ + pInitCfg->eOverrunMode = ADC_OVERRUN_MODE_PRESERVE; /* Old conversion data preserved when overrun occured */ + pInitCfg->eVoltageRef = ADC_REF_INTERNAL; /* Use internal reference */ + pInitCfg->bHwAvgEnable = false; /* Disable averaging functionality */ + pInitCfg->eHwAverage = ADC_AVERAGE_4; /* Average by 4 samples if average is enabled */ + pInitCfg->aSampleTimes[0] = ADC_DEFAULT_SAMPLE_TIME_OPTION_0; /* Sample time option 0 is 4 ADC Clock */ + pInitCfg->aSampleTimes[1] = ADC_DEFAULT_SAMPLE_TIME_OPTION_1; /* Sample time option 1 is 10 ADC Clock */ + pInitCfg->aSampleTimes[2] = ADC_DEFAULT_SAMPLE_TIME_OPTION_2; /* Sample time option 2 is 34 ADC Clock */ + pInitCfg->aSampleTimes[3] = ADC_DEFAULT_SAMPLE_TIME_OPTION_3; /* Sample time option 3 is 130 ADC Clock */ +} + +void ADC_Init(const ADC_InstanceType eInstance, const ADC_InitType *const pInitCfg) +{ + DEV_ASSERT(eInstance < ADC_INSTANCE_COUNT); + DEV_ASSERT(pInitCfg != NULL); + + ADC_Type *const pAdc = s_apAdcBase[eInstance]; + uint32_t u32TimeOut = 15000000U; + uint32_t u32Cfg1; + uint32_t u32Cfg2; + uint32_t u32Cal; + ADC_TrigSrcType eTriggerSrc; + ADC_TrigModeType eTriggerMode; + uint32_t u32ClockDiv; + uint32_t u32StartupCnt; + + if (pInitCfg->bSequenceGroupModeEnable == false) + { + if (pInitCfg->eSequenceMode == ADC_SEQMODE_DISCONTINUOUS_1) + { + eTriggerSrc = ADC_TRIGSRC_PTIMER; + eTriggerMode = ADC_TRIGMODE_RISING_EDGE; + } + else + { + eTriggerSrc = ADC_TRIGSRC_TRGSEL; + eTriggerMode = pInitCfg->eTriggerMode; + } + } + else + { + eTriggerSrc = ADC_TRIGSRC_TRIG_LATCH_UNIT; + eTriggerMode = ADC_TRIGMODE_RISING_EDGE; + } + + PCC_ClkSrcType eAdcClkName = PCC_CLK_ADC0; + uint32_t u32AdcClk; + + switch (eInstance) + { + case ADC_INSTANCE_0: + { + eAdcClkName = PCC_CLK_ADC0; + break; + } + + case ADC_INSTANCE_1: + { + eAdcClkName = PCC_CLK_ADC1; + break; + } + + default: + break; + } + u32ClockDiv = 1U << pInitCfg->eClockDivider; + + u32AdcClk = PCC_GetPccFunctionClock(eAdcClkName); + + /* The start up count shall be around 5us */ + u32StartupCnt = u32AdcClk / u32ClockDiv / 1000000U * 5U + 1U; + if (u32StartupCnt < 2U) + { + u32StartupCnt = 2U; + } + else if (u32StartupCnt > 255U) + { + u32StartupCnt = 255U; + } + else + {} + + ADC_HWA_Reset(pAdc); + + u32Cfg1 = ADC_CFG1_OVRMOD(pInitCfg->eOverrunMode) | + ADC_CFG1_SEQGP_EN(pInitCfg->bSequenceGroupModeEnable) | + ADC_CFG1_SEQ_LEN(0) | + ADC_CFG1_SEQ_MOD(pInitCfg->eSequenceMode) | + ADC_CFG1_AUTO_DIS(pInitCfg->bAutoDis) | + ADC_CFG1_WAIT(pInitCfg->bWaitEnable) | + ADC_CFG1_TRIGSRC(eTriggerSrc) | + ADC_CFG1_TRIGMODE(eTriggerMode) | + ADC_CFG1_ALIGN(pInitCfg->eAlign) | + ADC_CFG1_RES(pInitCfg->eResolution) | + ADC_CFG1_DMAEN(false); + ADC_HWA_SetConfig1(pAdc, u32Cfg1); + + u32Cfg2 = ADC_CFG2_FWMARK(ADC_DEFAULT_WATER_MARK) | + ADC_CFG2_TRG_PRI(pInitCfg->eTrgLatchUnitPri) | + ADC_CFG2_TRG_CLR(1U) | + ADC_CFG2_AVG_EN(pInitCfg->bHwAvgEnable) | + ADC_CFG2_AVG_LEN(pInitCfg->eHwAverage) | + ADC_CFG2_REF_EXT(pInitCfg->eVoltageRef) | + ADC_CFG2_STCNT(u32StartupCnt); + ADC_HWA_SetConfig2(pAdc, u32Cfg2); + + u32Cal = ADC_CAL_CAL_EN(pInitCfg->bCalEnable) | + ADC_CAL_OFFSET(pInitCfg->s32CalOffset) | + ADC_CAL_GAIN(pInitCfg->s32CalGain); + + ADC_HWA_SetCal(pAdc, u32Cal); + + ADC_HWA_SetClockGatingEnableFlag(pAdc, true); + while ((ADC_HWA_GetClockGatingAck(pAdc) != true) && (u32TimeOut != 0)) + { + u32TimeOut--; + } + if (ADC_HWA_GetClockGatingAck(pAdc) == true) + { + ADC_HWA_SetClockDivider(pAdc, pInitCfg->eClockDivider); + } + u32TimeOut = 15000000U; + ADC_HWA_SetClockGatingEnableFlag(pAdc, false); + while ((ADC_HWA_GetClockGatingAck(pAdc) != false) && (u32TimeOut != 0)) + { + u32TimeOut--; + } + + uint8_t u8SmprIndex; + for (u8SmprIndex = 0U; u8SmprIndex < ADC_SAMPLE_TIME_OPTION_CNT; u8SmprIndex++) + { + ADC_HWA_SetSampleTime(pAdc, u8SmprIndex, pInitCfg->aSampleTimes[u8SmprIndex] - 2U); + } +} + +void ADC_DeInit(const ADC_InstanceType eInstance) +{ + DEV_ASSERT(eInstance < ADC_INSTANCE_COUNT); + + ADC_Type *const pAdc = s_apAdcBase[eInstance]; + uint32_t u32Cfg1; + uint32_t u32Cfg2; + + ADC_HWA_Reset(pAdc); + + ADC_HWA_SetInterruptEnable(pAdc, 0U); + + u32Cfg1 = ADC_CFG1_OVRMOD(ADC_OVERRUN_MODE_PRESERVE) | + ADC_CFG1_SEQGP_EN(false) | + ADC_CFG1_SEQ_LEN(0U) | + ADC_CFG1_SEQ_MOD(ADC_SEQMODE_SINGLE) | + ADC_CFG1_AUTO_DIS(false) | + ADC_CFG1_WAIT(false) | + ADC_CFG1_TRIGSRC(ADC_TRIGSRC_PTIMER) | + ADC_CFG1_TRIGMODE(ADC_TRIGMODE_SW) | + ADC_CFG1_ALIGN(ADC_ALIGN_RIGHT) | + ADC_CFG1_RES(ADC_RESOLUTION_12_BIT) | + ADC_CFG1_DMAEN(false); + ADC_HWA_SetConfig1(pAdc, u32Cfg1); + + u32Cfg2 = ADC_CFG2_FWMARK(ADC_DEFAULT_WATER_MARK) | + ADC_CFG2_TRG_PRI(TRG_LATCH_UNIT_PRI_ROUND_ROBIN) | + ADC_CFG2_TRG_CLR(1U) | + ADC_CFG2_AVG_EN(false) | + ADC_CFG2_AVG_LEN(ADC_AVERAGE_4) | + ADC_CFG2_REF_EXT(ADC_REF_INTERNAL) | + ADC_CFG2_STCNT(ADC_DEFAULT_STARTUP_COUNTER); + ADC_HWA_SetConfig2(pAdc, u32Cfg2); + + ADC_HWA_SetSampleTime(pAdc, 0U, ADC_DEFAULT_SAMPLE_TIME_OPTION_0 - 2U); + ADC_HWA_SetSampleTime(pAdc, 1U, ADC_DEFAULT_SAMPLE_TIME_OPTION_1 - 2U); + ADC_HWA_SetSampleTime(pAdc, 2U, ADC_DEFAULT_SAMPLE_TIME_OPTION_2 - 2U); + ADC_HWA_SetSampleTime(pAdc, 3U, ADC_DEFAULT_SAMPLE_TIME_OPTION_3 - 2U); + + ADC_HWA_SetHwCompareEnableFlag(pAdc, false); + ADC_HWA_SetHwCompareChannel(pAdc, ADC_CMP_CHANNEL_ALL, 0U); + + ADC_HWA_SetHwCompareThreshold(pAdc, ADC_DEFAULT_COMPARE_LOW_THRESHOLD, ADC_DEFAULT_COMPARE_HIGH_THRESHOLD); + + uint8_t u8ChnIndex; + for (u8ChnIndex = 0U; u8ChnIndex < ADC_SC_COUNT; u8ChnIndex++) + { + ADC_HWA_SetChannelSampleTimeIndex(pAdc, u8ChnIndex, 0U); + ADC_HWA_SetChannelInterruptEnable(pAdc, u8ChnIndex, false); + ADC_HWA_SetChannelInput(pAdc, u8ChnIndex, ADC_DEFAULT_SC_CHANNEL); + } + + /* TODO : CAL Rregister */ +} + +void ADC_InitChannel(const ADC_InstanceType eInstance, const ADC_ChannelCfgType aChannels[], + const uint8_t u8ChnCnt) +{ + DEV_ASSERT(eInstance < ADC_INSTANCE_COUNT); + DEV_ASSERT(u8ChnCnt < ADC_SC_COUNT); + DEV_ASSERT(aChannels != NULL); + + ADC_Type *const pAdc = s_apAdcBase[eInstance]; + + s_u8ChannelCnt[eInstance] = u8ChnCnt; + + uint8_t u8ChnIndex; + for (u8ChnIndex = 0U; u8ChnIndex < u8ChnCnt; u8ChnIndex++) + { + ADC_HWA_SetChannelDiff(pAdc, u8ChnIndex, aChannels[u8ChnIndex].bDiff); + ADC_HWA_SetChannelSampleTimeIndex(pAdc, u8ChnIndex, aChannels[u8ChnIndex].eSampleTimeOption); + ADC_HWA_SetChannelInterruptEnable(pAdc, u8ChnIndex, false); + ADC_HWA_SetChannelInput(pAdc, u8ChnIndex, aChannels[u8ChnIndex].eChannel); + } + + if (ADC_HWA_GetSeqGpEn(pAdc) != true && ADC_HWA_GetSequenceMode(pAdc) != ADC_SEQMODE_DISCONTINUOUS_1) + { + ADC_HWA_SetSequenceLength(pAdc, u8ChnCnt - 1U); + ADC_HWA_SetFIFOWaterMark(pAdc, u8ChnCnt - 1U); + } +} + +void ADC_InitSequenceGroup(const ADC_InstanceType eInstance, const ADC_SequenceGroupType aSeqGroup[], + const uint8_t u8SeqGroupCnt) +{ + DEV_ASSERT(eInstance < ADC_INSTANCE_COUNT); + DEV_ASSERT(u8SeqGroupCnt < ADC_SEQUENCE_GROUP_CNT); + DEV_ASSERT(aSeqGroup != NULL); + + ADC_Type *const pAdc = s_apAdcBase[eInstance]; + + s_u8SeqGroupCnt[eInstance] = u8SeqGroupCnt; + + uint8_t u8ChnIndex; + for (u8ChnIndex = 0U; u8ChnIndex < u8SeqGroupCnt; u8ChnIndex++) + { + ADC_HWA_SetSeqGroupStartEndPoint(pAdc, u8ChnIndex, aSeqGroup[u8ChnIndex].u8Start, aSeqGroup[u8ChnIndex].u8Start + aSeqGroup[u8ChnIndex].u8Len); + ADC_HWA_SetEndOfSequenceGroupInterruptEnable(pAdc, u8ChnIndex, false); + } +} + +void ADC_InitCompare(const ADC_InstanceType eInstance, const ADC_CompareType *const pCmpCfg) +{ + DEV_ASSERT(eInstance < ADC_INSTANCE_COUNT); + DEV_ASSERT(pCmpCfg != NULL); + + ADC_Type *const pAdc = s_apAdcBase[eInstance]; + + ADC_HWA_SetHwCompareChannel(pAdc, pCmpCfg->eCmpSingleChn, pCmpCfg->u8CmpChnSel); + ADC_HWA_SetHwCompareThreshold(pAdc, pCmpCfg->u16LowThres, pCmpCfg->u16HighThres); + ADC_HWA_SetHwCompareEnableFlag(pAdc, pCmpCfg->bCmpEnable); +} + +void ADC_InitInterrupt(const ADC_InstanceType eInstance, const ADC_InterruptType *const pInterruptCfg) +{ + DEV_ASSERT(eInstance < ADC_INSTANCE_COUNT); + DEV_ASSERT(pInterruptCfg != NULL); + DEV_ASSERT(s_u8ChannelCnt[eInstance] > 0U); + ADC_Type *const pAdc = s_apAdcBase[eInstance]; + uint32_t u32InterruptCfg; + uint8_t u8SeqGroupIndex; + + if (ADC_HWA_GetSeqGpEn(pAdc) == false) + { + s_apAdcResultBuffer[eInstance] = pInterruptCfg->pResultBuffer; + if (ADC_HWA_GetSequenceMode(pAdc) == ADC_SEQMODE_DISCONTINUOUS_1) + { + u32InterruptCfg = ADC_INT_ENABLE_TRGERR_IE(false) | + ADC_INT_ENABLE_FIFO_RDY_IE(false) | + ADC_INT_ENABLE_ACMP_IE(pInterruptCfg->bAnalogCmpIntEn) | + ADC_INT_ENABLE_OVRIE(false) | + ADC_INT_ENABLE_EOSEQIE(false) | + ADC_INT_ENABLE_EOCIE(false) | + ADC_INT_ENABLE_EOSMPIE(false) | + ADC_INT_ENABLE_ADRDYIE(false); + ADC_HWA_SetInterruptEnable(pAdc, u32InterruptCfg); + ADC_HWA_SetChannelInterruptEnable(pAdc, s_u8ChannelCnt[eInstance] - 1U, pInterruptCfg->bConversionCompleteIntEn); + } + else + { + u32InterruptCfg = ADC_INT_ENABLE_TRGERR_IE(false) | + ADC_INT_ENABLE_FIFO_RDY_IE(false) | + ADC_INT_ENABLE_ACMP_IE(pInterruptCfg->bAnalogCmpIntEn) | + ADC_INT_ENABLE_OVRIE(pInterruptCfg->bOverRunIntEn) | + ADC_INT_ENABLE_EOSEQIE(pInterruptCfg->bConversionCompleteIntEn) | + ADC_INT_ENABLE_EOCIE(false) | + ADC_INT_ENABLE_EOSMPIE(false) | + ADC_INT_ENABLE_ADRDYIE(false); + ADC_HWA_SetInterruptEnable(pAdc, u32InterruptCfg); + } + } + else + { + for (u8SeqGroupIndex = 0U; u8SeqGroupIndex < ADC_SEQUENCE_GROUP_CNT; u8SeqGroupIndex++) + { + s_apAdcSeqGroupResultBuffer[eInstance][u8SeqGroupIndex] = pInterruptCfg->pSequenceGroupResultBuffer[u8SeqGroupIndex]; + } + u32InterruptCfg = ADC_INT_ENABLE_TRGERR_IE(false) | + ADC_INT_ENABLE_FIFO_RDY_IE(false) | + ADC_INT_ENABLE_ACMP_IE(pInterruptCfg->bAnalogCmpIntEn) | + ADC_INT_ENABLE_OVRIE(false) | + ADC_INT_ENABLE_EOSEQIE(false) | + ADC_INT_ENABLE_EOCIE(false) | + ADC_INT_ENABLE_EOSMPIE(false) | + ADC_INT_ENABLE_ADRDYIE(false); + ADC_HWA_SetInterruptEnable(pAdc, u32InterruptCfg); + for (u8SeqGroupIndex = 0U; u8SeqGroupIndex < s_u8SeqGroupCnt[eInstance]; u8SeqGroupIndex++) + { + ADC_HWA_SetEndOfSequenceGroupInterruptEnable(pAdc, u8SeqGroupIndex, true); + } + } + + s_apAdcCoCoNotify[eInstance] = pInterruptCfg->pConvCompleteNotify; + s_apAdcOvrNotify[eInstance] = pInterruptCfg->pOverRunNotify; + s_apAdcCmpNotify[eInstance] = pInterruptCfg->pCompareNotify; + s_apEndOfSeqGroupNotify[eInstance] = pInterruptCfg->pEndOfSeqGroupNotify; +} + +void ADC_InitDmaChannel(const ADC_InstanceType eInstance, const ADC_DmaType *const pAdcDmaCfg) +{ + DEV_ASSERT(eInstance < ADC_INSTANCE_COUNT); + DEV_ASSERT(pAdcDmaCfg != NULL); + uint32_t u32ResultStart; + uint32_t u32ResultEnd; + + ADC_Type *const pAdc = s_apAdcBase[eInstance]; + + if (pAdcDmaCfg->bDmaEnable == true) + { + s_apAdcResultBuffer[eInstance] = pAdcDmaCfg->pResultBuffer; + s_apAdcCoCoNotify[eInstance] = pAdcDmaCfg->pConvCompleteNotify; + + DMA_ChannelCfgType tDmaCfg; + if (ADC_HWA_GetSeqGpEn(pAdc) == true) + { + u32ResultStart = ADC_HWA_GetSeqGroupStartPoint(pAdc, (uint8_t)pAdcDmaCfg->eSeqGroupIndex); + u32ResultEnd = ADC_HWA_GetSeqGroupEndPoint(pAdc, (uint8_t)pAdcDmaCfg->eSeqGroupIndex); + tDmaCfg.pSrcBuffer = &pAdc->RESULT[u32ResultStart]; + tDmaCfg.pDestBuffer = pAdcDmaCfg->pResultBuffer; + tDmaCfg.u32BlockSize = 4U; + tDmaCfg.u16BlockCount = u32ResultStart - u32ResultEnd; + tDmaCfg.eSrcIncMode = DMA_INCREMENT_DATA_SIZE; + } + else if (ADC_HWA_GetSequenceMode(pAdc) == ADC_SEQMODE_DISCONTINUOUS_1) + { + tDmaCfg.pSrcBuffer = &pAdc->RESULT[0U]; + tDmaCfg.pDestBuffer = pAdcDmaCfg->pResultBuffer; + tDmaCfg.u32BlockSize = 4U; + tDmaCfg.u16BlockCount = s_u8ChannelCnt[eInstance]; + tDmaCfg.eSrcIncMode = DMA_INCREMENT_DATA_SIZE; + } + else + { + tDmaCfg.pSrcBuffer = &pAdc->FIFO_DATA; + tDmaCfg.pDestBuffer = pAdcDmaCfg->pResultBuffer; + tDmaCfg.u32BlockSize = 4U * s_u8ChannelCnt[eInstance]; + tDmaCfg.u16BlockCount = 1U; + tDmaCfg.eSrcIncMode = DMA_INCREMENT_DISABLE; + } + tDmaCfg.eDestIncMode = DMA_INCREMENT_DATA_SIZE; + tDmaCfg.eSrcDataSize = DMA_TRANSFER_SIZE_4B; + tDmaCfg.eDestDataSize = DMA_TRANSFER_SIZE_4B; + tDmaCfg.u8ChannelPriority = pAdcDmaCfg->u8ChannelPriority; + tDmaCfg.bSrcBlockOffsetEn = false; + tDmaCfg.bDestBlockOffsetEn = false; + tDmaCfg.s32BlockOffset = 0; + tDmaCfg.bSrcAddrLoopbackEn = true; + tDmaCfg.bDestAddrLoopbackEn = true; + tDmaCfg.bAutoStop = false; + tDmaCfg.bSrcCircularBufferEn = false; + tDmaCfg.u32SrcCircBufferSize = DMA_CIRCULAR_BUFFER_SIZE_1B; + tDmaCfg.bDestCircularBufferEn = false; + tDmaCfg.u32DestCircBufferSize = DMA_CIRCULAR_BUFFER_SIZE_1B; + if (eInstance == ADC_INSTANCE_0) + { + tDmaCfg.eTriggerSrc = DMA_REQ_ADC0; + } + else if (eInstance == ADC_INSTANCE_1) + { + tDmaCfg.eTriggerSrc = DMA_REQ_ADC1; + } + else + {} + + DMA_InterruptCfgType dmaIntCfg = {0}; + dmaIntCfg.bTransferCompleteIntEn = true; + if (eInstance == ADC_INSTANCE_0) + { + dmaIntCfg.pTransferCompleteNotify = ADC0_DMAHandler; + } + else if (eInstance == ADC_INSTANCE_1) + { + dmaIntCfg.pTransferCompleteNotify = ADC1_DMAHandler; + } + else + {} + + dmaIntCfg.bTransferErrorIntEn = false; + dmaIntCfg.pTransferErrorNotify = NULL; + + ADC_HWA_SetDMAEnableFlag(pAdc, true); + + DMA_InitChannel(pAdcDmaCfg->eDmaInstance, pAdcDmaCfg->eDmaChannel, &tDmaCfg); + DMA_InitChannelInterrupt(pAdcDmaCfg->eDmaInstance, pAdcDmaCfg->eDmaChannel, &dmaIntCfg); + } + else + { + ADC_HWA_SetDMAEnableFlag(pAdc, false); + } +} + +ADC_StatusType ADC_Enable(const ADC_InstanceType eInstance) +{ + DEV_ASSERT(eInstance < ADC_INSTANCE_COUNT); + ADC_StatusType eRet = ADC_STATUS_SUCCESS; + uint32_t u32TimeOut = 15000000U; + ADC_Type *const pAdc = s_apAdcBase[eInstance]; + + ADC_HWA_Enable(pAdc); + while ((ADC_HWA_GetReady(pAdc) != true) && (u32TimeOut != 0U)) + { + u32TimeOut--; + } + if (u32TimeOut != 0U) + { + ADC_HWA_ClearReady(pAdc); + eRet = ADC_STATUS_SUCCESS; + } + else + { + eRet = ADC_STATUS_TIMEOUT; + } + return eRet; +} + +ADC_StatusType ADC_Disable(const ADC_InstanceType eInstance) +{ + DEV_ASSERT(eInstance < ADC_INSTANCE_COUNT); + ADC_StatusType eRet = ADC_STATUS_SUCCESS; + uint32_t u32TimeOut = 15000000U; + ADC_Type *const pAdc = s_apAdcBase[eInstance]; + + if (ADC_HWA_GetStart(pAdc) == true) + { + eRet = ADC_Stop(eInstance); + } + + if (eRet == ADC_STATUS_SUCCESS) + { + ADC_HWA_Disable(pAdc); + while ((ADC_HWA_GetEnable(pAdc) == true) && (u32TimeOut != 0U)) + { + u32TimeOut--; + } + if (u32TimeOut != 0U) + { + eRet = ADC_STATUS_SUCCESS; + } + else + { + eRet = ADC_STATUS_TIMEOUT; + } + } + return eRet; +} + +void ADC_Start(const ADC_InstanceType eInstance) +{ + DEV_ASSERT(eInstance < ADC_INSTANCE_COUNT); + ADC_Type *const pAdc = s_apAdcBase[eInstance]; + ADC_HWA_Start(pAdc); +} + +ADC_StatusType ADC_Stop(const ADC_InstanceType eInstance) +{ + DEV_ASSERT(eInstance < ADC_INSTANCE_COUNT); + ADC_StatusType eRet = ADC_STATUS_ERROR; + uint32_t u32TimeOut = 15000000U; + ADC_Type *const pAdc = s_apAdcBase[eInstance]; + + ADC_HWA_Stop(pAdc); + + while ((ADC_HWA_GetStop(pAdc) == true) && (u32TimeOut != 0U)) + { + u32TimeOut--; + } + if (u32TimeOut != 0U) + { + eRet = ADC_STATUS_SUCCESS; + } + else + { + eRet = ADC_STATUS_TIMEOUT; + } + return eRet; +} + +void ADC_Reset(const ADC_InstanceType eInstance) +{ + DEV_ASSERT(eInstance < ADC_INSTANCE_COUNT); + ADC_Type *const pAdc = s_apAdcBase[eInstance]; + ADC_HWA_Reset(pAdc); +} diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_aontimer.c b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_aontimer.c new file mode 100644 index 0000000..a36ecae --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_aontimer.c @@ -0,0 +1,187 @@ +/** + * @file fc7xxx_driver_aontimer.c + * @author Flagchip + * @brief FC7xxx aontimer driver type definition and API + * @version 0.1.0 + * @date 2024-01-10 + * + * @copyright Copyright (c) 2023 Flagchip Semiconductors Co., Ltd. + * + * @details + */ +/******************************************************************************** +* Revision History: +* +* Version Date Initials CR# Descriptions +* --------- ---------- ------------ ---------- --------------- +* 0.1.0 2024-01-10 Flagchip0076 N/A First version for FC7240 +********************************************************************************/ +#include "fc7xxx_driver_aontimer.h" + +#include "fc7xxx_driver_csc.h" + +extern void AONTIMER_IRQHandler(void); + +/** @brief Aontimer common interrupt handle function */ +static void Aontimer_CommonProcessInterrupt(void); + +/** @brief Aontimer user defined interrupt function */ +static Aontimer_InterruptCallBackType s_pAontimerNotifyPtr = NULL; + +/** + * @brief Initialize aontimer instance + * + * @param pInitStruct Aontimer Initialize structure + */ +void AONTIMER_Init(const AONTIMER_InitType *const pInitStruct) +{ + DEV_ASSERT(pInitStruct != NULL); + /* Disable the Aontimer, and clear control register. */ + AONTIMER_HWA_ConfigModule((uint32_t)0U); + AONTIMER_HWA_ConfigModulePrescale((uint32_t)0U); + AONTIMER->CSR |= AONTIMER_CSR_DBGEN(pInitStruct->eDbgMode); + if (AONTIMER_PULSE_MODE == pInitStruct->eMode) + { + AONTIMER_HWA_SelectClkSrcOnPulseMode(pInitStruct->ePulseClkSrc); + AONTIMER_HWA_ConfigModulePolarity(pInitStruct->ePulsePol); + AONTIMER_HWA_EnablePulseMode(); + if (pInitStruct->bBypassEn) + { + AONTIMER_HWA_EnableBypassMode(); + } + else + { + AONTIMER_HWA_DisableBypassMode(); + } + AONTIMER_HWA_SetPrescale(pInitStruct->u8PulseFilterWidth); + } + else + { + AONTIMER_HWA_SetPrescale(pInitStruct->u8Prescaler); + } + AONTIMER_HWA_SetModuleRunOnDebug(); + AONTIMER_HWA_SelectModuleClkSrc(pInitStruct->eClkSrc); + AONTIMER_HWA_SetModuleCompareValue((uint32_t)pInitStruct->u16StartValue); +} + +/** + * @brief De-initialize aontimer instance + * + */ +void AONTIMER_Deinit(void) +{ + AONTIMER_HWA_ConfigModule((uint32_t)0U); + AONTIMER_HWA_ConfigModulePrescale((uint32_t)0U); + AONTIMER_HWA_SetModuleCompareValue((uint32_t)0xFFFFFFFFU); + s_pAontimerNotifyPtr = NULL; +} + +/** + * @brief Initialize aontimer interrupt functionality + * + * @param pIntStruct Aontimer interrupt structure + * @return Aontimer return type + * @note this function will disable timer + */ +AONTIMER_StatusType AONTIMER_InitInterrupt(const AONTIMER_IntType *const pIntStruct) +{ + AONTIMER_StatusType eRet = AONTIMER_STATUS_SUCCESS; + if (NULL == pIntStruct) + { + eRet = AONTIMER_STATUS_PARAM_INVALID; + } + else + { + AONTIMER_HWA_DisableTimer(); + if (pIntStruct->bIntEn) + { + AONTIMER_HWA_EnableModuleInterrupt(); + s_pAontimerNotifyPtr = pIntStruct->pIsrNotify; + } + else + { + AONTIMER_HWA_DisableModuleInterrupt(); + s_pAontimerNotifyPtr = NULL; + } + } + return eRet; +} + +/** + * @brief Enable AONTIMER interrupt + * @note this function will enable AONTIEMR timer. + */ +void AONTIMER_EnableInterrupt(void) +{ + AONTIMER_HWA_DisableTimer(); + AONTIMER_HWA_EnableModuleInterrupt(); + AONTIMER_HWA_EnableTimer(); +} + +/** + * @brief Disable AONTIMER interrupt + * @note this function will enable AONTIEMR timer. + * + */ +void AONTIMER_DisableInterrupt(void) +{ + AONTIMER_HWA_DisableTimer(); + AONTIMER_HWA_DisableModuleInterrupt(); + AONTIMER_HWA_EnableTimer(); +} + +/** + * @brief Start Aontimer + * + */ +void AONTIMER_StartTimer(void) +{ + AONTIMER_HWA_EnableTimer(); +} + +/** + * @brief Stop Aontimer + * + */ +void AONTIMER_StopTimer(void) +{ + AONTIMER_HWA_DisableTimer(); +} + +/** + * @brief Update value of aontimer counter + * + * @param u16StartValue input value, range : 0~65535 + */ +void AONTIMER_UpdateCounterValue(const uint16_t u16StartValue) +{ + if (0U == (AONTIMER->CSR & AONTIMER_CSR_TMS_MASK)) + { + AONTIMER_HWA_DisableTimer(); + AONTIMER_HWA_SetModuleCompareValue((uint32_t)u16StartValue); + AONTIMER_HWA_EnableTimer(); + } +} + +/** + * @brief Aontimer common interrupt handle function + * + */ +static void Aontimer_CommonProcessInterrupt(void) +{ + if (NULL != s_pAontimerNotifyPtr) + { + s_pAontimerNotifyPtr(); + } +} + +/** + * @brief Aontimer interrupt entry + * + */ +void AONTIMER_IRQHandler(void) +{ + Aontimer_CommonProcessInterrupt(); + AONTIMER_HWA_ClearInterruptFlag(); + AONTIMER_HWA_EnableTimer(); +} diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_cmp.c b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_cmp.c new file mode 100644 index 0000000..260ff16 --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_cmp.c @@ -0,0 +1,324 @@ +/** + * @file fc7xxx_driver_cmp.c + * @author Flagchip0126 + * @brief FC7xxx CMP driver source code + * @version 0.1.0 + * @date 2024-01-15 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + */ +/******************************************************************************** +* Revision History: +* +* Version Date Author CR# Descriptions +* --------- ---------- ------------ ---------- ------------------------ +* 0.1.0 2024-01-15 Flagchip0126 N/A First version for FC7240 +**********************************************************************************/ + +#include "fc7xxx_driver_cmp.h" +#include "interrupt_manager.h" + +/********* Local Variables ************/ +static CMP_Type *const s_apCmpBase[CMP_INSTANCE_COUNT] = CMP_BASE_PTRS; +static CMP_CompleteIntCallback s_apCmpIntNotify[CMP_INSTANCE_COUNT] = {NULL}; + +/******* Local Function Prototype *********/ + +/** + * @brief set CMPn IRQHandler + * + * @param eInstance the CMP instance to use + */ +static void CMPn_IRQHandler(const CMP_InstanceType eInstance); + +void CMP0_IRQHandler(void); + +void CMP1_IRQHandler(void); + +static void CMPn_IRQHandler(const CMP_InstanceType eInstance) +{ + DEV_ASSERT(eInstance < CMP_INSTANCE_COUNT); + + /*callback function*/ + if (s_apCmpIntNotify[eInstance] != NULL) + { + s_apCmpIntNotify[eInstance](); + } + else + { + /*Noting to do*/ + } + + /*clear interrupter status regs*/ + CMP_ClearIntFlag(eInstance); +} + +void CMP0_IRQHandler(void) +{ + CMPn_IRQHandler(CMP_INSTANCE_0); +} + +void CMP1_IRQHandler(void) +{ + CMPn_IRQHandler(CMP_INSTANCE_1); +} + +/********* Local Functions ************/ +void CMP_Enable(const CMP_InstanceType eInstance) +{ + DEV_ASSERT(eInstance < CMP_INSTANCE_COUNT); + CMP_Type *const pCmp = s_apCmpBase[eInstance]; + + CMP_HWA_Enable(pCmp); +} + +void CMP_Disable(const CMP_InstanceType eInstance) +{ + DEV_ASSERT(eInstance < CMP_INSTANCE_COUNT); + CMP_Type *const pCmp = s_apCmpBase[eInstance]; + + CMP_HWA_Disable(pCmp); +} + +void CMP_CSEnable(const CMP_InstanceType eInstance) +{ + DEV_ASSERT(eInstance < CMP_INSTANCE_COUNT); + CMP_Type *const pCmp = s_apCmpBase[eInstance]; + + CMP_HWA_CSEnable(pCmp); +} + +void CMP_CSDisable(const CMP_InstanceType eInstance) +{ + DEV_ASSERT(eInstance < CMP_INSTANCE_COUNT); + CMP_Type *const pCmp = s_apCmpBase[eInstance]; + + CMP_HWA_CSDisable(pCmp); +} + +bool CMP_GetCmpOut(const CMP_InstanceType eInstance) +{ + bool CmpOut; + + DEV_ASSERT(eInstance < CMP_INSTANCE_COUNT); + CMP_Type *const pCmp = s_apCmpBase[eInstance]; + + CmpOut = CMP_HWA_GetCmpOut(pCmp); + return CmpOut; +} + +void CMP_SetDacData(const CMP_InstanceType eInstance, uint8_t u8Data) +{ + DEV_ASSERT(eInstance < CMP_INSTANCE_COUNT); + CMP_Type *const pCmp = s_apCmpBase[eInstance]; + + CMP_HWA_SetDacData(pCmp, u8Data); +} + +CMP_OutStatus CMP_GetOutFlagStatus(const CMP_InstanceType eInstance) +{ + DEV_ASSERT(eInstance < CMP_INSTANCE_COUNT); + bool bCFF_Status = false; + bool bCFR_Status = false; + CMP_Type *const pCmp = s_apCmpBase[eInstance]; + CMP_OutStatus eRetVal = CMP_OUT_NONE; + + bCFF_Status = CMP_HWA_GetIntFlag_Falling(pCmp); + bCFR_Status = CMP_HWA_GetIntFlag_Rising(pCmp); + + if ((bCFF_Status == true) && (bCFR_Status == false)) + { + eRetVal = CMP_OUT_FALLING_EDGE; + } + else if ((bCFF_Status == false) && (bCFR_Status == true)) + { + eRetVal = CMP_OUT_RISING_EDGE; + } + else + { + eRetVal = CMP_OUT_NONE; + } + + return eRetVal; +} + +bool CMP_GetChannelScanFlagStatus(const CMP_InstanceType eInstance) +{ + DEV_ASSERT(eInstance < CMP_INSTANCE_COUNT); + bool bCSF_Status = false; + CMP_Type *const pCmp = s_apCmpBase[eInstance]; + + bCSF_Status = CMP_HWA_GetIntFlag_ChannelScan(pCmp); + + return bCSF_Status; +} + +void CMP_ClearIntFlag(const CMP_InstanceType eInstance) +{ + DEV_ASSERT(eInstance < CMP_INSTANCE_COUNT); + CMP_Type *const pCmp = s_apCmpBase[eInstance]; + + CMP_HWA_ClearIntFlag_Rising(pCmp); + CMP_HWA_ClearIntFlag_Falling(pCmp); + CMP_HWA_ClearIntFlag_ChannelScan(pCmp); +} + +void CMP_Init(const CMP_InstanceType eInstance, const CMP_InitType *const pInitCfg) +{ + DEV_ASSERT(eInstance < CMP_INSTANCE_COUNT); + DEV_ASSERT(pInitCfg != NULL); + CMP_Type *const pCmp = s_apCmpBase[eInstance]; + + /* disable CMP module */ + CMP_HWA_Disable(pCmp); + + /* determine comparator function mode */ + CMP_HWA_SetComparatorMod(pCmp, (pInitCfg->tComparatorConfig).eModSel, ((pInitCfg->tComparatorConfig).u8FilterPeriod), ((pInitCfg->tComparatorConfig).eFilterCnt)); + + /* configure CMP module */ + /* CCR0 register */ + CMP_HWA_SetEnStopMod(pCmp, (pInitCfg->tComparatorConfig).bStopModEn); + CMP_HWA_SetDacEnableSrc(pCmp, (pInitCfg->tDacConfig).eDacEnsrc); + + /* CCR1 register */ + CMP_HWA_SetCmpOutInvert(pCmp, (pInitCfg->tComparatorConfig).eInvert); + CMP_HWA_SetCmpOutSel(pCmp, (pInitCfg->tComparatorConfig).eOutSelect); + CMP_HWA_SetEnCmpOutPack(pCmp, (pInitCfg->tComparatorConfig).bOutToPackagePinEn); + CMP_HWA_SetCmpOutWinLevel(pCmp, (pInitCfg->tComparatorConfig).eOutWinLevel); + CMP_HWA_SetCmpOutWin(pCmp, (pInitCfg->tComparatorConfig).eOutWin); + CMP_HWA_SetEnWinSampleInvert(pCmp, (pInitCfg->tComparatorConfig).bWinSampleInvertEn); + CMP_HWA_SetEnEventCloseWin(pCmp, (pInitCfg->tComparatorConfig).bEventCloseWinEn); + CMP_HWA_SetEventCloseWin(pCmp, (pInitCfg->tComparatorConfig).eEventSelect); + + /* CCR2 register */ + CMP_HWA_SetSpeedMod(pCmp, (pInitCfg->tComparatorConfig).eSpeedMod); + CMP_HWA_SetHystCtrl(pCmp, (pInitCfg->tComparatorConfig).eHystCrtl); + CMP_HWA_SetPSelMux(pCmp, (pInitCfg->tMuxConfig).ePSelMux); + CMP_HWA_SetNSelMux(pCmp, (pInitCfg->tMuxConfig).eNSelMux); + CMP_HWA_SetINPSel(pCmp, (pInitCfg->tMuxConfig).eINPSel); + CMP_HWA_SetINNSel(pCmp, (pInitCfg->tMuxConfig).eINNSel); + + /* CCR3 register */ + CMP_HWA_SetAnalogConfTransByp(pCmp, (pInitCfg->tComparatorConfig).bAnalogConfTransByp); + CMP_HWA_SetAnalogConfTransBypCnt(pCmp, (pInitCfg->tComparatorConfig).u16AnalogConfTransBypCnt); + + /* DCR register */ + CMP_HWA_SetEnDac(pCmp, (pInitCfg->tDacConfig).bDacEn); + CMP_HWA_SetVinRefSel(pCmp, (pInitCfg->tDacConfig).eVinRefSel); + CMP_HWA_SetDacData(pCmp, (pInitCfg->tDacConfig).u8DacData); + + if ((pInitCfg->tComparatorConfig).eModSel == CMP_MOD_CHANNEL_SCAN) + { + /* CSCR0 register */ + CMP_HWA_SetCSInitModulus(pCmp, (pInitCfg->tChannelScanConfig).u8ChannelScanInitModulus); + CMP_HWA_SetCSNumOfSampleClocks(pCmp, (pInitCfg->tChannelScanConfig).u8ChannelScanNumOfSampleClocks); + + /* CSCR1 register */ + CMP_HWA_SetCSFixedChannel(pCmp, (pInitCfg->tMuxConfig).eChannelScanFixedChannel); + CMP_HWA_SetCSFixedPort(pCmp, (pInitCfg->tMuxConfig).eChannelScanFixedPort); + + /* CSCSR register */ + CMP_HWA_SetCSComparisonResultsAutoClearEn(pCmp, (pInitCfg->tChannelScanConfig).bComparisonResultAutoClear); + } +} + +void CMP_InitInterrupt(const CMP_InstanceType eInstance, const CMP_InterruptType *const pInterruptCfg) +{ + DEV_ASSERT(eInstance < CMP_INSTANCE_COUNT); + DEV_ASSERT(pInterruptCfg != NULL); + CMP_Type *const pCmp = s_apCmpBase[eInstance]; + + /*disable DMA*/ + CMP_HWA_DmaDisable(pCmp); + + /*clear interrupter flag*/ + CMP_ClearIntFlag(eInstance); + + /*configure interrupter */ + CMP_SetIntEn(eInstance, pInterruptCfg); + + s_apCmpIntNotify[eInstance] = pInterruptCfg->pInterrupterNotify; +} + +void CMP_InitInterrupt_Dma(const CMP_InstanceType eInstance, const CMP_DmaType *const pInterruptDmaCfg) +{ + DEV_ASSERT(eInstance < CMP_INSTANCE_COUNT); + DEV_ASSERT(pInterruptDmaCfg != NULL); + + CMP_InterruptType pInterruptCfg; + + pInterruptCfg.bRisingIntEn = pInterruptDmaCfg->bRisingDmaEn; + pInterruptCfg.bFallingIntEn = pInterruptDmaCfg->bFallingDmaEn; + pInterruptCfg.bChannelScanFlagIntEn = false; + pInterruptCfg.pInterrupterNotify = NULL; + + /* Set rising/falling edge interrupt to trigger Dma*/ + CMP_SetIntEn(eInstance, &pInterruptCfg); + + if ((pInterruptDmaCfg->bRisingDmaEn == true) || (pInterruptDmaCfg->bFallingDmaEn == true)) + { + CMP_DmaEnable(eInstance); + } + else + { + CMP_DmaDisable(eInstance); + } +} + +void CMP_SetIntEn(const CMP_InstanceType eInstance, const CMP_InterruptType *const pInterruptCfg) +{ + CMP_Type *const pCmp = s_apCmpBase[eInstance]; + + /*set rising edges interrupter enable*/ + CMP_HWA_SetIntEn_Rising(pCmp, pInterruptCfg->bRisingIntEn); + /*set falling edges interrupter enable*/ + CMP_HWA_SetIntEn_Falling(pCmp, pInterruptCfg->bFallingIntEn); + /*set channel scan flag interrupter enable*/ + CMP_HWA_SetIntEn_ChannelScan(pCmp, pInterruptCfg->bChannelScanFlagIntEn); +} + +void CMP_DmaEnable(const CMP_InstanceType eInstance) +{ + CMP_Type *const pCmp = s_apCmpBase[eInstance]; + CMP_HWA_DmaEnable(pCmp); +} + +void CMP_DmaDisable(const CMP_InstanceType eInstance) +{ + CMP_Type *const pCmp = s_apCmpBase[eInstance]; + CMP_HWA_DmaDisable(pCmp); +} + +void CMP_SetCSChannls(const CMP_InstanceType eInstance, const CMP_ChannelScanChannelCfgType s_tChnCfg[], const uint8_t u8ChnCnt) +{ + DEV_ASSERT(eInstance < CMP_INSTANCE_COUNT); + uint8_t u8ChnIndex; + + CMP_Type *const pCmp = s_apCmpBase[eInstance]; + for (u8ChnIndex = 0U; u8ChnIndex < u8ChnCnt; u8ChnIndex++) + { + CMP_HWA_SetCSChannelEn(pCmp, s_tChnCfg[u8ChnIndex].eChannel, true); + CMP_HWA_SetCSChannelPresetstate(pCmp, s_tChnCfg[u8ChnIndex].eChannel, s_tChnCfg[u8ChnIndex].bPreSetState); + } +} + +void CMP_GetCSChannlsOut(const CMP_InstanceType eInstance, CMP_ChannelScanChannelCfgType s_tChnCfg[], const uint8_t u8ChnCnt) +{ + DEV_ASSERT(eInstance < CMP_INSTANCE_COUNT); + uint8_t u8ChnIndex; + + CMP_Type *const pCmp = s_apCmpBase[eInstance]; + for (u8ChnIndex = 0U; u8ChnIndex < u8ChnCnt; u8ChnIndex++) + { + s_tChnCfg[u8ChnIndex].bCurState = CMP_HWA_GetCSChannelsOut(pCmp, s_tChnCfg[u8ChnIndex].eChannel); + } +} + +bool CMP_GetCmpCSActive(const CMP_InstanceType eInstance) +{ + DEV_ASSERT(eInstance < CMP_INSTANCE_COUNT); + CMP_Type *const pCmp = s_apCmpBase[eInstance]; + + return CMP_HWA_GetCSActive(pCmp); +} diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_cmu.c b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_cmu.c new file mode 100644 index 0000000..594849e --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_cmu.c @@ -0,0 +1,386 @@ +/** + * @file fc7xxx_driver_cmu.c + * @author Flagchip085 + * @brief FC7xxx CMU driver type definition and API + * @version 0.1.0 + * @date 2024-01-12 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + */ +/******************************************************************************** +* Revision History: +* +* Version Date Initials CR# Descriptions +* --------- ---------- ------------ ---------- --------------- +* 0.1.0 2024-01-12 Flagchip085 N/A First version for FC7240 +********************************************************************************/ +#include "fc7xxx_driver_cmu.h" +#include "fc7xxx_driver_scg.h" +#include "fc7xxx_driver_csc.h" +#include "HwA_cmu.h" + +#define CMU_MULTIPLY_FACTOR 100U +#define CMU_PERCENT_FACTOR 100U +#define CMU_DIVID_FACTOR_1K 1000U + +/** @brief CMU Reference clock div type. */ + +/** + * @brief Defines the CMU_ClkFrequenceType + * + * This structure is used to configure the CMU frequence include Reference clock and monitor clock + * + */ +typedef struct +{ + uint32_t u32RefClk; /*!< The Reference clock frequence */ + uint32_t u32MonitorClk; /*!< The target monitored clock frequence. */ +} CMU_ClkFrequenceType; + +typedef struct +{ + uint32_t u32RefWindow; /*!< CMU_REF_WINDOW (Reference Window). */ + uint32_t u32IdealMonitorCnts; /*!< Ideal monitor counter value, used to calculate the MIN,Max threshold. */ + uint32_t u32MinThreshold; /*!< CMU_MIN (Minimum threshold). */ + uint32_t u32MaxThreshold; /*!< CMU_MAX (Maximum threshold). */ + uint32_t u32PerWindow; /*!< CMU_PERIOD (Period monitor mode configuration). */ +} CMU_RegMapType; + + +static CMU_Type *const s_apCmuBase[CMU_INSTANCE_COUNT] = CMU_BASE_PTRS; +static CMU_ISRCallbackType s_apCmuISRCallback[CMU_INSTANCE_COUNT] = {NULL}; + +void CMU0_IRQHandler(void); +void CMU1_IRQHandler(void); +void CMU2_IRQHandler(void); +void CMU3_IRQHandler(void); +void CMU4_IRQHandler(void); + +/* Check Reference clock and monitor clock status.*/ +static CMU_StatusType CMU_ClkStatusCheck(CMU_InstanceType eInstance, CMU_ClkFrequenceType *ptCmuFreq) +{ + CSC_RetStatusType bCscClkStatus; + CMU_StatusType bCmuClkStatus = CMU_VALID; + + if (eInstance == CMU_INSTANCE_0) + { + /* Instance ---- Reference CLK ---- Monitored CLK.*/ + /* CMU0 ---- SIRC ---- RTC_CLK.*/ + ptCmuFreq->u32RefClk = SCG_GetScgClockFreq(SCG_SIRC_CLK); + + bCscClkStatus = CSC0_GetCSC0ClockFreq(CSC0_RTC_CLK, &(ptCmuFreq->u32MonitorClk)); + if (bCscClkStatus != CSC_E_OK) + { + bCmuClkStatus = CMU_CLK_ERROR; + } + } + else if (eInstance == CMU_INSTANCE_1) + { + /* Instance ---- Reference CLK ---- Monitored CLK.*/ + /* CMU1 ---- SIRC ---- FOSC.*/ + ptCmuFreq->u32RefClk = SCG_GetScgClockFreq(SCG_SIRC_CLK); + ptCmuFreq->u32MonitorClk = SCG_GetScgClockFreq(SCG_FOSC_CLK); + } + else if (eInstance == CMU_INSTANCE_2) + { + /* Instance ---- Reference CLK ---- Monitored CLK.*/ + /* CMU2 ---- SIRC ---- FIRC.*/ + ptCmuFreq->u32RefClk = SCG_GetScgClockFreq(SCG_SIRC_CLK); + ptCmuFreq->u32MonitorClk = SCG_GetScgClockFreq(SCG_FIRC_CLK); + } + else if (eInstance == CMU_INSTANCE_3) + { + /* Instance ---- Reference CLK ---- Monitored CLK.*/ + /* CMU3 ---- FIRC ---- SIRC.*/ + ptCmuFreq->u32RefClk = SCG_GetScgClockFreq(SCG_FIRC_CLK); + ptCmuFreq->u32MonitorClk = SCG_GetScgClockFreq(SCG_SIRC_CLK); + } + else if (eInstance == CMU_INSTANCE_4) + { + /* Instance ---- Reference CLK ---- Monitored CLK.*/ + /* CMU4 ---- SIRC ---- SLOW CLOCK.*/ + ptCmuFreq->u32MonitorClk = SCG_GetScgClockFreq(SCG_SLOW_CLK); + ptCmuFreq->u32RefClk = SCG_GetScgClockFreq(SCG_CMU4REF_CLK); + } + else + { + /* Never come here */ + bCmuClkStatus = CMU_CLK_ERROR; + } + + if(bCmuClkStatus == CMU_VALID) + { + if ((ptCmuFreq->u32MonitorClk == 0U) || (ptCmuFreq->u32RefClk == 0U)) + { + bCmuClkStatus = CMU_CLK_ERROR; + } + } + + return bCmuClkStatus; +} + +CMU_StatusType CMU_Init(CMU_InstanceType eInstance, const CMU_CfgType *pInitCfg) +{ + CMU_StatusType eStatus; + CMU_Type *pCmu; + CMU_RefClockDivType eDiv; + CMU_ClkFrequenceType tCmuFreq; + uint32_t u32RefWindow, u32MaxRefWindow, u32MinRefWindow; + uint32_t u32MonitorCnts, u32MinMonitorCnts, u32MaxMonitorCnts; + uint32_t u32RefClk, u32MonitorClk; + uint32_t u32Temp; + + DEV_ASSERT((uint8_t)eInstance < CMU_INSTANCE_COUNT); + DEV_ASSERT(pInitCfg != NULL); + pCmu = s_apCmuBase[(uint8_t)eInstance]; + eDiv = pInitCfg->eDiv; + + /* Check Reference clock and monitor clock status.*/ + eStatus = CMU_ClkStatusCheck(eInstance, &tCmuFreq); + + if (eStatus == CMU_VALID) + { + /* divide the clock value by 1K_factor */ + u32RefClk = (tCmuFreq.u32RefClk >> eDiv) / CMU_DIVID_FACTOR_1K; + u32MonitorClk = tCmuFreq.u32MonitorClk / CMU_DIVID_FACTOR_1K; + + if (u32RefClk / u32MonitorClk <= 0x100U) + { + u32MaxRefWindow = (0xffffffU - 3U) / u32MonitorClk * u32RefClk / 105U * CMU_PERCENT_FACTOR - 2U; + + if (u32MaxRefWindow > 0xffffffU) + { + u32MaxRefWindow = 0xffffffU; + } + } + else + { + u32MaxRefWindow = 0xffffffU; + } + + u32MinRefWindow = 6U + 5U * u32RefClk / u32MonitorClk; + u32RefWindow = 100U * u32MinRefWindow; + + if (u32RefWindow > u32MaxRefWindow) + { + u32RefWindow = u32MaxRefWindow; + } + + u32MonitorCnts = u32MonitorClk * (u32RefWindow + 2U) / u32RefClk; + u32MinMonitorCnts = u32MonitorCnts * 95U / CMU_PERCENT_FACTOR - 3U; + u32MaxMonitorCnts = u32MonitorCnts * 105U / CMU_PERCENT_FACTOR + 3U; + + CMU_HWA_SetRefWindow(pCmu, u32RefWindow); + CMU_HWA_SetMinCnts(pCmu, u32MinMonitorCnts); + CMU_HWA_SetMaxCnts(pCmu, u32MaxMonitorCnts); + + /* Program program PERIOD[EN] and PERIOD[WINDOW]. */ + CMU_HWA_SetPeriodEnable(pCmu, false); + if (pInitCfg->bPerMonitorEnable == true) + { + uint8_t u8MaxPeriod = (uint8_t)(u32RefClk / u32RefWindow); + + if ((u8MaxPeriod >> (uint8_t)CMU_PERIOD_WINDOW_WIDTH) != 0U) + { + u8MaxPeriod = (1U << (uint8_t)CMU_PERIOD_WINDOW_WIDTH) - 1U; + } + + if (u8MaxPeriod != 0U) + { + if (pInitCfg->u8PerMonitorWindow <= u8MaxPeriod) + { + CMU_HWA_SetPeriodWindow(pCmu, (uint32_t)(pInitCfg->u8PerMonitorWindow)); + } + else + { + CMU_HWA_SetPeriodWindow(pCmu, (uint32_t)(u8MaxPeriod)); + } + CMU_HWA_SetPeriodEnable(pCmu, pInitCfg->bPerMonitorEnable); + } + } + + /* Program DIV,IRQ_EN,LP_EN,STOP_EN,ENABLE */ + u32Temp = CMU_HWA_GetCTRL(pCmu); + u32Temp &= ~(uint32_t)(CMU_CTRL_REF_DIV_MASK | CMU_CTRL_IRQ_EN_MASK | \ + CMU_CTRL_LP_EN_MASK | CMU_CTRL_STOP_EN_MASK | CMU_CTRL_ENABLE_MASK); + u32Temp |= (uint32_t)(CMU_CTRL_REF_DIV(eDiv) | CMU_CTRL_IRQ_EN(pInitCfg->bIntEnable) | \ + CMU_CTRL_LP_EN(pInitCfg->bLpen) | CMU_CTRL_STOP_EN(pInitCfg->bSten) | \ + CMU_CTRL_ENABLE(pInitCfg->bEnable)); + CMU_HWA_SETCTRL(pCmu, u32Temp); + + s_apCmuISRCallback[(uint8_t)eInstance] = pInitCfg->pIsrCallback; + } + else + { + /* clock status invalid, change, do nothing */ + } + + return eStatus; +} + +void CMU_Enable(CMU_InstanceType eInstance) +{ + DEV_ASSERT((uint8_t)eInstance < CMU_INSTANCE_COUNT); + CMU_HWA_Enable(s_apCmuBase[(uint8_t)eInstance]); +} + +void CMU_Disable(CMU_InstanceType eInstance) +{ + CMU_Type *pCmu; + + DEV_ASSERT((uint8_t)eInstance < CMU_INSTANCE_COUNT); + pCmu = s_apCmuBase[(uint8_t)eInstance]; + + CMU_HWA_Disable(pCmu); + CMU_HWA_ClearST(pCmu); +} + +void CMU_EnableInterrupt(CMU_InstanceType eInstance) +{ + DEV_ASSERT((uint8_t)eInstance < CMU_INSTANCE_COUNT); + CMU_HWA_IrqEnable(s_apCmuBase[(uint8_t)eInstance],true); +} + +void CMU_DisableInterrupt(CMU_InstanceType eInstance) +{ + DEV_ASSERT((uint8_t)eInstance < CMU_INSTANCE_COUNT); + CMU_HWA_IrqEnable(s_apCmuBase[(uint8_t)eInstance],false); +} + +CMU_InterruptType CMU_GetInterruptType(CMU_InstanceType eInstance) +{ + uint32_t u32Temp; + CMU_InterruptType eStatus; + + DEV_ASSERT((uint8_t)eInstance < CMU_INSTANCE_COUNT); + + u32Temp = CMU_HWA_GetST(s_apCmuBase[(uint8_t)eInstance]); + if ((u32Temp & CMU_ST_LOC_MASK) != 0U) + { + eStatus = CMU_INTERRUPT_LOC; + } + else if ((u32Temp & CMU_ST_MIS_MASK) != 0U) + { + eStatus = CMU_INTERRUPT_MIS; + } + else + { + eStatus = CMU_INTERRUPT_NONE; + } + + return eStatus; +} + +CMU_StatusType CMU_SetCmu4RefSrc(CMU_Cmu4ClkSrcType eSrc) +{ + SCG_StatusType eStatus; + + SCG_HWA_SetCmu4Clk(0U); + + if (CMU_CMU4_REF_CLK_FOSC == eSrc) + { + eStatus = SCG_SetCmu4Clk(SCG_CMU4CLK_SRC_FOSC); + } + else if (CMU_CMU4_REF_CLK_SIRC == eSrc) + { + eStatus = SCG_SetCmu4Clk(SCG_CMU4CLK_SRC_SIRC); + } + else + { + eStatus = SCG_STATUS_PARAM_ERROR; + } + + return (eStatus == SCG_STATUS_SUCCESS) ? CMU_VALID : CMU_CLK_ERROR; +} + +uint32_t CMU_GetCount(CMU_InstanceType eInstance) +{ + DEV_ASSERT((uint8_t)eInstance < CMU_INSTANCE_COUNT); + + return CMU_HWA_GetCount(s_apCmuBase[(uint8_t)eInstance]); +} + +uint32_t CMU_GetMinCount(CMU_InstanceType eInstance) +{ + DEV_ASSERT((uint8_t)eInstance < CMU_INSTANCE_COUNT); + + return CMU_HWA_GetMinCnts(s_apCmuBase[(uint8_t)eInstance]); +} + +uint32_t CMU_GetMaxCount(CMU_InstanceType eInstance) +{ + DEV_ASSERT((uint8_t)eInstance < CMU_INSTANCE_COUNT); + + return CMU_HWA_GetMaxCnts(s_apCmuBase[(uint8_t)eInstance]); +} + +void CMU_LowPowerModeEnable(CMU_InstanceType eInstance, CMU_LowpowerModeType eMode, bool bModeEnable, bool bRestartEnable) +{ + CMU_Type *pCmu; + + DEV_ASSERT((uint8_t)eInstance < CMU_INSTANCE_COUNT); + pCmu = s_apCmuBase[(uint8_t)eInstance]; + + if (eMode == CMU_STANDBY_MODE) + { + CMU_HWA_StopModeEnable(pCmu, bModeEnable); + CMU_HWA_StanbyModeEnable(pCmu, bModeEnable); + } + else if (eMode == CMU_STOP_MODE) + { + CMU_HWA_StopModeEnable(pCmu, bModeEnable); + } + else + { + + } + + CMU_HWA_LPRestartEnable(pCmu, bRestartEnable); +} + + +/***************CMU IRQ Functions*****************/ + +static void CMU_IRQHandler(CMU_InstanceType eInstance) +{ + CMU_Type *pCmu; + CMU_InterruptType eStatus; + + DEV_ASSERT((uint8_t)eInstance < CMU_INSTANCE_COUNT); + pCmu = s_apCmuBase[(uint8_t)eInstance]; + + eStatus = CMU_GetInterruptType(eInstance); + + if (s_apCmuISRCallback[(uint8_t)eInstance] != NULL) + { + s_apCmuISRCallback[(uint8_t)eInstance](eInstance, eStatus); + } + + CMU_HWA_ClearST(pCmu); +} + +void CMU0_IRQHandler(void) +{ + CMU_IRQHandler(CMU_INSTANCE_0); +} + +void CMU1_IRQHandler(void) +{ + CMU_IRQHandler(CMU_INSTANCE_1); +} + +void CMU2_IRQHandler(void) +{ + CMU_IRQHandler(CMU_INSTANCE_2); +} + +void CMU3_IRQHandler(void) +{ + CMU_IRQHandler(CMU_INSTANCE_3); +} + +void CMU4_IRQHandler(void) +{ + CMU_IRQHandler(CMU_INSTANCE_4); +} diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_cordic.c b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_cordic.c new file mode 100644 index 0000000..4f4162a --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_cordic.c @@ -0,0 +1,280 @@ +/** + * @file fc7xxx_driver_cordic.c + * @author Flagchip + * @brief FC7xxx Cordic driver source code + * @version 0.1.0 + * @date 2024-01-11 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-01-11 Flagchip054 N/A First version for FC7240 + ******************************************************************************** */ +#include "fc7xxx_driver_cordic.h" +#include "interrupt_manager.h" + +#define CORDIC_SIGN_BIT 0x80000000UL +#define CORDIC_EXP_BIT 0x7F800000UL +#define CORDIC_TAIL_BIT 0x007FFFFFUL + +#define REVERSE_SCALEING_FACTOR_K 0x4dba76b2 +#define REVERSE_SCALEING_FACTOR_KA 0x9A8F4314 + +#define USE_FPU_HARDWARE 0 + + +/** + * @brief Floating-point conversion to 24 bit fixed-point + * + * @param nFloat Input value + */ + + +/*************** Local Functions ***************/ +/** + * @brief Clips Q63 to Q31 values. + */ +__attribute__((always_inline)) static inline int32_t clip_q63_to_q31( + int64_t x) +{ + return ((int32_t)(x >> 32) != ((int32_t) x >> 31)) ? + ((0x7FFFFFFF ^ ((int32_t)(x >> 63)))) : (int32_t) x; +} + + +static int32_t Float2Fix_Convert(const float data) +{ + return clip_q63_to_q31((int64_t)(data * 2147483648.0f)); +} + +/***************** Global Functions *******************/ +/** + * @brief The function to calculate sin & cos + * + * @param radian the input value to calculate + * + * input range (−90°, +90°)/180° + */ +CORDIC_SinCos_Type Cordic_Circular_Sin_Cos(const float radian) +{ + /* angles are expressed in radian, multiplied by a constant number. 𝜃/180 * 𝜋c (where 𝜋c is 13.42177) */ + CORDIC_SinCos_Type tRetVal; + //float tmp = REVERSE_SCALEING_FACTOR_K; + float tmp = 0; + int32_t fix_radian = Float2Fix_Convert(radian); + int32_t x_input = REVERSE_SCALEING_FACTOR_K; + Cordic_HWA_Set_XInput(x_input); + Cordic_HWA_Set_YInput(0); + Cordic_HWA_Set_ZInput(fix_radian); + /* Disable interrupt + Iteration Number16 + Trigonometric system + Rotate mode */ + Cordic_HWA_SetCtrl(CORDIC_CTR_VAL(0, false, (uint32_t)CORDIC_Iteration_16, (uint32_t)CORDIC_Trigonometric, (uint32_t)CORDIC_Rotate)); + while (!Cordic_HWA_Get_Stat()) {} + tmp = (int32_t)Cordic_HWA_Get_YOutput() / 2147483648.f; //134217728.f; + tRetVal.sinx = tmp; + tmp = (int32_t)Cordic_HWA_Get_XOutput() / 2147483648.f; //134217728.f; + tRetVal.cosx = tmp; + return tRetVal; +} + +/** + * @brief The function to calculate circular radical add + * + * @param1 x the first input value + * + * @param2 y the second input value + */ +CORDIC_Radical_Type Cordic_Circular_Radical_Add(const float x, const float y) +{ + CORDIC_Radical_Type tRetVal; + /*** 40752053.5625 = REVERSE_SCALEING_FACTOR_K / 32 ***/ + int32_t x_input = (int32_t)(40752053.5625 * x); + int32_t y_input = (int32_t)(40752053.5625 * y); + Cordic_HWA_Set_XInput(x_input); + Cordic_HWA_Set_YInput(y_input); + Cordic_HWA_Set_ZInput(0); + /* Disable interrupt + Iteration Number16 + Trigonometric system + Vector mode */ + Cordic_HWA_SetCtrl(CORDIC_CTR_VAL(5, false, (uint32_t)CORDIC_Iteration_16, (uint32_t)CORDIC_Trigonometric, (uint32_t)CORDIC_Vector)); + while (!Cordic_HWA_Get_Stat()) {} + /*** 67,108,864 = 2147483648.f / 32 ***/ + tRetVal = Cordic_HWA_Get_XOutput() / 67108864.f; + return tRetVal; +} + +/** + * @brief The function to calculate circular arctan + * + * @param y the input value + */ +CORDIC_Arctan_Type Cordic_Circular_Arctan_F(const float y) +{ + CORDIC_Arctan_Type tRetVal; + if ((y > 96.6) || (y < -96.6)) + { + tRetVal = 89.4069; + } + else + { + int32_t x_input = 2147484; + int32_t y_input = (int32_t)(y * 2147484); + Cordic_HWA_Set_XInput(x_input); + Cordic_HWA_Set_YInput(y_input); + Cordic_HWA_Set_ZInput(0); + /* Disable interrupt + Iteration Number16 + Trigonometric system + Vector mode */ + Cordic_HWA_SetCtrl(CORDIC_CTR_VAL(0, false, (uint32_t)CORDIC_Iteration_16, (uint32_t)CORDIC_Trigonometric, (uint32_t)CORDIC_Vector)); + while (!Cordic_HWA_Get_Stat()) {} + /*** 11,930,464.711111 = 12147483648 / 180 ***/; + tRetVal = (int32_t)Cordic_HWA_Get_ZOutput() / 11930464.711111; + } + return tRetVal; +} + +/** + * @brief The function to calculate circular arctan + * + * @param1 x the first input value + * + * @param2 y the second input value + */ +CORDIC_Arctan_Type Cordic_Circular_Arctan(const int32_t x, const int32_t y) +{ + CORDIC_Arctan_Type tRetVal; + + Cordic_HWA_Set_XInput(x); + Cordic_HWA_Set_YInput(y); + Cordic_HWA_Set_ZInput(0); + /* Disable interrupt + Iteration Number16 + Trigonometric system + Vector mode */ + Cordic_HWA_SetCtrl(CORDIC_CTR_VAL(0, false, (uint32_t)CORDIC_Iteration_16, (uint32_t)CORDIC_Trigonometric, (uint32_t)CORDIC_Vector)); + while (!Cordic_HWA_Get_Stat()) {} + /*** 11,930,464.711111 = 12147483648 / 180 ***/; + tRetVal = (int32_t)Cordic_HWA_Get_ZOutput() / 11930464.711111; + return tRetVal; +} + +/** + * @brief The function to calculate circular Sinh & Cosh + * + * @param z the input value + */ +CORDIC_SinhCosh_Type Cordic_Circular_Sinh_Cosh(const float z) +{ + CORDIC_SinhCosh_Type tRetVal; + float tmp = 0; + + /*** 1073741824 = 2147483648 / 2 ***/ + int32_t z_input = (int32_t)(z * 1073741824.f); + /*** 1296540042 = REVERSE_SCALEING_FACTOR_KA / 2 ***/ + int32_t x_input = 1296540042; + + Cordic_HWA_Set_XInput(x_input); + Cordic_HWA_Set_YInput(0); + Cordic_HWA_Set_ZInput(z_input); + /* Scale 1 + Disable interrupt + Iteration Number16 + Hyperbolic system + Rotate mode */ + Cordic_HWA_SetCtrl(CORDIC_CTR_VAL(1, false, (uint32_t)CORDIC_Iteration_16, (uint32_t)CORDIC_Hyperbolic, (uint32_t)CORDIC_Rotate)); + while (!Cordic_HWA_Get_Stat()) {} + /*** 1073741824 = 2147483648 / 2 ***/ + tmp = (int32_t)Cordic_HWA_Get_YOutput() / 1073741824.f ; + tRetVal.sinxh = tmp; + /*** 1073741824 = 2147483648 / 2 ***/ + tmp = (int32_t)Cordic_HWA_Get_XOutput() / 1073741824.f; + tRetVal.cosxh = tmp; + return tRetVal; +} + +/** + * @brief The function to calculate circular radical sub + * + * @param1 x the first input value + * + * @param2 y the second input value + */ +CORDIC_Radical_Type Cordic_Circular_Radical_Sub(const float x, const float y) +{ + CORDIC_Radical_Type tRetVal; + /*** 162067505 = REVERSE_SCALEING_FACTOR_KA / 16 ***/ + int32_t x_input = (int32_t)(162067505.f * x); + int32_t y_input = (int32_t)(162067505.f * y); + + Cordic_HWA_Set_XInput(x_input); + Cordic_HWA_Set_YInput(y_input); + Cordic_HWA_Set_ZInput(0); + /* Disable interrupt + Iteration Number16 + Hyperbolic system + Vector mode */ + Cordic_HWA_SetCtrl(CORDIC_CTR_VAL(4, false, (uint32_t)CORDIC_Iteration_16, (uint32_t)CORDIC_Hyperbolic, (uint32_t)CORDIC_Vector)); + while (!Cordic_HWA_Get_Stat()) {} + /*** 134217728 = 2147483648.f / 16 ***/ + tRetVal = Cordic_HWA_Get_XOutput() / 134217728.f; + return tRetVal; +} + +/** + * @brief The function to calculate circular arctanh + * + * @param y the input value + */ +CORDIC_Arctanh_Type Cordic_Circular_Arctanh(const float y) +{ + CORDIC_Arctanh_Type tRetVal; + + /*** 1073741824 = 2147483648 / 2 ***/ + int32_t x_input = 1073741824; + int32_t y_input = (int32_t)(y * 1073741824.f); + + Cordic_HWA_Set_XInput(x_input); + Cordic_HWA_Set_YInput(y_input); + Cordic_HWA_Set_ZInput(0); + /* Disable interrupt + Iteration Number16 + Hyperbolic system + Vector mode */ + Cordic_HWA_SetCtrl(CORDIC_CTR_VAL(1, false, (uint32_t)CORDIC_Iteration_16, (uint32_t)CORDIC_Hyperbolic, (uint32_t)CORDIC_Vector)); + while (!Cordic_HWA_Get_Stat()) {} + /*** 1073741824 = 2147483648 / 2 ***/ + tRetVal = (int32_t)Cordic_HWA_Get_ZOutput() / 1073741824.f; + return tRetVal; +} + +/** + * @brief The function to calculate ln + * + * @param y the input value (0.1068482375 , 9.3590687463) + */ +CORDIC_Ln_Type Cordic_Extended_LN(const float y) +{ + CORDIC_Ln_Type tRetVal; + /*** 134217728 = 2147483648 / 16 ***/ + int32_t x_input = (int32_t)((y + 1) * 134217728.f); + int32_t f_input = (int32_t)((y - 1) * 134217728.f); + Cordic_HWA_Set_XInput(x_input); + Cordic_HWA_Set_YInput(f_input); + Cordic_HWA_Set_ZInput(0); + /* Disable interrupt + Iteration Number16 + Hyperbolic system + Vector mode */ + Cordic_HWA_SetCtrl(CORDIC_CTR_VAL(4, false, (uint32_t)CORDIC_Iteration_16, (uint32_t)CORDIC_Hyperbolic, (uint32_t)CORDIC_Vector)); + while (!Cordic_HWA_Get_Stat()) {} + /*** 67108864 = 12147483648.f / 32 ***/; + tRetVal = (int32_t)Cordic_HWA_Get_ZOutput() / 67108864.f; + return tRetVal; +} + +/** + * @brief The function to calculate sqrt + * + * @param y the input value (0.0267120594,2.3397671865) + */ +CORDIC_Ln_Type Cordic_Extended_Sqrt(const float y) +{ + CORDIC_Radical_Type tRetVal; + /*** 648270021 = 2593080084 / 4 ***/ + int32_t x_input = (int32_t)(648270021.f * (y + 0.25)); + int32_t y_input = (int32_t)(648270021.f * (y - 0.25)); + + Cordic_HWA_Set_XInput(x_input); + Cordic_HWA_Set_YInput(y_input); + Cordic_HWA_Set_ZInput(0); + /* Disable interrupt + Iteration Number16 + Hyperbolic system + Vector mode */ + Cordic_HWA_SetCtrl(CORDIC_CTR_VAL(2, false, (uint32_t)CORDIC_Iteration_16, (uint32_t)CORDIC_Hyperbolic, (uint32_t)CORDIC_Vector)); + while (!Cordic_HWA_Get_Stat()) {} + /*** 536870912 = 2147483648 / 4 ***/ + tRetVal = Cordic_HWA_Get_XOutput() / 536870912.f; + return tRetVal; +} diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_cpm.c b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_cpm.c new file mode 100644 index 0000000..688ce50 --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_cpm.c @@ -0,0 +1,210 @@ + /* @file fc7xxx_driver_cpm.c + * @author Flagchip + * @brief FC7xxx CPM driver type definition and API + * @version 0.1.0 + * @date 2024-01-5 + * + * @copyright Copyright (c) 2023 Flagchip Semiconductors Co., Ltd. + * + */ + + /* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-1-5 Flagchip120 N/A First version for FC7240 + ******************************************************************************** */ +#include "fc7xxx_driver_cpm.h" +#include "interrupt_manager.h" +#include "fc7xxx_driver_fcuart.h" + +/** + * @brief Cpm user defined interrupt function + * */ +static CPM_InterruptCallBackType s_pCpmNotifyPtr = NULL; + +/* ################################################################################## */ +/* ########################### Local Prototype Functions ############################ */ +void CPM_IRQHandler(void); + +/* ################################################################################## */ +/* ################################ Global Functions ################################ */ +/** + * + * @brief Configures the CPM module interrupts. + * + * This function configures the CPM module interrupts to enable/disable various interrupt sources. + * + * @param eIntSrc CPM FPU interrupt type. refer CPM FISCR register + * @param bEnable 1: interrupt enable, 0:interrupt disable. + */ +void CPM_FpuIntMode(FPU_IntType eIntSrc, bool bEnable) +{ + switch (eIntSrc) + { + case CPM_FPU_FIO: + CPM_HWA_SetFioceInt(bEnable); + break; + case CPM_FPU_FDZ: + CPM_HWA_SetFdzceInt(bEnable); + break; + case CPM_FPU_FOF: + CPM_HWA_SetFofceInt(bEnable); + break; + case CPM_FPU_FUF: + CPM_HWA_SetFufceInt(bEnable); + break; + case CPM_FPU_FIX: + CPM_HWA_SetFixceInt(bEnable); + break; + case CPM_FPU_FID: + CPM_HWA_SetFidceInt(bEnable); + break; + default : + /* Invalid parameter: return */ + break; + } +} + +/** + * @brief Get CPM Interrupt occurred flag + * + * This function returns the interrupt flag. + * + * @param eIntSrc CPM FPU interrupt type. refer CPM FISCR register + * @return true interrupt occurred + * @return false No interrupt + */ +bool CPM_GetFpuIntStatus(FPU_IntType eIntSrc) +{ + bool bRetVal = false; + switch(eIntSrc){ + case CPM_FPU_FIO: + bRetVal = CPM_HWA_GetFpuFiocFlag(); + break; + case CPM_FPU_FDZ: + bRetVal = CPM_HWA_GetFpuFdzcFlag(); + break; + case CPM_FPU_FOF: + bRetVal = CPM_HWA_GetFpuFofcFlag(); + break; + case CPM_FPU_FUF: + bRetVal = CPM_HWA_GetFpuFufcFlag(); + break; + case CPM_FPU_FIX: + bRetVal = CPM_HWA_GetFpuFixcFlag(); + break; + case CPM_FPU_FID: + bRetVal = CPM_HWA_GetFpuFidcFlag(); + break; + default: + break; + + } + return bRetVal; +} + + +#ifdef FPU_USED_ENABLE +/** + * @brief CPM_Read_FPSCR + * Return the current value of FPSCR + * @return u32RetVal + */ +uint32_t CPM_Read_FPSCR(void) +{ + uint32_t u32RetVal = 0U; + __asm( + "vmrs %0, fpscr" : "=r" (u32RetVal) + ); + return u32RetVal; +} + +/** + * @brief CPM_Write_FPSCR + * + * @param u32SetVal set the value for FPSCR + */ +void CPM_Write_FPSCR(uint32_t u32SetVal) +{ + __asm( + "vmsr fpscr, %0" : : "r" (u32SetVal) + ); +} + +/** + * @brief Deinit Cpm set interrupt + * + * Restore the Cpm FISCR to its reset state + */ +void CPM_DeInitInterrupt(void) +{ + uint32_t u32RetVal; + CPM_HWA_SetFiscr(0x0U); + u32RetVal = CPM_Read_FPSCR(); + /* Clear FPSCR IDC/IXC/UFC/OPF/DZC/IOC flag*/ + u32RetVal &=0xFFFFFF90u; + CPM_Write_FPSCR(u32RetVal); +} +#endif + +/** + * @brief CPM interrupt function + * + */ +void CPM_IRQHandler(void) +{ + if(s_pCpmNotifyPtr != NULL) + { + s_pCpmNotifyPtr(); + } +} + +/** + * @brief Cpm set interrupt + * + * @param pIntStruct interrupt structure pointer + * @return Cpm return type + */ +CPM_RetType CPM_InitInterrupt(const CPM_InterruptType *pIntStruct) +{ + CPM_RetType eRet = CPM_STATUS_SUCCESS; + if(NULL == pIntStruct) + { + eRet = CPM_STATUS_PARAM_INVALID; + } + else + { + if(pIntStruct->u8CpmEnable != 0U) + { + if(((uint32_t)(pIntStruct->eFPU_IntType) & CPM_FISCR_FIOC_MASK) == CPM_FPU_FIO) + { + CPM_FpuIntMode(CPM_FPU_FIO,true); + } + if(((uint32_t)(pIntStruct->eFPU_IntType) & CPM_FISCR_FDZC_MASK) == CPM_FPU_FDZ) + { + CPM_FpuIntMode(CPM_FPU_FDZ,true); + } + if(((uint32_t)(pIntStruct->eFPU_IntType) & CPM_FISCR_FUFC_MASK) == CPM_FPU_FUF) + { + CPM_FpuIntMode(CPM_FPU_FUF,true); + } + if(((uint32_t)(pIntStruct->eFPU_IntType) & CPM_FISCR_FOFC_MASK) == CPM_FPU_FOF) + { + CPM_FpuIntMode(CPM_FPU_FOF,true); + } + if(((uint32_t)(pIntStruct->eFPU_IntType) & CPM_FISCR_FIDC_MASK) == CPM_FPU_FID) + { + CPM_FpuIntMode(CPM_FPU_FID,true); + } + if(((uint32_t)(pIntStruct->eFPU_IntType) & CPM_FISCR_FIXC_MASK) == CPM_FPU_FIX) + { + CPM_FpuIntMode(CPM_FPU_FIX,true); + } + } + s_pCpmNotifyPtr = pIntStruct->pIsrNotify; + } + return eRet; +} + diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_crc.c b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_crc.c new file mode 100644 index 0000000..feacc2f --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_crc.c @@ -0,0 +1,167 @@ +/** + * @file fc7xxx_driver_crc.c + * @author Flagchip + * @brief FC7xxx CRC driver source code + * @version 0.1.0 + * @date 2024-01-12 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + */ +/******************************************************************************** +* Revision History: +* +* Version Date Initials CR# Descriptions +* --------- ---------- ------------ ---------- --------------- +* 0.1.0 2024-01-12 Flagchip119 N/A First version for FC7240 +********************************************************************************/ + +#include "fc7xxx_driver_crc.h" + + + +/********* Local Variables ************/ +static CRC_Type *const s_apCrcBase[CRC_INSTANCE_COUNT] = CRC_BASE_PTRS; + + +/********* Local Functions ************/ + +void CRC_Init(uint8_t u8Instance, const CRC_InitType *const pInitCfg) +{ + DEV_ASSERT(u8Instance < CRC_INSTANCE_COUNT); + DEV_ASSERT(pInitCfg != NULL); + CRC_Type *const pCrc = s_apCrcBase[u8Instance]; + + if (pInitCfg->eBitWidth == CRC_BIT_8) + { + /* set CRC bit width(8-bit) */ + CRC_HWA_Set_8Bit_Width(pCrc, (CRC_BitWidthType)(pInitCfg->eBitWidth - 1)); + CRC_HWA_SetBitWidth(pCrc, (CRC_BitWidthType)0); + } + else + { + /* set CRC bit width(16-bit or 32-bit) */ + CRC_HWA_Set_8Bit_Width(pCrc, (CRC_BitWidthType)0); + CRC_HWA_SetBitWidth(pCrc, pInitCfg->eBitWidth); + } + + /* set CRC write/read swap and FXOR */ + CRC_HWA_SetWriteDataSwap(pCrc, pInitCfg->eWriteDataSwap); + CRC_HWA_SetReadDataSwap(pCrc, pInitCfg->eReadDataSwap); + CRC_HWA_SetReadDataFXOR(pCrc, pInitCfg->eReadDataFXOR); + + /* set CRC polynomial value */ + CRC_HWA_SetPolyVal(pCrc, pInitCfg->u32Polynomial); + + /* set CRC seed value */ + CRC_SetSeed(u8Instance, pInitCfg->u32SeedValue); +} + +void CRC_DeInit(uint8_t u8Instance) +{ + DEV_ASSERT(u8Instance < CRC_INSTANCE_COUNT); + CRC_Type *const pCrc = s_apCrcBase[u8Instance]; + + /* set CRC bit width(32-bit) */ + CRC_HWA_SetBitWidth(pCrc, CRC_BIT_32); + + /* set CRC write/read swap and FXOR */ + CRC_HWA_SetWriteDataSwap(pCrc, WRITE_DATASWAP_NONE); + CRC_HWA_SetReadDataSwap(pCrc, READ_DATASWAP_NONE); + CRC_HWA_SetReadDataFXOR(pCrc, READ_DATA_NORMAL); + + /* set CRC polynomial value */ + CRC_HWA_SetPolyVal(pCrc, CRC_DEFAULT_POLY); + + /* set CRC seed value */ + CRC_SetSeed(u8Instance, CRC_DEFAULT_INTVAL); +} + +uint32_t CRC_GetCrcResult(uint8_t u8Instance) +{ + DEV_ASSERT(u8Instance < CRC_INSTANCE_COUNT); + CRC_Type *const pCrc = s_apCrcBase[u8Instance]; + CRC_ReadDataSwapType eTempVal; + uint32_t u32Ret; + + eTempVal = CRC_HWA_GetReadDataSwap(pCrc); + + if (CRC_BIT_8 == CRC_HWA_Get8BitWidth(pCrc)) + { + /* Returns upper 8 bits of CRC because of swap in 8 bits mode */ + if ((eTempVal == READ_DATASWAP_BIT_BYTE) || (eTempVal == READ_DATASWAP_BYTE)) + { + u32Ret = CRC_HWA_GetData_U8_H(pCrc); + } + else + { + u32Ret = CRC_HWA_GetData_U8_L(pCrc); + } + return u32Ret; + } + else if (CRC_BIT_16 == CRC_HWA_GetBitWidth(pCrc)) + { + /* Returns upper 16 bits of CRC because of swap in 16 bits mode */ + if ((eTempVal == READ_DATASWAP_BIT_BYTE) || (eTempVal == READ_DATASWAP_BYTE)) + { + u32Ret = CRC_HWA_GetData_U16_H(pCrc); + } + else + { + u32Ret = CRC_HWA_GetData_U16_L(pCrc); + } + } + else + { + u32Ret = CRC_HWA_GetData_U32(pCrc); + } + + return u32Ret; +} + +void CRC_SetCalcData_U8(uint8_t u8Instance, uint8_t u8Data) +{ + DEV_ASSERT(u8Instance < CRC_INSTANCE_COUNT); + CRC_Type *const pCrc = s_apCrcBase[u8Instance]; + + CRC_HWA_SetData_U8(pCrc, u8Data); +} + +void CRC_SetCalcData_U16(uint8_t u8Instance, uint16_t u16Data) +{ + DEV_ASSERT(u8Instance < CRC_INSTANCE_COUNT); + CRC_Type *const pCrc = s_apCrcBase[u8Instance]; + + CRC_HWA_SetData_U16(pCrc, u16Data); +} + +void CRC_SetCalcData_U32(uint8_t u8Instance, uint32_t u32Data) +{ + DEV_ASSERT(u8Instance < CRC_INSTANCE_COUNT); + CRC_Type *const pCrc = s_apCrcBase[u8Instance]; + + CRC_HWA_SetData_U32(pCrc, u32Data); +} + +void CRC_SetSeed(uint8_t u8Instance, uint32_t u32SeedVal) +{ + DEV_ASSERT(u8Instance < CRC_INSTANCE_COUNT); + CRC_Type *const pCrc = s_apCrcBase[u8Instance]; + + CRC_HWA_SetDataOrSeed(pCrc, WRITE_COMMAND_SEED); + CRC_HWA_SetData_U32(pCrc, u32SeedVal); + CRC_HWA_SetDataOrSeed(pCrc, WRITE_COMMAND_DATA); +} + +void CRC_SetInputData(uint8_t u8Instance, const uint8_t pData[], uint32_t u32DataSize) +{ + DEV_ASSERT(u8Instance < CRC_INSTANCE_COUNT); + uint32_t i; + + for (i = 0U; i < u32DataSize; i++) + { + CRC_SetCalcData_U8(u8Instance, pData[i]); + } +} + + diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_csc.c b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_csc.c new file mode 100644 index 0000000..71e091d --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_csc.c @@ -0,0 +1,1698 @@ +/** + * @file fc7xxx_driver_csc.h + * @author Flagchip + * @brief FC7xxx csc driver type definition and API + * @version 0.1.0 + * @date 2024-01-12 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + */ + +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-01-12 Flagchip085 N/A First version for FC7240 + ******************************************************************************** */ + +#include "fc7xxx_driver_csc.h" +#include "fc7xxx_driver_scg.h" + +/********* Local Macros ************/ +#define CSC_GET_CPU_ID() ((CSC_WPB_CpuType)1U) + +/********* Local Variables ************/ + +/********* Local functions ************/ + +/** + * @brief Get the frequency of AONCLK clock selected by CSC0_AONCLKSR[AONCLKSEL]. + * + * @return the frequency of AONCLK + */ +static uint32_t CSC0_GetAONClkFreq(void) +{ + CSC0_AONClkSrcType eAonClkSrc; + uint32_t u32Freq; + + eAonClkSrc = CSC0_HWA_GetAONClkSrc(); + + if (CSC0_AON_SIRCDIV_128K_CLK == eAonClkSrc) + { + u32Freq = CSC0_AONCLK_128K; + } + else if (CSC0_AON_SIRC32_1K_CLK == eAonClkSrc) + { + u32Freq = CSC0_AONCLK_1K; + } + else + { + u32Freq = CSC0_AONCLK_32K; + } + return u32Freq; +} + +/** + * @brief Get the frequency of AON32K clock selected by CSC0_AONCLKSR[AON32KCLKSEL]. + * + * @return the frequency of AON32K + */ +static uint32_t CSC0_GetAON32kClkFreq(void) +{ + CSC0_AON32KClkSrcType eAon32KSrc; + uint32_t u32Freq; + + eAon32KSrc = CSC0_HWA_GetAON32kClkSrc(); + + if (CSC0_AON32K_SOSC32K_CLK == eAon32KSrc) + { + u32Freq = CSC0_AONCLK_SOSC_32K; + } + else + { + u32Freq = CSC0_AONCLK_32K; + } + return u32Freq; +} + +/** + * @brief Get the frequency of RTC clock selected by CSC0_AONCLKSR[RTCCLKSEL]. + * + * @return the frequency of RTC + */ +static uint32_t CSC0_GetRTCClkFreq(void) +{ + CSC0_RTCClkSrcType eRtcClkSrc; + uint32_t u32Freq; + + eRtcClkSrc = CSC0_HWA_GetRTCClkSrc(); + if (CSC0_RTC_FOSCDIVL_CLK == eRtcClkSrc) + { + u32Freq = SCG_GetScgClockFreq(SCG_FOSCDIVL_CLK); + } + else if (CSC0_RTC_SOSC_CLK == eRtcClkSrc) + { + u32Freq = CSC0_AONCLK_SOSC_32K; + } + else + { + u32Freq = CSC0_AONCLK_32K; + } + + return u32Freq; +} + +/** + * @brief Get the frequency of output clock selected by CSC0_CLKOUT_CTRL[CLKOUT_SEL]. + * + * @return the frequency of CSC0 output clock + */ +static uint32_t CSC0_GetClockOutFreq(void) +{ + uint32_t u32Freq; + CSC0_ClockOutSrcType eClkOutSrc; + CSC0_ClockOutDivType eClkOutDiv; + + + eClkOutSrc = CSC0_HWA_GetClkOutSel(); + eClkOutDiv = CSC0_HWA_GetClkOutDiv(); + + if(eClkOutSrc == CSC0_CLKOUT_SCG_CLKOUT) + { + u32Freq = SCG_GetScgClockFreq(SCG_SCG_CLKOUT_CLK); + } + else if(eClkOutSrc == CSC0_CLKOUT_FOSC_DIVM_CLK) + { + u32Freq = SCG_GetScgClockFreq(SCG_FOSCDIVM_CLK); + } + else if(eClkOutSrc == CSC0_CLKOUT_SLOW_CLK) + { + u32Freq = SCG_GetScgClockFreq(SCG_SLOW_CLK); + } + else if(eClkOutSrc == CSC0_CLKOUT_SIRC_DIVM_CLK) + { + u32Freq = SCG_GetScgClockFreq(SCG_SIRCDIVM_CLK); + } + else if(eClkOutSrc == CSC0_CLKOUT_PLL1_DIVM_CLK) + { + u32Freq = SCG_GetScgClockFreq(SCG_PLL1DIVM_CLK); + } + else if(eClkOutSrc == CSC0_CLKOUT_FIRC_DIVM_CLK) + { + u32Freq = SCG_GetScgClockFreq(SCG_FIRCDIVM_CLK); + } + else if(eClkOutSrc == CSC0_CLKOUT_CORE_CLK) + { + u32Freq = SCG_GetScgClockFreq(SCG_CORE_CLK); + } + else if(eClkOutSrc == CSC0_CLKOUT_PLL0_DIVM_CLK) + { + u32Freq = SCG_GetScgClockFreq(SCG_PLL0DIVM_CLK); + } + else if(eClkOutSrc == CSC0_CLKOUT_BUS_CLK) + { + u32Freq = SCG_GetScgClockFreq(SCG_BUS_CLK); + } + else if(eClkOutSrc == CSC0_CLKOUT_SIRC_128K_CLK) + { + u32Freq = CSC0_AONCLK_128K; + } + else if(eClkOutSrc == CSC0_CLKOUT_AON_CLK) + { + u32Freq = CSC0_GetAONClkFreq(); + } + else if(eClkOutSrc == CSC0_CLKOUT_RTC_CLK) + { + u32Freq = CSC0_GetRTCClkFreq(); + } + else + { + u32Freq = 0U; + } + + return u32Freq / ((uint32_t)eClkOutDiv + 1U); +} + +/** + * @brief Set cpu to control peripheral group 0 in CSC0. + * + * @param eCpuType Cpu to use + * @param eTarget Target to be set stop ack/request + * @param bLockStatus Lock current register.Once locked, calling the API returns an error(CSC_E_LOCK). + * + * @return Set clock out operation success/failed + */ +static CSC_RetStatusType CSC0_SetCpuCtrlGrp0(const CSC_WPB_CpuType eCpuType, CSC_SetTargetType eTarget, bool bLockStatus) +{ + CSC_RetStatusType eRetVal = CSC_E_LOCK; + + if (CSC_STOPACK == eTarget) + { + if (0U == CSC0_HWA_MODER0_GetWPBLockStatus()) + { + CSC0_HWA_MODER0_SetCpuWritePermit(eCpuType); + + if(bLockStatus != false) + { + CSC0_HWA_MODER0_LockWritePermit(); + } + eRetVal = CSC_E_OK; + } + } + else + { + if (0U == CSC0_HWA_REQR0_GetWPBLockStatus()) + { + CSC0_HWA_REQR0_SetCpuWritePermit(eCpuType); + if(bLockStatus != false) + { + CSC0_HWA_REQR0_LockWritePermit(); + } + eRetVal = CSC_E_OK; + } + } + + return eRetVal; +} + +/** + * @brief Set cpu to control peripheral group 1 in CSC0. + * + * @param eCpuType Cpu to use + * @param eTarget Target to be set stop ack/request + * + * @return Set clock out operation success/failed + */ +static CSC_RetStatusType CSC0_SetCpuCtrlGrp1(const CSC_WPB_CpuType eCpuType, CSC_SetTargetType eTarget, bool bLockStatus) +{ + CSC_RetStatusType eRetVal = CSC_E_LOCK; + + if (CSC_STOPACK == eTarget) + { + if (0U == CSC0_HWA_MODER1_GetWPBLockStatus()) + { + CSC0_HWA_MODER1_SetCpuWritePermit(eCpuType); + if(bLockStatus != false) + { + CSC0_HWA_MODER1_LockWritePermit(); + } + eRetVal = CSC_E_OK; + } + } + else + { + if (0U == CSC0_HWA_REQR1_GetWPBLockStatus()) + { + CSC0_HWA_REQR1_SetCpuWritePermit(eCpuType); + if(bLockStatus != false) + { + CSC0_HWA_REQR1_LockWritePermit(); + } + eRetVal = CSC_E_OK; + } + } + + return eRetVal; +} + +/** + * @brief Set cpu to control peripheral group 2 in CSC0. + * + * @param eCpuType Cpu to use + * @param eTarget Target to be set stop ack/request + * + * @return Set clock out operation success/failed + */ +static CSC_RetStatusType CSC0_SetCpuCtrlGrp2(const CSC_WPB_CpuType eCpuType, CSC_SetTargetType eTarget, bool bLockStatus) +{ + CSC_RetStatusType eRetVal = CSC_E_LOCK; + + if (CSC_STOPACK == eTarget) + { + if (0U == CSC0_HWA_MODER2_GetWPBLockStatus()) + { + CSC0_HWA_MODER2_SetCpuWritePermit(eCpuType); + if(bLockStatus != false) + { + CSC0_HWA_MODER2_LockWritePermit(); + } + eRetVal = CSC_E_OK; + } + } + else + { + if (0U == CSC0_HWA_REQR2_GetWPBLockStatus()) + { + CSC0_HWA_REQR2_SetCpuWritePermit(eCpuType); + if(bLockStatus != false) + { + CSC0_HWA_REQR2_LockWritePermit(); + } + eRetVal = CSC_E_OK; + } + } + + return eRetVal; +} + +/** + * @brief Set the stop mode ACK of all group peripherals in CSC0. + * + * @param ePeriphGrp the group of peripherals to set the stop mode ACK value + * @param u32Value the CSCx_STOP_MODERx register value + * + * @return Operation success/failed + */ +static CSC_RetStatusType CSC0_SetStopModeAck(const CSC_PeriphGrpType ePeriphGrp,uint32_t u32Value) +{ + CSC_RetStatusType eRetVal = CSC_E_NO_PERM; + CSC_WPB_CpuType eCtrlCpu; + + if(ePeriphGrp == CSC_STOP_CTRL_GROUP_0) + { + eCtrlCpu = CSC0_HWA_MODER0_GetCpuWritePermit(); + + if((eCtrlCpu == CSC_GET_CPU_ID()) || (eCtrlCpu == CSC_WP_CPU_ALL)) + { + CSC0_HWA_MODER0_SetMultiStopAck(u32Value); + eRetVal = CSC_E_OK; + } + + } + else if(ePeriphGrp == CSC_STOP_CTRL_GROUP_1) + { + eCtrlCpu = CSC0_HWA_MODER1_GetCpuWritePermit(); + + if((eCtrlCpu == CSC_GET_CPU_ID()) || (eCtrlCpu == CSC_WP_CPU_ALL)) + { + CSC0_HWA_MODER1_SetMultiStopAck(u32Value); + eRetVal = CSC_E_OK; + } + + } + else + { + eCtrlCpu = CSC0_HWA_MODER2_GetCpuWritePermit(); + + if((eCtrlCpu == CSC_GET_CPU_ID()) || (eCtrlCpu == CSC_WP_CPU_ALL)) + { + CSC0_HWA_MODER2_SetMultiStopAck(u32Value); + eRetVal = CSC_E_OK; + } + + } + + return eRetVal; +} + +/** + * @brief Set the stop request of all group peripherals in CSC0. + * + * @param eTargetCpuType The target CPU which acknowledges the peripherals when entering stop mode. + * @param ePeriphGrp the group of peripherals to set the stop request value + * @param u32Value the CSCx_STOP_REQRx register value + * + * @return Operation success/failed + */ +static CSC_RetStatusType CSC0_SetStopRequest(const CSC_PeriphGrpType ePeriphGrp,uint32_t u32Value) +{ + CSC_RetStatusType eRetVal = CSC_E_NO_PERM; + CSC_WPB_CpuType eCtrlCpu; + + if(ePeriphGrp == CSC_STOP_CTRL_GROUP_0) + { + eCtrlCpu = CSC0_HWA_REQR0_GetCpuWritePermit(); + + if((eCtrlCpu == CSC_GET_CPU_ID()) || (eCtrlCpu == CSC_WP_CPU_ALL)) + { + CSC0_HWA_REQR0_SetMultiStopRequest(u32Value); + eRetVal = CSC_E_OK; + } + + } + else if(ePeriphGrp == CSC_STOP_CTRL_GROUP_1) + { + eCtrlCpu = CSC0_HWA_REQR1_GetCpuWritePermit(); + + if((eCtrlCpu == CSC_GET_CPU_ID()) || (eCtrlCpu == CSC_WP_CPU_ALL)) + { + CSC0_HWA_REQR1_SetMultiStopRequest(u32Value); + eRetVal = CSC_E_OK; + } + + } + else + { + eCtrlCpu = CSC0_HWA_REQR2_GetCpuWritePermit(); + + if((eCtrlCpu == CSC_GET_CPU_ID()) || (eCtrlCpu == CSC_WP_CPU_ALL)) + { + CSC0_HWA_REQR2_SetMultiStopRequest(u32Value); + eRetVal = CSC_E_OK; + } + + } + + return eRetVal; +} + +/** + * @brief Get the stop Acknowledge status of all group peripherals in CSC0. + * + * @param ePeriphType the peripheral to get stop acknowledge status + * @return uint32_t the stop ACK status of all the peripherals in the group indicated by ePeriphGrp. + */ +static uint32_t CSC0_GetStopAckStatus(const CSC_PeriphGrpType ePeriphGrp) +{ + uint32_t eRetVal; + + if(CSC_STOP_CTRL_GROUP_0 == ePeriphGrp) + { + eRetVal = CSC0_HWA_ACKR0_GetMultiStopAckStatus(CSC_STOP_PERIPH_GROUP0_MASK); + } + else if(CSC_STOP_CTRL_GROUP_1 == ePeriphGrp) + { + eRetVal = CSC0_HWA_ACKR1_GetMultiStopAckStatus(CSC_STOP_PERIPH_GROUP1_MASK); + } + else + { + eRetVal = CSC0_HWA_ACKR2_GetMultiStopAckStatus(CSC_STOP_PERIPH_GROUP2_MASK); + } + return eRetVal; +} + + + + + + +/********* Global functions ************/ +/** + * @brief set clock out. with clock out pin configure, the clock would be monitored. + * This Function may combined with SCG_ClkOut setting + * need to call SCG_SetClkOut,if clock out source set to SCG_CLKOUT. * + * @param pCsc0ClkOut to Csc0ClkOut instance for clock out configuration + * @param bLockStatus to lock current register.Once locked, calling the API returns an error(CSC_E_LOCK). + * + * @return CSC_RetStatusType + * CSC_E_OK: The API is successfully called + * CSC_E_LOCK: The register has been locked and can not be written + * @note configuration sequence: + * 1. Disable CLKOUTEN + * 2. Set CLKOUTSEL + * 3. Enable CLKOUTEN + */ +CSC_RetStatusType CSC0_SetClockOut(const CSC0_ClkoutType *const pCsc0ClkOut, bool bLockStatus) +{ + DEV_ASSERT(pCsc0ClkOut != NULL); + CSC_RetStatusType eRetVal; + + /* Check CSC0_CLKOUT_CTRL register lock status */ + if (0U == CSC0_HWA_CLKOUT_CTRL_GetLockStatus()) + { + eRetVal = CSC_E_OK; + /* Disable CLKOUTEN */ + CSC0_HWA_DisableClockOut(); + /* Set CLKOUTDIV */ + CSC0_HWA_SetClkOutDiv(pCsc0ClkOut->eDivider); + /* Set CLKOUTSEL */ + CSC0_HWA_SetClkOutSel(pCsc0ClkOut->eClkOutSrc); + /* Enable CLKOUTEN */ + CSC0_HWA_EnableClockOut(); + + if (true == bLockStatus) + { + /* Lock CSC0_CLKOUT_CTRL register */ + CSC0_HWA_LockCLKOUT_CTRL(); + } + } + else + { + eRetVal = CSC_E_LOCK; + } + + return eRetVal; +} + +/** + * @brief set always on clock source configuration include AON32K, RTC, AONCLK clock. + * + * @param pAonclkSrcType pointer to AONCLKSR instance for AON clock source configuration + * @param bLockStatus to lock current register.Once locked, calling the API returns an error(CSC_E_LOCK). + * + * @return CSC_RetStatusType + * CSC_E_OK: The API is successfully called + * CSC_E_LOCK: The register has been locked and can not be written + */ +CSC_RetStatusType CSC0_SetAonClkSrc(const CSC0_AONCLKSRType *const pAonclkSrcType, bool bLockStatus) +{ + CSC_RetStatusType eRetVal; + + DEV_ASSERT(pAonclkSrcType != NULL); + DEV_ASSERT(pAonclkSrcType->eAon32KSel == CSC0_AON32K_SIRCDIV_32K_CLK || + pAonclkSrcType->eAon32KSel == CSC0_AON32K_SOSC32K_CLK || + pAonclkSrcType->eAon32KSel == CSC0_AON32K_SIRC32K_CLK); + DEV_ASSERT(pAonclkSrcType->eRtcSel == CSC0_RTC_FOSCDIVL_CLK || + pAonclkSrcType->eRtcSel == CSC0_RTC_SIRCDIV_32K_CLK || + pAonclkSrcType->eRtcSel == CSC0_RTC_SOSC_CLK || + pAonclkSrcType->eRtcSel == CSC0_RTC_SIRC32K_CLK); + DEV_ASSERT(pAonclkSrcType->eAonSel == CSC0_AON_SIRCDIV_128K_CLK || + pAonclkSrcType->eAonSel == CSC0_AON_SIRC32K_CLK || + pAonclkSrcType->eAonSel == CSC0_AON_SIRCDIV_32K_CLK || + pAonclkSrcType->eAonSel == CSC0_AON_SIRC32_1K_CLK); + + + /* Check CSC0_AONCLKSR register lock status */ + if (0U == CSC0_HWA_AONCLKSR_GetLockStaus()) + { + eRetVal = CSC_E_OK; + + /* Gating SIRC_32K clock*/ + if ((CSC0_AON32K_SIRCDIV_32K_CLK == pAonclkSrcType->eAon32KSel) || + (CSC0_AON_SIRCDIV_32K_CLK == pAonclkSrcType->eAonSel) || + (CSC0_RTC_SIRCDIV_32K_CLK == pAonclkSrcType->eRtcSel)) + { + CSC0_HWA_EnableSIRCDIV_32KClkOut(); + } + + /* Gating SIRC32_1K clock*/ + if (CSC0_AON_SIRC32_1K_CLK == pAonclkSrcType->eAonSel) + { + CSC0_HWA_EnableSIRC32_1KClkOut(); + } + + /* Set AONCLOCK configuration */ + CSC0_HWA_SetAON32kClkSrc(pAonclkSrcType->eAon32KSel); + CSC0_HWA_SetRTCClkSrc(pAonclkSrcType->eRtcSel); + CSC0_HWA_SetAONClkSrc(pAonclkSrcType->eAonSel); + + if (true == bLockStatus) + { + /* Lock CSC0_AONCLKSR register */ + CSC0_HWA_LockAONCLKSR(); + } + } + else + { + eRetVal = CSC_E_LOCK; + } + + return eRetVal; +} + +/** + * @brief Report the clock source status and frequency configured in MCU run time. + * The clock frequency and status would change by clock set function. + * + * @param eClkkName: the CSC0 clock source to query + * @param pFreq: frequency variable point to get the frequency value + * + * @return CSC_RetStatusType + * CSC_E_OK: The API is successfully called + * CSC_E_NOT_OK: eClkkName invalid + */ +CSC_RetStatusType CSC0_GetCSC0ClockFreq(CSC0_ClkSrcType eClkkName, uint32_t *const pFreq) +{ + CSC_RetStatusType eRetVal; + DEV_ASSERT(pFreq != NULL); + + if ((uint32_t)eClkkName >= (uint32_t)CSC0_END_OF_CLOCKS) + { + eRetVal = CSC_E_NOT_OK; + *pFreq = 0U; + } + else + { + eRetVal = CSC_E_OK; + + if (CSC0_AON_CLK == eClkkName) + { + *pFreq = CSC0_GetAONClkFreq(); + } + else if (CSC0_AON32K_CLK == eClkkName) + { + *pFreq = CSC0_GetAON32kClkFreq(); + } + else if (CSC0_RTC_CLK == eClkkName) + { + *pFreq = CSC0_GetRTCClkFreq(); + } + else + { + /* CSC0_CLKOUT_CLK */ + *pFreq = CSC0_GetClockOutFreq(); + } + } + + return eRetVal; +} + +/** + * @brief SCG MAM stall request. + * @details Need to assert the SCG_STALL to stall MAM when configuring the SCG clock source. + * + * @param bEnable: true asserts SCG MAM stall request + * false do not asserts SCG MAM stall request + * @param bLockStatus: Lock the register.Once locked, calling the API returns an error(CSC_E_LOCK). + * + * @return CSC_RetStatusType + * CSC_E_OK: The API is successfully called + * CSC_E_LOCK: The register has been locked + */ +CSC_RetStatusType CSC0_ScgMAMStallRequest(bool bEnable, bool bLockStatus) +{ + CSC_RetStatusType eRetVal= CSC_E_LOCK; + + if (0U == CSC0_HWA_SCG_MAM_STALL_GetLockStatus()) + { + if(bEnable != false) + { + CSC0_HWA_EnalbeSCGStall(); + } + else + { + CSC0_HWA_DisableSCGStall(); + } + + if(bLockStatus != false) + { + CSC0_HWA_LockSCG_MAM_STALL(); + } + + eRetVal = CSC_E_OK; + } + + return eRetVal; +} + +/** + * @brief Set request to SMU of group 0. + * + * @param u32Value Value to be set(the or bits defined in CSC_SMU_CtrlGrp0Type,do not involve lock bit) + * @param bLockStatus Lock the register.Once locked, calling the API returns an error(CSC_E_LOCK). + * + * @return CSC_RetStatusType + * CSC_E_OK: The API is successfully called + * CSC_E_NOT_OK: The u32Value contains invalid bits + * CSC_E_LOCK: The register has been locked + */ +CSC_RetStatusType CSC0_SetReqToSMUGrp0(uint32_t u32Value, bool bLockStatus) +{ + CSC_RetStatusType eRetVal = CSC_E_PARAM; + + /* Check register bits invalid */ + if((u32Value & (~CSC_SMU_CTRL_GROUP0_MASK)) == 0U) + { + + /* Check register lock status */ + if (0U == CSC0_HWA_SMU_CTRL0_GetLockStatus()) + { + eRetVal = CSC_E_OK; + /* Set value(do not involve lock bit) */ + CSC0_HWA_CTRL0_SetMultiReqToSMU(u32Value); + if (true == bLockStatus) + { + /* Lock register */ + CSC0_HWA_LockSMU_CTRL0(); + } + } + else + { + eRetVal = CSC_E_LOCK; + } + } + + return eRetVal; +} + +/** + * @brief Set request to SMU of group 1. + * + * @param u32Value Value to be set(the or bits defined in CSC_SMU_CtrlGrp1Type,do not involve lock bit) + * @param bLockStatus Lock the register.Once locked, calling the API returns an error(CSC_E_LOCK). + * + * @return CSC_RetStatusType + * CSC_E_OK: The API is successfully called + * CSC_E_NOT_OK: The u32Value contains invalid bits + * CSC_E_LOCK: The register has been locked + */ +CSC_RetStatusType CSC0_SetReqToSMUGrp1(uint32_t u32Value, bool bLockStatus) +{ + CSC_RetStatusType eRetVal = CSC_E_PARAM; + + /* Check register bits invalid */ + if((u32Value & (~CSC_SMU_CTRL_GROUP1_MASK)) == 0U) + { + + /* Check register lock status */ + if (0U == CSC0_HWA_SMU_CTRL1_GetLockStatus()) + { + eRetVal = CSC_E_OK; + /* Set value(do not involve lock bit) */ + CSC0_HWA_CTRL1_SetMultiReqToSMU(u32Value); + if (true == bLockStatus) + { + /* Lock register */ + CSC0_HWA_LockSMU_CTRL1(); + } + } + else + { + eRetVal = CSC_E_LOCK; + } + } + + return eRetVal; +} + +/** + * @brief Set request to SMU of group 4. + * + * @param u32Value Value to be set(the or bits defined in CSC_SMU_CtrlGrp4Type,do not involve lock bit) + * @param bLockStatus Lock the register.Once locked, calling the API returns an error(CSC_E_LOCK). + * + * @return CSC_RetStatusType + * CSC_E_OK: The API is successfully called + * CSC_E_NOT_OK: The u32Value contains invalid bits + * CSC_E_LOCK: The register has been locked + */ +CSC_RetStatusType CSC0_SetReqToSMUGrp4(uint32_t u32Value, bool bLockStatus) +{ + CSC_RetStatusType eRetVal = CSC_E_PARAM; + + /* Check register bits invalid */ + if((u32Value & (~CSC_SMU_CTRL_GROUP4_MASK)) == 0U) + { + + /* Check register lock status */ + if (0U == CSC0_HWA_SMU_CTRL4_GetLockStatus()) + { + eRetVal = CSC_E_OK; + /* Set value(do not involve lock bit) */ + CSC0_HWA_CTRL4_SetMultiReqToSMU(u32Value); + if (true == bLockStatus) + { + /* Lock register */ + CSC0_HWA_LockSMU_CTRL4(); + } + } + else + { + eRetVal = CSC_E_LOCK; + } + } + + return eRetVal; +} + +/** + * @brief Set request to SMU of group 5. + * + * @param u32Value Value to be set(the or bits defined in CSC_SMU_CtrlGrp5Type,do not involve lock bit) + * @param bLockStatus Lock the register.Once locked, calling the API returns an error(CSC_E_LOCK). + * + * @return CSC_RetStatusType + * CSC_E_OK: The API is successfully called + * CSC_E_NOT_OK: The u32Value contains invalid bits + * CSC_E_LOCK: The register has been locked + */ +CSC_RetStatusType CSC0_SetReqToSMUGrp5(uint32_t u32Value, bool bLockStatus) +{ + CSC_RetStatusType eRetVal = CSC_E_PARAM; + + /* Check register bits invalid */ + if((u32Value & (~CSC_SMU_CTRL_GROUP5_MASK)) == 0U) + { + + /* Check register lock status */ + if (0U == CSC0_HWA_SMU_CTRL5_GetLockStatus()) + { + eRetVal = CSC_E_OK; + /* Set value(do not involve lock bit) */ + CSC0_HWA_CTRL5_SetMultiReqToSMU(u32Value); + if (true == bLockStatus) + { + /* Lock register */ + CSC0_HWA_LockSMU_CTRL5(); + } + } + else + { + eRetVal = CSC_E_LOCK; + } + } + + return eRetVal; +} + +/** + * @brief Set request to SMU . + * + * @param eCtrlGrp CSC0_SMU control group + * @param u32Value Value to be set(the or bits defined in CSC_SMU_CtrlGrp5Type,do not involve lock bit) + * @param bLockStatus Lock the register.Once locked, calling the API returns an error(CSC_E_LOCK). + * + * @return CSC_RetStatusType + * CSC_E_OK: The API is successfully called + * CSC_E_PARAM: The eCtrlGrp is invalid + * CSC_E_NOT_OK: The u32Value contains invalid bits + * CSC_E_LOCK: The register has been locked + * @note Group must be matched with u32Value which select from CSC0_SmuCtrlGrpType + */ +CSC_RetStatusType CSC0_SetReqToSMU(CSC0_SmuCtrlGrpType eCtrlGrp, uint32_t u32Value, bool bLockStatus) +{ + CSC_RetStatusType eRetVal; + + if (CSC0_SMU_CTRL_GROUP_0 == eCtrlGrp) + { + eRetVal = CSC0_SetReqToSMUGrp0(u32Value, bLockStatus); + } + else if (CSC0_SMU_CTRL_GROUP_1 == eCtrlGrp) + { + eRetVal = CSC0_SetReqToSMUGrp1(u32Value, bLockStatus); + } + else if (CSC0_SMU_CTRL_GROUP_4 == eCtrlGrp) + { + eRetVal = CSC0_SetReqToSMUGrp4(u32Value, bLockStatus); + } + else if (CSC0_SMU_CTRL_GROUP_5 == eCtrlGrp) + { + eRetVal = CSC0_SetReqToSMUGrp5(u32Value, bLockStatus); + } + else + { + eRetVal = CSC_E_NOT_OK; + } + + return eRetVal; +} + +/** + * @brief Configure the low power wakeup PAD output in CSC0_LP_WAKEUP register. + * + * @param eLPWakeupCfg: the low power wakeup PAD source and polarity configuration + * @param bLockStatus: Lock the register.Once locked, calling the API returns an error(CSC_E_LOCK). + * + * @return CSC_RetStatusType + * CSC_E_OK: The API is successfully called + * CSC_E_LOCK: The WPB of CSCx_STOP_MODERx is already locked + */ +CSC_RetStatusType CSC0_LP_WakeupPadOutputCfg(const CSC0_LPWakeupCfgType * const eLPWakeupCfg, bool bLockStatus) +{ + CSC_RetStatusType eRetVal; + + DEV_ASSERT(eLPWakeupCfg != NULL_PTR); + DEV_ASSERT((uint32_t)eLPWakeupCfg->eCfgGrp0 <= (uint32_t)CSC_LP_WAKEUP_FCPIT0_TRIGGER_OUT3); + DEV_ASSERT((uint32_t)eLPWakeupCfg->eCfgGrp1 <= (uint32_t)CSC_LP_WAKEUP_FCPIT0_TRIGGER_OUT3); + DEV_ASSERT((uint32_t)eLPWakeupCfg->eCfgGrp2 <= (uint32_t)CSC_LP_WAKEUP_FCPIT0_TRIGGER_OUT3); + DEV_ASSERT((uint32_t)eLPWakeupCfg->eCfgGrp3 <= (uint32_t)CSC_LP_WAKEUP_FCPIT0_TRIGGER_OUT3); + DEV_ASSERT((uint32_t)eLPWakeupCfg->eCfgGrp4 <= (uint32_t)CSC_LP_WAKEUP_FCPIT0_TRIGGER_OUT3); + DEV_ASSERT((uint32_t)eLPWakeupCfg->ePolGrp0 <= (uint32_t)CSC_LP_WAKEUP_POL_INVERT); + DEV_ASSERT((uint32_t)eLPWakeupCfg->ePolGrp1 <= (uint32_t)CSC_LP_WAKEUP_POL_INVERT); + DEV_ASSERT((uint32_t)eLPWakeupCfg->ePolGrp2 <= (uint32_t)CSC_LP_WAKEUP_POL_INVERT); + DEV_ASSERT((uint32_t)eLPWakeupCfg->ePolGrp3 <= (uint32_t)CSC_LP_WAKEUP_POL_INVERT); + DEV_ASSERT((uint32_t)eLPWakeupCfg->ePolGrp4 <= (uint32_t)CSC_LP_WAKEUP_POL_INVERT); + + if (0U == CSC0_HWA_LP_WAKEUP_GetLockStatus()) + { + CSC0_HWA_SetLP_WAKEUPCfgSrc(CSC_LP_WAKEUP_GROUP_0,eLPWakeupCfg->eCfgGrp0); + CSC0_HWA_SetLP_WAKEUPCfgSrc(CSC_LP_WAKEUP_GROUP_1,eLPWakeupCfg->eCfgGrp1); + CSC0_HWA_SetLP_WAKEUPCfgSrc(CSC_LP_WAKEUP_GROUP_2,eLPWakeupCfg->eCfgGrp2); + CSC0_HWA_SetLP_WAKEUPCfgSrc(CSC_LP_WAKEUP_GROUP_3,eLPWakeupCfg->eCfgGrp3); + CSC0_HWA_SetLP_WAKEUPCfgSrc(CSC_LP_WAKEUP_GROUP_4,eLPWakeupCfg->eCfgGrp4); + CSC0_HWA_SetLP_WAKEUPCfgPol(CSC_LP_WAKEUP_GROUP_0,eLPWakeupCfg->ePolGrp0); + CSC0_HWA_SetLP_WAKEUPCfgPol(CSC_LP_WAKEUP_GROUP_1,eLPWakeupCfg->ePolGrp1); + CSC0_HWA_SetLP_WAKEUPCfgPol(CSC_LP_WAKEUP_GROUP_2,eLPWakeupCfg->ePolGrp2); + CSC0_HWA_SetLP_WAKEUPCfgPol(CSC_LP_WAKEUP_GROUP_3,eLPWakeupCfg->ePolGrp3); + CSC0_HWA_SetLP_WAKEUPCfgPol(CSC_LP_WAKEUP_GROUP_4,eLPWakeupCfg->ePolGrp4); + + if(bLockStatus != false) + { + CSC0_HWA_LockLP_WAKEUP(); + } + + eRetVal = CSC_E_OK; + } + else + { + eRetVal = CSC_E_LOCK; + } + return eRetVal; +} + + +/** + * @brief Set CPU stop mode control permission. + * @detail This API is used to set the CPU write permission of a CPU's stop mode registers. + * eg.If the CPU(eTargetCpuType) enter stop mode, it acknowledges the peripherals according to the configuration + * in CSCx_STOP_MODERy (x: (CPUID) range[0] , y:(GROUP) range[0,1,2]), and the CPU(eCtrlCpuType) + * has the write permission of CSCx_STOP_MODERy registers, the permission is controlled by this API. + * + * @param eTargetCpuType The target CPU to set. + * @param eCtrlCpuType The CPU that has the write permission to the CSCx_STOP_MODERy register. + * @param ePeriphGrp Peripheral group (range:0,1,2) + * @param bLockStatus Lock the WPB of CSCx_STOP_MODERy.Once locked, calling the API returns an error(CSC_E_LOCK). + * + * @return CSC_RetStatusType + * CSC_E_OK: The API is successfully called + * CSC_E_NOT_OK: eTargetCpuType invalid + * CSC_E_LOCK: The WPB of CSCx_STOP_MODERx is already locked + */ +CSC_RetStatusType CSC_SetStopModeAckPermission(CSC_WPB_CpuType eTargetCpuType, CSC_WPB_CpuType eCtrlCpuType, + CSC_PeriphGrpType ePeriphGrp, bool bLockStatus) +{ + CSC_RetStatusType eRetVal = CSC_E_NOT_OK; + DEV_ASSERT((uint32_t)eCtrlCpuType < (uint32_t)CSC_WP_CPU_NONE); + DEV_ASSERT((uint32_t)ePeriphGrp <= (uint32_t)CSC_STOP_CTRL_GROUP_2); + + if (CSC_WP_CPU_0 == eTargetCpuType) + { + if (CSC_STOP_CTRL_GROUP_0 == ePeriphGrp) + { + eRetVal = CSC0_SetCpuCtrlGrp0(eCtrlCpuType, CSC_STOPACK, bLockStatus); + } + else if (CSC_STOP_CTRL_GROUP_1 == ePeriphGrp) + { + eRetVal = CSC0_SetCpuCtrlGrp1(eCtrlCpuType, CSC_STOPACK, bLockStatus); + } + else + { + eRetVal = CSC0_SetCpuCtrlGrp2(eCtrlCpuType, CSC_STOPACK, bLockStatus); + } + } + + return eRetVal; +} + +/** + * @brief Set CPU stop mode request control permission. + * @detail This API is used to set the CPU write permission of a CPU's stop mode request registers + * to generate a stop request to peripherals + * + * @param eTargetCpuType The target CPU to acknowledges stop mode to the enabled peripherals. + * @param eCtrlCpuType The CPU that has the write permission to the CSCx_STOP_REQRx register. + * @param ePeriphGrp Peripheral group (range:0,1,2) + * @param bLockStatus Lock the WPB of CSCx_STOP_REQRx.Once locked, calling the API returns an error(CSC_E_LOCK). + * + * @return CSC_RetStatusType + * CSC_E_OK: The API is successfully called + * CSC_E_NOT_OK: eTargetCpuType invalid + * CSC_E_LOCK: The WPB of CSCx_STOP_REQRx is already locked + */ +CSC_RetStatusType CSC_SetStopRequestPermission(CSC_WPB_CpuType eTargetCpuType, CSC_WPB_CpuType eCtrlCpuType, + CSC_PeriphGrpType ePeriphGrp, bool bLockStatus) +{ + CSC_RetStatusType eRetVal = CSC_E_NOT_OK; + DEV_ASSERT((uint32_t)eCtrlCpuType < (uint32_t)CSC_WP_CPU_NONE); + DEV_ASSERT((uint32_t)ePeriphGrp <= (uint32_t)CSC_STOP_CTRL_GROUP_2); + + if (CSC_WP_CPU_0 == eTargetCpuType) + { + if (CSC_STOP_CTRL_GROUP_0 == ePeriphGrp) + { + eRetVal = CSC0_SetCpuCtrlGrp0(eCtrlCpuType, CSC_STOPREQ, bLockStatus); + } + else if (CSC_STOP_CTRL_GROUP_1 == ePeriphGrp) + { + eRetVal = CSC0_SetCpuCtrlGrp1(eCtrlCpuType, CSC_STOPREQ, bLockStatus); + } + else + { + eRetVal = CSC0_SetCpuCtrlGrp2(eCtrlCpuType, CSC_STOPREQ, bLockStatus); + } + } + + return eRetVal; +} + +/** + * @brief Set the stop mode ACK of peripheral group 0 in CSC. + * + * @param eTargetCpuType The target CPU which acknowledges the ePeriphType when entering stop mode. + * @param ePeriphType the peripheral to enable or disable the stop mode ACK + * @param bEnable true: enable the stop mode ACK + * false: disable the stop mode ACK + * + * @return CSC_RetStatusType + * CSC_E_OK: The API is successfully called + * CSC_E_NOT_OK: eTargetCpuType invalid + * CSC_E_NO_PERM: Current CPU has no permission to access the register + */ +CSC_RetStatusType CSC_SetStopModeAckGrp0(CSC_WPB_CpuType eTargetCpuType, CSCx_Reg0_PeriphType ePeriphType, bool bEnable) +{ + CSC_RetStatusType eRetVal = CSC_E_NOT_OK; + CSC_WPB_CpuType eCtrlCpu; + + DEV_ASSERT((ePeriphType == CSC_STOPMODE_FLEXCAN1) || + (ePeriphType == CSC_STOPMODE_FLEXCAN0) || + (ePeriphType == CSC_STOPMODE_FREQM) || + (ePeriphType == CSC_STOPMODE_FCUART3) || + (ePeriphType == CSC_STOPMODE_FCUART2) || + (ePeriphType == CSC_STOPMODE_FCUART1) || + (ePeriphType == CSC_STOPMODE_FCSPI2) || + (ePeriphType == CSC_STOPMODE_FCSPI1) || + (ePeriphType == CSC_STOPMODE_SENT0) || + (ePeriphType == CSC_STOPMODE_TMU) || + (ePeriphType == CSC_STOPMODE_ADC1) || + (ePeriphType == CSC_STOPMODE_ADC0) || + (ePeriphType == CSC_STOPMODE_CMU4) || + (ePeriphType == CSC_STOPMODE_WDOG0) || + (ePeriphType == CSC_STOPMODE_ISM0) || + (ePeriphType == CSC_STOPMODE_DMA0)); + + if (CSC_WP_CPU_0 == eTargetCpuType) + { + eCtrlCpu = CSC0_HWA_MODER0_GetCpuWritePermit(); + + if((eCtrlCpu == CSC_GET_CPU_ID()) || (eCtrlCpu == CSC_WP_CPU_ALL)) + { + /* Set peripheral stop ack enable */ + if(bEnable != false) + { + CSC0_HWA_MODER0_EnableStopAck(ePeriphType); + } + else + { + CSC0_HWA_MODER0_DisableStopAck(ePeriphType); + } + eRetVal = CSC_E_OK; + } + else + { + eRetVal = CSC_E_NO_PERM; + } + } + + return eRetVal; +} + +/** + * @brief Set the stop request of peripheral group 0 in CSC. + * + * @param eTargetCpuType The target CPU which acknowledges the ePeriphType when entering stop mode. + * @param ePeriphType the peripheral to set stop request + * @param bEnable true: set the stop request + * false: clear the stop request + * + * @return CSC_RetStatusType + * CSC_E_OK: The API is successfully called + * CSC_E_NOT_OK: eTargetCpuType invalid + * CSC_E_NO_PERM: Current CPU has no permission to access the register + */ +CSC_RetStatusType CSC_SetStopRequestGrp0(CSC_WPB_CpuType eTargetCpuType, CSCx_Reg0_PeriphType ePeriphType, bool bEnable) +{ + CSC_RetStatusType eRetVal = CSC_E_NOT_OK; + CSC_WPB_CpuType eCtrlCpu; + + DEV_ASSERT((ePeriphType == CSC_STOPMODE_FLEXCAN1) || + (ePeriphType == CSC_STOPMODE_FLEXCAN0) || + (ePeriphType == CSC_STOPMODE_FREQM) || + (ePeriphType == CSC_STOPMODE_FCUART3) || + (ePeriphType == CSC_STOPMODE_FCUART2) || + (ePeriphType == CSC_STOPMODE_FCUART1) || + (ePeriphType == CSC_STOPMODE_FCSPI2) || + (ePeriphType == CSC_STOPMODE_FCSPI1) || + (ePeriphType == CSC_STOPMODE_SENT0) || + (ePeriphType == CSC_STOPMODE_TMU) || + (ePeriphType == CSC_STOPMODE_ADC1) || + (ePeriphType == CSC_STOPMODE_ADC0) || + (ePeriphType == CSC_STOPMODE_CMU4) || + (ePeriphType == CSC_STOPMODE_WDOG0) || + (ePeriphType == CSC_STOPMODE_ISM0) || + (ePeriphType == CSC_STOPMODE_DMA0)); + + if (CSC_WP_CPU_0 == eTargetCpuType) + { + eCtrlCpu = CSC0_HWA_REQR0_GetCpuWritePermit(); + + if((eCtrlCpu == CSC_GET_CPU_ID()) || (eCtrlCpu == CSC_WP_CPU_ALL)) + { + /* Set peripheral stop ack enable */ + if(bEnable != false) + { + CSC0_HWA_REQR0_SetStopRequest(ePeriphType); + } + else + { + CSC0_HWA_REQR0_ClearStopRequest(ePeriphType); + } + eRetVal = CSC_E_OK; + } + else + { + eRetVal = CSC_E_NO_PERM; + } + } + + return eRetVal; +} + +/** + * @brief Set the stop mode ACK of peripheral group 1 in CSC. + * + * @param eTargetCpuType The target CPU which acknowledges the ePeriphType when entering stop mode. + * @param ePeriphType the peripheral to enable or disable the stop mode ACK + * @param bEnable true: enable the stop mode ACK + * false: disable the stop mode ACK + * + * @return CSC_RetStatusType + * CSC_E_OK: The API is successfully called + * CSC_E_NOT_OK: eTargetCpuType invalid + * CSC_E_NO_PERM: Current CPU has no permission to access the register + */ +CSC_RetStatusType CSC_SetStopModeAckGrp1(CSC_WPB_CpuType eTargetCpuType, CSCx_Reg1_PeriphType ePeriphType, bool bEnable) +{ + CSC_RetStatusType eRetVal = CSC_E_NOT_OK; + CSC_WPB_CpuType eCtrlCpu; + + DEV_ASSERT((ePeriphType == CSC_STOPMODE_FLEXCAN3) || + (ePeriphType == CSC_STOPMODE_FLEXCAN2) || + (ePeriphType == CSC_STOPMODE_MSC0) || + (ePeriphType == CSC_STOPMODE_FCUART7) || + (ePeriphType == CSC_STOPMODE_FCUART6) || + (ePeriphType == CSC_STOPMODE_FCUART5) || + (ePeriphType == CSC_STOPMODE_FCUART4) || + (ePeriphType == CSC_STOPMODE_FCIIC1) || + (ePeriphType == CSC_STOPMODE_FCSPI5) || + (ePeriphType == CSC_STOPMODE_FCSPI4) || + (ePeriphType == CSC_STOPMODE_FCSPI3) || + (ePeriphType == CSC_STOPMODE_WDOG1)); + + if (CSC_WP_CPU_0 == eTargetCpuType) + { + eCtrlCpu = CSC0_HWA_MODER1_GetCpuWritePermit(); + + if((eCtrlCpu == CSC_GET_CPU_ID()) || (eCtrlCpu == CSC_WP_CPU_ALL)) + { + /* Set peripheral stop ack enable */ + if(bEnable != false) + { + CSC0_HWA_MODER1_EnableStopAck(ePeriphType); + } + else + { + CSC0_HWA_MODER1_DisableStopAck(ePeriphType); + } + eRetVal = CSC_E_OK; + } + else + { + eRetVal = CSC_E_NO_PERM; + } + } + + return eRetVal; +} + +/** + * @brief Set the stop request of peripheral group 1 in CSC. + * + * @param eTargetCpuType The target CPU which acknowledges the ePeriphType when entering stop mode. + * @param ePeriphType the peripheral to set stop request + * @param bEnable true: set the stop request + * false: clear the stop request + * + * @return CSC_RetStatusType + * CSC_E_OK: The API is successfully called + * CSC_E_NOT_OK: eTargetCpuType invalid + * CSC_E_NO_PERM: Current CPU has no permission to access the register + */ +CSC_RetStatusType CSC_SetStopRequestGrp1(CSC_WPB_CpuType eTargetCpuType, CSCx_Reg1_PeriphType ePeriphType, bool bEnable) +{ + CSC_RetStatusType eRetVal = CSC_E_NOT_OK; + CSC_WPB_CpuType eCtrlCpu; + + DEV_ASSERT((ePeriphType == CSC_STOPMODE_FLEXCAN3) || + (ePeriphType == CSC_STOPMODE_FLEXCAN2) || + (ePeriphType == CSC_STOPMODE_MSC0) || + (ePeriphType == CSC_STOPMODE_FCUART7) || + (ePeriphType == CSC_STOPMODE_FCUART6) || + (ePeriphType == CSC_STOPMODE_FCUART5) || + (ePeriphType == CSC_STOPMODE_FCUART4) || + (ePeriphType == CSC_STOPMODE_FCIIC1) || + (ePeriphType == CSC_STOPMODE_FCSPI5) || + (ePeriphType == CSC_STOPMODE_FCSPI4) || + (ePeriphType == CSC_STOPMODE_FCSPI3) || + (ePeriphType == CSC_STOPMODE_WDOG1)); + + if (CSC_WP_CPU_0 == eTargetCpuType) + { + eCtrlCpu = CSC0_HWA_REQR1_GetCpuWritePermit(); + + if((eCtrlCpu == CSC_GET_CPU_ID()) || (eCtrlCpu == CSC_WP_CPU_ALL)) + { + /* Set peripheral stop ack enable */ + if(bEnable != false) + { + CSC0_HWA_REQR1_SetStopRequest(ePeriphType); + } + else + { + CSC0_HWA_REQR1_ClearStopRequest(ePeriphType); + } + eRetVal = CSC_E_OK; + } + else + { + eRetVal = CSC_E_NO_PERM; + } + } + + return eRetVal; +} + +/** + * @brief Set the stop mode ACK of peripheral group 2 in CSC. + * + * @param eTargetCpuType The target CPU which acknowledges the ePeriphType when entering stop mode. + * @param ePeriphType the peripheral to enable or disable the stop mode ACK + * @param bEnable true: enable the stop mode ACK + * false: disable the stop mode ACK + * + * @return CSC_RetStatusType + * CSC_E_OK: The API is successfully called + * CSC_E_NOT_OK: eTargetCpuType invalid + * CSC_E_NO_PERM: Current CPU has no permission to access the register + */ +CSC_RetStatusType CSC_SetStopModeAckGrp2(CSC_WPB_CpuType eTargetCpuType, CSCx_Reg2_PeriphType ePeriphType, bool bEnable) +{ + CSC_RetStatusType eRetVal = CSC_E_NOT_OK; + CSC_WPB_CpuType eCtrlCpu; + + DEV_ASSERT((ePeriphType == CSC_STOPMODE_FCUART0) || + (ePeriphType == CSC_STOPMODE_FCIIC0) || + (ePeriphType == CSC_STOPMODE_FCSPI0) || + (ePeriphType == CSC_STOPMODE_CMP1) || + (ePeriphType == CSC_STOPMODE_CMP0) || + (ePeriphType == CSC_STOPMODE_CMU3) || + (ePeriphType == CSC_STOPMODE_CMU2) || + (ePeriphType == CSC_STOPMODE_CMU1) || + (ePeriphType == CSC_STOPMODE_CMU0)); + + if (CSC_WP_CPU_0 == eTargetCpuType) + { + eCtrlCpu = CSC0_HWA_MODER2_GetCpuWritePermit(); + + if((eCtrlCpu == CSC_GET_CPU_ID()) || (eCtrlCpu == CSC_WP_CPU_ALL)) + { + /* Set peripheral stop ack enable */ + if(bEnable != false) + { + CSC0_HWA_MODER2_EnableStopAck(ePeriphType); + } + else + { + CSC0_HWA_MODER2_DisableStopAck(ePeriphType); + } + eRetVal = CSC_E_OK; + } + else + { + eRetVal = CSC_E_NO_PERM; + } + } + + return eRetVal; +} + +/** + * @brief Set the stop request of peripheral group 2 in CSC. + * + * @param eTargetCpuType The target CPU which acknowledges the ePeriphType when entering stop mode. + * @param ePeriphType the peripheral to set stop request + * @param bEnable true: set the stop request + * false: clear the stop request + * + * @return CSC_RetStatusType + * CSC_E_OK: The API is successfully called + * CSC_E_NOT_OK: eTargetCpuType invalid + * CSC_E_NO_PERM: Current CPU has no permission to access the register + */ +CSC_RetStatusType CSC_SetStopRequestGrp2(CSC_WPB_CpuType eTargetCpuType, CSCx_Reg2_PeriphType ePeriphType, bool bEnable) +{ + CSC_RetStatusType eRetVal = CSC_E_NOT_OK; + CSC_WPB_CpuType eCtrlCpu; + + DEV_ASSERT((ePeriphType == CSC_STOPMODE_FCUART0) || + (ePeriphType == CSC_STOPMODE_FCIIC0) || + (ePeriphType == CSC_STOPMODE_FCSPI0) || + (ePeriphType == CSC_STOPMODE_CMP1) || + (ePeriphType == CSC_STOPMODE_CMP0) || + (ePeriphType == CSC_STOPMODE_CMU3) || + (ePeriphType == CSC_STOPMODE_CMU2) || + (ePeriphType == CSC_STOPMODE_CMU1) || + (ePeriphType == CSC_STOPMODE_CMU0)); + + if (CSC_WP_CPU_0 == eTargetCpuType) + { + eCtrlCpu = CSC0_HWA_REQR2_GetCpuWritePermit(); + + if((eCtrlCpu == CSC_GET_CPU_ID()) || (eCtrlCpu == CSC_WP_CPU_ALL)) + { + /* Set peripheral stop ack enable */ + if(bEnable != false) + { + CSC0_HWA_REQR2_SetStopRequest(ePeriphType); + } + else + { + CSC0_HWA_REQR2_ClearStopRequest(ePeriphType); + } + eRetVal = CSC_E_OK; + } + else + { + eRetVal = CSC_E_NO_PERM; + } + } + + return eRetVal; +} + +/** + * @brief Set the stop mode ACK of all group peripherals in CSC. + * + * @param eTargetCpuType The target CPU which acknowledges the peripherals when entering stop mode. + * @param ePeriphGrp the group of peripherals to set the stop mode ACK value + * @param u32Value the CSCx_STOP_MODERx register value + * + * @return CSC_RetStatusType + * CSC_E_OK: The API is successfully called + * CSC_E_NOT_OK: eTargetCpuType invalid + * CSC_E_PARAM: ePeriphGrp or u32Value invalid + * CSC_E_NO_PERM: Current CPU has no permission to access the register + */ +CSC_RetStatusType CSC_SetStopModeAck(CSC_WPB_CpuType eTargetCpuType, CSC_PeriphGrpType ePeriphGrp, uint32_t u32Value) +{ + CSC_RetStatusType eRetVal = CSC_E_NOT_OK; + uint32_t eGrpMask[CSC_STOP_PERIPH_GROUP_MAX] = {CSC_STOP_PERIPH_GROUP0_MASK, + CSC_STOP_PERIPH_GROUP1_MASK, + CSC_STOP_PERIPH_GROUP2_MASK + }; + + if((uint32_t)ePeriphGrp >= (uint32_t)CSC_STOP_PERIPH_GROUP_MAX) + { + eRetVal = CSC_E_PARAM; + } + else if(((~eGrpMask[(uint32_t)ePeriphGrp]) & u32Value) != 0U) + { + eRetVal = CSC_E_PARAM; + } + else + { + if (CSC_WP_CPU_0 == eTargetCpuType) + { + eRetVal = CSC0_SetStopModeAck(ePeriphGrp,u32Value); + } + } + + return eRetVal; +} + +/** + * @brief Set the stop request of all group peripherals in CSC. + * + * @param eTargetCpuType The target CPU which acknowledges the peripherals when entering stop mode. + * @param ePeriphGrp the group of peripherals to set the stop request value + * @param u32Value the CSCx_STOP_REQRx register value + * + * @return CSC_RetStatusType + * CSC_E_OK: The API is successfully called + * CSC_E_NOT_OK: eTargetCpuType invalid + * CSC_E_PARAM: ePeriphGrp or u32Value invalid + * CSC_E_NO_PERM: Current CPU has no permission + */ +CSC_RetStatusType CSC_SetStopRequest(CSC_WPB_CpuType eTargetCpuType, CSC_PeriphGrpType ePeriphGrp, uint32_t u32Value) +{ + CSC_RetStatusType eRetVal = CSC_E_NOT_OK; + uint32_t eGrpMask[CSC_STOP_PERIPH_GROUP_MAX] = {CSC_STOP_PERIPH_GROUP0_MASK, + CSC_STOP_PERIPH_GROUP1_MASK, + CSC_STOP_PERIPH_GROUP2_MASK + }; + + if((uint32_t)ePeriphGrp >= (uint32_t)CSC_STOP_PERIPH_GROUP_MAX) + { + eRetVal = CSC_E_PARAM; + } + else if(((~eGrpMask[(uint32_t)ePeriphGrp]) & u32Value) != 0U) + { + eRetVal = CSC_E_PARAM; + } + else + { + if (CSC_WP_CPU_0 == eTargetCpuType) + { + eRetVal = CSC0_SetStopRequest(ePeriphGrp,u32Value); + } + } + + return eRetVal; +} + +/** + * @brief Get the stop Acknowledge status of peripherals group0 in CSC. + * + * @param eTargetCpuType The target CPU which acknowledges the peripherals when entering stop mode. + * @param ePeriphType the peripheral to get stop acknowledge status + * @param bool true: Stop acknowledge is asserted (the module is in Stop mode) + * false: Stop acknowledge is not asserted + * @return Operation success/failed + */ +CSC_RetStatusType CSC_GetStopAckStatusGrp0(CSC_WPB_CpuType eTargetCpuType,CSCx_Reg0_PeriphType ePeriphType, bool * const pStatus) +{ + CSC_RetStatusType eRetVal = CSC_E_NOT_OK; + DEV_ASSERT((ePeriphType == CSC_STOPMODE_FLEXCAN1) || + (ePeriphType == CSC_STOPMODE_FLEXCAN0) || + (ePeriphType == CSC_STOPMODE_FREQM) || + (ePeriphType == CSC_STOPMODE_FCUART3) || + (ePeriphType == CSC_STOPMODE_FCUART2) || + (ePeriphType == CSC_STOPMODE_FCUART1) || + (ePeriphType == CSC_STOPMODE_FCSPI2) || + (ePeriphType == CSC_STOPMODE_FCSPI1) || + (ePeriphType == CSC_STOPMODE_SENT0) || + (ePeriphType == CSC_STOPMODE_TMU) || + (ePeriphType == CSC_STOPMODE_ADC1) || + (ePeriphType == CSC_STOPMODE_ADC0) || + (ePeriphType == CSC_STOPMODE_CMU4) || + (ePeriphType == CSC_STOPMODE_WDOG0) || + (ePeriphType == CSC_STOPMODE_ISM0) || + (ePeriphType == CSC_STOPMODE_DMA0)); + + if (CSC_WP_CPU_0 == eTargetCpuType) + { + *pStatus = (bool)(0U != CSC0_HWA_ACKR0_GetStopAckStatus(ePeriphType)); + eRetVal = CSC_E_OK; + } + return eRetVal; +} + +/** + * @brief Get the stop Acknowledge status of peripherals group1 in CSC. + * + * @param eTargetCpuType The target CPU which acknowledges the peripherals when entering stop mode. + * @param ePeriphType the peripheral to get stop acknowledge status + * @param bool true: Stop acknowledge is asserted (the module is in Stop mode) + * false: Stop acknowledge is not asserted + * @return Operation success/failed + */ +CSC_RetStatusType CSC_GetStopAckStatusGrp1(CSC_WPB_CpuType eTargetCpuType, CSCx_Reg1_PeriphType ePeriphType, bool * const pStatus) +{ + CSC_RetStatusType eRetVal = CSC_E_NOT_OK; + DEV_ASSERT((ePeriphType == CSC_STOPMODE_FLEXCAN3) || + (ePeriphType == CSC_STOPMODE_FLEXCAN2) || + (ePeriphType == CSC_STOPMODE_MSC0) || + (ePeriphType == CSC_STOPMODE_FCUART7) || + (ePeriphType == CSC_STOPMODE_FCUART6) || + (ePeriphType == CSC_STOPMODE_FCUART5) || + (ePeriphType == CSC_STOPMODE_FCUART4) || + (ePeriphType == CSC_STOPMODE_FCIIC1) || + (ePeriphType == CSC_STOPMODE_FCSPI5) || + (ePeriphType == CSC_STOPMODE_FCSPI4) || + (ePeriphType == CSC_STOPMODE_FCSPI3) || + (ePeriphType == CSC_STOPMODE_WDOG1)); + + if (CSC_WP_CPU_0 == eTargetCpuType) + { + *pStatus = (bool)(0U != CSC0_HWA_ACKR1_GetStopAckStatus(ePeriphType)); + eRetVal = CSC_E_OK; + } + return eRetVal; +} + +/** + * @brief Get the stop Acknowledge status of peripherals group2 in CSC. + * + * @param eTargetCpuType The target CPU which acknowledges the peripherals when entering stop mode. + * @param ePeriphType the peripheral to get stop acknowledge status + * @param bool true: Stop acknowledge is asserted (the module is in Stop mode) + * false: Stop acknowledge is not asserted + * @return Operation success/failed + */ +CSC_RetStatusType CSC_GetStopAckStatusGrp2(CSC_WPB_CpuType eTargetCpuType,CSCx_Reg2_PeriphType ePeriphType, bool * const pStatus) +{ + CSC_RetStatusType eRetVal = CSC_E_NOT_OK; + DEV_ASSERT((ePeriphType == CSC_STOPMODE_FCUART0) || + (ePeriphType == CSC_STOPMODE_FCIIC0) || + (ePeriphType == CSC_STOPMODE_FCSPI0) || + (ePeriphType == CSC_STOPMODE_CMP1) || + (ePeriphType == CSC_STOPMODE_CMP0) || + (ePeriphType == CSC_STOPMODE_CMU3) || + (ePeriphType == CSC_STOPMODE_CMU2) || + (ePeriphType == CSC_STOPMODE_CMU1) || + (ePeriphType == CSC_STOPMODE_CMU0)); + + if (CSC_WP_CPU_0 == eTargetCpuType) + { + *pStatus = (bool)(0U != CSC0_HWA_ACKR2_GetStopAckStatus(ePeriphType)); + eRetVal = CSC_E_OK; + } + return eRetVal; +} + +/** + * @brief Get the stop Acknowledge status of all group peripherals in CSC. + * + * @param eTargetCpuType The target CPU which acknowledges the peripherals when entering stop mode. + * @param ePeriphType the peripheral to get stop acknowledge status + * @param pU32Status Output parameter,to save the stop ACK status of all the peripherals in the group indicated by ePeriphGrp. + * The corresponding bit is 1, indicates that stop acknowledge is asserted,and 0 not asserted. + * @return CSC_RetStatusType Operation success/failed + * CSC_E_OK: The API is successfully called + * CSC_E_NOT_OK: eTargetCpuType invalid + */ +CSC_RetStatusType CSC_GetStopAckStatus(CSC_WPB_CpuType eTargetCpuType,CSC_PeriphGrpType ePeriphGrp, uint32_t * const pU32Status) +{ + CSC_RetStatusType eRetVal = CSC_E_NOT_OK; + DEV_ASSERT((uint32_t)ePeriphGrp <= (uint32_t)CSC_STOP_CTRL_GROUP_2); + + if (CSC_WP_CPU_0 == eTargetCpuType) + { + *pU32Status = CSC0_GetStopAckStatus(ePeriphGrp); + eRetVal = CSC_E_OK; + } + return eRetVal; +} + +/** + * @brief Set the CPU write permission of CSCx_CCMx_CFG register in CSC. + * + * @param eTargetCpuType The target CPU controlled by CSCx_CCMx_CFG register. + * @param eCtrlCpuType The CPU that has the permission to access the CSCx_CCMx_CFG register. + * @param bLockStatus Lock the WPB of CSCx_CCMx_CFG register.Once locked, calling the API returns an error(CSC_E_LOCK). + * + * @return CSC_RetStatusType + * CSC_E_OK: The API is successfully called + * CSC_E_NOT_OK: eTargetCpuType invalid + * CSC_E_LOCK: WPB is locked(WPB_LOCK set 1) and can not be written + */ +CSC_RetStatusType CSC_SetCCMCfgPermission(CSC_WPB_CpuType eTargetCpuType, CSC_WPB_CpuType eCtrlCpuType, bool bLockStatus) +{ + CSC_RetStatusType eRetVal = CSC_E_NOT_OK; + DEV_ASSERT((uint32_t)eCtrlCpuType < (uint32_t)CSC_WP_CPU_NONE); + + if (CSC_WP_CPU_0 == eTargetCpuType) + { + if (0U == CSC0_HWA_CCM0_GetWPBLockStatus()) + { + CSC0_HWA_CCM0_SetCpuWritePermit(eCtrlCpuType); + + if(bLockStatus != false) + { + CSC0_HWA_CCM0_LockWritePermit(); + } + eRetVal = CSC_E_OK; + } + else + { + eRetVal = CSC_E_LOCK; + } + } + return eRetVal; +} + +/** + * @brief Set the CCM configuration of CPUx indicated by eTargetCpuType. + * + * @param eTargetCpuType The target CPU controlled by CSCx_CCMx_CFG register. + * @param pCCMCfg Pointer to the configuration of CSCx_CCMx_CFG register. + * + * @return CSC_RetStatusType + * CSC_E_OK: The API is successfully called + * CSC_E_NOT_OK: eTargetCpuType invalid + * CSC_E_LOCK: Current CPU has no permission + */ +CSC_RetStatusType CSC_SetCCMConfiguration(CSC_WPB_CpuType eTargetCpuType,const CSC_CCMCfgType *const pCCMCfg) +{ + CSC_RetStatusType eRetVal = CSC_E_NOT_OK; + CSC_WPB_CpuType eCtrlCpu; + + DEV_ASSERT(pCCMCfg != NULL_PTR); + DEV_ASSERT(pCCMCfg->eHandShakeMode == CSC_WAIT_ALL_ACK || + pCCMCfg->eHandShakeMode == CSC_WAIT_REQ_ACK); + + if (CSC_WP_CPU_0 == eTargetCpuType) + { + eCtrlCpu = CSC0_HWA_CCM0_GetCpuWritePermit(); + + if((eCtrlCpu == CSC_GET_CPU_ID()) || (eCtrlCpu == CSC_WP_CPU_ALL)) + { + CSC0_HWA_HClockEnable(pCCMCfg->HclkEn); + CSC0_HWA_SetHandShakeMode(pCCMCfg->eHandShakeMode); + eRetVal = CSC_E_OK; + } + else + { + eRetVal = CSC_E_LOCK; + } + } + return eRetVal; +} + +/** + * @brief Get the CCM stop clock status. + * + * @param eTargetCpuType The target CPU controlled by CSCx_CCMx_CFG register. + * @param eCCMType CCM stop clock type. + * @param pStatus Pointer to memory to save the clock status. + * + * @return CSC_RetStatusType + * CSC_E_OK: The API is successfully called + * CSC_E_NOT_OK: eTargetCpuType invalid + */ +CSC_RetStatusType CSC_GetCCMStopClockStatus(CSC_WPB_CpuType eTargetCpuType, CSCx_CCM_StopClockType eCCMType, bool * const pStatus) +{ + CSC_RetStatusType eRetVal = CSC_E_NOT_OK; + + DEV_ASSERT(pStatus != NULL_PTR); + DEV_ASSERT(eCCMType == CSC_CCM_STOPCLOCK_STATUS_SYS_SLAVE || + eCCMType == CSC_CCM_STOPCLOCK_STATUS_MASTER || + eCCMType == CSC_CCM_STOPCLOCK_STATUS_SLOW_SLAVE || + eCCMType == CSC_CCM_STOPCLOCK_STATUS_BUS_SLAVE); + + if (CSC_WP_CPU_0 == eTargetCpuType) + { + *pStatus = (bool)(0u != CSC0_HWA_CCM0_GetClockStatus(eCCMType)); + eRetVal = CSC_E_OK; + } + return eRetVal; +} + +/** + * @brief Set the CPU write permission of CSCx_CPUx_INT register in CSC. + * + * @param eTargetCpuType The target CPU controlled by CSCx_CPUx_INT register. + * @param eCtrlCpuType The CPU that has the permission to access the CSCx_CPUx_INT register. + * @param bLockStatus Lock the WPB of CSCx_CPUx_INT register.Once locked, calling the API returns an error(CSC_E_LOCK). + * + * @return CSC_RetStatusType + * CSC_E_OK: The API is successfully called + * CSC_E_NOT_OK: eTargetCpuType invalid + * CSC_E_LOCK: WPB is locked(WPB_LOCK set 1) and can not be written + */ +CSC_RetStatusType CSC_SetCpuIntPermission(CSC_WPB_CpuType eTargetCpuType, CSC_WPB_CpuType eCtrlCpuType, bool bLockStatus) +{ + CSC_RetStatusType eRetVal = CSC_E_NOT_OK; + DEV_ASSERT((uint32_t)eCtrlCpuType < (uint32_t)CSC_WP_CPU_NONE); + + if (CSC_WP_CPU_0 == eTargetCpuType) + { + if (0U == CSC0_HWA_CPU0INT_GetWPBLockStatus()) + { + CSC0_HWA_CPU0INT_SetCpuWritePermit(eCtrlCpuType); + + if(bLockStatus != false) + { + CSC0_HWA_CPU0INT_LockWritePermit(); + } + eRetVal = CSC_E_OK; + } + else + { + eRetVal = CSC_E_LOCK; + } + } + return eRetVal; +} + +/** + * @brief Generate software interrupt via CSCx_CPUx_INT. + * + * @param eTargetCpuType The target CPU to generate interrupt. + * @param bEnable true: Generate software interrupt. + * false: Do not generate software interrupt. + * + * @return CSC_RetStatusType + * CSC_E_OK: The API is successfully called + * CSC_E_NOT_OK: eTargetCpuType invalid + * CSC_E_LOCK: The current CPU has no permission to access this bit + */ +CSC_RetStatusType CSC_CpuSwInterruptGen(CSC_WPB_CpuType eTargetCpuType, bool bEnable) +{ + CSC_RetStatusType eRetVal = CSC_E_NOT_OK; + CSC_WPB_CpuType eCtrlCpu; + + if (CSC_WP_CPU_0 == eTargetCpuType) + { + eCtrlCpu = CSC0_HWA_CPU0INT_GetCpuWritePermit(); + + if((eCtrlCpu == CSC_GET_CPU_ID()) || (eCtrlCpu == CSC_WP_CPU_ALL)) + { + if(bEnable != false) + { + CSC0_HWA_CPU0INT_EnableSWInterrupt(); + } + else + { + CSC0_HWA_CPU0INT_DisableSWInterrupt(); + } + eRetVal = CSC_E_OK; + } + else + { + eRetVal = CSC_E_LOCK; + } + } + return eRetVal; +} diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_dma.c b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_dma.c new file mode 100644 index 0000000..76882f4 --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_dma.c @@ -0,0 +1,818 @@ +/** + * @file fc7xxx_driver_dma.c + * @author Flagchip0126 + * @brief FC7xxx DMA driver source code + * @version 0.1.0 + * @date 2024-01-15 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Author CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-01-15 Flagchip0126 N/A First version for FC7240 + ******************************************************************************** */ + +#include "fc7xxx_driver_dma.h" +#include "interrupt_manager.h" + +#define DMA_CHANNEL_INVALID (0xFFU) + +#define CPM_CORE_ID_CORE0 (0x0U) +#define CPM_CORE_ID_CORE1 (0x2U) +#define CPM_CORE_ID_CORE2 (0x4U) + +static uint8_t s_aDmaDumoUsedStatus[DMA_DUMO_COUNT] = {DMA_CHANNEL_INVALID, DMA_CHANNEL_INVALID, DMA_CHANNEL_INVALID, DMA_CHANNEL_INVALID}; + +static DMA_TransferCompleteCallbackType s_dmaTransferCompleteNotify[DMA_INSTANCE_COUNT][DMA_CFG_COUNT] = {NULL}; +static DMA_TransferErrorCallbackType s_dmaTransferErrorNotify[DMA_INSTANCE_COUNT][DMA_CFG_COUNT] = {NULL}; + +/** + * @brief DMA IRQ function prototypes + * + */ +void DMA0_IRQHandler(void); +void DMA1_IRQHandler(void); +void DMA2_IRQHandler(void); +void DMA3_IRQHandler(void); +void DMA4_IRQHandler(void); +void DMA5_IRQHandler(void); +void DMA6_IRQHandler(void); +void DMA7_IRQHandler(void); +void DMA8_IRQHandler(void); +void DMA9_IRQHandler(void); +void DMA10_IRQHandler(void); +void DMA11_IRQHandler(void); +void DMA12_IRQHandler(void); +void DMA13_IRQHandler(void); +void DMA14_IRQHandler(void); +void DMA15_IRQHandler(void); +void DMA_Error_IRQHandler(void); + + +/** + * @brief Get the first unused DUMO register index + * + * @param [out] pDumoIndex the DUMO register index + * @return DMA_StatusType whether there is unused DUMO index + * @return DMA_STATUS_SUCCESS the DUMO register index is successfully get + * @return DMA_STATUS_NO_RESOURCE all DUMO registers are already occupied + */ +static inline DMA_StatusType DMA_GetDumoIndex(uint8_t *pDumoIndex); + +/** + * @brief Check whether the value is power of 2 and return the ceil value of the log2(u32Value) + * + * @param [in] u32Value the value to check + * @param [out] u8Log2 the ceil value of log2(u32Value) + * @return true the u32Value is power of 2 + * @return false the u32Value is not power of 2 + */ +static bool DMA_IsPowerOf2(uint32_t u32Value, uint8_t *u8Log2); + +/** + * @brief Reset the DMAMUX config values + * @param Dmamux_Instance the selected DMA Instance + * + */ +static inline void Dmamux_Reset(DMAMUX_Type * const Dmamux_Instance); + +/** + * @brief Get the data offset value of the selected increment mode and data size + * + * @param eIncMode the selected increment mode + * @param eDataSize the selected data size + * @return int16_t the calculated data offset + */ +static inline uint16_t DMA_GetDataOffset(DMA_IncrementModeType eIncMode, + DMA_TransferSizeType eDataSize); + +/** + * @brief Get the IRQ number of the selected DMA channel + * + * @param u8Channel the selected DMA channel + * @return IRQn_Type the IRQ number of the selected DMA channel + */ +//static inline IRQn_Type DMA_GetChannelIRQn(const DMA_InstanceType eDma_Instance); + +/** + * @brief The internal interrupt handler for DMA transfer complete + * + * @param u8Channel the channel of the DMA interrpt + */ +static inline void DMA_Transfer_Complete_IRQHandler(const DMA_InstanceType eDma_Instance, const DMA_ChannelType eChannel); + +static inline DMA_StatusType DMA_GetDumoIndex(uint8_t *pDumoIndex) +{ + DMA_StatusType ret = DMA_STATUS_ERROR; + for (*pDumoIndex = 0U; *pDumoIndex < DMA_DUMO_COUNT; (*pDumoIndex)++) + { + if (s_aDmaDumoUsedStatus[*pDumoIndex] == DMA_CHANNEL_INVALID) + { + ret = DMA_STATUS_SUCCESS; + break; + } + } + if (*pDumoIndex == DMA_DUMO_COUNT) + { + ret = DMA_STATUS_NO_RESOURCE; + } + return ret; +} + +static bool DMA_IsPowerOf2(uint32_t u32Value, uint8_t *u8Log2) +{ + bool ret = (bool)false; + *u8Log2 = 0U; + while (u32Value > (1UL << *u8Log2)) + { + (*u8Log2)++; + } + if ((u32Value & ((1UL << *u8Log2) - 1U)) == 0U) + { + ret = (bool)true; + } + return ret; +} + +static inline uint16_t DMA_GetDataOffset(DMA_IncrementModeType eIncMode, + DMA_TransferSizeType eDataSize) +{ + uint16_t u16DataOffset = 0U; + switch (eIncMode) + { + case DMA_INCREMENT_DISABLE: + { + u16DataOffset = 0U; + break; + } + + case DMA_INCREMENT_DATA_SIZE: + { + u16DataOffset = (uint16_t)(1UL << ((uint8_t)eDataSize)); + break; + } + + case DMA_INCREMENT_DATA_SIZE_4BYTE_ALIGNED: + { + switch (eDataSize) + { + case DMA_TRANSFER_SIZE_1B: + case DMA_TRANSFER_SIZE_2B: + case DMA_TRANSFER_SIZE_4B: + u16DataOffset = 4U; + break; + + case DMA_TRANSFER_SIZE_8B: + u16DataOffset = 8U; + break; + + case DMA_TRANSFER_SIZE_32B: + u16DataOffset = 32U; + break; + + default: + break; + } + break; + } + + default: + break; + } + return u16DataOffset; +} + +void DMA0_IRQHandler(void) +{ + DMA_Transfer_Complete_IRQHandler(DMA_INSTANCE_0, DMA_CHANNEL_0); +} + +void DMA1_IRQHandler(void) +{ + DMA_Transfer_Complete_IRQHandler(DMA_INSTANCE_0, DMA_CHANNEL_1); +} + +void DMA2_IRQHandler(void) +{ + DMA_Transfer_Complete_IRQHandler(DMA_INSTANCE_0, DMA_CHANNEL_2); +} + +void DMA3_IRQHandler(void) +{ + DMA_Transfer_Complete_IRQHandler(DMA_INSTANCE_0, DMA_CHANNEL_3); +} + +void DMA4_IRQHandler(void) +{ + DMA_Transfer_Complete_IRQHandler(DMA_INSTANCE_0, DMA_CHANNEL_4); +} + +void DMA5_IRQHandler(void) +{ + DMA_Transfer_Complete_IRQHandler(DMA_INSTANCE_0, DMA_CHANNEL_5); +} + +void DMA6_IRQHandler(void) +{ + DMA_Transfer_Complete_IRQHandler(DMA_INSTANCE_0, DMA_CHANNEL_6); +} + +void DMA7_IRQHandler(void) +{ + DMA_Transfer_Complete_IRQHandler(DMA_INSTANCE_0, DMA_CHANNEL_7); +} + +void DMA8_IRQHandler(void) +{ + DMA_Transfer_Complete_IRQHandler(DMA_INSTANCE_0, DMA_CHANNEL_8); +} + +void DMA9_IRQHandler(void) +{ + DMA_Transfer_Complete_IRQHandler(DMA_INSTANCE_0, DMA_CHANNEL_9); +} + +void DMA10_IRQHandler(void) +{ + DMA_Transfer_Complete_IRQHandler(DMA_INSTANCE_0, DMA_CHANNEL_10); +} + +void DMA11_IRQHandler(void) +{ + DMA_Transfer_Complete_IRQHandler(DMA_INSTANCE_0, DMA_CHANNEL_11); +} + +void DMA12_IRQHandler(void) +{ + DMA_Transfer_Complete_IRQHandler(DMA_INSTANCE_0, DMA_CHANNEL_12); +} + +void DMA13_IRQHandler(void) +{ + DMA_Transfer_Complete_IRQHandler(DMA_INSTANCE_0, DMA_CHANNEL_13); +} + +void DMA14_IRQHandler(void) +{ + DMA_Transfer_Complete_IRQHandler(DMA_INSTANCE_0, DMA_CHANNEL_14); +} + +void DMA15_IRQHandler(void) +{ + DMA_Transfer_Complete_IRQHandler(DMA_INSTANCE_0, DMA_CHANNEL_15); +} + +void DMA_Error_IRQHandler(void) +{ + uint8_t u8Channel; + DMA_InstanceType eDma_Instance; + DMA_Type *pDma; + DMA_Type * aDma[] = DMA_BASE_PTRS; + + eDma_Instance = DMA_INSTANCE_0; + + pDma = aDma[DMA_INSTANCE_0]; + for (u8Channel = 0U; u8Channel < DMA_CFG_COUNT; u8Channel++) + { + if (DMA_HWA_GetChannelErrorFlag(pDma, u8Channel) == true) + { + DMA_HWA_ClearChannelErrorFlag(pDma, u8Channel); + if (s_dmaTransferErrorNotify[eDma_Instance][u8Channel] != NULL) + { + s_dmaTransferErrorNotify[eDma_Instance][u8Channel](); + } + } + } +} + +static inline void DMA_Transfer_Complete_IRQHandler(const DMA_InstanceType eDma_Instance, const DMA_ChannelType eChannel) +{ + DMA_Type * aDma[] = DMA_BASE_PTRS; + DMA_Type *const pDma = aDma[eDma_Instance]; + + DMA_HWA_ClearChannelInterruptFlag(pDma, (uint8_t)eChannel); + if (s_dmaTransferCompleteNotify[eDma_Instance][eChannel] != NULL) + { + s_dmaTransferCompleteNotify[eDma_Instance][eChannel](); + } +} + +static inline void Dmamux_Reset(DMAMUX_Type * const Dmamux_Instance) +{ + uint8_t u8Index; + for (u8Index = 0U; u8Index < DMAMUX_CHCFG_COUNT; u8Index++) + { + DMAMUX_HWA_SetRequestSource(Dmamux_Instance, u8Index, false, DMA_REQ_DISABLED); + } + for (u8Index = 0U; u8Index < DMAMUX_CHTRG_TRG_COUNT; u8Index++) + { + //DMAMUX_HWA_SetPeriodicTrigFlag(Dmamux_Instance, u8Index, false); + } +} + +void DMA_Init(const DMA_InstanceType eDma_Instance, const DMA_InitType *const pInitCfg) +{ + DEV_ASSERT(eDma_Instance < DMA_INSTANCE_MAX); + DEV_ASSERT(pInitCfg != NULL); + + DMA_Type * aDma[] = DMA_BASE_PTRS; + DMA_Type *const pDma = aDma[eDma_Instance]; + + DMA_DeInit(eDma_Instance); + DMA_HWA_SetHaltOnErrorFlag(pDma, pInitCfg->bHaltOnError); + DMA_HWA_SetArbitrationAlgorithm(pDma, pInitCfg->eArbitrationAlgorithm); + DMA_HWA_SetInnerLoopMappingEnableFlag(pDma, true); +} + +void DMA_DeInit(const DMA_InstanceType eDma_Instance) +{ + DEV_ASSERT(eDma_Instance < DMA_INSTANCE_MAX); + + uint8_t u8Index; + DMA_Type * aDma[] = DMA_BASE_PTRS; + DMA_Type *const pDma = aDma[eDma_Instance]; + DMAMUX_Type * aDmamux[] = DMAMUX_BASE_PTRS; + DMAMUX_Type *const pDmamux = aDmamux[eDma_Instance]; + + DMA_HWA_SetControlRegister(pDma, 0U); + DMA_HWA_DisableAllChannelErrorInterrupt(pDma); + DMA_HWA_DisableAllChannelRequest(pDma); + DMA_HWA_ClearAllChannelDoneStatus(pDma); + DMA_HWA_ClearAllChannelErrorFlag(pDma); + DMA_HWA_ClearAllChannelInterruptFlag(pDma); + pDma->DUME[0] = 0U; + for (u8Index = 0U; u8Index < DMA_DUMO_COUNT; u8Index++) + { + DMA_HWA_SetUnalignModulo(pDma, u8Index, 0U, 0U); + } + for (u8Index = 0U; u8Index < DMA_CFG_COUNT; u8Index++) + { + DMA_HWA_SetUnalignModuloEnableFlag(pDma, u8Index, false, false); + DMA_HWA_SetPriority(pDma, u8Index, u8Index); + DMA_HWA_SetSrcAddr(pDma, u8Index, 0U); + DMA_HWA_SetSrcOffset(pDma, u8Index, 0); + DMA_HWA_SetSrcLastAddrAdjustment(pDma, u8Index, 0); + DMA_HWA_SetDestAddr(pDma, u8Index, 0U); + DMA_HWA_SetDestOffset(pDma, u8Index, 0); + DMA_HWA_SetDestLastAddrAdjustment(pDma, u8Index, 0); + DMA_HWA_SetSrcDataSize(pDma, u8Index, DMA_TRANSFER_SIZE_1B); + DMA_HWA_SetSrcModulo(pDma, u8Index, 0U); + DMA_HWA_SetDestDataSize(pDma, u8Index, DMA_TRANSFER_SIZE_1B); + DMA_HWA_SetDestModulo(pDma, u8Index, 0U); + DMA_HWA_SetInnerLoopSize(pDma, u8Index, 0U); + DMA_HWA_SetChannelControlStatus(pDma, u8Index, 0U); + DMA_HWA_SetChannelToChannelTrig(pDma, u8Index, false, 0U); + DMA_HWA_SetLoopCount(pDma, u8Index, 0U); + } + Dmamux_Reset(pDmamux); + +} + +DMA_StatusType DMA_InitChannel(const DMA_InstanceType eDma_Instance, const DMA_ChannelType eChannel, const DMA_ChannelCfgType *const pChnCfg) +{ + DEV_ASSERT(eDma_Instance < DMA_INSTANCE_MAX); + DEV_ASSERT(eChannel < DMA_CHANNEL_MAX); + DEV_ASSERT(pChnCfg != NULL); + DEV_ASSERT(pChnCfg->u16BlockCount > 0U); + DEV_ASSERT(pChnCfg->u32BlockSize > 0U); + DEV_ASSERT(((pChnCfg->u32BlockSize >> pChnCfg->eSrcDataSize) << pChnCfg->eSrcDataSize == pChnCfg->u32BlockSize) && + ((pChnCfg->u32BlockSize >> pChnCfg->eDestDataSize) << pChnCfg->eDestDataSize == pChnCfg->u32BlockSize)); + + DMA_Type * aDma[] = DMA_BASE_PTRS; + DMA_Type *const pDma = aDma[eDma_Instance]; + DMAMUX_Type * aDmamux[] = DMAMUX_BASE_PTRS; + DMAMUX_Type *const pDmamux = aDmamux[eDma_Instance]; + + DMA_StatusType ret; + + uint16_t u16SrcDataOffset = DMA_GetDataOffset(pChnCfg->eSrcIncMode, pChnCfg->eSrcDataSize); + uint16_t u16DestDataOffset = DMA_GetDataOffset(pChnCfg->eDestIncMode, pChnCfg->eDestDataSize); + + int32_t s32SrcLastOffset; + int32_t s32DestLastOffset; + + uint8_t u8SrcMod = 0U; + uint8_t u8DestMod = 0U; + + bool bUseSrcDumo = (bool)false; + bool bUseDestDumo = (bool)false; + uint8_t u8DumoIndex = 0U; + uint16_t u16Sumo = 0U; + uint16_t u16Dumo = 0U; + + if ((pChnCfg->bSrcCircularBufferEn == true) || (pChnCfg->bDestCircularBufferEn == true)) + { + /* If the circular buffer size is not power of 2 aligned, need to use the DUMO */ + if (pChnCfg->bSrcCircularBufferEn == true) + { + DEV_ASSERT(pChnCfg->u32SrcCircBufferSize != 0U); + bUseSrcDumo = (bool)(DMA_IsPowerOf2(pChnCfg->u32SrcCircBufferSize, &u8SrcMod) ? false : true); + } + if (pChnCfg->bDestCircularBufferEn == true) + { + DEV_ASSERT(pChnCfg->u32DestCircBufferSize != 0U); + bUseDestDumo = (bool)(DMA_IsPowerOf2(pChnCfg->u32DestCircBufferSize, &u8DestMod) ? false : true); + } + + /* If circular buffer is enabled, the buffer address must be power of 2 aligned */ + if (((pChnCfg->bSrcCircularBufferEn == true) && + (((uint32_t)pChnCfg->pSrcBuffer & ((1UL << u8SrcMod) - 1U)) != 0U)) || + ((pChnCfg->bDestCircularBufferEn == true) && + (((uint32_t)pChnCfg->pDestBuffer & ((1UL << u8DestMod) - 1U)) != 0U))) + { + ret = DMA_STATUS_INVALID_ADDRESS; + } + /* If circular buffer is enabled, the buffer size must not less than the data offset */ + else if (((pChnCfg->bSrcCircularBufferEn == true) && + (pChnCfg->u32SrcCircBufferSize < u16SrcDataOffset)) || + ((pChnCfg->bDestCircularBufferEn == true) && + (pChnCfg->u32DestCircBufferSize < u16SrcDataOffset))) + { + ret = DMA_STATUS_UNSUPPORTED; + } + /* If source or destination unalign modulo is used, check whether all DUMO registers are occupied */ + else if ((bUseSrcDumo == true) || (bUseDestDumo == true)) + { + ret = DMA_GetDumoIndex(&u8DumoIndex); + if (ret == DMA_STATUS_SUCCESS) + { + s_aDmaDumoUsedStatus[u8DumoIndex] = (uint8_t)eChannel; + } + } + else + { + ret = DMA_STATUS_SUCCESS; + } + } + else + { + ret = DMA_STATUS_SUCCESS; + } + + if (ret == DMA_STATUS_SUCCESS) + { + if (pChnCfg->bSrcAddrLoopbackEn == true) + { + if (pChnCfg->bSrcBlockOffsetEn == false) + { + s32SrcLastOffset = -((int32_t)((pChnCfg->u32BlockSize >> pChnCfg->eSrcDataSize) * u16SrcDataOffset) * + (int32_t)(pChnCfg->u16BlockCount)); + } + else + { + s32SrcLastOffset = -(((int32_t)((pChnCfg->u32BlockSize >> pChnCfg->eSrcDataSize) * u16SrcDataOffset)) * + (int32_t)(pChnCfg->u16BlockCount)) - ((pChnCfg->s32BlockOffset) * (int32_t)(pChnCfg->u16BlockCount - 1U)); + } + } + else + { + s32SrcLastOffset = 0; + } + if (pChnCfg->bDestAddrLoopbackEn == true) + { + if (pChnCfg->bDestBlockOffsetEn == false) + { + s32DestLastOffset = -(((pChnCfg->u32BlockSize >> pChnCfg->eDestDataSize) * u16DestDataOffset) * + (pChnCfg->u16BlockCount)); + } + else + { + s32DestLastOffset = -(((int32_t)((pChnCfg->u32BlockSize >> pChnCfg->eDestDataSize) * u16DestDataOffset)) * + (int32_t)(pChnCfg->u16BlockCount)) - ((pChnCfg->s32BlockOffset) * (int32_t)(pChnCfg->u16BlockCount - 1U)); + } + } + else + { + s32DestLastOffset = 0; + } + + DMA_HWA_SetSrcAddr(pDma, (uint8_t)eChannel, (uint32_t)pChnCfg->pSrcBuffer); + DMA_HWA_SetDestAddr(pDma, (uint8_t)eChannel, (uint32_t)pChnCfg->pDestBuffer); + DMA_HWA_SetPriority(pDma, (uint8_t)eChannel, pChnCfg->u8ChannelPriority); + + if ((pChnCfg->bSrcCircularBufferEn == true) && (pChnCfg->bDestCircularBufferEn == true)) + { + DMA_HWA_SetSrcDataSize(pDma, (uint8_t)eChannel, pChnCfg->eSrcDataSize); + DMA_HWA_SetSrcModulo(pDma, (uint8_t)eChannel, u8SrcMod); + DMA_HWA_SetDestDataSize(pDma, (uint8_t)eChannel, pChnCfg->eDestDataSize); + DMA_HWA_SetDestModulo(pDma, (uint8_t)eChannel, u8DestMod); + } + else if (pChnCfg->bSrcCircularBufferEn == true) + { + DMA_HWA_SetSrcDataSize(pDma, (uint8_t)eChannel, pChnCfg->eSrcDataSize); + DMA_HWA_SetSrcModulo(pDma, (uint8_t)eChannel, u8SrcMod); + DMA_HWA_SetDestDataSize(pDma, (uint8_t)eChannel, pChnCfg->eDestDataSize); + DMA_HWA_SetDestModulo(pDma, (uint8_t)eChannel, 0U); + } + else if (pChnCfg->bDestCircularBufferEn == true) + { + DMA_HWA_SetSrcDataSize(pDma, (uint8_t)eChannel, pChnCfg->eSrcDataSize); + DMA_HWA_SetSrcModulo(pDma, (uint8_t)eChannel, 0U); + DMA_HWA_SetDestDataSize(pDma, (uint8_t)eChannel, pChnCfg->eDestDataSize); + DMA_HWA_SetDestModulo(pDma, (uint8_t)eChannel, u8DestMod); + } + else + { + DMA_HWA_SetSrcDataSize(pDma, (uint8_t)eChannel, pChnCfg->eSrcDataSize); + DMA_HWA_SetSrcModulo(pDma, (uint8_t)eChannel, 0U); + DMA_HWA_SetDestDataSize(pDma, (uint8_t)eChannel, pChnCfg->eDestDataSize); + DMA_HWA_SetDestModulo(pDma, (uint8_t)eChannel, 0U); + } + + if (bUseSrcDumo == true) + { + u16Sumo = (uint16_t)((pChnCfg->u32SrcCircBufferSize / u16SrcDataOffset - 1U) * u16SrcDataOffset); + } + if (bUseDestDumo == true) + { + u16Dumo = (uint16_t)((pChnCfg->u32DestCircBufferSize / u16DestDataOffset - 1U) * u16DestDataOffset); + } + if ((bUseSrcDumo == true) || (bUseDestDumo == true)) + { + DMA_HWA_SetUnalignModulo(pDma, u8DumoIndex, u16Sumo, u16Dumo); + DMA_HWA_SetUnalignModuloEnableFlag(pDma, (uint8_t)eChannel, bUseSrcDumo, bUseDestDumo); + DMA_HWA_SetUnalignModuloSel(pDma, (uint8_t)eChannel, u8DumoIndex); + } + DMA_HWA_SetAutoDisableReuqestEnableFlag(pDma, (uint8_t)eChannel, pChnCfg->bAutoStop); + + DMA_HWA_SetSrcOffset(pDma, (uint8_t)eChannel, (int16_t)u16SrcDataOffset); + DMA_HWA_SetDestOffset(pDma, (uint8_t)eChannel, (int16_t)u16DestDataOffset); + + DMA_HWA_SetInnerLoopOffset(pDma, (uint8_t)eChannel, pChnCfg->bSrcBlockOffsetEn, pChnCfg->bDestBlockOffsetEn, + pChnCfg->s32BlockOffset); + DMA_HWA_SetInnerLoopSize(pDma, (uint8_t)eChannel, pChnCfg->u32BlockSize); + + if ((pChnCfg->u16BlockCount > 1U) && (true == pChnCfg->bInnerChannelChain)) + { + DMA_HWA_SetChannelToChannelTrig(pDma, (uint8_t)eChannel, true, (uint8_t)eChannel); + DMA_HWA_SetLoopCount(pDma, (uint8_t)eChannel, pChnCfg->u16BlockCount); + } + else + { + DMA_HWA_SetChannelToChannelTrig(pDma, (uint8_t)eChannel, false, 0U); + DMA_HWA_SetLoopCount(pDma, (uint8_t)eChannel, pChnCfg->u16BlockCount); + } + + DMA_HWA_SetSrcLastAddrAdjustment(pDma, (uint8_t)eChannel, s32SrcLastOffset); + DMA_HWA_SetDestLastAddrAdjustment(pDma, (uint8_t)eChannel, s32DestLastOffset); + + if (pChnCfg->eTriggerSrc == DMA_REQ_DISABLED) + { + DMAMUX_HWA_SetRequestSource(pDmamux, (uint8_t)eChannel, false, DMA_REQ_DISABLED); + } + else + { + DMAMUX_HWA_SetRequestSource(pDmamux, (uint8_t)eChannel, true, pChnCfg->eTriggerSrc); + } + } + return ret; +} + +void DMA_DeinitChannel(const DMA_InstanceType eDma_Instance, const DMA_ChannelType eChannel) +{ + DEV_ASSERT(eDma_Instance < DMA_INSTANCE_MAX); + DEV_ASSERT(eChannel < DMA_CHANNEL_MAX); + + DMA_Type * aDma[] = DMA_BASE_PTRS; + DMA_Type *const pDma = aDma[eDma_Instance]; + uint8_t u8DumoIndex; + + for (u8DumoIndex = 0U; u8DumoIndex < DMA_DUMO_COUNT; u8DumoIndex++) + { + if (s_aDmaDumoUsedStatus[u8DumoIndex] == (uint8_t)eChannel) + { + s_aDmaDumoUsedStatus[u8DumoIndex] = DMA_CHANNEL_INVALID; + DMA_HWA_SetUnalignModulo(pDma, u8DumoIndex, 0U, 0U); + } + } + DMA_HWA_SetUnalignModuloEnableFlag(pDma, (uint8_t)eChannel, false, false); + DMA_HWA_DisableChannelErrorInterrupt(pDma, (uint8_t)eChannel); + DMA_HWA_DisableChannelRequest(pDma, (uint8_t)eChannel); + DMA_HWA_ClearChannelDoneStatus(pDma, (uint8_t)eChannel); + DMA_HWA_ClearChannelErrorFlag(pDma, (uint8_t)eChannel); + DMA_HWA_ClearChannelInterruptFlag(pDma, (uint8_t)eChannel); + + DMA_HWA_SetSrcAddr(pDma, (uint8_t)eChannel, 0U); + DMA_HWA_SetSrcOffset(pDma, (uint8_t)eChannel, 0); + DMA_HWA_SetSrcLastAddrAdjustment(pDma, (uint8_t)eChannel, 0); + DMA_HWA_SetDestAddr(pDma, (uint8_t)eChannel, 0U); + DMA_HWA_SetDestOffset(pDma, (uint8_t)eChannel, 0); + DMA_HWA_SetDestLastAddrAdjustment(pDma, (uint8_t)eChannel, 0); + DMA_HWA_SetSrcDataSize(pDma, (uint8_t)eChannel, DMA_TRANSFER_SIZE_1B); + DMA_HWA_SetSrcModulo(pDma, (uint8_t)eChannel, 0U); + DMA_HWA_SetDestDataSize(pDma, (uint8_t)eChannel, DMA_TRANSFER_SIZE_1B); + DMA_HWA_SetDestModulo(pDma, (uint8_t)eChannel, 0U); + DMA_HWA_SetInnerLoopOffset(pDma, (uint8_t)eChannel, false, false, 0); + DMA_HWA_SetInnerLoopSize(pDma, (uint8_t)eChannel, 0U); + DMA_HWA_SetChannelControlStatus(pDma, (uint8_t)eChannel, 0U); + DMA_HWA_SetChannelToChannelTrig(pDma, (uint8_t)eChannel, false, 0U); + DMA_HWA_SetLoopCount(pDma, (uint8_t)eChannel, 0U); +} + +void DMA_InitChannelInterrupt(const DMA_InstanceType eDma_Instance, const DMA_ChannelType eChannel, const DMA_InterruptCfgType *const pInterruptCfg) +{ + DEV_ASSERT(eDma_Instance < DMA_INSTANCE_MAX); + DEV_ASSERT(eChannel < DMA_CHANNEL_MAX); + DEV_ASSERT(pInterruptCfg != NULL); + + DMA_Type * aDma[] = DMA_BASE_PTRS; + DMA_Type *const pDma = aDma[eDma_Instance]; + + if (pInterruptCfg->bTransferCompleteIntEn) + { + s_dmaTransferCompleteNotify[eDma_Instance][eChannel] = pInterruptCfg->pTransferCompleteNotify; + DMA_HWA_EnableTransferCompleteInterrupt(pDma, (uint8_t)eChannel); + //IntMgr_EnableInterrupt(DMA_GetChannelIRQn(eChannel)); + } + else + { + DMA_HWA_DisableTransferCompleteInterrupt(pDma, (uint8_t)eChannel); + s_dmaTransferCompleteNotify[eDma_Instance][eChannel] = NULL; + //IntMgr_DisableInterrupt(DMA_GetChannelIRQn(eChannel)); + } + + if (pInterruptCfg->bTransferErrorIntEn) + { + s_dmaTransferErrorNotify[eDma_Instance][eChannel] = pInterruptCfg->pTransferErrorNotify; + DMA_HWA_EnableChannelErrorInterrupt(pDma, (uint8_t)eChannel); + //IntMgr_EnableInterrupt(DMA_error_IRQn); + } + else + { + DMA_HWA_DisableChannelErrorInterrupt(pDma, (uint8_t)eChannel); + s_dmaTransferErrorNotify[eDma_Instance][eChannel] = NULL; + //if (DMA_HWA_GetAllChannelErrorInterruptEnableFlag(pDma) == 0U) + //{ + //IntMgr_DisableInterrupt(DMA_error_IRQn); + //} + } +} + +void DMA_ConfigChainedTransfer(const DMA_InstanceType eDma_Instance, const DMA_ChannelType eChannel, + const DMA_ChainTransferType *const pChainTransferCfg) +{ + DEV_ASSERT(eDma_Instance < DMA_INSTANCE_MAX); + DEV_ASSERT(eChannel < DMA_CHANNEL_MAX); + DEV_ASSERT(pChainTransferCfg != NULL); + + DMA_Type * aDma[] = DMA_BASE_PTRS; + DMA_Type *const pDma = aDma[eDma_Instance]; + + DMA_HWA_SetOuterLoopTrigEnableFlag(pDma, (uint8_t)eChannel, pChainTransferCfg->bChanelChainEn); + DMA_HWA_SetOuterLoopTrigChannel(pDma, (uint8_t)eChannel, pChainTransferCfg->u8ChainedChannel); +} + + + +DMA_StatusType DMA_ModifySize(const DMA_InstanceType eDma_Instance, const DMA_ChannelType eChannel, uint16_t u16LoopCnt) { + DEV_ASSERT(eDma_Instance < DMA_INSTANCE_MAX); + DEV_ASSERT(eChannel < DMA_CHANNEL_MAX); + + DMA_Type * aDma[] = DMA_BASE_PTRS; + DMA_Type *const pDma = aDma[eDma_Instance]; + DMA_StatusType ret; + + if (DMA_GetChannelStatus(eDma_Instance, eChannel) == DMA_RUNNING_STATUS_IDLE) + { + DMA_HWA_SetLoopCount(pDma, (uint8_t)eChannel, u16LoopCnt); + + ret = DMA_STATUS_SUCCESS; + } + else + { + ret = DMA_STATUS_BUSY; + } + return ret; +} + +DMA_StatusType DMA_ModifyAddress(const DMA_InstanceType eDma_Instance, const DMA_ChannelType eChannel, + const volatile void *pSrcBuffer, const volatile void *pDestBuffer) +{ + DEV_ASSERT(eDma_Instance < DMA_INSTANCE_MAX); + DEV_ASSERT(eChannel < DMA_CHANNEL_MAX); + + DMA_Type * aDma[] = DMA_BASE_PTRS; + DMA_Type *const pDma = aDma[eDma_Instance]; + DMA_StatusType ret; + + if (DMA_GetChannelStatus(eDma_Instance, eChannel) == DMA_RUNNING_STATUS_IDLE) + { + if (pSrcBuffer != NULL) + { + DMA_HWA_SetSrcAddr(pDma, (uint8_t)eChannel, (uint32_t)pSrcBuffer); + } + if (pDestBuffer != NULL) + { + DMA_HWA_SetDestAddr(pDma, (uint8_t)eChannel, (uint32_t)pDestBuffer); + } + ret = DMA_STATUS_SUCCESS; + } + else + { + ret = DMA_STATUS_BUSY; + } + return ret; +} + +void DMA_StartChannel(const DMA_InstanceType eDma_Instance, const DMA_ChannelType eChannel) +{ + DEV_ASSERT(eDma_Instance < DMA_INSTANCE_MAX); + DEV_ASSERT(eChannel < DMA_CHANNEL_MAX); + + DMA_Type * aDma[] = DMA_BASE_PTRS; + DMA_Type *const pDma = aDma[eDma_Instance]; + + if (DMA_GetChannelRequestSrc(eDma_Instance, eChannel) == DMA_REQ_DISABLED) + { + DMA_HWA_SetChannelStart(pDma, (uint8_t)eChannel); + } + else + { + DMA_HWA_EnableChannelRequest(pDma, (uint8_t)eChannel); + } +} + +void DMA_StopChannel(const DMA_InstanceType eDma_Instance, const DMA_ChannelType eChannel) +{ + DEV_ASSERT(eDma_Instance < DMA_INSTANCE_MAX); + DEV_ASSERT(eChannel < DMA_CHANNEL_MAX); + + DMA_Type * aDma[] = DMA_BASE_PTRS; + DMA_Type *const pDma = aDma[eDma_Instance]; + + DMA_HWA_DisableChannelRequest(pDma, (uint8_t)eChannel); +} + +DMA_StatusType DMA_CancelTransfer(const DMA_InstanceType eDma_Instance, bool bGenerateErr) +{ + DEV_ASSERT(eDma_Instance < DMA_INSTANCE_MAX); + + DMA_Type * aDma[] = DMA_BASE_PTRS; + DMA_Type *const pDma = aDma[eDma_Instance]; + DMA_StatusType eRet; + uint32_t u32TimeOut = 15000000U; + + if (bGenerateErr) + { + DMA_HWA_ErrorCancelTransfer(pDma); + while ((DMA_HWA_GetErrorCancelTransferStatus(pDma) == true) && (u32TimeOut != 0U)) + { + u32TimeOut--; + } + } + else + { + DMA_HWA_CancelTransfer(pDma); + while ((DMA_HWA_GetCancelTransferStatus(pDma) == true) && (u32TimeOut != 0U)) + { + u32TimeOut--; + } + } + if (u32TimeOut != 0U) + { + eRet = DMA_STATUS_SUCCESS; + } + else + { + eRet = DMA_STATUS_TIMEOUT; + } + return eRet; +} + +DMA_RequestSourceType DMA_GetChannelRequestSrc(const DMA_InstanceType eDma_Instance, const DMA_ChannelType eChannel) +{ + DEV_ASSERT(eDma_Instance < DMA_INSTANCE_MAX); + DEV_ASSERT(eChannel < DMA_CHANNEL_MAX); + + DMAMUX_Type * aDmamux[] = DMAMUX_BASE_PTRS; + DMAMUX_Type *const pDmamux = aDmamux[eDma_Instance]; + + DMA_RequestSourceType eReqSrc = DMAMUX_HWA_GetRequestSource(pDmamux, (uint8_t)eChannel); + + return eReqSrc; +} + +DMA_RunningStatusType DMA_GetStatus(const DMA_InstanceType eDma_Instance) +{ + DEV_ASSERT(eDma_Instance < DMA_INSTANCE_MAX); + + DMA_Type * aDma[] = DMA_BASE_PTRS; + DMA_Type *const pDma = aDma[eDma_Instance]; + DMA_RunningStatusType eDMAStatus = DMA_HWA_GetStatus(pDma); + return eDMAStatus; +} + +DMA_RunningStatusType DMA_GetChannelStatus(const DMA_InstanceType eDma_Instance, const DMA_ChannelType eChannel) +{ + DEV_ASSERT(eDma_Instance < DMA_INSTANCE_MAX); + DEV_ASSERT(eChannel < DMA_CHANNEL_MAX); + + DMA_Type * aDma[] = DMA_BASE_PTRS; + DMA_Type *const pDma = aDma[eDma_Instance]; + DMA_RunningStatusType eChannelStatus = DMA_HWA_GetChannelActiveStatus(pDma, (uint8_t)eChannel); + return eChannelStatus; +} diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_dsp.c b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_dsp.c new file mode 100644 index 0000000..51f181b --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_dsp.c @@ -0,0 +1,38 @@ +/** + * @file fc7xxx_driver_dsp.c + * @author Flagchip051 + * @brief FC4xxx DSP driver type definition and API + * @version 0.1.0 + * @date 2022-04-23 + * + * @copyright Copyright (c) 2022 Flagchip Semiconductors Co., Ltd. + * + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2022-04-23 Flagchip054 N/A First version for FC7300 + ******************************************************************************** */ + +#include "fc7xxx_driver_dsp.h" + + +/* + * @details @verbatim +If only want use FPU, +1) configure FCIDE to enable FPU compiler support, "Properties" -> C/C++ Build -> Settings -> Tool Settings -> Target Processor -> Float ABI -> FP instructions(hard) -> FPU Type set to "fpv5-sp-d16" +2) configure FCIDE to enable FPU compiler support, "Properties" -> C/C++ Build -> Settings -> Tool Settings -> GNU Arm Cross C Compiler -> Preprocessor -> Defined symbols(-D) -> Add "__FPU_PRESENT=1" (without ") +3) and call FPU_Enable to enable FPU at the beginning of program. + +If want to use DSP, +1) configure FCIDE to enable FPU compiler support, Properties -> C/C++ Build -> Settings -> Tool Settings -> Target Processor -> Float ABI -> FP instructions(hard) +2) add MACRO "DRIVER_CM7_DSP_ENABLE" in FCIDE Properties -> C/C++ General -> Paths and Symbols -> Symbols -> GNU C and GNU C++ and Assembly +3) add Include Path to project Properties -> C/C++ General -> Paths and Symbols -> Includes -> GNU C and GNU C++ and Assembly: + ../../../../../../Template/Device/CMSIS5_590/DSP/Include + ../../../../../../Template/Device/CMSIS5_590/Core/Include + ../../../../../../Template/Device/CMSIS5_590/DSP/PrivateInclude +4) and call FPU_Enable to enable FPU at the beginning of program. + @endverbatim + */ diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_eim.c b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_eim.c new file mode 100644 index 0000000..b18e4e6 --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_eim.c @@ -0,0 +1,217 @@ +/** + * @file fc7xxx_driver_eim.c + * @author Flagchip + * @brief FC7xxx EIM driver type definition and API + * @version 0.1.0 + * @date 2024-01-14 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + */ +/******************************************************************************** +* Revision History: +* +* Version Date Initials CR# Descriptions +* --------- ---------- ------------ ---------- --------------- +* 0.1.0 2024-01-14 qxw0100 N/A First version for FC7240 +********************************************************************************/ + +#include "fc7xxx_driver_eim.h" +#include "fc7xxx_driver_pcc.h" + +/******************* Local Variables ***********************/ + +/******************* Local Function Prototype **************/ + + +/****************** Global Functions ***********************/ +/** + * @brief Initialize EIM function + * + * @param pEimInitCfg Initialization structure of EIM + * @return return 0: initialize successful. 1: invalid parameter + */ +EIM_RetType EIM_Init(const EIM_InitType *pEimInitCfg) +{ + EIM_RetType eRet = EIM_STATUS_SUCCESS; + uint32_t u32CtrlVal = 0U; + uint32_t u32BusVal = 0U; + uint8_t u8BusChn; + if (NULL == pEimInitCfg) + { + eRet = EIM_STATUS_PARAM_INVALID; + } + else + { + u32CtrlVal |= EIM_CTRL_REG_BUS_SEL(pEimInitCfg->u8BusSelIdx); + u8BusChn = (uint8_t)pEimInitCfg->u8BusSelIdx; + if(pEimInitCfg->u8Attreenable != 0U) + { + if((pEimInitCfg->u8EimChn>=1U) && (pEimInitCfg->u8EimChn<=23U)) + { + u32CtrlVal |= EIM_CTRL_REG_ATTREIE(1U); + u32BusVal |= EIM_BUS_REG_ATTR(pEimInitCfg->u8AttrPosition); + } + else + { + eRet = EIM_STATUS_PARAM_INVALID; + } + + } + if(pEimInitCfg->u8Addreenable != 0U) + { + if((pEimInitCfg->u8EimChn>=1U) && (pEimInitCfg->u8EimChn<=23U)) + { + u32CtrlVal |= EIM_CTRL_REG_ADDREIE(1U); + u32BusVal |= EIM_BUS_REG_ADDR(pEimInitCfg->u8AddrePosition); + } + else + { + eRet = EIM_STATUS_PARAM_INVALID; + } + } + if(pEimInitCfg->u8Data0enable != 0U) + { + u32CtrlVal |= EIM_CTRL_REG_DATA0EIE(1U); + u32BusVal |= EIM_BUS_REG_DATA0(pEimInitCfg->u8Data0Val); + } + if(pEimInitCfg->u8Data1enable != 0U) + { + u32CtrlVal |= EIM_CTRL_REG_DATA1EIE(1U); + u32BusVal |= EIM_BUS_REG_DATA1(pEimInitCfg->u8Data1Val); + } + EIM_HWA_Set_BUSRegn(u8BusChn,u32BusVal); + EIM_HWA_Set_CtrlRegn((uint8_t)pEimInitCfg->u8EimChn,u32CtrlVal); + EIM_HWA_EnableGlobalErrorInjection(); + } + + return eRet; +} + +/** + * @brief Initialize EIM function + * + * @param eEimChannel channel want to set + * @param eDwpType Cpu to use + * @param bLockStatus Lock the cpu control settings + * @return Set operation success/failed + */ +EIM_RetType EIM_SetDwpMode(const EIM_ChannelType eEimChannel, const EIM_DWPType eDwpType, bool bLockStatus) +{ + uint8_t u8ChnIdx = (uint8_t)eEimChannel; + EIM_RetType eRet = EIM_STATUS_SUCCESS; + if (0U == EIM_HWA_GetCtrlDWPLockStatus(u8ChnIdx)) + { + EIM_HWA_Set_CtrlLockMode((uint8_t)eEimChannel,(uint8_t)eDwpType); + if(true == bLockStatus) + { + /* Lock the dwp mode until reset */ + EIM_HWA_CtrlRegnWritePermit(u8ChnIdx); + } + } + else + { + eRet = EIM_STATUS_PARAM_INVALID; + } + + return eRet; +} + +/** + * @brief Enable CPU lockstep monitor + * + * @param eEimCpuType EIM_CPU0_LOCKSTEP or EIM_CPU1_LOCKSTEP + * @param eMonitorType EIM_MONITOR0 or EIM_MONITOR1 + */ +void EIM_CpuLockStepMonitorSet_MonSet(const EIM_CPU_ChnType eEimCpuType,const EIM_MONType eMonitorType) +{ + uint32_t u32val = 0U; + + u32val = EIM_HWA_Get_CPULockstep((uint8_t)eEimCpuType); + + if(eMonitorType == EIM_MONITOR0) + { + u32val &= 0xFFFFFFFD;//clear mon0 clr + u32val |= EIM_CPU0_LOCKSTEP_LOCKSTEP_MON0_SET(1U); + } + + if(eMonitorType == EIM_MONITOR1) + { + u32val &= 0xFFFFFFFE;//clear mon1 clr + u32val |= EIM_CPU0_LOCKSTEP_LOCKSTEP_MON1_SET(1U); + } + + EIM_HWA_Set_CPULockstep((uint8_t)eEimCpuType, u32val); +} + +/** + * @brief Clear CPU lockstep monitor + * + * @param eEimCpuType EIM_CPU0_LOCKSTEP or EIM_CPU1_LOCKSTEP + * @param eMonitorType EIM_MONITOR0 or EIM_MONITOR1 + */ +void EIM_CpuLockStepMonitorSet_MonClr(const EIM_CPU_ChnType eEimCpuType,const EIM_MONType eMonitorType) +{ + uint32_t u32val = 0U; + + u32val = EIM_HWA_Get_CPULockstep((uint8_t)eEimCpuType); + + if(eMonitorType == EIM_MONITOR0) + { + u32val |= EIM_CPU0_LOCKSTEP_LOCKSTEP_MON0_CLR(1U); + } + if(eMonitorType == EIM_MONITOR1) + { + u32val |= EIM_CPU0_LOCKSTEP_LOCKSTEP_MON1_CLR(1U); + } + + EIM_HWA_Set_CPULockstep((uint8_t)eEimCpuType, u32val); +} + +/** + * @brief Clean CPU lockstep monitor bit + * + * @param eEimCpuType EIM_CPU0_LOCKSTEP or EIM_CPU1_LOCKSTEP + * @param eMonitorType EIM_MONITOR0 or EIM_MONITOR1 + */ +void EIM_CpuLockStepMonitorClr(const EIM_CPU_ChnType eEimCpuType, const EIM_MONType eMonitorType) +{ + uint32_t u32val = 0U; + + u32val = EIM_HWA_Get_CPULockstep((uint8_t)eEimCpuType); + + if(eMonitorType == EIM_MONITOR0) + { + u32val &= 0xFFFFFFF5;//clear mon0 clr + } + + if(eMonitorType == EIM_MONITOR1) + { + u32val &= 0xFFFFFFFA;//clear mon1 clr + } + + EIM_HWA_Set_CPULockstep((uint8_t)eEimCpuType, u32val); +} + +/** + * @brief Deinin EIM function + * + */ +void Eim_Deinit(void) +{ + uint8_t u8loop; + EIM_HWA_DisableGlobalErrorInjection(); + for (u8loop = 0U; u8loop < EIM_CTRL_REG_COUNT; u8loop++) + { + EIM_HWA_Set_CtrlRegn(u8loop, 0U); + } + + EIM_HWA_Set_CPULockstep(EIM_CPU0_LOCKSTEP, 0U); + EIM_HWA_Set_CPULockstep(EIM_DMA0_LOCKSTEP, 0U); + + for (u8loop = 0U; u8loop < EIM_BUS_REG_COUNT; u8loop++) + { + EIM_HWA_Set_BUSRegn(u8loop, 0U); + } +} + diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_erm.c b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_erm.c new file mode 100644 index 0000000..432356b --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_erm.c @@ -0,0 +1,175 @@ +/** + * @file fc7xxx_driver_erm.c + * @author Flagchip + * @brief FC7xxx ERM driver type definition and API + * @version 0.1.0 + * @date 2024-01-14 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + */ +/******************************************************************************** +* Revision History: +* +* Version Date Initials CR# Descriptions +* --------- ---------- ------------ ---------- --------------- +* 0.1.0 2024-01-14 qxw0100 N/A First version for FC7240 +********************************************************************************/ + +#include "fc7xxx_driver_erm.h" +#include "fc7xxx_driver_pcc.h" +#include "interrupt_manager.h" + +/* ############################## Local Variables ################################ */ +/** + * @brief Erm user defined interrupt function + * */ +static ERM_InterruptCallBackType s_pErmNotifyPtr = NULL; + +/* ################################################################################## */ +/* ########################### Global Prototype Functions ########################### */ + +void ERM_fault_IRQHandler(void); + +/* ################################################################################## */ +/* ################################ Local Functions ################################# */ +/** + * @brief Initialize ERM function + * + * @param pErmInt_cfg Initialization structure of ERM + * @return return 0: initialize successful. 1: invalid parameter + */ + +ERM_RetType Erm_Init(const ERM_MemorytInitType *pErmInt_cfg) +{ + ERM_RetType eRet = ERM_STATUS_SUCCESS; + uint32_t u32ErmCrVal = 0U; + ERM_ClearSRnRegister(); + + if (NULL == pErmInt_cfg) + { + eRet = ERM_STATUS_PARAM_INVALID; + } + else + { + if(pErmInt_cfg->u8ErmEnable != 0U) + { + if ((uint32_t)pErmInt_cfg->eChannel < 8U) + { + u32ErmCrVal |= (uint32_t)((uint32_t)pErmInt_cfg->eInt << (30UL - (uint32)pErmInt_cfg->eChannel*4U)); + ERM_HWA_Set_CRn(0, u32ErmCrVal); + } + else if (((uint32_t)pErmInt_cfg->eChannel >= 8U) && ((uint32_t)pErmInt_cfg->eChannel < 16U)) + { + u32ErmCrVal |= (uint32_t)((uint32_t)pErmInt_cfg->eInt << (62UL - (uint32)pErmInt_cfg->eChannel*4U)); + ERM_HWA_Set_CRn(1, u32ErmCrVal); + } + else if (((uint32_t)pErmInt_cfg->eChannel >= 16U) && ((uint32_t)pErmInt_cfg->eChannel < 24U)) + { + u32ErmCrVal |= (uint32_t)((uint32_t)pErmInt_cfg->eInt << (94UL - (uint32)pErmInt_cfg->eChannel*4U)); + ERM_HWA_Set_CRn(2, u32ErmCrVal); + } + else if (((uint32_t)pErmInt_cfg->eChannel >= 24U) && ((uint32_t)pErmInt_cfg->eChannel < 32U)) + { + u32ErmCrVal |= (uint32_t)((uint32_t)pErmInt_cfg->eInt << (126UL - (uint32)pErmInt_cfg->eChannel*4U)); + ERM_HWA_Set_CRn(3, u32ErmCrVal); + } + else + { + eRet = ERM_STATUS_PARAM_INVALID; + } + if(eRet == ERM_STATUS_SUCCESS) + { + s_pErmNotifyPtr = pErmInt_cfg->pIsrNotify; + } + } + + } + return eRet; +} +/** + * @brief De-initialize ERM function + * Restore the ERM instance to its reset state + */ +void Erm_DeInit(void) +{ + uint8_t u8loop; + for (u8loop = 0U; u8loop < 4U; u8loop++) + { + ERM_HWA_Set_CRn(u8loop, 0x0U); + ERM_HWA_Set_SRn(u8loop, 0x0U); + } +} +/** + * @brief ERM Clear SR0 register. + * + * This function Clear ERM SR0 register. + */ +void ERM_ClearSRnRegister(void) +{ + uint8_t u8loop; + for (u8loop = 0U; u8loop < 4U; u8loop++) + { + ERM_HWA_Set_SRn(u8loop, ERM_SR_MASK); + } +} + +/** + * @brief ERM read SRn register. + * + * This function Clear ERM SRn register. + * @param u8Index the SRn channel + */ +uint32_t ERM_ReadSRnVal(uint8_t u8Index) +{ + uint32_t u32Val; + u32Val = ERM_HWA_Get_SRn(u8Index); + return u32Val; +} +/** + * @brief ERM clear CRn register. + * + * This function Clear ERM CRn register. + * @param u8Index of the CRn channel + */ +void ERM_ClearCRnVal(uint8_t u8Index) +{ + ERM_HWA_Set_CRn(u8Index, 0UL); +} + +/** + * @brief ERM clear SRn register. + * + * This function Clear ERM SR0 register. + * @param u8Index the SRn channel + */ +uint32_t ERM_ClearSRnVal(uint8_t u8Index) +{ + uint32_t u32Val; + u32Val = ERM_HWA_Get_SRn(u8Index); + ERM_HWA_Set_SRn(u8Index, u32Val); + return u32Val; +} +/** + * @brief ERM interrupt function + */ +void ERM_fault_IRQHandler(void) +{ + if(s_pErmNotifyPtr != NULL) + { + s_pErmNotifyPtr(); + } +} +/** + * @brief ERM Read EARn address. + * @param eChannel The channel type + * @return u32Address The error address + */ +/* +uint32_t ERM_ReadAddress(ERM_channelType eChannel) +{ + uint32_t u32Address = 0U; + u32Address = ERM_HWA_GetEARn(eChannel); + return u32Address; +}*/ + diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_fciic.c b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_fciic.c new file mode 100644 index 0000000..d56136f --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_fciic.c @@ -0,0 +1,817 @@ +/** + * @file fc7xxx_driver_fciic.c + * @author Flagchip + * @brief FC7xxx FCIIC driver type definition and API + * @version 0.1.0 + * @date 2022-12-31 + * + * @copyright Copyright (c) 2023 Flagchip Semiconductors Co., Ltd. + * + */ + +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024/1/10 qxw0095 N/A First version for FC7240 + ******************************************************************************** */ + +#include "fc7xxx_driver_fciic.h" +#include "interrupt_manager.h" + +#include "stdarg.h" +#include "stdio.h" +#include "string.h" +#include "stdlib.h" + +/* #define FCIIC_RX_FIFO */ + + +/* iic instance value */ +static FCIIC_Type *const s_aFCIIC_InstanceTable[FCIIC_INSTANCE_COUNT] = FCIIC_BASE_PTRS; + +/* store notify callback function point */ +static FCIIC_ErrorInterrupt_CallBackType s_aFCIIC_ErrorNotifyTable[FCIIC_INSTANCE_COUNT] = {NULL}; +static FCIIC_RxInterrupt_CallBackType s_aFCIIC_RxNotifyTable[FCIIC_INSTANCE_COUNT] = {NULL}; + +#ifdef FCIIC_RX_ALL_POLLING + /* check every pFciic instance whether is used */ + static uint8_t s_aFCIIC_IicMasterUsed[FCIIC_INSTANCE_COUNT]; + static uint8_t s_aFCIIC_IicSlaveUsed[FCIIC_INSTANCE_COUNT]; +#endif + + +/* ################################################################################## */ +/* ########################### Local Prototype Functions ############################ */ +#if 0 +static void CheckAndClear(FCIIC_Type *pFciic); +#endif +static void FCIIC_LL_MasterIRQnHandler(uint8_t u8IicIndex); +static void FCIIC_LL_SlaveIRQnHandler(uint8_t u8IicIndex); +static uint8_t FCIIC_Init_Master(uint8_t u8IicIndex, FCIIC_InitType *pInitCfg); +static uint8_t FCIIC_Init_Slave(uint8_t u8IicIndex, FCIIC_InitType *pInitCfg); + + +/* ################################################################################## */ +/* ########################### Global Prototype Functions ########################### */ + +void FCIIC0_IRQHandler(void); +void FCIIC1_IRQHandler(void); + +/* ################################################################################## */ +/* ################################ Local Functions ################################# */ + + +#if 0 +static void CheckAndClear(FCIIC_Type *pFciic) +{ + FCIIC_Master_HwA_CheckClearStatus(pFciic, FCIIC_MSR_EPF_STATUS); + FCIIC_Master_HwA_CheckClearStatus(pFciic, FCIIC_MSR_SDF_STATUS); + FCIIC_Master_HwA_CheckClearStatus(pFciic, FCIIC_MSR_NDF_STATUS); + FCIIC_Master_HwA_CheckClearStatus(pFciic, FCIIC_MSR_FEF_STATUS); + FCIIC_Master_HwA_CheckClearStatus(pFciic, FCIIC_MSR_ALF_STATUS); +} +#endif + + + +/*************************************************** + * FCIIC_LL_MasterIRQnHandler + * @detail: Iic n interrupt process + * + * param in : u8IicIndex, 0,1,2,3 + * param out: none + * + * return : none + * ************************************************/ +static void FCIIC_LL_MasterIRQnHandler(uint8_t u8IicIndex) +{ + /* uint8_t iic_status; */ + uint8_t u8RetVal; + FCIIC_RxDataType pRxData; + uint32_t u32ErrorValue; + + /* check pFciic receive data */ + u8RetVal = FCIIC_Master_Receive(u8IicIndex, &pRxData); + + if ((s_aFCIIC_RxNotifyTable[u8IicIndex] != NULL) && (u8RetVal == 0U)) + { + s_aFCIIC_RxNotifyTable[u8IicIndex](u8IicIndex, &pRxData); + } + + /* check error */ + u32ErrorValue = FCIIC_Master_GetError(u8IicIndex); + if ((u32ErrorValue != 0U) && (s_aFCIIC_ErrorNotifyTable[u8IicIndex] != NULL)) + { + s_aFCIIC_ErrorNotifyTable[u8IicIndex](u8IicIndex, 1U, u32ErrorValue); + FCIIC_Master_ClrError(u8IicIndex); + } + +} + + +/*************************************************** + * FCIIC_LL_SlaveIRQnHandler + * @detail: Iic n interrupt process + * + * param in : u8IicIndex, 0,1,2,3 + * param out: none + * + * return : none + * ************************************************/ +static void FCIIC_LL_SlaveIRQnHandler(uint8_t u8IicIndex) +{ + /* uint8_t iic_status; */ + uint8_t u8RetVal; + FCIIC_RxDataType pRxData; + uint32_t u32ErrorValue; + + /* check pFciic receive data */ + u8RetVal = FCIIC_Slave_Receive(u8IicIndex, &pRxData); + + if ((s_aFCIIC_RxNotifyTable[u8IicIndex] != NULL) && (u8RetVal == 0U)) + { + s_aFCIIC_RxNotifyTable[u8IicIndex](u8IicIndex, &pRxData); + } + + /* check error */ + u32ErrorValue = FCIIC_Slave_GetError(u8IicIndex); + if ((u32ErrorValue != 0U) && (s_aFCIIC_ErrorNotifyTable[u8IicIndex] != NULL)) + { + s_aFCIIC_ErrorNotifyTable[u8IicIndex](u8IicIndex, 0U, u32ErrorValue); + FCIIC_Slave_ClrError(u8IicIndex); + } + +} + + + + + +/*************************************************** + * FCIIC_Init_Master + * @detail: Iic device master mode initial + * + * param in : pInitCfg, pFciic initial config parameters + * structure address + * param out: none + * + * return : 0 is ok, others are not ok + * ************************************************/ +static uint8_t FCIIC_Init_Master(uint8_t u8IicIndex, FCIIC_InitType *pInitCfg) +{ + uint32_t u32TempMcr, u32TempMder, u32TempMcfgr0, u32TempMcfgr1, u32TempMcfgr2, u32TempMcfgr3, u32TempMccr0; + uint32_t u32TempMFCR; + + FCIIC_Type *pFciic; + uint32_t u32ClkSrcHz; + uint32_t u32FreqDeltaCur, u32FreqDeltaOld; + uint32_t u32FreqDesired, u32FreqCur; + uint32_t u32Prescale, u8PrescaleTemp; + uint32_t u32CLKHI, u32CLKHITemp; + uint32_t u32CLKLO, u32CLKLOTemp; + + pFciic = (FCIIC_Type *)s_aFCIIC_InstanceTable[u8IicIndex]; + + u32ClkSrcHz = pInitCfg->u32ClkSrcHz; + u32FreqDesired = pInitCfg->u32Frequency; + u32FreqDeltaOld = u32FreqDesired; + + /* SCL_LATENCY is defined as ROUNDDOWN ((2 + FILTSCL + SCL_RISETIME) / (2 ^ PRESCALE)) */ + /* CLKLO: Minimum value is 0x3 */ + /* CLKHI: Minimum value is 0x1 */ + /* SCL clock period: (CLKHI + CLKLO + 2 + SCL_LATENCY) �� (2 ^ PRESCALE) �� function clock period */ + for(u32CLKHITemp=1U; (u32CLKHITemp < 63U); u32CLKHITemp++) + { + for(u32CLKLOTemp=3U; (u32CLKLOTemp < 63U); u32CLKLOTemp++) + { + /* get the linear prescale */ + for (u8PrescaleTemp = 0U; u8PrescaleTemp < 8U; u8PrescaleTemp++) + { + u32FreqCur = u32ClkSrcHz / Fc_Power(2U, (uint32_t)u8PrescaleTemp)/(u32CLKHITemp+u32CLKLOTemp+2U); + /* If the current frequency is less than the desired frequency, + * compare the delta with the previous one and select the parameter with the smallest delta + * */ + if(u32FreqCur <= u32FreqDesired) + { + u32FreqDeltaCur = u32FreqDesired - u32FreqCur; + if (u32FreqDeltaCur < u32FreqDeltaOld) + { + u32FreqDeltaOld = u32FreqDeltaCur; + u32Prescale = u8PrescaleTemp; + u32CLKHI = u32CLKHITemp; + u32CLKLO = u32CLKLOTemp; + } + break; + } + } + + if(u32FreqDeltaOld == 0U) + { + break; + } + } + + if(u32FreqDeltaOld==0U) + { + break; + } + } + + u32TempMcr = FCIIC_MCR_RRF(0U) | + FCIIC_MCR_RTF(0U) | + FCIIC_MCR_DBGEN(0U) | + FCIIC_MCR_RST(0U) | + FCIIC_MCR_MEN(1U); /* master enable */ + + + u32TempMder = FCIIC_MDER_RDDE(pInitCfg->bEnDma) | /* enable receive dma */ + FCIIC_MDER_TDDE(pInitCfg->bEnDma); /* enable transmit dma */ + + u32TempMcfgr0 = FCIIC_MCFGR0_RDMO(0U) | + FCIIC_MCFGR0_TRGEN(0U); + + u32TempMcfgr1 = FCIIC_MCFGR1_PINCFG(0U) | /* 0=open drain; 1=push-pull mode */ + FCIIC_MCFGR1_MATCFG(0U) | + FCIIC_MCFGR1_TIMECFG(0U) | + FCIIC_MCFGR1_IGNACK(1U) | + FCIIC_MCFGR1_AUTOSTOP(0U) | + FCIIC_MCFGR1_PRESCALE(u32Prescale); /* Prescaler = 2^n */ + + u32TempMcfgr2 = FCIIC_MCFGR2_FILTSDA(0U) | + FCIIC_MCFGR2_FILTSCL(0U) | + FCIIC_MCFGR2_BUSIDLE(0U); + + u32TempMcfgr3 = FCIIC_MCFGR3_PINLOW(0U); + + + u32TempMccr0 = FCIIC_MCCR_DATAVD(0x09U) | + FCIIC_MCCR_SETHOLD(0x13U) | + FCIIC_MCCR_CLKHI(u32CLKHI) | + FCIIC_MCCR_CLKLO(u32CLKLO); /* 0x09131327; */ + + u32TempMFCR = FCIIC_MFCR_TXWATER(pInitCfg->bTxFifoWMrk) | FCIIC_MFCR_RXWATER(pInitCfg->bRxFifoWMrk); + + FCIIC_HWA_SetMder(pFciic, u32TempMder); + FCIIC_HWA_SetMCFGR0(pFciic, u32TempMcfgr0); + FCIIC_HWA_SetMCFGR1(pFciic, u32TempMcfgr1); + FCIIC_HWA_SetMCFGR2(pFciic, u32TempMcfgr2); + FCIIC_HWA_SetMCFGR3(pFciic, u32TempMcfgr3); + FCIIC_HWA_SetMCCR(pFciic, u32TempMccr0); + FCIIC_HWA_SetMFCR(pFciic, u32TempMFCR); + + FCIIC_HWA_SetMcr(pFciic, u32TempMcr); /* | FCIIC_MCR_RRF_MASK | FCIIC_MCR_RTF_MASK | FCIIC_MCR_DBGEN_MASK | FCIIC_MCR_RST_MASK; */ + + #ifdef FCIIC_INIT_WAITRESET + u8RetVal = 1; + + while (u8RetVal) + { + u8RetVal = (pFciic->MCR & FCIIC_MCR_RST_MASK) >> FCIIC_MCR_RST_SHIFT; + pFciic->MCR = u32TempMcr; + } + #endif + return 0U; +} + + + +/*************************************************** + * FCIIC_DeInit_Master + * @detail: Iic device master mode de-initial + * + * param in : u8IicIndex + * param out: none + * + * return : 0 is ok, others are not ok + * ************************************************/ +static uint8_t FCIIC_DeInit_Master(uint8_t u8IicIndex) +{ + uint32_t u32TempMcr, u32TempMder; + + FCIIC_Type *pFciic; + pFciic = (FCIIC_Type *)s_aFCIIC_InstanceTable[u8IicIndex]; + + + u32TempMcr = FCIIC_MCR_RRF(0U) | + FCIIC_MCR_RTF(0U) | + FCIIC_MCR_DBGEN(0U) | + FCIIC_MCR_RST(0U) | + FCIIC_MCR_MEN(0U); /* master enable */ + + + u32TempMder = FCIIC_MDER_RDDE(0U) | /* disable receive dma */ + FCIIC_MDER_TDDE(0U); /* disable transmit dma */ + + + + + FCIIC_HWA_SetMder(pFciic, u32TempMder); + + FCIIC_HWA_SetMcr(pFciic, u32TempMcr); /* | FCIIC_MCR_RRF_MASK | FCIIC_MCR_RTF_MASK | FCIIC_MCR_DBGEN_MASK | FCIIC_MCR_RST_MASK; */ + + + return 0U; +} + + + +/*************************************************** + * FCIIC_Init_Slave + * @detail: Iic device master mode initial + * + * param in : u8IicIndex + * param out: none + * + * return : 0 is ok, others are not ok + * ************************************************/ +static uint8_t FCIIC_Init_Slave(uint8_t u8IicIndex, FCIIC_InitType *pInitCfg) +{ + uint32_t u32TempScr, u32TempSder, u32TempScfgr1, u32TempScfgr2, u32TempSamr; + + FCIIC_Type *pFciic; + + pFciic = (FCIIC_Type *)s_aFCIIC_InstanceTable[u8IicIndex]; + + + u32TempScr = FCIIC_SCR_FILTEN(0U) | + FCIIC_SCR_RST(0U) | + FCIIC_SCR_SEN(1U); /* slave enable */ + + + u32TempSder = FCIIC_SDER_AVDE(pInitCfg->bEnDma) | + FCIIC_SDER_RDDE(pInitCfg->bEnDma) | /* enable receive dma */ + FCIIC_SDER_TDDE(pInitCfg->bEnDma); /* enable transmit dma */ + + + + u32TempScfgr1 = FCIIC_SCFGR1_ADDRCFG(0U) | /* Address Configuration, 7bit */ + FCIIC_SCFGR1_HSMEN(0U) | + FCIIC_SCFGR1_IGNACK(1U) | + FCIIC_SCFGR1_RXCFG(0U) | + FCIIC_SCFGR1_TXCFG(0U) | + FCIIC_SCFGR1_SAEN(0U) | + FCIIC_SCFGR1_GCEN(0U) | + FCIIC_SCFGR1_ACKSTALL(0U) | + FCIIC_SCFGR1_TXDSTALL(0U) | + FCIIC_SCFGR1_RXSTALL(0U) | + FCIIC_SCFGR1_ADRSTALL(0U); + + u32TempScfgr2 = FCIIC_SCFGR2_FILTSDA(0U) | + FCIIC_SCFGR2_FILTSCL(0U) | + FCIIC_SCFGR2_DATAVD(0x09U) | + FCIIC_SCFGR2_CLKHOLD(1U); + + + + + u32TempSamr = FCIIC_SAMR_ADDR1(0U) | + FCIIC_SAMR_ADDR0(pInitCfg->u8SlaveAddr); + + + + FCIIC_HWA_SetSDER(pFciic, u32TempSder); + FCIIC_HWA_SetSCFGR1(pFciic, u32TempScfgr1); + FCIIC_HWA_SetSCFGR2(pFciic, u32TempScfgr2); + FCIIC_HWA_SetSAMR(pFciic, u32TempSamr); + + + FCIIC_HWA_SetSCR(pFciic, u32TempScr); + + return 0U; +} + + +/*************************************************** + * FCIIC_DeInit_Slave + * @detail: Iic device master mode de-initial + * + * param in : pInitCfg, pFciic initial config parameters + * structure address + * param out: none + * + * return : 0 is ok, others are not ok + * ************************************************/ +static uint8_t FCIIC_DeInit_Slave(uint8_t u8IicIndex) +{ + uint32_t u32TempScr, u32TempSder; + + FCIIC_Type *pFciic; + + pFciic = (FCIIC_Type *)s_aFCIIC_InstanceTable[u8IicIndex]; + + u32TempScr = FCIIC_SCR_FILTEN(0U) | + FCIIC_SCR_RST(0U) | + FCIIC_SCR_SEN(0U); /* slave enable */ + + + u32TempSder = FCIIC_SDER_AVDE(0U) | + FCIIC_SDER_RDDE(0U) | /* disable receive dma */ + FCIIC_SDER_TDDE(0U); /* disable transmit dma */ + + FCIIC_HWA_SetSDER(pFciic, u32TempSder); + + + FCIIC_HWA_SetSCR(pFciic, u32TempScr); + + return 0U; + +} + + +/* ################################################################################## */ +/* ################################ Global Functions ################################ */ + + + +/** + * \brief This Function is used to initial IIC instance + * + * \param u8IicIndex Iic Index, 0,1 + * \param pInitCfg is the structure address of IIC initial configuration parameters, and it contains IIC instance + * \return 0 is ok, others are not ok + */ +uint8_t FCIIC_Init(uint8_t u8IicIndex, FCIIC_InitType *pInitCfg) +{ + /* master mode */ + if (pInitCfg->bMasterMode != 0U) + { + FCIIC_Init_Master(u8IicIndex, pInitCfg); + #ifdef FCIIC_RX_ALL_POLLING + s_aFCIIC_IicMasterUsed[u8IicIndex] = 1U; + s_aFCIIC_IicSlaveUsed[u8IicIndex] = 0U; + #endif + } + else /* slave mode */ + { + FCIIC_Init_Slave(u8IicIndex, pInitCfg); + #ifdef FCIIC_RX_ALL_POLLING + s_aFCIIC_IicMasterUsed[u8IicIndex] = 0U; + s_aFCIIC_IicSlaveUsed[u8IicIndex] = 1U; + #endif + } + #if (defined(__ICCARM__)) + u8IicIndex = u8IicIndex; + #elif defined __GNUC__ + (void)u8IicIndex; + #endif + + return 0U; +} + + +/** + * \brief This Function is used to de-initial IIC instance + * + * \param u8IicIndex Iic Index, 0,1 + * \param pInitCfg is the structure address of IIC initial configuration parameters, bMaster should be set + * \return 0 is ok, others are not ok + */ +uint8_t FCIIC_DeInit(uint8_t u8IicIndex, FCIIC_InitType *pInitCfg) +{ + + /* master mode */ + if (pInitCfg->bMasterMode != 0U) + { + FCIIC_DeInit_Master(u8IicIndex); + #ifdef FCIIC_RX_ALL_POLLING + s_aFCIIC_IicMasterUsed[u8IicIndex] = 0U; + s_aFCIIC_IicSlaveUsed[u8IicIndex] = 0U; + #endif + } + else /* slave mode */ + { + FCIIC_DeInit_Slave(u8IicIndex); + #ifdef FCIIC_RX_ALL_POLLING + s_aFCIIC_IicMasterUsed[u8IicIndex] = 0U; + s_aFCIIC_IicSlaveUsed[u8IicIndex] = 0U; + #endif + } + + + #if (defined(__ICCARM__)) + u8IicIndex = u8IicIndex; + #elif defined __GNUC__ + (void)u8IicIndex; + #endif + + return 0U; +} + + +/** + * \brief This Function is used to configure IIC master interrupt + * + * \param u8IicIndex Iic Index, 0,1 + * \param pIntCfg contains IIC instance and interrupt callback functions + * \return 0 is ok, others are not ok + */ +uint8_t FCIIC_Master_SetInterrupt(uint8_t u8IicIndex, FCIIC_InterruptType *pIntCfg) +{ + FCIIC_Type *pFciic; + + pFciic = (FCIIC_Type *)s_aFCIIC_InstanceTable[u8IicIndex]; + + if ((pIntCfg->bEnErrorInterrupt != 0U) || (pIntCfg->bEnRxInterrupt != 0U)) + { + /* enable global interrupt for pFciic */ + IntMgr_EnableInterrupt((IRQn_Type)((uint8_t)((uint8_t)FCIIC0_IRQn + u8IicIndex))); + /* IntMag_ReplaceHandler(FCIIC0_IRQn+u8IicIndex,u8IicIndex==0?FCIIC0_IRQHandler:FCIIC1_IRQHandler); */ + } + + if (pIntCfg->bEnErrorInterrupt != 0U) + { + FCIIC_Master_HWA_EnableErrorInterrupt(pFciic); + s_aFCIIC_ErrorNotifyTable[u8IicIndex] = pIntCfg->pErrorNotify; + } + + if (pIntCfg->bEnRxInterrupt != 0U) + { + /* pFciic->MIER |= FCIIC_MIER_RDIE_MASK; */ + FCIIC_Master_HWA_EnableReceiveInterrupt(pFciic); + s_aFCIIC_RxNotifyTable[u8IicIndex] = pIntCfg->pRxNotify; + } + + return 0U; +} + + + + +/** + * \brief This Function is used to transmit data in master mode + * + * \param u8IicIndex Iic Index, 0,1 + * \param pTxData contains IIC instance and buffer address + * \return 0 is ok, others are not ok + */ +uint8_t FCIIC_Master_Transmit(uint8_t u8IicIndex, FCIIC_TxDataType *pTxData) +{ + uint8_t u8RetVal; + FCIIC_Type *pFciic; + + pFciic = (FCIIC_Type *)s_aFCIIC_InstanceTable[u8IicIndex]; + + /* clear error flag */ + /* CheckAndClear(pFciic); */ + + /* check tx data flag */ + u8RetVal = FCIIC_Master_HWA_GetStatus(pFciic, FCIIC_MSR_TDF_STATUS); + + /* pFciic->MSR |= FCIIC_MSR_FEF_MASK; */ /* clear fifo error error */ + if (u8RetVal == 1U) + { + FCIIC_Master_HWA_Transmit(pFciic, pTxData->eCmd, pTxData->u8Data); + } + + return (uint8_t)(1U >> u8RetVal); +} + + + +/** + * \brief This Function is used to get master status + * + * \param u8IicIndex is IIC instance + * \param eStatus is status type enumeration + * \return 0 is ok, others are not ok + */ +uint8_t FCIIC_Master_GetStatus(uint8_t u8IicIndex, FCIIC_MasterStatusType eStatus) +{ + FCIIC_Type *pFciic = (FCIIC_Type *)s_aFCIIC_InstanceTable[u8IicIndex]; + return (uint8_t)(1U >> FCIIC_Master_HWA_GetStatus(pFciic, eStatus)); +} + + +/** + * \brief This Function is used to receive data when polling (not used when rx interrupt enabled) in master mode + * + * \param u8IicIndex Iic Index, 0,1 + * \param pRxData contains IIC instance + * \return 0 is ok, others are not ok + */ +uint8_t FCIIC_Master_Receive(uint8_t u8IicIndex, FCIIC_RxDataType *pRxData) +{ + FCIIC_Type *pFciic; + uint8_t u8RetVal; + + pFciic = (FCIIC_Type *)s_aFCIIC_InstanceTable[u8IicIndex]; + + /* CheckAndClear(pFciic); */ + + + /* check receive flag */ + u8RetVal = FCIIC_Master_HWA_GetStatus(pFciic, FCIIC_MSR_RDF_STATUS); + + /* u8RetVal = (pFciic->MRDR & FCIIC_MRDR_RXEMPTY_MASK)>>FCIIC_MRDR_RXEMPTY_SHIFT; */ + + if (u8RetVal == 1U) + { + /* copy data */ + pRxData->u8Data = FCIIC_Master_HWA_Receive(pFciic); + } + + return (uint8_t)(1U >> u8RetVal); +} + +/** + * \brief This Function is used to get master error value + * + * \param u8IicIndex Iic Index, 0,1 + * \return error value + */ +uint32_t FCIIC_Master_GetError(uint8_t u8IicIndex) +{ + FCIIC_Type *pFciic; + uint32_t u32RetVal; + + pFciic = (FCIIC_Type *)s_aFCIIC_InstanceTable[u8IicIndex]; + + /* check receive flag */ + u32RetVal = FCIIC_Master_HWA_GetErrorFlag(pFciic); + + return u32RetVal; +} + +/** + * \brief This Function is used to clear master error value + * + * \param u8IicIndex Iic Index, 0,1 + */ +void FCIIC_Master_ClrError(uint8_t u8IicIndex) +{ + FCIIC_Type *pFciic; + + pFciic = (FCIIC_Type *)s_aFCIIC_InstanceTable[u8IicIndex]; + + /* clear receive flag */ + FCIIC_Master_HWA_ClrErrorFlag(pFciic); + +} + +/** + * \brief This Function is used to configure IIC slave interrupt + * + * \param u8IicIndex Iic Index, 0,1 + * \param pIntCfg contains IIC instance and interrupt callback functions + * \return 0 is ok, others are not ok + */ +uint8_t FCIIC_Slave_SetInterrupt(uint8_t u8IicIndex, FCIIC_InterruptType *pIntCfg) +{ + FCIIC_Type *pFciic; + + pFciic = (FCIIC_Type *)s_aFCIIC_InstanceTable[u8IicIndex]; + + if ((pIntCfg->bEnErrorInterrupt != 0U) || (pIntCfg->bEnRxInterrupt != 0U)) + { + /* enable global interrupt for pFciic */ + IntMgr_EnableInterrupt((IRQn_Type)((uint8_t)((uint8_t)FCIIC0_IRQn + u8IicIndex))); + /* IntMag_ReplaceHandler(FCIIC0_IRQn+u8IicIndex,u8IicIndex==0?FCIIC0_IRQHandler:FCIIC1_IRQHandler); */ + } + + + if (pIntCfg->bEnErrorInterrupt != 0U) + { + FCIIC_Slave_HWA_EnableErrorInterrupt(pFciic); + s_aFCIIC_ErrorNotifyTable[u8IicIndex] = pIntCfg->pErrorNotify; + } + + if (pIntCfg->bEnRxInterrupt != 0U) + { + FCIIC_Slave_HWA_EnableReceiveInterrupt(pFciic); + + s_aFCIIC_RxNotifyTable[u8IicIndex] = pIntCfg->pRxNotify; + } + + return 0U; +} + + +/** + * \brief This Function is used to transmit data in slave mode + * + * \param u8IicIndex Iic Index, 0,1 + * \param pTxData contains IIC instance and buffer address + * \return 0 is ok, others are not ok + */ +uint8_t FCIIC_Slave_Transmit(uint8_t u8IicIndex, FCIIC_TxDataType *pTxData) +{ + #ifdef FCIIC_TX_CHECK + uint8_t u8RetVal; + uint32_t u32TryTick; + uint32_t u32TryCount; + #endif + FCIIC_Type *pFciic; + + pFciic = (FCIIC_Type *)s_aFCIIC_InstanceTable[u8IicIndex]; + + #ifdef FCIIC_TX_CHECK + /* u8RetVal = (pFciic->SSR & FCIIC_SSR_TDF_MASK)>> FCIIC_SSR_TDF_SHIFT; */ + + /* pFciic->SSR |= FCIIC_SSR_TREF_MASK; */ /* clear receive & transmit error error */ + /* if(u8RetVal) */ + { + #endif + FCIIC_Slave_HWA_Transmit(pFciic, pTxData->u8Data); + #ifdef FCIIC_TX_CHECK + /* after transmit completed, close TE */ + /* u8RetVal = 0; */ + /* u32TryCount = 0; */ + /* while(u8RetVal==0 && u32TryCount++<100) */ + /* { */ + /* u8RetVal = (pFciic->SSR & FCIIC_SSR_TDF_MASK)>> FCIIC_SSR_TDF_SHIFT; */ + /* u32TryTick = 0; */ + /* while(u32TryTick++<100){} */ + + /* } */ + } + #endif + + return 0U; +} + + + +/** + * \brief This Function is used to receive data when polling (not used when rx interrupt enabled) in slave mode + * + * \param u8IicIndex Iic Index, 0,1 + * \param pRxData contains IIC instance and buffer address + * \return 0 is ok, others are not ok + */ +uint8_t FCIIC_Slave_Receive(uint8_t u8IicIndex, FCIIC_RxDataType *pRxData) +{ + FCIIC_Type *pFciic; + uint8_t u8RetVal; + + pFciic = (FCIIC_Type *)s_aFCIIC_InstanceTable[u8IicIndex]; + + + /* check slave receive flag */ + u8RetVal = FCIIC_Slave_HWA_GetStatus(pFciic, FCIIC_SSR_RDF_STATUS); + + /* u8RetVal = (pFciic->MRDR & FCIIC_MRDR_RXEMPTY_MASK)>>FCIIC_MRDR_RXEMPTY_SHIFT; */ + + if (u8RetVal != 0U) + { + /* get received data */ + pRxData->u8Data = FCIIC_Slave_HWA_Receive(pFciic); + } + + return (uint8_t)(1U >> u8RetVal); +} + + +/** + * \brief This Function is used to get slave error value + * + * \param u8IicIndex Iic Index, 0,1 + * \return error value + */ +uint32_t FCIIC_Slave_GetError(uint8_t u8IicIndex) +{ + FCIIC_Type *pFciic; + uint32_t u32RetVal; + + pFciic = (FCIIC_Type *)s_aFCIIC_InstanceTable[u8IicIndex]; + + /* check receive flag */ + u32RetVal = FCIIC_Slave_HWA_GetErrorFlag(pFciic); + + return u32RetVal; +} + +/** + * \brief This Function is used to clear slave error value + * + * \param u8IicIndex Iic Index, 0,1 + */ +void FCIIC_Slave_ClrError(uint8_t u8IicIndex) +{ + FCIIC_Type *pFciic; + + pFciic = (FCIIC_Type *)s_aFCIIC_InstanceTable[u8IicIndex]; + + /* clear receive flag */ + FCIIC_Slave_HWA_ClrErrorFlag(pFciic); +} + + +/* ################################################################################## */ +/* ############################## Interrupt Services ################################ */ + + +void FCIIC0_IRQHandler(void) +{ + FCIIC_LL_MasterIRQnHandler(0U); + FCIIC_LL_SlaveIRQnHandler(0U); +} + +void FCIIC1_IRQHandler(void) +{ + FCIIC_LL_MasterIRQnHandler(1U); + FCIIC_LL_SlaveIRQnHandler(1U); +} + + diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_fcpit.c b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_fcpit.c new file mode 100644 index 0000000..5c6bd51 --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_fcpit.c @@ -0,0 +1,524 @@ +/** + * @file fc7xxx_driver_fcpit.h + * @author Flagchip + * @brief FC7xxx FCPIT driver type definition and API + * @version 0.1.0 + * @date 2024-01-10 + * + * @copyright Copyright (c) 2023 Flagchip Semiconductors Co., Ltd. + * + * @details + */ +/******************************************************************************** +* Revision History: +* +* Version Date Initials CR# Descriptions +* --------- ---------- ------------ ---------- --------------- +* 0.1.0 2024-01-10 Flagchip0076 N/A First version for FC7240 +********************************************************************************/ +#include "fc7xxx_driver_fcpit.h" +#include "interrupt_manager.h" + + +/********* Local Variables ************/ +/** @brief FCPIT instance list */ +static FCPIT_Type *s_pFcpitInstanceTable[FCPIT_INSTANCE_COUNT] = FCPIT_BASE_PTRS; + +/** @brief Fcpit user defined interrupt function */ +static FCPIT_InterruptCallBackType s_aFcpitIntNotifyTab[FCPIT_INSTANCE_COUNT][MAX_FCPIT_CHANNEL_NUM] = {0}; + + + + +/** @brief Fcpit interrupt entry */ +void FCPIT0_IRQHandler(void); + +/** @brief Fcpit common interrupt handle function */ +static void Fcpit_CommonProcessInterrupt(const FCPIT_InstanceType eFcpit, const FCPIT_ChannelType eChannel); + + +/** + * @brief Initialize Fcpit instance. + * @param eFcpit instance + * @param pInitStruct Fcpit initialization structure + * @return Fcpit return type + */ +FCPIT_StatusType FCPIT_Init(const FCPIT_InstanceType eFcpit, const FCPIT_InitType *const pInitStruct) +{ + FCPIT_Type *pFcpit; + FCPIT_StatusType eRet = FCPIT_STATUS_SUCCESS; + + if ( ((uint32_t)eFcpit >= FCPIT_INSTANCE_COUNT) || (NULL == pInitStruct) ) + { + eRet = FCPIT_STATUS_PARAM_INVALID; + } + else + { + pFcpit = s_pFcpitInstanceTable[eFcpit]; + /*Enable module clock*/ + FCPIT_HWA_EnableModule(pFcpit); + if (pInitStruct->bDebugEn) + { + FCPIT_HWA_SetChannelRunOnDebug(pFcpit); + } + else + { + FCPIT_HWA_SetChannelStopOnDebug(pFcpit); + } + + if (pInitStruct->bLowPowerModeEn) + { + FCPIT_HWA_SetChannelRunOnLpm(pFcpit); + } + else + { + FCPIT_HWA_SetChannelStopOnLpm(pFcpit); + } + /* w1c , clear channel interrupt flag*/ + FCPIT_HWA_ClearChannelsInterruptFlag(pFcpit, (uint32_t)1U << (uint32_t)pInitStruct->eFcpitChannel); + + FCPIT_HWA_ConfigChannel(pFcpit, pInitStruct->eFcpitChannel, (uint32_t)0U); + FCPIT_HWA_ConfigChannelMode(pFcpit, pInitStruct->eFcpitChannel, pInitStruct->eMode); + + if (pInitStruct->bChainModeEn) + { + if (pInitStruct->eFcpitChannel > FCPIT_CHANNEL_0) + { + FCPIT_HWA_EnableChannelChainMode(pFcpit, pInitStruct->eFcpitChannel); + } + else + { + /* channel 0 is the first channel can not be chained to last channel */ + eRet = FCPIT_STATUS_PARAM_INVALID; + } + } + else + { + /*Chain mode is not enabled, no operation */ + } + + FCPIT_HWA_SetChannelValue(pFcpit, pInitStruct->eFcpitChannel, pInitStruct->u32TimerValue); + } + + return eRet; +} + +/** + * @brief Initialize Fcpit trigger configuration + * @param eFcpit instance + * @param pTrgStruct Fcpit trigger structure + * @return Fcpit return type + */ +FCPIT_StatusType FCPIT_InitTrigger(const FCPIT_InstanceType eFcpit, const FCPIT_TrggerType *const pTrgStruct) +{ + FCPIT_Type *pFcpit; + FCPIT_StatusType eRet = FCPIT_STATUS_SUCCESS; + + if ( ((uint32_t)eFcpit >= FCPIT_INSTANCE_COUNT) || (NULL == pTrgStruct) ) + { + eRet = FCPIT_STATUS_PARAM_INVALID; + } + else + { + pFcpit = s_pFcpitInstanceTable[eFcpit]; + if ( (uint32_t)0U == FCPIT_HWA_ReadModuleEnable(pFcpit) ) + { + eRet = FCPIT_STATUS_FUNCTION_ERROR; + } + else + { + if (pTrgStruct->bStartOnTrigger) + { + FCPIT_HWA_SetChannelStartOnTrig(pFcpit, pTrgStruct->eFcpitChannel); + } + else + { + FCPIT_HWA_ClearChannelStartOnTrig(pFcpit, pTrgStruct->eFcpitChannel); + } + + if (pTrgStruct->bStopOnInterrupt) + { + FCPIT_HWA_SetChannelStopOnInterrupt(pFcpit, pTrgStruct->eFcpitChannel); + } + else + { + FCPIT_HWA_ClearChannelStopOnInterrupt(pFcpit, pTrgStruct->eFcpitChannel); + } + + if (pTrgStruct->bReloadOnTrigger) + { + FCPIT_HWA_SetChannelReloadOnTrig(pFcpit, pTrgStruct->eFcpitChannel); + } + else + { + FCPIT_HWA_ClearChannelReloadOnTrig(pFcpit, pTrgStruct->eFcpitChannel); + } + + if (FCPIT_TRIGGER_EXTERNAL != pTrgStruct->eTriggerSel) + { + FCPIT_HWA_SetChannelTriggerSrc(pFcpit, pTrgStruct->eFcpitChannel); + FCPIT_HWA_SelectChannelTrigger(pFcpit, pTrgStruct->eFcpitChannel, (uint8_t)pTrgStruct->eTriggerSel); + } + else + { + FCPIT_HWA_ClearChannelTriggerSrc(pFcpit, pTrgStruct->eFcpitChannel); + FCPIT_HWA_SelectChannelTrigger(pFcpit, pTrgStruct->eFcpitChannel, (uint8_t)pTrgStruct->eFcpitChannel); + } + + } + + } + + return eRet; +} + +/** + * @brief De-initialize Fcpit instance. + * @param eFcpit instance + */ +FCPIT_StatusType FCPIT_Deinit(const FCPIT_InstanceType eFcpit) +{ + uint8_t u8Index; + FCPIT_Type *pFcpit; + FCPIT_StatusType eRet = FCPIT_STATUS_SUCCESS; + + if ((uint32_t)eFcpit >= FCPIT_INSTANCE_COUNT) + { + eRet = FCPIT_STATUS_PARAM_INVALID; + } + else + { + pFcpit = s_pFcpitInstanceTable[eFcpit]; + FCPIT_HWA_ConfigModule(pFcpit, (uint32_t)FCPIT_MCR_M_CEN_MASK); + FCPIT_HWA_ClearChannelsInterruptFlag(pFcpit, (uint32_t)(FCPIT_MSR_TIF3_MASK | FCPIT_MSR_TIF2_MASK | FCPIT_MSR_TIF1_MASK | + FCPIT_MSR_TIF0_MASK)); + FCPIT_HWA_DisableChannelsInterrupt(pFcpit, (uint32_t)0U); + for (u8Index = 0U; u8Index < MAX_FCPIT_CHANNEL_NUM; u8Index++) + { + FCPIT_HWA_ConfigChannel(pFcpit, (FCPIT_ChannelType)u8Index, (uint32_t)0U); + FCPIT_HWA_SetChannelValue(pFcpit, (FCPIT_ChannelType)u8Index, (uint32_t)0U); + s_aFcpitIntNotifyTab[eFcpit][u8Index] = NULL; + } + FCPIT_HWA_ConfigModule(pFcpit, (uint32_t)0U); + } + + return eRet; +} + +/** + * @brief Initialize Fcpit interrupt functionality + * @param eFcpit instance + * @param pIntStruct Fcpit interrupt structure + * @return Fcpit return type + * @note this function will stop timer + */ +FCPIT_StatusType FCPIT_InitInterrupt(const FCPIT_InstanceType eFcpit, const FCPIT_IntType *const pIntStruct) +{ + FCPIT_Type *pFcpit; + FCPIT_StatusType eRet = FCPIT_STATUS_SUCCESS; + + if ( ((uint8_t)eFcpit >= FCPIT_INSTANCE_COUNT) || (NULL == pIntStruct) ) + { + eRet = FCPIT_STATUS_PARAM_INVALID; + } + else + { + pFcpit = s_pFcpitInstanceTable[eFcpit]; + if ((uint32_t)0U == (uint32_t)FCPIT_HWA_ReadModuleEnable(pFcpit)) + { + eRet = FCPIT_STATUS_FUNCTION_ERROR; + } + else + { + FCPIT_HWA_DisableChannel(pFcpit, pIntStruct->eFcpitChannel); + /* w1c , clear channel interrupt flag*/ + FCPIT_HWA_ClearChannelsInterruptFlag(pFcpit, (uint32_t)1U << (uint32_t)pIntStruct->eFcpitChannel); + if (pIntStruct->bChannelIsrEn) + { + FCPIT_HWA_EnableChannelsInterrupt(pFcpit, (uint32_t)1U << (uint32_t)pIntStruct->eFcpitChannel); + s_aFcpitIntNotifyTab[eFcpit][pIntStruct->eFcpitChannel] = pIntStruct->pIsrNotify; + } + else + { + FCPIT_HWA_DisableChannelsInterrupt(pFcpit, (uint32_t)1U << (uint32_t)pIntStruct->eFcpitChannel); + s_aFcpitIntNotifyTab[eFcpit][pIntStruct->eFcpitChannel] = pIntStruct->pIsrNotify; + } + } + } + + return eRet; +} + +/** + * @brief Enable Fcpit interrupt + * @param eFcpit instance + * @param eChannel Fcpit channel + * @return Fcpit return type + */ +FCPIT_StatusType FCPIT_EnableInterrupt(const FCPIT_InstanceType eFcpit, const FCPIT_ChannelType eChannel) +{ + FCPIT_Type *pFcpit; + FCPIT_StatusType eRet = FCPIT_STATUS_SUCCESS; + + if ( ((uint32_t)eFcpit >= FCPIT_INSTANCE_COUNT) || ((uint32_t)eChannel >= MAX_FCPIT_CHANNEL_NUM)) + { + eRet = FCPIT_STATUS_PARAM_INVALID; + } + else + { + pFcpit = s_pFcpitInstanceTable[eFcpit]; + + if ((uint32_t)0U == (uint32_t)FCPIT_HWA_ReadModuleEnable(pFcpit)) + { + eRet = FCPIT_STATUS_FUNCTION_ERROR; + } + else + { + FCPIT_HWA_DisableChannel(pFcpit, eChannel); + /* w1c , clear channel interrupt flag*/ + FCPIT_HWA_ClearChannelsInterruptFlag(pFcpit, (uint32_t)1U << (uint32_t)eChannel); + FCPIT_HWA_EnableChannelsInterrupt(pFcpit, (uint32_t)1U << (uint32_t)eChannel); + FCPIT_HWA_EnableChannel(pFcpit, eChannel); + } + + } + + return eRet; +} + +/** + * @brief Disable Fcpit interrupt + * @param eFcpit instance + * @param eChannel Fcpit channel + * @return Fcpit return type + */ +FCPIT_StatusType FCPIT_DisableInterrupt(const FCPIT_InstanceType eFcpit, const FCPIT_ChannelType eChannel) +{ + FCPIT_Type *pFcpit; + FCPIT_StatusType eRet = FCPIT_STATUS_SUCCESS; + + if ( ((uint32_t)eFcpit >= FCPIT_INSTANCE_COUNT) || ((uint32_t)eChannel >= MAX_FCPIT_CHANNEL_NUM) ) + { + eRet = FCPIT_STATUS_PARAM_INVALID; + } + else + { + pFcpit = s_pFcpitInstanceTable[eFcpit]; + + if ((uint32_t)0U == (uint32_t)FCPIT_HWA_ReadModuleEnable(pFcpit)) + { + eRet = FCPIT_STATUS_FUNCTION_ERROR; + } + else + { + FCPIT_HWA_DisableChannel(pFcpit, eChannel); + /* w1c , clear channel interrupt flag*/ + FCPIT_HWA_ClearChannelsInterruptFlag(pFcpit, (uint32_t)1U << (uint32_t)eChannel); + FCPIT_HWA_DisableChannelsInterrupt(pFcpit, (uint32_t)1U << (uint32_t)eChannel); + FCPIT_HWA_EnableChannel(pFcpit, eChannel); + } + } + + return eRet; +} + +/** + * @brief Fcpit start timer + * @param eFcpit instance + * @param eChannel Fcpit channel + * @return Fcpit return type + */ +FCPIT_StatusType FCPIT_Start(const FCPIT_InstanceType eFcpit, const FCPIT_ChannelType eChannel) +{ + FCPIT_Type *pFcpit; + FCPIT_StatusType eRet = FCPIT_STATUS_SUCCESS; + if ( ((uint32_t)eFcpit >= FCPIT_INSTANCE_COUNT) || ((uint32_t)eChannel >= MAX_FCPIT_CHANNEL_NUM) ) + { + eRet = FCPIT_STATUS_PARAM_INVALID; + } + else + { + pFcpit = s_pFcpitInstanceTable[eFcpit]; + if ((uint32_t)0U == (uint32_t)FCPIT_HWA_ReadModuleEnable(pFcpit)) + { + eRet = FCPIT_STATUS_FUNCTION_ERROR; + } + + if (FCPIT_STATUS_SUCCESS == eRet) + { + FCPIT_HWA_EnableChannel(pFcpit, eChannel); + } + } + + return eRet; +} + +/** + * @brief Fcpit stop + * @param eFcpit instance + * @param eChannel Fcpit channel + * @return Fcpit return type + */ +FCPIT_StatusType FCPIT_Stop(const FCPIT_InstanceType eFcpit, const FCPIT_ChannelType eChannel) +{ + FCPIT_Type *pFcpit; + FCPIT_StatusType eRet = FCPIT_STATUS_SUCCESS; + + if ( ((uint32_t)eFcpit >= FCPIT_INSTANCE_COUNT) || ((uint32_t)eChannel >= MAX_FCPIT_CHANNEL_NUM) ) + { + eRet = FCPIT_STATUS_PARAM_INVALID; + } + else + { + pFcpit = s_pFcpitInstanceTable[eFcpit]; + if ((uint32_t)0U == (uint32_t)FCPIT_HWA_ReadModuleEnable(pFcpit)) + { + eRet = FCPIT_STATUS_FUNCTION_ERROR; + } + else + { + FCPIT_HWA_DisableChannel(pFcpit, eChannel); + } + } + + return eRet; +} + +/** + * @brief Immediately update Fcpit channel value + * @param eFcpit instance + * @param eChannel Fcpit channel + * @param u32ChannelValue in/Out value + * @return Fcpit return type + */ +FCPIT_StatusType FCPIT_ImmediateUpdateChannelValue(const FCPIT_InstanceType eFcpit, const FCPIT_ChannelType eChannel, const uint32_t u32ChannelValue) +{ + FCPIT_Type *pFcpit; + FCPIT_StatusType eRet; + + pFcpit = s_pFcpitInstanceTable[eFcpit]; + + eRet = FCPIT_Stop(eFcpit, eChannel); + + if (FCPIT_STATUS_SUCCESS == eRet) + { + FCPIT_HWA_SetChannelValue(pFcpit, eChannel, u32ChannelValue); + eRet = FCPIT_Start(eFcpit, eChannel); + } + else + { + return eRet; + } + + return eRet; +} + +/** + * @brief Update Fcpit channel value + * @param eFcpit instance + * @param eChannel Fcpit channel + * @param u32ChannelValue in/Out value + * @return Fcpit return type + */ +FCPIT_StatusType FCPIT_UpdateChannelValue(const FCPIT_InstanceType eFcpit, const FCPIT_ChannelType eChannel, const uint32_t u32ChannelValue) +{ + FCPIT_Type *pFcpit; + FCPIT_StatusType eRet = FCPIT_STATUS_SUCCESS; + + if ( ((uint32_t)eFcpit >= FCPIT_INSTANCE_COUNT) || ((uint32_t)eChannel >= MAX_FCPIT_CHANNEL_NUM) ) + { + eRet = FCPIT_STATUS_PARAM_INVALID; + } + else + { + pFcpit = s_pFcpitInstanceTable[eFcpit]; + if ((uint32_t)0U == (uint32_t)FCPIT_HWA_ReadModuleEnable(pFcpit)) + { + eRet = FCPIT_STATUS_FUNCTION_ERROR; + } + + if (FCPIT_STATUS_SUCCESS == eRet) + { + FCPIT_HWA_SetChannelValue(pFcpit, eChannel, u32ChannelValue); + } + } + + return eRet; +} + +/** + * @brief read Fcpit channel time stamps. + * #param eFcpit Fcpit instance + * @param eChannel Fcpit channel + * @param *u32timeStampValue value + * @return Fcpit return type + */ + +FCPIT_StatusType FCPIT_ReadTimstamp(const FCPIT_InstanceType eFcpit, const FCPIT_ChannelType eChannel,uint32_t *u32timeStampValue) +{ + FCPIT_Type *pFcpit; + FCPIT_StatusType eRet = FCPIT_STATUS_SUCCESS; + if ( ((uint32_t)eFcpit >= FCPIT_INSTANCE_COUNT) || ((uint32_t)eChannel >= MAX_FCPIT_CHANNEL_NUM) ) + { + eRet = FCPIT_STATUS_PARAM_INVALID; + } + pFcpit = s_pFcpitInstanceTable[eFcpit]; + + if((uint32_t)0x3u != FCPIT_HWA_ReadChannelMode(pFcpit,eChannel)) + { + eRet = FCPIT_STATUS_PARAM_INVALID; + } + else + { + + *u32timeStampValue = FCPIT_HWA_ReadChannelValue(pFcpit,eChannel); + } + return eRet; +} + + + +/** + * @brief Fcpit common interrupt handle function + * @param eFcpit instance + * @param eChannel Fcpit interrupt channel + */ +static void Fcpit_CommonProcessInterrupt(const FCPIT_InstanceType eFcpit, const FCPIT_ChannelType eChannel) +{ + if (NULL != s_aFcpitIntNotifyTab[eFcpit][eChannel]) + { + s_aFcpitIntNotifyTab[eFcpit][eChannel](); + } +} + +/** + * @brief Fcpit_0 interrupt handler entry + * + */ +void FCPIT0_IRQHandler(void) +{ + uint32_t u32TifValue = FCPIT_HWA_ReadEnableInterruptFlag(FCPIT) & FCPIT_HWA_ReadInterruptFlag(FCPIT); + + if ((u32TifValue & FCPIT_MSR_TIF0_MASK) != 0u) + { + Fcpit_CommonProcessInterrupt(FCPIT_0, FCPIT_CHANNEL_0); + FCPIT_HWA_ClearChannelsInterruptFlag(FCPIT, (uint32_t)FCPIT_MSR_TIF0_MASK); + } + if ((u32TifValue & FCPIT_MSR_TIF1_MASK) != 0u) + { + Fcpit_CommonProcessInterrupt(FCPIT_0, FCPIT_CHANNEL_1); + FCPIT_HWA_ClearChannelsInterruptFlag(FCPIT, (uint32_t)FCPIT_MSR_TIF1_MASK); + } + if ((u32TifValue & FCPIT_MSR_TIF2_MASK) != 0u) + { + Fcpit_CommonProcessInterrupt(FCPIT_0, FCPIT_CHANNEL_2); + FCPIT_HWA_ClearChannelsInterruptFlag(FCPIT, (uint32_t)FCPIT_MSR_TIF2_MASK); + } + if ((u32TifValue & FCPIT_MSR_TIF3_MASK) != 0u) + { + Fcpit_CommonProcessInterrupt(FCPIT_0, FCPIT_CHANNEL_3); + FCPIT_HWA_ClearChannelsInterruptFlag(FCPIT, (uint32_t)FCPIT_MSR_TIF3_MASK); + } + +} + diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_fcsmu.c b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_fcsmu.c new file mode 100644 index 0000000..61df4e6 --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_fcsmu.c @@ -0,0 +1,408 @@ +/** + * @file fc7xxx_driver_fcsmu.c + * @author Flagchip + * @brief FC7xxx FCSMU driver type definition and API + * @version 0.1.0 + * @date 2024-01-14 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-01-14 qxw0100 N/A First version for FC7240 + ******************************************************************************** */ +#include "fc7xxx_driver_fcsmu.h" +#include "HwA_csc.h" + +/* ################################################################################## */ +/* ####################################### Macro #################################### */ + +#define FCSMU_FST_UNLOCK_KEY 0x951413CFU +#define FCSMU_OPC1_UNLOCK_KEY 0xFC2020CFU +#define FCSMU_OPC2_UNLOCK_KEY 0x20FCCF20U +#define FCSMU_CONFIG_TMEP_UNLOCK_KEY 0xFCU + +/* ################################################################################## */ +/* ################################### Type define ################################## */ + +/* ################################################################################## */ +/* ################################ Local Variables ################################# */ +static FCSMU_Type *const s_apFcsmuBase[FCSMU_INSTANCE_COUNT] = FCSMU_BASE_PTRS; +static FCSMU_ISRCallbackType s_apFcsmuISRCallback = NULL; + +/* ################################################################################## */ +/* ########################### Local Prototype Functions ############################ */ + +/* ################################################################################## */ +/* ######################### Global prototype Functions ############################ */ +void FCSMU0_IRQHandler(void); +/* ################################################################################## */ +/* ################################ Local Functions ################################ */ + +/* ################################################################################## */ +/* ################################ Global Functions ################################ */ + +FCSMU_StatusType FCSMU_init(const FCSMU_InitCfgType *pInitConfig) +{ + DEV_ASSERT(pInitConfig != NULL); + FCSMU_StatusType eRet; + + FCSMU_Type *const pFcsmu = s_apFcsmuBase[FCSMU_INSTANCE_0]; + + eRet = FCSMU_TransStateNTC(); + + if (eRet != FCSMU_STATUS_SUCCESS) + { + return eRet; + } + + if (pInitConfig->u32WarnTo > 432000U) + { + FCSMU_HWA_SetWaringTo(pFcsmu, 432000U); + } + else + { + FCSMU_HWA_SetWaringTo(pFcsmu, pInitConfig->u32WarnTo); + } + FCSMU_HWA_ClearCfgToIrq(pFcsmu); + FCSMU_HWA_SetWarningEn0(pFcsmu, pInitConfig->u32WarnChannel); + FCSMU_HWA_SetWarningIen(pFcsmu, pInitConfig->u32WarnInterruptChannel); + FCSMU_HWA_SetFaultIen(pFcsmu, pInitConfig->u32FaultInterruptChannel); + FCSMU_HWA_SetFRST0(pFcsmu, pInitConfig->u32FaultResetChannel); + FCSMU_HWA_SetFe0(pFcsmu, pInitConfig->u32FaultChannel); + FCSMU_HWA_SetFccr0(pFcsmu, pInitConfig->u32SoftwareClearedChannel); + + eRet = FCSMU_TransStateCTN(); + FCSMU_HWA_SetTempUnlk(pFcsmu, 0xFFU); + + s_apFcsmuISRCallback = pInitConfig->pISRCallback; + + return eRet; +} + +FCSMU_StatusType FCSMU_ConfigStatusOutput(FCSMU_StatusOutputConfigType *pInitConfig) +{ + + DEV_ASSERT(pInitConfig != NULL); + + FCSMU_Type *const pFcsmu = s_apFcsmuBase[FCSMU_INSTANCE_0]; + uint32_t u32TempValue; + FCSMU_StatusType eRet; + + if (pInitConfig->eFastMode == true) + { + if (pInitConfig->eProtocal != FCSMU_SOUT_PROTOCOL_DUAL_RAIL && pInitConfig->eProtocal != FCSMU_SOUT_PROTOCOL_TIME_SWITCH) + { + return FCSMU_STATUS_ERROR; + } + } + + u32TempValue = FCSMU_SOCTRL_SOUT_PEN(pInitConfig->bEnable) | + FCSMU_SOCTRL_FASTEN(pInitConfig->eFastMode) | + FCSMU_SOCTRL_POLSW(pInitConfig->ePolarity) | + FCSMU_SOCTRL_SOUT_PTC(pInitConfig->eProtocal) | + FCSMU_SOCTRL_DIVEX(pInitConfig->bDivex) | + FCSMU_SOCTRL_SOUT_CTRL(pInitConfig->eSoutCtrl) | + FCSMU_SOCTRL_SOUT_DIV(pInitConfig->u32Divder) | + FCSMU_SOCTRL_SMRDT(pInitConfig->u32Delaytimer); + + eRet = FCSMU_TransStateNTC(); + + if (eRet != FCSMU_STATUS_SUCCESS) + { + return eRet; + } + + FCSMU_HWA_SetSoctrl(pFcsmu, u32TempValue); + FCSMU_HWA_SetSoutEn(pFcsmu, pInitConfig->u32SoutChannel); + + eRet = FCSMU_TransStateCTN(); + + return eRet; +} + +void FCSMU_CrcGen(void) +{ + FCSMU_Type *const pFcsmu = s_apFcsmuBase[FCSMU_INSTANCE_0]; + FCSMU_HWA_GenerateCrc(pFcsmu); +} + +bool FCSMU_IsCrcBusy(void) +{ + FCSMU_Type *const pFcsmu = s_apFcsmuBase[FCSMU_INSTANCE_0]; + return FCSMU_HWA_GetCrcBusy(pFcsmu); +} + +FCSMU_StatusType FCSMU_CrcConfig(FCSMU_CrcModeType eMode) +{ + FCSMU_Type *const pFcsmu = s_apFcsmuBase[FCSMU_INSTANCE_0]; + uint32_t u32TimeoutTimes = 65535U; + FCSMU_StatusType eRet = FCSMU_STATUS_SUCCESS; + + FCSMU_HWA_GenerateCrc(pFcsmu); + while (FCSMU_HWA_GetCrcBusy(pFcsmu) == FCSMU_Crc_STATE_BUSY) + { + u32TimeoutTimes--; + if (u32TimeoutTimes == 0U) + { + eRet = FCSMU_STATUS_ERROR; + break; + } + } + + if (eRet == FCSMU_STATUS_SUCCESS) + { + if (eMode == FCSMU_CRC_TRIGGER_MODE) + { + FCSMU_HWA_EnableTrigger(pFcsmu, true); + } + else + { + + } + + CSC0_HWA_CTRL4_EnableReqToSMU(CSC_SMU_SCF_IRQ); + FCSMU_HWA_EnableErrorOutput(pFcsmu, true); + FCSMU_HWA_EnableCrcChecker(pFcsmu, true); + } + + return eRet; + +} + +FCSMU_StatusType FCSMU_ClearFaultFlag(uint32_t u32FaultChannel) +{ + FCSMU_Type *const pFcsmu = s_apFcsmuBase[FCSMU_INSTANCE_0]; + uint32_t u32TimeoutTimes = 65535U; + FCSMU_StatusType eRet = FCSMU_STATUS_SUCCESS; + + FCSMU_HWA_SetFunlk(pFcsmu, FCSMU_FST_UNLOCK_KEY); + FCSMU_HWA_SetFst0(pFcsmu, u32FaultChannel); + + while (FCSMU_HWA_GetCtrlOps(pFcsmu) != (uint32_t)FCSMU_OP_STATE_SUCCESSFUL) + { + u32TimeoutTimes--; + if (u32TimeoutTimes == 0U) + { + eRet = FCSMU_STATUS_ERROR; + break; + } + } + + return eRet; +} + +FCSMU_StatusType FCSMU_TransStateCTN(void) +{ + FCSMU_Type *const pFcsmu = s_apFcsmuBase[FCSMU_INSTANCE_0]; + uint32_t u32TimeoutTimes; + uint32_t u32RetryTimes = 65535U; + uint32_t u32Temp; + FCSMU_StatusType eRet = FCSMU_STATUS_ERROR; + + while (u32RetryTimes != 0U) + { + u32TimeoutTimes = 65535U; + u32Temp = (uint32_t)FCSMU_HWA_GetCtrl(pFcsmu); + u32Temp |= (uint32_t)FCSMU_OPC_MOVE_TO_NORMAL; + + FCSMU_HWA_SetOprk(pFcsmu, FCSMU_OPC2_UNLOCK_KEY); + FCSMU_HWA_SetCrtl(pFcsmu, u32Temp); + + while (FCSMU_HWA_GetCtrlOps(pFcsmu) != (uint32_t)FCSMU_OP_STATE_SUCCESSFUL) + { + u32TimeoutTimes--; + if (u32TimeoutTimes == 0U) + { + break; + } + } + + if (u32TimeoutTimes != 0U) + { + if (FCSMU_HWA_GetState(pFcsmu) == (uint32_t)FCSMU_STATE_NORMAL) + { + break; + } + } + + u32RetryTimes--; + } + + if (u32RetryTimes != 0U) + { + eRet = FCSMU_STATUS_SUCCESS; + } + + return eRet; +} + +FCSMU_StatusType FCSMU_TransStateNTC(void) +{ + FCSMU_Type *const pFcsmu = s_apFcsmuBase[FCSMU_INSTANCE_0]; + uint32_t u32TimeoutTimes; + uint32_t u32RetryTimes = 65535U; + FCSMU_StatusType eRet = FCSMU_STATUS_ERROR; + uint32_t u32Temp; + + while (u32RetryTimes != 0U) + { + u32TimeoutTimes = 65535U; + u32Temp = FCSMU_HWA_GetCtrl(pFcsmu); + u32Temp |= (uint32_t)FCSMU_OPC_MOVE_TO_CONFIG; + FCSMU_HWA_SetTempUnlk(pFcsmu, FCSMU_CONFIG_TMEP_UNLOCK_KEY); + FCSMU_HWA_SetOprk(pFcsmu, FCSMU_OPC1_UNLOCK_KEY); + FCSMU_HWA_SetCrtl(pFcsmu, u32Temp); + + while (FCSMU_HWA_GetCtrlOps(pFcsmu) != (uint32_t)FCSMU_OP_STATE_SUCCESSFUL) + { + if (FCSMU_HWA_GetCtrlOps(pFcsmu) == (uint32_t)FCSMU_OP_STATE_BUSY) + { + u32TimeoutTimes--; + if (u32TimeoutTimes == 0U) + { + break; + } + } + else + { + break; + } + } + + if (u32TimeoutTimes != 0U) + { + if (FCSMU_HWA_GetState(pFcsmu) == (uint32_t)FCSMU_STATE_CONGIG) + { + break; + } + } + + u32RetryTimes--; + } + + if (u32RetryTimes != 0U) + { + eRet = FCSMU_STATUS_SUCCESS; + } + + return eRet; +} + +void FCSMU_InjectionFault(uint32_t u32ChannelIndex) +{ + FCSMU_Type *const pFcsmu = s_apFcsmuBase[FCSMU_INSTANCE_0]; + + FCSMU_HWA_SetInject(pFcsmu, u32ChannelIndex); +} + +uint32_t FCSMU_GetFaultChannel(void) +{ + FCSMU_Type *const pFcsmu = s_apFcsmuBase[FCSMU_INSTANCE_0]; + + return FCSMU_HWA_GetFst0(pFcsmu); +} + +uint32_t FCSMU_GetIrqState(void) +{ + FCSMU_Type *const pFcsmu = s_apFcsmuBase[FCSMU_INSTANCE_0]; + + return FCSMU_HWA_GetIrqStat(pFcsmu); +} + +uint32_t FCSMU_GetNtfFlag(void) +{ + FCSMU_Type *const pFcsmu = s_apFcsmuBase[FCSMU_INSTANCE_0]; + + return FCSMU_HWA_GetNtf(pFcsmu); +} + +uint32_t FCSMU_GetWtfFlag(void) +{ + FCSMU_Type *const pFcsmu = s_apFcsmuBase[FCSMU_INSTANCE_0]; + + return FCSMU_HWA_GetWtf(pFcsmu); +} + +uint32_t FCSMU_GetNtwFlag(void) +{ + FCSMU_Type *const pFcsmu = s_apFcsmuBase[FCSMU_INSTANCE_0]; + + return FCSMU_HWA_GetNtw(pFcsmu); +} + +static void FCSMUn_IRQHandler(void) +{ + uint32_t u32TempValue = FCSMU_GetIrqState(); + uint32_t u32IrqChannel; + + if ((FCSMU_IRQ_STAT_FAULT_IRQ_MASK & u32TempValue) == FCSMU_IRQ_STAT_FAULT_IRQ_MASK) + { + if ((FCSMU_GetNtfFlag() & FCSMU_NTF_FLAG_MASK) == FCSMU_NTF_FLAG_MASK) + { + u32IrqChannel = FCSMU_GetNtfFlag() & 0xFFU; + } + else + { + u32IrqChannel = FCSMU_GetWtfFlag() & 0xFFU; + } + + if (u32IrqChannel == 0xFFU) + { + u32IrqChannel = FCSMU_GetFaultChannel(); + } + else + { + if (u32IrqChannel > 0U && u32IrqChannel <= 32U) + { + u32IrqChannel = (uint32_t)1U << (u32IrqChannel - (uint32_t)1U); + } + else + { + u32IrqChannel = 0U; + } + } + + s_apFcsmuISRCallback(FCSMU_FAULT_IRQ, u32IrqChannel); + } + else if ((FCSMU_IRQ_STAT_WARNING_IRQ_MASK & u32TempValue) == FCSMU_IRQ_STAT_WARNING_IRQ_MASK) + { + u32IrqChannel = FCSMU_GetNtwFlag() & 0xFFU; + + if (u32IrqChannel == 0xFFU) + { + u32IrqChannel = FCSMU_GetFaultChannel(); + } + else + { + if (u32IrqChannel > 0U && u32IrqChannel <= 32U) + { + u32IrqChannel = (uint32_t)1U << (u32IrqChannel - (uint32_t)1U); + } + else + { + u32IrqChannel = 0U; + } + } + + s_apFcsmuISRCallback(FCSMU_WARNING_IRQ, u32IrqChannel); + + } + else if ((FCSMU_IRQ_STAT_CFG_TO_IRQ_MASK & u32TempValue) == FCSMU_IRQ_STAT_CFG_TO_IRQ_MASK) + { + s_apFcsmuISRCallback(FCSMU_CFG_TIMEOUT, 0); + } + else + { + + } +} + +void FCSMU0_IRQHandler(void) +{ + FCSMUn_IRQHandler(); +} diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_fcspi.c b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_fcspi.c new file mode 100644 index 0000000..3bb82e8 --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_fcspi.c @@ -0,0 +1,3229 @@ +/** + * @file fc7xxx_driver_fcspi.c + * @author Flagchip + * @brief FC7xxx FCSPI driver type definition and API + * @version 0.1.0 + * @date 2024-01-14 + * + * @copyright Copyright (c) 2023 Flagchip Semiconductors Co., Ltd. + * + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024/01/12 Flagchip071 N/A First version for FC240 + ******************************************************************************** */ + +#include "interrupt_manager.h" +#include "fc7xxx_driver_fcspi.h" +#define FCSPI_DRV_STATUS_REG_W1C_U32 ((uint32_t)( FCSPI_STATUS_DMF(1) | \ + FCSPI_STATUS_RX_FO(1) | \ + FCSPI_STATUS_TX_FU(1) | \ + FCSPI_STATUS_TCF(1) | \ + FCSPI_STATUS_FEF(1) | \ + FCSPI_STATUS_RX_WF(1))) + +#define FCSPI_DRV_STATUS_REG_W1C_MASK_U32 ((uint32_t)(FCSPI_STATUS_DMF_MASK | \ + FCSPI_STATUS_RX_FO_MASK | \ + FCSPI_STATUS_TX_FU_MASK | \ + FCSPI_STATUS_TCF_MASK | \ + FCSPI_STATUS_FEF_MASK | \ + FCSPI_STATUS_RX_WF_MASK)) + +#define FCSPI_DRV_INT_EN_REG_ALL_U32 ((uint32_t)(FCSPI_INT_EN_DMIE(1) | \ + FCSPI_INT_EN_RFOIE(1) | \ + FCSPI_INT_EN_TFUIE(1) | \ + FCSPI_INT_EN_TCIE(1) | \ + FCSPI_INT_EN_FEIE(1) | \ + FCSPI_INT_EN_RWIE(1) | \ + FCSPI_INT_EN_RX_PEIE(1) | \ + FCSPI_INT_EN_TX_PEIE(1) | \ + FCSPI_INT_EN_RFIE(1) | \ + FCSPI_INT_EN_TFIE(1))) + +#define FCSPI_DRV_RX_FIFO_WORD_CNT (8) + +#define FCSPI_DRV_TX_FIFO_WORD_CNT (8) + +#define FCSPI_CFGR1_PCS23_PCS_MODE_U32 FCSPI_CFG1_PCS_CFG(0) /* PCS[3:2] as PCS feature */ +#define FCSPI_CFGR1_PCS23_DATABUS_IN_4BIT_MODE_U32 FCSPI_CFG1_PCS_CFG(1) /* PCS[3:2] as data bus in 4-bit mode */ + +#define FCSPI_CFGR1_OUTCFG_RETAIN_LAST_WHEN_NEGATE_U32 FCSPI_CFG1_OUT_CFG(0) +#define FCSPI_CFGR1_OUTCFG_TRISTATE_WHEN_NEGATE_U32 FCSPI_CFG1_OUT_CFG(1) + +#define FCSPI_CFGR1_PINCFG_SIN_INPUT_SOUT_OUTPUT_U32 FCSPI_CFG1_PIN_CFG(0) /* SIN is used for input data and SOUT for output data */ +#define FCSPI_CFGR1_PINCFG_SIN_INPUT_OUTPUT_U32 FCSPI_CFG1_PIN_CFG(1) /* SIN is used for both input and output data */ +#define FCSPI_CFGR1_PINCFG_SOUT_INPUT_OUTPUT_U32 FCSPI_CFG1_PIN_CFG(2) /* SOUT is used for both input and output data */ +#define FCSPI_CFGR1_PINCFG_SOUT_INPUT_SIN_OUTPUT_U32 FCSPI_CFG1_PIN_CFG(3) /* SOUT is used for input data and SIN for output data */ + +#define FCSPI_CFGR1_PCS0_ACTIVE_HIGH_U32 FCSPI_CFG1_PCS_POL(1) /* Peripheral Chip Select Polarity - Active High */ +#define FCSPI_CFGR1_PCS0_POL_MASK_U32 FCSPI_CFG1_PCS_POL(1) +#define FCSPI_CFGR1_PCS1_ACTIVE_HIGH_U32 FCSPI_CFG1_PCS_POL(2) /* Peripheral Chip Select Polarity - Active High */ +#define FCSPI_CFGR1_PCS1_POL_MASK_U32 FCSPI_CFG1_PCS_POL(2) +#define FCSPI_CFGR1_PCS2_ACTIVE_HIGH_U32 FCSPI_CFG1_PCS_POL(4) /* Peripheral Chip Select Polarity - Active High */ +#define FCSPI_CFGR1_PCS2_POL_MASK_U32 FCSPI_CFG1_PCS_POL(4) +#define FCSPI_CFGR1_PCS3_ACTIVE_HIGH_U32 FCSPI_CFG1_PCS_POL(8) /* Peripheral Chip Select Polarity - Active High */ +#define FCSPI_CFGR1_PCS3_POL_MASK_U32 FCSPI_CFG1_PCS_POL(8) + +#define FCSPI_TRCR_SCKPOL_ACTIVE_HIGH_U32 FCSPI_TR_CTRL_SCK_POL(0) /* When inactive, SCK is low */ +#define FCSPI_TRCR_SCKPOL_ACTIVE_LOW_U32 FCSPI_TR_CTRL_SCK_POL(1) /* When inactive, SCK is high */ + +#define FCSPI_TRCR_SCKPHA_CAP_LEADING_U32 FCSPI_TR_CTRL_SCK_PHA(0) /* Data is changed on the leading edge of SCK and captured on the following edge */ +#define FCSPI_TRCR_SCKPHA_CAP_TRAILING_U32 FCSPI_TR_CTRL_SCK_PHA(1) /* Data is captured on the leading edge of SCK and changed on the following edge */ + +#define FCSPI_TRCR_PRESCALE_1_U32 FCSPI_TR_CTRL_PRESCALE(0) /* Divide by 1 */ +#define FCSPI_TRCR_PRESCALE_2_U32 FCSPI_TR_CTRL_PRESCALE(1) /* Divide by 2 */ +#define FCSPI_TRCR_PRESCALE_4_U32 FCSPI_TR_CTRL_PRESCALE(2) /* Divide by 4 */ +#define FCSPI_TRCR_PRESCALE_8_U32 FCSPI_TR_CTRL_PRESCALE(3) /* Divide by 8 */ +#define FCSPI_TRCR_PRESCALE_16_U32 FCSPI_TR_CTRL_PRESCALE(4) /* Divide by 16 */ +#define FCSPI_TRCR_PRESCALE_32_U32 FCSPI_TR_CTRL_PRESCALE(5) /* Divide by 32 */ +#define FCSPI_TRCR_PRESCALE_64_U32 FCSPI_TR_CTRL_PRESCALE(6) /* Divide by 64 */ +#define FCSPI_TRCR_PRESCALE_128_U32 FCSPI_TR_CTRL_PRESCALE(7) /* Divide by 128 */ + +#define FCSPI_TRCR_PCS0_EN_U32 FCSPI_TR_CTRL_PCS(0) /* Transfer using FCSPI_PCS[0] */ +#define FCSPI_TRCR_PCS1_EN_U32 FCSPI_TR_CTRL_PCS(1) /* Transfer using FCSPI_PCS[1] */ +#define FCSPI_TRCR_PCS2_EN_U32 FCSPI_TR_CTRL_PCS(2) /* Transfer using FCSPI_PCS[2] */ +#define FCSPI_TRCR_PCS3_EN_U32 FCSPI_TR_CTRL_PCS(3) /* Transfer using FCSPI_PCS[3] */ + +#define FCSPI_TRCR_MSB_U32 FCSPI_TR_CTRL_LSBF(0) /* Data is transferred MSB first */ +#define FCSPI_TRCR_LSB_U32 FCSPI_TR_CTRL_LSBF(1) /* Data is transferred LSB first */ + +#define FCSPI_TRCR_BYSW_EN_U32 FCSPI_TR_CTRL_BYSW(1) /* Byte swap enabled */ +#define FCSPI_TRCR_BYSW_DIS_U32 FCSPI_TR_CTRL_BYSW(0) /* Byte swap disable */ + +#define FCSPI_TRCR_CONT_EN_U32 FCSPI_TR_CTRL_CT_EN(1) /* Continuous transfer enabled */ +#define FCSPI_TRCR_CONT_DIS_U32 FCSPI_TR_CTRL_CT_EN(0) /* Continuous transfer disabled */ + +#define FCSPI_TRCR_CONTC_EN_U32 FCSPI_TR_CTRL_CT_GO(1) /* Command word for continuing transfer */ + +#define FCSPI_TRCR_WIDTH_1_U32 FCSPI_TR_CTRL_WIDTH(0) /* Single bit transfer */ +#define FCSPI_TRCR_WIDTH_2_U32 FCSPI_TR_CTRL_WIDTH(1) /* Two bita transfer */ +#define FCSPI_TRCR_WIDTH_4_U32 FCSPI_TR_CTRL_WIDTH(2) /* Four bits transfer */ + +#define ITCM_START_ADDRESS 0x0u +#define ITCM_END_ADDRESS 0xFFFFu +#define DTCM_START_ADDRESS 0x20000000u +#define DTCM_END_ADDRESS 0x2001FFFFu +#define ITCM_TO_BACKDOOR_OFFSET 0x24000000u +#define DTCM_TO_BACKDOOR_OFFSET 0x02000000u + + + +typedef enum { + SIN_INPUT_SOUT_OUTPUT = 0, + SIN_INPUT_OUTPUT = 1, + SOUT_INPUT_OUTPUT = 2, + SOUT_INPUT_SIN_OUTPUT = 3 +} FCSPI_PinModeType; + +typedef enum { + FCSPI_PRESCALE_1 = 0, + FCSPI_PRESCALE_2 = 1, + FCSPI_PRESCALE_4 = 2, + FCSPI_PRESCALE_8 = 3, + FCSPI_PRESCALE_16 = 4, + FCSPI_PRESCALE_32 = 5, + FCSPI_PRESCALE_64 = 6, + FCSPI_PRESCALE_128 = 7, + FCSPI_PRESCALE_MAX = 8 +} FCSPI_PrescaleValueType; + +typedef enum { + FCSPI_TRANSFER_1_BIT = 0, /* 1-bit shift at a time, data out on SDO, in on SDI (normal mode) */ + FCSPI_TRANSFER_2_BIT = 1, /* 2-bits shift out on SDO/SDI and in on SDO/SDI */ + FCSPI_TRANSFER_4_BIT = 2 /* 4-bits shift out on SDO/SDI/PCS[3:2] and in on SDO/SDI/PCS[3:2] */ +} FCSPI_TransferWidthType; + +typedef enum { + PINOUT_RETAIN_LAST = 0, + PINOUT_TRISTATE = 1 +} FCSPI_NegatedPinOutStatType; + +typedef enum { + PCS2_3_PCS = 0, + PCS2_3_DATA_BUS_IN_4BIT_MODE = 1 +} FCSPI_PCS2_3ModeType; + +typedef struct { + FCSPI_SckPolarityType eSckPolarity; + FCSPI_SckSamplePhaseType eSckPhase; + FCSPI_PrescaleValueType ePrescalerValue; + FCSPI_PCSType ePCSSelect; + FCSPI_BitFirstOrderType eBitFirstOrder; + FCSPI_AtomicBoolType eByteSwap; + FCSPI_AtomicBoolType eContTransEnable; + FCSPI_AtomicBoolType eContCmdEnable; + FCSPI_AtomicBoolType eRxDisable; + FCSPI_AtomicBoolType eTxDisable; + FCSPI_TransferWidthType eTransferWidth; + uint16_t u16FrameBitCnt; +} FCSPI_TxRxCtrlType; + +typedef enum { + FCSPI_TRANSFER_OK = 0U, /* Transfer OK */ + FCSPI_TRANSFER_TX_FAIL, /* Error during transmission */ + FCSPI_TRANSFER_RX_FAIL, /* Error during reception */ + FCSPI_TRANSFER_ABORT, /* Transfer is aborted */ +} FCSPI_TransferStatusType; + +typedef struct { + uint16_t u16BitsPerFrame; /* count of bits per frame: 8-4096bits */ + uint16_t u16BytesCntFrameNeed; /* count of bytes per frame: 1-512bytes for external buffer passed into driver */ + FCSPI_BitFirstOrderType eBitFirstOrder; /* MSB/LSB first to send/receive */ + uint8_t u8TxFifoSize; /* Tx fifo size */ + uint8_t u8RxFifoSize; /* Rx fifo size */ + FCSPI_TriggerDmaInfType tTriggerDmaInf; + FCSPI_TriggerSrcType eTransferTriggerSrc; /* Type of transfer */ + FCSPI_StopCbType pStopNotifyCb; /* callback to transfer stop, transfer successfully or aborted */ + FCSPI_SemaphoreResetCbType pSemaResetCb; /* synchronous send need, reset the semaphore */ + FCSPI_SemaphoreTakeCbType pSemaTakeCb; /* synchronous send need, acquire the semaphore */ + FCSPI_SemaphorePostCbType pSemaPostCb; /* synchronous send need, release the semaphore outside of the interrupt */ + uint32_t u32DmaDummyData; /* DMA mode, TX is NULL, just send this data, RX is NULL, just store in this var */ + + FCSPI_SckSamplePhaseType eSckSamplePhase; /* select which edge of active sck clock to capture data */ + FCSPI_SckPolarityType eSckPolarity; /* select output sclk clock polarity */ + + FCSPI_PCSType ePcs; /* chip select pin */ + FCSPI_PcsPolarityType ePcsPolarity; /* chip select pin polarity */ + + /* only master mode use, slave not */ + FCSPI_AtomicBoolType eIsPcsContinuous; /* Option to keep chip select asserted until transfer complete; needed for TCR programming */ + uint32_t u32FCSpiSrcClk; /* Module source clock */ + uint32_t u32Baundrate; /* the bit per second of current transmission */ + + /* dynamic state */ + volatile uint8_t u8WaitSemaphore; + const uint8_t *pbyTxBuff; /* The buffer from which transmitted bytes are taken */ + uint8_t *pbyRxBuff; /* The buffer into which received bytes are placed */ + volatile uint16_t u16TxIndex; + volatile uint16_t u16RxIndex; + + volatile uint16_t u16TxByteCntRemainToSend; /* Number of bytes remaining to send */ + volatile uint16_t u16RxByteCntRemainToGet; /* Number of bytes remaining to receive */ + volatile uint16_t u16TxSendByteCntOfCurFrame; /* Number of bytes from current frame which were already sent */ + volatile uint16_t u16RxGetByteCntOfCurFrame; /* Number of bytes from current frame which were already received */ + volatile FCSPI_TransferStatusType eTransferStat; /* The status of the current */ + volatile FCSPI_AtomicBoolType eIsInTransfer; /* True if there is an active transfer */ +} FCSPI_DrvStateType; + +typedef struct +{ + FCSPI_MemMapPtr tFCSpiInstance; + FCSPI_DrvStateType tFCSpiStat; + IRQn_Type eFCSpiIrq; +} FCSPI_DriverInfoType; + +static FCSPI_DriverInfoType s_atFCSpiInfo[FCSPI_INSTANCE_COUNT] = { + {FCSPI0, {0} ,FCSPI0_IRQn}, + {FCSPI1, {0} ,FCSPI1_IRQn}, + {FCSPI2, {0} ,FCSPI2_IRQn}, + {FCSPI3, {0} ,FCSPI3_IRQn}, + {FCSPI4, {0} ,FCSPI4_IRQn}, + {FCSPI5, {0} ,FCSPI5_IRQn} + }; + + +/* soft reset just reset the logic and registers except CTRL */ +static void FCSpi_Hw_Reset(FCSPI_InstanceType eInst, + FCSPI_AtomicBoolType eRxFifo, + FCSPI_AtomicBoolType eTxFifo, + FCSPI_AtomicBoolType eSoftRst); +static FCSPI_StatusType FCSpi_Hw_Disable(FCSPI_InstanceType eInst); + +/* get status value and check using macro */ +#define FCSpi_Hw_ChkBusy(status) (((status) & FCSPI_STATUS_BF_MASK) != 0U) +#define FCSpi_Hw_ChkDataMatch(status) (((status) & FCSPI_STATUS_DMF_MASK) != 0U) +#define FCSpi_Hw_ChkRxFifoOverflow(status) (((status) & FCSPI_STATUS_RX_FO_MASK) != 0U) +#define FCSpi_Hw_ChkTxFifoUnderrun(status) (((status) & FCSPI_STATUS_TX_FU_MASK) != 0U) +#define FCSpi_Hw_ChkTransferComplete(status) (((status) & FCSPI_STATUS_TCF_MASK) != 0U) +#define FCSpi_Hw_ChkFrameEndDetected(status) (((status) & FCSPI_STATUS_FEF_MASK) != 0U) +#define FCSpi_Hw_ChkReceiveWordComplete(status) (((status) & FCSPI_STATUS_RX_WF_MASK) != 0U) +#define FCSpi_Hw_ChkRxGreaterThanWater(status) (((status) & FCSPI_STATUS_RX_FF_MASK) != 0U) +#define FCSpi_Hw_ChkTxEqualOrLessThanWater(status) (((status) & FCSPI_STATUS_TX_FF_MASK) != 0U) + +static void FCSpi_Hw_ClearSomeStatusW1CFlag(FCSPI_InstanceType eInst, uint32_t u32FlagBitSet); /* refer to FCSPI_DRV_STATUS_REG_W1C_U32 */ +static void FCSpi_Hw_EnableMoreInterrupts(FCSPI_InstanceType eInst, uint32_t u32Interrupts); /* refer to FCSPI_INT_EN_DMIE(1) */ +static void FCSpi_Hw_DisableSomeInterrupts(FCSPI_InstanceType eInst, uint32_t u32Interrupts); /* refer to FCSPI_INT_EN_DMIE(1) */ +#define FCSpi_Hw_EnableTransmitDataInterrupt(eInst) FCSpi_Hw_EnableMoreInterrupts((eInst), FCSPI_INT_EN_TFIE_MASK) +#define FCSpi_Hw_DisableTransmitDataInterrupt(eInst) FCSpi_Hw_DisableSomeInterrupts((eInst), FCSPI_INT_EN_TFIE_MASK) +#define FCSpi_Hw_EnableReceiveDataInterrupt(eInst) FCSpi_Hw_EnableMoreInterrupts((eInst), FCSPI_INT_EN_RFIE_MASK) +#define FCSpi_Hw_DisableReceiveDataInterrupt(eInst) FCSpi_Hw_DisableSomeInterrupts((eInst), FCSPI_INT_EN_RFIE_MASK) +#define FCSpi_Hw_EnableTransmitCompleteInterrupt(eInst) FCSpi_Hw_EnableMoreInterrupts((eInst), FCSPI_INT_EN_TCIE_MASK) +#define FCSpi_Hw_DisableTransmitCompleteInterrupt(eInst) FCSpi_Hw_DisableSomeInterrupts((eInst), FCSPI_INT_EN_TCIE_MASK) + +static void FCSpi_Hw_SetPcs_2_3_Mode(FCSPI_InstanceType eInst, FCSPI_PCS2_3ModeType eMode); +static void FCSpi_Hw_SetPin(FCSPI_InstanceType eInst, FCSPI_PinModeType eMode, FCSPI_NegatedPinOutStatType eStat); + +static void FCSpi_Hw_SetOnePcsPolarity(FCSPI_InstanceType eInst, + FCSPI_PCSType ePcs, FCSPI_PcsPolarityType ePolarity); + +static void FCSpi_Hw_Master_SetSckLoopbackSample(FCSPI_InstanceType eInst, FCSPI_AtomicBoolType eEnable); + +#define FCSpi_Hw_PrescalerRegToActualVal(eVal) (((uint32_t)1) << ((uint8_t)(eVal))) +static void FCSpi_Hw_SetContinuousCommand(FCSPI_InstanceType eInst, FCSPI_AtomicBoolType eEnable); + +static void FCSpi_Hw_SelectUsePcs(FCSPI_InstanceType eInst, FCSPI_PCSType ePCS); +static uint32_t FCSpi_Hw_Master_CalcBaudRate(const FCSPI_MasterCfgType *pCfg, uint32_t *pdwPrescaleRegVal, uint32_t *pdwActualSckDiv); + +static FCSPI_StatusType FCSpi_Hw_SetTRCR(FCSPI_InstanceType eInst, FCSPI_TxRxCtrlType *ptCtrl); +static FCSPI_PrescaleValueType FCSpi_Hw_GetRegPrescalerVal(FCSPI_InstanceType eInst); + +static void FCSpi_Hw_Get_SCK_PCS_DIV_Hold(FCSPI_InstanceType eInst, uint8_t *pbySCKPCS, uint8_t *pbyPCSSCK, uint8_t *pbyPCSPCS, uint8_t *pbySCKDIV); +static void FCSpi_Hw_Set_SCK_PCS_DIV_Hold(FCSPI_InstanceType eInst, uint8_t u8SCKPCS, uint8_t u8PCSSCK, uint8_t u8PCSPCS, uint8_t u8SCKDIV); +static void FCSpi_Hw_Set_SCK_PCS_Hold(FCSPI_InstanceType eInst, uint8_t u8SCKPCS, uint8_t u8PCSSCK, uint8_t u8PCSPCS); +static void FCSpi_Hw_SetRxTxDmaEnableStatus(FCSPI_InstanceType eInst, FCSPI_AtomicBoolType eRxEnable, FCSPI_AtomicBoolType eTxEnable); +static void fcspi_read_rx_fifo(FCSPI_InstanceType eInst); +static void fcspi_write_tx_fifo(FCSPI_InstanceType eInst); +static void fcspi_master_clean_transfer(FCSPI_InstanceType eInst, FCSPI_AtomicBoolType bIsInInterrupt); +static void fcspi_master_abort_transfer(FCSPI_InstanceType eInst, FCSPI_AtomicBoolType bIsInISR); +static void fcspi_master_dma_rx_err_interrupt(FCSPI_InstanceType eInst); +static void fcspi_0_master_dma_rx_err_interrupt(void); +static void fcspi_1_master_dma_rx_err_interrupt(void); +static void fcspi_2_master_dma_rx_err_interrupt(void); +static void fcspi_3_master_dma_rx_err_interrupt(void); +static void fcspi_4_master_dma_rx_err_interrupt(void); +static void fcspi_5_master_dma_rx_err_interrupt(void); +static void fcspi_master_dma_rx_finish_interrupt(void); +static void fcspi_master_dma_tx_err_interrupt(FCSPI_InstanceType eInst); +static void fcspi_0_master_dma_tx_err_interrupt(void); +static void fcspi_1_master_dma_tx_err_interrupt(void); +static void fcspi_2_master_dma_tx_err_interrupt(void); +static void fcspi_3_master_dma_tx_err_interrupt(void); +static void fcspi_4_master_dma_tx_err_interrupt(void); +static void fcspi_5_master_dma_tx_err_interrupt(void); +static void fcspi_master_dma_tx_finish_interrupt(FCSPI_InstanceType eInst); +static void fcspi_0_master_dma_tx_finish_interrupt(void); +static void fcspi_1_master_dma_tx_finish_interrupt(void); +static void fcspi_2_master_dma_tx_finish_interrupt(void); +static void fcspi_3_master_dma_tx_finish_interrupt(void); +static void fcspi_4_master_dma_tx_finish_interrupt(void); +static void fcspi_5_master_dma_tx_finish_interrupt(void); +static FCSPI_StatusType fcspi_master_async_transfer_bytes(FCSPI_InstanceType eInst, + const uint8_t *pSendBuffer, uint8_t *pReceiveBuffer, + uint16_t u16TransferByteCnt); +static FCSPI_StatusType fcspi_master_trigger(FCSPI_InstanceType eInst, FCSPI_AtomicBoolType bIsInIsr); +static void fcspi_slave_clean_transfer(FCSPI_InstanceType eInst, FCSPI_AtomicBoolType bIsInInterrupt); +static void fcspi_slave_abort_transfer(FCSPI_InstanceType eInst, FCSPI_AtomicBoolType bIsInInterrupt); +static void fcspi_slave_dma_rx_err_interrupt(FCSPI_InstanceType eInst); +static void fcspi_0_slave_dma_rx_err_interrupt(void); +static void fcspi_1_slave_dma_rx_err_interrupt(void); +static void fcspi_2_slave_dma_rx_err_interrupt(void); +static void fcspi_3_slave_dma_rx_err_interrupt(void); +static void fcspi_4_slave_dma_rx_err_interrupt(void); +static void fcspi_5_slave_dma_rx_err_interrupt(void); +static void fcspi_slave_dma_rx_finish_interrupt(FCSPI_InstanceType eInst); +static void fcspi_0_slave_dma_rx_finish_interrupt(void); +static void fcspi_1_slave_dma_rx_finish_interrupt(void); +static void fcspi_2_slave_dma_rx_finish_interrupt(void); +static void fcspi_3_slave_dma_rx_finish_interrupt(void); +static void fcspi_4_slave_dma_rx_finish_interrupt(void); +static void fcspi_5_slave_dma_rx_finish_interrupt(void); +static void fcspi_slave_dma_tx_err_interrupt(FCSPI_InstanceType eInst); +static void fcspi_0_slave_dma_tx_err_interrupt(void); +static void fcspi_1_slave_dma_tx_err_interrupt(void); +static void fcspi_2_slave_dma_tx_err_interrupt(void); +static void fcspi_3_slave_dma_tx_err_interrupt(void); +static void fcspi_4_slave_dma_tx_err_interrupt(void); +static void fcspi_5_slave_dma_tx_err_interrupt(void); +static void fcspi_slave_dma_tx_finish_interrupt(FCSPI_InstanceType eInst); +static void fcspi_0_slave_dma_tx_finish_interrupt(void); +static void fcspi_1_slave_dma_tx_finish_interrupt(void); +static void fcspi_2_slave_dma_tx_finish_interrupt(void); +static void fcspi_3_slave_dma_tx_finish_interrupt(void); +static void fcspi_4_slave_dma_tx_finish_interrupt(void); +static void fcspi_5_slave_dma_tx_finish_interrupt(void); + +static FCSPI_StatusType fcspi_slave_async_transfer_bytes(FCSPI_InstanceType eInst, + const uint8_t *pSendBuffer, uint8_t *pReceiveBuffer, uint16_t u16TransferByteCnt); +static FCSPI_StatusType fcspi_slave_trigger(FCSPI_InstanceType eInst, FCSPI_AtomicBoolType bIsInISR); +static void fcspi_irq_handler(FCSPI_InstanceType eInst); + +static void FCSpi_Hw_Reset(FCSPI_InstanceType eInst, + FCSPI_AtomicBoolType eRxFifo, FCSPI_AtomicBoolType eTxFifo, FCSPI_AtomicBoolType eSoftRst) +{ + uint32_t u32Flag = 0U; + uint32_t u32OldFlag = FCSPI_HWA_GetCtrlValue(s_atFCSpiInfo[eInst].tFCSpiInstance); + uint32_t u32Mask = FCSPI_CTRL_MASK; + + if (eRxFifo) + { + u32Flag |= FCSPI_CTRL_RST_RF(1); + } + + if (eTxFifo) + { + u32Flag |= FCSPI_CTRL_RST_TF(1); + } + + if (FCSPI_TRUE == eSoftRst) + { + u32Flag |= FCSPI_CTRL_SW_RST(1); + } + + u32Flag |= u32OldFlag; + FCSPI_HWA_SetCtrlValue(s_atFCSpiInfo[eInst].tFCSpiInstance, u32Flag); + + /* no need delay */ + if (FCSPI_TRUE == eSoftRst) + { + FCSPI_HWA_SetCtrlValue(s_atFCSpiInfo[eInst].tFCSpiInstance, 0U); + } + else + { + FCSPI_HWA_SetCtrlValue(s_atFCSpiInfo[eInst].tFCSpiInstance, (u32OldFlag & u32Mask)); + } +} + +#ifdef FCSPI_DRV_INTERNAL_FUNC_EN +static FCSPI_AtomicBoolType FCSpi_Hw_ChkEnabled(FCSPI_InstanceType eInst) +{ + return (FCSPI_AtomicBoolType)((FCSPI_HWA_GetCtrlValue(s_atFCSpiInfo[eInst].tFCSpiInstance) & + FCSPI_CTRL_M_EN_MASK) >> FCSPI_CTRL_M_EN_SHIFT); +} +#endif + +static FCSPI_StatusType FCSpi_Hw_Disable(FCSPI_InstanceType eInst) +{ + FCSPI_StatusType eStatus = FCSPI_STATUS_SUCCESS; + + if (0U != (FCSPI_HWA_GetStatus(s_atFCSpiInfo[eInst].tFCSpiInstance) & FCSPI_STATUS_BF_MASK)) + { + eStatus = FCSPI_STATUS_BUSY; + } + else + { + FCSPI_HWA_ModuleDisable(s_atFCSpiInfo[eInst].tFCSpiInstance); + } + + return eStatus; +} + +static void FCSpi_Hw_ClearSomeStatusW1CFlag( + FCSPI_InstanceType eInst, uint32_t u32FlagBitSet) /* refer to FCSPI_DRV_STATUS_REG_W1C_U32 */ +{ + FCSPI_HWA_ClearStatus(s_atFCSpiInfo[eInst].tFCSpiInstance, (u32FlagBitSet & FCSPI_DRV_STATUS_REG_W1C_MASK_U32)); +} + +#ifdef FCSPI_DRV_INTERNAL_FUNC_EN +static void FCSpi_Hw_SetAllInterruptEnableStatus( + FCSPI_InstanceType eInst, uint32_t u32Interrupts) /* refer to FCSPI_DRV_INT_EN_REG_ALL_U32 */ +{ + FCSPI_HWA_SetInterruptEnableReg(s_atFCSpiInfo[eInst].tFCSpiInstance, (u32Interrupts & FCSPI_INT_EN_MASK)); +} + +static uint32_t FCSpi_Hw_GetAllInterruptEnableStatus(FCSPI_InstanceType eInst) +{ + return FCSPI_HWA_GetIntrruptEnableReg(s_atFCSpiInfo[eInst].tFCSpiInstance); +} +#endif + +static void FCSpi_Hw_EnableMoreInterrupts(FCSPI_InstanceType eInst, uint32_t u32Interrupts) +{ + uint32_t u32RegVal = FCSPI_HWA_GetIntrruptEnableReg(s_atFCSpiInfo[eInst].tFCSpiInstance); + u32RegVal |= (u32Interrupts & FCSPI_INT_EN_MASK); + + FCSPI_HWA_SetInterruptEnableReg(s_atFCSpiInfo[eInst].tFCSpiInstance, u32RegVal); +} + +static void FCSpi_Hw_DisableSomeInterrupts(FCSPI_InstanceType eInst, uint32_t u32Interrupts) +{ + uint32_t u32RegVal = FCSPI_HWA_GetIntrruptEnableReg(s_atFCSpiInfo[eInst].tFCSpiInstance); + u32RegVal &= (~(u32Interrupts & FCSPI_INT_EN_MASK)); + + FCSPI_HWA_SetInterruptEnableReg(s_atFCSpiInfo[eInst].tFCSpiInstance, u32RegVal); +} + +static void FCSpi_Hw_SetRxTxDmaEnableStatus( + FCSPI_InstanceType eInst, FCSPI_AtomicBoolType eRxEnable, FCSPI_AtomicBoolType eTxEnable) +{ + uint32_t u32Flag = 0U; + + if (eRxEnable) + { + u32Flag |= FCSPI_DMA_EN_RFDE(1); + } + + if (eTxEnable) + { + u32Flag |= FCSPI_DMA_EN_TFDE(1); + } + + FCSPI_HWA_SetDMAEnableReg(s_atFCSpiInfo[eInst].tFCSpiInstance, u32Flag); +} + +#ifdef FCSPI_DRV_INTERNAL_FUNC_EN +static void FCSpi_Hw_SetRxDmaEnableStatus(FCSPI_InstanceType eInst, FCSPI_AtomicBoolType eEnable) +{ + uint32_t u32RegVal = FCSPI_HWA_GetDMAEnableReg(s_atFCSpiInfo[eInst].tFCSpiInstance); + + if (eEnable) + { + u32RegVal |= FCSPI_DMA_EN_RFDE(1); + } + else + { + u32RegVal &= (~(FCSPI_DMA_EN_RFDE_MASK)); + } + + FCSPI_HWA_SetDMAEnableReg(s_atFCSpiInfo[eInst].tFCSpiInstance, u32RegVal); +} + +static void FCSpi_Hw_SetTxDmaEnableStatus(FCSPI_InstanceType eInst, FCSPI_AtomicBoolType eEnable) +{ + uint32_t u32RegVal = FCSPI_HWA_GetDMAEnableReg(s_atFCSpiInfo[eInst].tFCSpiInstance); + + if (FCSPI_TRUE == eEnable) + { + u32RegVal |= FCSPI_DMA_EN_TFDE(1); + } + else + { + u32RegVal &= (~(FCSPI_DMA_EN_TFDE_MASK)); + } + + FCSPI_HWA_SetDMAEnableReg(s_atFCSpiInfo[eInst].tFCSpiInstance, u32RegVal); +} +#endif + +static void FCSpi_Hw_SetPcs_2_3_Mode(FCSPI_InstanceType eInst, FCSPI_PCS2_3ModeType eMode) +{ + uint32_t u32RegVal = FCSPI_HWA_GetCFG1Reg(s_atFCSpiInfo[eInst].tFCSpiInstance); + + if (PCS2_3_PCS == eMode) + { + u32RegVal &= (~(FCSPI_CFG1_PCS_CFG_MASK)); + } + else + { + u32RegVal |= (FCSPI_CFGR1_PCS23_DATABUS_IN_4BIT_MODE_U32); + } + + FCSPI_HWA_SetCFG1Reg(s_atFCSpiInfo[eInst].tFCSpiInstance, u32RegVal); +} + +static void FCSpi_Hw_SetPin(FCSPI_InstanceType eInst, + FCSPI_PinModeType eMode, FCSPI_NegatedPinOutStatType eStat) +{ + uint32_t u32Flag = FCSPI_HWA_GetCFG1Reg(s_atFCSpiInfo[eInst].tFCSpiInstance); + + u32Flag &= (~(FCSPI_CFG1_PIN_CFG_MASK)); + u32Flag &= (~(FCSPI_CFG1_OUT_CFG_MASK)); + + switch (eMode) + { + case SIN_INPUT_OUTPUT: + u32Flag |= FCSPI_CFGR1_PINCFG_SIN_INPUT_OUTPUT_U32; + break; + case SOUT_INPUT_OUTPUT: + u32Flag |= FCSPI_CFGR1_PINCFG_SOUT_INPUT_OUTPUT_U32; + break; + case SOUT_INPUT_SIN_OUTPUT: + u32Flag |= FCSPI_CFGR1_PINCFG_SOUT_INPUT_SIN_OUTPUT_U32; + break; + case SIN_INPUT_SOUT_OUTPUT: + u32Flag |= FCSPI_CFGR1_PINCFG_SIN_INPUT_SOUT_OUTPUT_U32; + break; + default: + u32Flag |= FCSPI_CFGR1_PINCFG_SIN_INPUT_SOUT_OUTPUT_U32; + break; + } + + if (PINOUT_RETAIN_LAST == eStat) + { + u32Flag |= FCSPI_CFGR1_OUTCFG_RETAIN_LAST_WHEN_NEGATE_U32; + } + else + { + u32Flag |= FCSPI_CFGR1_OUTCFG_TRISTATE_WHEN_NEGATE_U32; + } + + FCSPI_HWA_SetCFG1Reg(s_atFCSpiInfo[eInst].tFCSpiInstance, u32Flag); +} + +#ifdef FCSPI_DRV_INTERNAL_FUNC_EN +static void FCSpi_Hw_SetPcsPolarity(FCSPI_InstanceType eInst, + FCSPI_AtomicBoolType eSetPCS0, FCSPI_PcsPolarityType ePCS0Polarity, + FCSPI_AtomicBoolType eSetPCS1, FCSPI_PcsPolarityType ePCS1Polarity, + FCSPI_AtomicBoolType eSetPCS2, FCSPI_PcsPolarityType ePCS2Polarity, + FCSPI_AtomicBoolType eSetPCS3, FCSPI_PcsPolarityType ePCS3Polarity) +{ + uint32_t u32Flag = FCSPI_HWA_GetCFG1Reg(s_atFCSpiInfo[eInst].tFCSpiInstance); + + if (eSetPCS0) + { + if (FCSPI_PCS_POL_ACTIVE_HIGH == ePCS0Polarity) + u32Flag |= FCSPI_CFGR1_PCS0_ACTIVE_HIGH_U32; + else + u32Flag &= (~(FCSPI_CFGR1_PCS0_POL_MASK_U32)); + } + + if (eSetPCS1) + { + if (FCSPI_PCS_POL_ACTIVE_HIGH == ePCS1Polarity) + u32Flag |= FCSPI_CFGR1_PCS1_ACTIVE_HIGH_U32; + else + u32Flag &= (~(FCSPI_CFGR1_PCS1_POL_MASK_U32)); + } + + if (eSetPCS2) + { + if (FCSPI_PCS_POL_ACTIVE_HIGH == ePCS2Polarity) + u32Flag |= FCSPI_CFGR1_PCS2_ACTIVE_HIGH_U32; + else + u32Flag &= (~(FCSPI_CFGR1_PCS2_POL_MASK_U32)); + } + + if (eSetPCS3) + { + if (FCSPI_PCS_POL_ACTIVE_HIGH == ePCS3Polarity) + u32Flag |= FCSPI_CFGR1_PCS3_ACTIVE_HIGH_U32; + else + u32Flag &= (~(FCSPI_CFGR1_PCS3_POL_MASK_U32)); + } + + FCSPI_HWA_SetCFG1Reg(s_atFCSpiInfo[eInst].tFCSpiInstance, u32Flag); +} +#endif + +static void FCSpi_Hw_SetOnePcsPolarity(FCSPI_InstanceType eInst, + FCSPI_PCSType ePcs, FCSPI_PcsPolarityType ePolarity) +{ + uint32_t u32Flag = FCSPI_HWA_GetCFG1Reg(s_atFCSpiInfo[eInst].tFCSpiInstance); + + if (FCSPI_PCS_POL_ACTIVE_HIGH == ePolarity) + { + if (0U == ((((uint32_t)0x1) << (FCSPI_CFG1_PCS_POL_SHIFT + (uint32_t)ePcs)) & u32Flag)) + { + u32Flag |= (((uint32_t)0x1) << (FCSPI_CFG1_PCS_POL_SHIFT + (uint32_t)ePcs)); + } + } + else /* active low */ + { + if (0U != ((((uint32_t)0x1) << (FCSPI_CFG1_PCS_POL_SHIFT + (uint32_t)ePcs)) & u32Flag)) + { + u32Flag &= (~(((uint32_t)0x1) << (FCSPI_CFG1_PCS_POL_SHIFT + (uint32_t)ePcs))); + } + } + + FCSPI_HWA_SetCFG1Reg(s_atFCSpiInfo[eInst].tFCSpiInstance, u32Flag); +} + +/* before call this function, ensure in master mode */ +static void FCSpi_Hw_Master_SetSckLoopbackSample( + FCSPI_InstanceType eInst, FCSPI_AtomicBoolType eEnable) +{ + uint32_t u32Flag = FCSPI_HWA_GetCFG1Reg(s_atFCSpiInfo[eInst].tFCSpiInstance); + + if (FCSPI_TRUE == eEnable) + { + if (FCSPI_CFG1_SCK_LB(1) != (u32Flag & FCSPI_CFG1_SCK_LB_MASK)) + { + u32Flag |= FCSPI_CFG1_SCK_LB(1); + } + } + else + { + if (FCSPI_CFG1_SCK_LB(0) != (u32Flag & FCSPI_CFG1_SCK_LB_MASK)) + { + u32Flag &= (~(FCSPI_CFG1_SCK_LB_MASK)); + } + } + + FCSPI_HWA_SetCFG1Reg(s_atFCSpiInfo[eInst].tFCSpiInstance, u32Flag); +} + +static void FCSpi_Hw_Set_SCK_PCS_DIV_Hold(FCSPI_InstanceType eInst, + uint8_t u8SCKPCS, uint8_t u8PCSSCK, uint8_t u8PCSPCS, uint8_t u8SCKDIV) +{ + uint32_t u32Flag = FCSPI_HWA_GetClockConfig(s_atFCSpiInfo[eInst].tFCSpiInstance); + uint32_t u32Val; + + { + u32Val = u8SCKPCS; + u32Flag &= (~(FCSPI_CLK_CFG_SCKPCS_MASK)); + u32Flag |= (u32Val << FCSPI_CLK_CFG_SCKPCS_SHIFT); + } + + { + u32Val = u8PCSSCK; + u32Flag &= (~(FCSPI_CLK_CFG_PCSSCK_MASK)); + u32Flag |= (u32Val << FCSPI_CLK_CFG_PCSSCK_SHIFT); + } + + { + u32Val = u8PCSPCS; + u32Flag &= (~(FCSPI_CLK_CFG_PCSPCS_MASK)); + u32Flag |= (u32Val << FCSPI_CLK_CFG_PCSPCS_SHIFT); + } + + { + u32Val = u8SCKDIV; + u32Flag &= (~(FCSPI_CLK_CFG_SCKDIV_MASK)); + u32Flag |= (u32Val << FCSPI_CLK_CFG_SCKDIV_SHIFT); + } + + { + FCSPI_HWA_SetClockConfig(s_atFCSpiInfo[eInst].tFCSpiInstance, u32Flag); + } +} + +static void FCSpi_Hw_Set_SCK_PCS_Hold(FCSPI_InstanceType eInst, + uint8_t u8SCKPCS, uint8_t u8PCSSCK, uint8_t u8PCSPCS) +{ + uint32_t u32Flag = FCSPI_HWA_GetClockConfig(s_atFCSpiInfo[eInst].tFCSpiInstance); + uint32_t u32Val; + + { + u32Val = u8SCKPCS; + u32Flag &= (~(FCSPI_CLK_CFG_SCKPCS_MASK)); + u32Flag |= (u32Val << FCSPI_CLK_CFG_SCKPCS_SHIFT); + } + + { + u32Val = u8PCSSCK; + u32Flag &= (~(FCSPI_CLK_CFG_PCSSCK_MASK)); + u32Flag |= (u32Val << FCSPI_CLK_CFG_PCSSCK_SHIFT); + } + + { + u32Val = u8PCSPCS; + u32Flag &= (~(FCSPI_CLK_CFG_PCSPCS_MASK)); + u32Flag |= (u32Val << FCSPI_CLK_CFG_PCSPCS_SHIFT); + } + + { + FCSPI_HWA_SetClockConfig(s_atFCSpiInfo[eInst].tFCSpiInstance, u32Flag); + } +} + +static void FCSpi_Hw_Get_SCK_PCS_DIV_Hold(FCSPI_InstanceType eInst, + uint8_t *pbySCKPCS, + uint8_t *pbyPCSSCK, + uint8_t *pbyPCSPCS, + uint8_t *pbySCKDIV) +{ + uint32_t u32Flag = FCSPI_HWA_GetClockConfig(s_atFCSpiInfo[eInst].tFCSpiInstance); + + if (pbySCKPCS != NULL) + { + *pbySCKPCS = (uint8_t)((u32Flag & FCSPI_CLK_CFG_SCKPCS_MASK) >> FCSPI_CLK_CFG_SCKPCS_SHIFT); + } + + if (pbyPCSSCK != NULL) + { + *pbyPCSSCK = (uint8_t)((u32Flag & FCSPI_CLK_CFG_PCSSCK_MASK) >> FCSPI_CLK_CFG_PCSSCK_SHIFT); + } + + if (pbyPCSPCS != NULL) + { + *pbyPCSPCS = (uint8_t)((u32Flag & FCSPI_CLK_CFG_PCSPCS_MASK) >> FCSPI_CLK_CFG_PCSPCS_SHIFT); + } + + if (pbySCKDIV != NULL) + { + *pbySCKDIV = ((uint8_t)(u32Flag & FCSPI_CLK_CFG_SCKDIV_MASK) >> FCSPI_CLK_CFG_SCKDIV_SHIFT); + } +} + +#ifdef FCSPI_DRV_INTERNAL_FUNC_EN +static void FCSpi_Hw_GetTRCR(FCSPI_InstanceType eInst, FCSPI_TxRxCtrlType *ptCtrl) +{ + uint32_t u32Flag = FCSPI_HWA_GetTxRxControl(s_atFCSpiInfo[eInst].tFCSpiInstance); + + ptCtrl->eSckPolarity = (FCSPI_SckPolarityType) + ((u32Flag & FCSPI_TR_CTRL_SCK_POL_MASK) >> FCSPI_TR_CTRL_SCK_POL_SHIFT); + ptCtrl->eSckPhase = (FCSPI_SckSamplePhaseType) + ((u32Flag & FCSPI_TR_CTRL_SCK_PHA_MASK) >> FCSPI_TR_CTRL_SCK_PHA_SHIFT); + ptCtrl->ePrescalerValue = (FCSPI_PrescaleValueType) + ((u32Flag & FCSPI_TR_CTRL_PRESCALE_MASK) >> FCSPI_TR_CTRL_PRESCALE_SHIFT); + ptCtrl->ePCSSelect = (FCSPI_PCSType) + ((u32Flag & FCSPI_TR_CTRL_PCS_MASK) >> FCSPI_TR_CTRL_PCS_SHIFT); + ptCtrl->eBitFirstOrder = (FCSPI_BitFirstOrderType) + ((u32Flag & FCSPI_TR_CTRL_LSBF_MASK) >> FCSPI_TR_CTRL_LSBF_SHIFT); + ptCtrl->eByteSwap = (FCSPI_AtomicBoolType) + ((u32Flag & FCSPI_TR_CTRL_BYSW_MASK) >> FCSPI_TR_CTRL_BYSW_SHIFT); + ptCtrl->eContTransEnable = (FCSPI_AtomicBoolType) + ((u32Flag & FCSPI_TR_CTRL_CT_EN_MASK) >> FCSPI_TR_CTRL_CT_EN_SHIFT); + + ptCtrl->eContCmdEnable = (FCSPI_AtomicBoolType) + ((u32Flag & FCSPI_TR_CTRL_CT_GO_MASK) >> FCSPI_TR_CTRL_CT_GO_SHIFT); + ptCtrl->eRxDisable = (FCSPI_AtomicBoolType) + ((u32Flag & FCSPI_TR_CTRL_RX_MSK_MASK) >> FCSPI_TR_CTRL_RX_MSK_SHIFT); + ptCtrl->eTxDisable = (FCSPI_AtomicBoolType) + ((u32Flag & FCSPI_TR_CTRL_TX_MSK_MASK) >> FCSPI_TR_CTRL_TX_MSK_SHIFT); + ptCtrl->eTransferWidth = (FCSPI_TransferWidthType) + ((u32Flag & FCSPI_TR_CTRL_WIDTH_MASK) >> FCSPI_TR_CTRL_WIDTH_SHIFT); + ptCtrl->u16FrameBitCnt = (uint16_t) + (((u32Flag & FCSPI_TR_CTRL_FRM_SZ_MASK) >> FCSPI_TR_CTRL_FRM_SZ_SHIFT)+1); +} +#endif + +static FCSPI_StatusType FCSpi_Hw_SetTRCR(FCSPI_InstanceType eInst, FCSPI_TxRxCtrlType *ptCtrl) +{ + uint32_t u32Flag = 0U; + FCSPI_StatusType eRet = FCSPI_STATUS_SUCCESS; + + if ((ptCtrl->u16FrameBitCnt < ((uint16_t)8)) || + (((uint16_t)0) != (ptCtrl->u16FrameBitCnt & ((uint16_t)0x1)))) + { + eRet = FCSPI_STATUS_PARAM_ERR; + } + else + { + u32Flag |= (((uint32_t)(ptCtrl->eSckPolarity)) << FCSPI_TR_CTRL_SCK_POL_SHIFT); + u32Flag |= (((uint32_t)(ptCtrl->eSckPhase)) << FCSPI_TR_CTRL_SCK_PHA_SHIFT); + u32Flag |= (((uint32_t)(ptCtrl->ePrescalerValue)) << FCSPI_TR_CTRL_PRESCALE_SHIFT); + u32Flag |= (((uint32_t)(ptCtrl->ePCSSelect)) << FCSPI_TR_CTRL_PCS_SHIFT); + u32Flag |= (((uint32_t)(ptCtrl->eBitFirstOrder)) << FCSPI_TR_CTRL_LSBF_SHIFT); + u32Flag |= (((uint32_t)(ptCtrl->eByteSwap)) << FCSPI_TR_CTRL_BYSW_SHIFT); + u32Flag |= (((uint32_t)(ptCtrl->eContTransEnable)) << FCSPI_TR_CTRL_CT_EN_SHIFT); + u32Flag |= (((uint32_t)(ptCtrl->eContCmdEnable)) << FCSPI_TR_CTRL_CT_GO_SHIFT); + u32Flag |= (((uint32_t)(ptCtrl->eRxDisable)) << FCSPI_TR_CTRL_RX_MSK_SHIFT); + u32Flag |= (((uint32_t)(ptCtrl->eTxDisable)) << FCSPI_TR_CTRL_TX_MSK_SHIFT); + u32Flag |= (((uint32_t)(ptCtrl->eTransferWidth)) << FCSPI_TR_CTRL_WIDTH_SHIFT); + u32Flag |= (((uint32_t)((uint16_t)(ptCtrl->u16FrameBitCnt - (uint16_t)1))) << FCSPI_TR_CTRL_FRM_SZ_SHIFT); + + FCSPI_HWA_SetTxRxControl(s_atFCSpiInfo[eInst].tFCSpiInstance, u32Flag); + } + + return eRet; +} + +/* caution:write TR_CTRL */ +static void FCSpi_Hw_SelectUsePcs(FCSPI_InstanceType eInst, FCSPI_PCSType ePCS) +{ + uint32_t u32Flag = FCSPI_HWA_GetTxRxControl(s_atFCSpiInfo[eInst].tFCSpiInstance); + + u32Flag &= (~(FCSPI_TR_CTRL_PCS_MASK)); + u32Flag |= (((uint32_t)ePCS) << FCSPI_TR_CTRL_PCS_SHIFT); + + FCSPI_HWA_SetTxRxControl(s_atFCSpiInfo[eInst].tFCSpiInstance, u32Flag); +} + +static FCSPI_PrescaleValueType FCSpi_Hw_GetRegPrescalerVal(FCSPI_InstanceType eInst) +{ + return (FCSPI_PrescaleValueType)((FCSPI_HWA_GetTxRxControl(s_atFCSpiInfo[eInst].tFCSpiInstance) & + FCSPI_TR_CTRL_PRESCALE_MASK) >> FCSPI_TR_CTRL_PRESCALE_SHIFT); +} + +/* caution:write TR_CTRL */ +static void FCSpi_Hw_SetContinuousCommand(FCSPI_InstanceType eInst, FCSPI_AtomicBoolType eEnable) +{ + uint32_t u32Flag = FCSPI_HWA_GetTxRxControl(s_atFCSpiInfo[eInst].tFCSpiInstance); + + u32Flag &= (~(FCSPI_TR_CTRL_CT_GO_MASK)); + u32Flag |= (((uint32_t)eEnable) << FCSPI_TR_CTRL_CT_GO_SHIFT); + + FCSPI_HWA_SetTxRxControl(s_atFCSpiInfo[eInst].tFCSpiInstance, u32Flag); +} + +#ifdef FCSPI_DRV_INTERNAL_FUNC_EN +static uint32_t FCSpi_Hw_ReadRxFifoFirstEntry(FCSPI_InstanceType eInst) +{ + return FCSPI_HWA_ReadData(s_atFCSpiInfo[eInst].tFCSpiInstance); +} +#endif + +#ifdef FCSPI_DRV_INTERNAL_FUNC_EN +static void FCSpi_Hw_WriteDataToTxFifo(FCSPI_InstanceType eInst, uint32_t u32TxData) +{ + FCSPI_HWA_WriteData(s_atFCSpiInfo[eInst].tFCSpiInstance, u32TxData); +} +#endif + +/* + * Before call this function, ensure the FCSPI is disabled and in MASTER mode. + * Src Clk -> Prescaler -> sck divider -> SCLK + */ +#define FCSPI_CAL_DISTANCE(x, y) ((x) > (y) ? ((x) - (y)) : ((y) - (x))) +typedef struct { + uint32_t u32CacheTargetBps; + uint32_t u32CacheSrcClkHz; + uint32_t u32CachePrescaleRegVal; + uint32_t u32CacheBps; + uint32_t u32CacheSckDiv; +} FCSPI_BaundrateCacheType; +#define FCSPI_PCS_CLK_CACHE_CNT ((uint8_t)2) + +/* Often use case, just set the same baundrate for specific external device linked with one FCSPI PCS */ +static uint32_t FCSpi_Hw_Master_CalcBaudRate(const FCSPI_MasterCfgType *pCfg, + uint32_t *pdwPrescaleRegVal, uint32_t *pdwActualSckDiv) +{ + uint32_t u32TargetBps = pCfg->u32BitCntPerSecond; + uint32_t u32SrcClkHz = pCfg->u32FCSpiSrcClk; + uint32_t u32TestFreq = 0U; + int16_t s16TestSckDivRegVal = (int16_t)0; + uint8_t u8PrescalerRegVal = (uint8_t)0; + int16_t s16SckDivLow, s16SckDivHigh; + uint32_t u32Prescale = 0U; + uint32_t u32ActualBps = 0U; + uint32_t u32ActualSckDiv = 0U; + uint32_t u32ActualPrescaleRegVal = 0U; + uint32_t u32ThisPrescaleBestBps = 0U; + uint32_t u32ThisPrescaleBestSckDiv = 0U; + uint32_t u32AbsDistance1, u32AbsDistance2; + uint8_t u8Find = (uint8_t)0; + uint32_t u32Ret = 0U; + + if (u32SrcClkHz < (u32TargetBps * 2U)) + { + u32Ret = 0U; + } + else + { + if ((uint8_t)0 == u8Find) + { + u32ActualSckDiv = 0U; + u32ActualPrescaleRegVal = 0U; + u32ActualBps = (uint32_t)(u32SrcClkHz / ((uint32_t)((((uint32_t)1) << + u32ActualPrescaleRegVal) * (u32ActualSckDiv + (uint32_t)2U)))); + + for (u8PrescalerRegVal = (uint8_t)0; u8PrescalerRegVal < FCSPI_PRESCALE_MAX; ++u8PrescalerRegVal) + { + s16SckDivLow = (int16_t)0; + + if ((FCSPI_SCK_SAMPLE_SECOND_EDGE == pCfg->eSckSamplePhase) && /* sample the 2nd edge */ + (FCSPI_FALSE != pCfg->eIsPcsContinuous)) /* continuous pcs */ + { + /* hw bug fix, sck must be 0 */ + s16SckDivHigh = (int16_t)0; + } + else + { + s16SckDivHigh = (int16_t)255; + } + + u32Prescale = ((uint32_t)1) << u8PrescalerRegVal; + u32ThisPrescaleBestSckDiv = 0U; + u32ThisPrescaleBestBps = (uint32_t)(u32SrcClkHz / ((uint32_t)(u32Prescale * + (u32ThisPrescaleBestSckDiv + (uint32_t)2U)))); + + while(s16SckDivHigh > s16SckDivLow) + { + s16TestSckDivRegVal = s16SckDivLow + s16SckDivHigh; + s16TestSckDivRegVal = (s16TestSckDivRegVal / (int16_t)2); + u32TestFreq = (uint32_t)(u32SrcClkHz / + ((uint32_t)(u32Prescale * ((uint32_t)s16TestSckDivRegVal + (uint32_t)2U)))); + + u32AbsDistance1 = FCSPI_CAL_DISTANCE(u32TargetBps, u32ThisPrescaleBestBps); + u32AbsDistance2 = FCSPI_CAL_DISTANCE(u32TargetBps, u32TestFreq); + if (u32AbsDistance1 > u32AbsDistance2) + { + u32ThisPrescaleBestBps = u32TestFreq; + u32ThisPrescaleBestSckDiv = (uint32_t)s16TestSckDivRegVal; + } + + if (u32TestFreq == u32TargetBps) + { + break; + } + else if (u32TestFreq < u32TargetBps) + { + s16SckDivHigh = s16TestSckDivRegVal - 1; + } + else + { + s16SckDivLow = s16TestSckDivRegVal + 1; + } + } + + u32AbsDistance1 = FCSPI_CAL_DISTANCE(u32TargetBps, u32ActualBps); + u32AbsDistance2 = FCSPI_CAL_DISTANCE(u32TargetBps, u32ThisPrescaleBestBps); + if (u32AbsDistance1 > u32AbsDistance2) + { + u32ActualBps = u32ThisPrescaleBestBps; + u32ActualSckDiv = u32ThisPrescaleBestSckDiv; + u32ActualPrescaleRegVal = u8PrescalerRegVal; + } + + if(u32ThisPrescaleBestBps == u32TargetBps) + { + break; + } + } + + if (0U != u32ActualBps) + { + if (NULL != pdwActualSckDiv) + { + *pdwActualSckDiv = u32ActualSckDiv; + } + + if (NULL != pdwPrescaleRegVal) + { + *pdwPrescaleRegVal = u32ActualPrescaleRegVal; + } + } + + /* return the actual calculated baud rate */ + u32Ret = u32ActualBps; + } + } + + return u32Ret; +} + +/* Master/Slave side all use */ + +static void fcspi_read_rx_fifo(FCSPI_InstanceType eInst) +{ + uint32_t u32RxWordData = 0U; + uint16_t u16ByteCount = (uint16_t)0; + uint8_t u8ByteIndex = (uint8_t)0; + uint8_t u8WordCntInRxFifo = FCSPI_HWA_GetRxFifoStoredCount(s_atFCSpiInfo[eInst].tFCSpiInstance); + + while (u8WordCntInRxFifo > (uint8_t)0) + { + u32RxWordData = FCSPI_HWA_ReadData(s_atFCSpiInfo[eInst].tFCSpiInstance); + /* Get the number of bytes which can be read from this 32 bites */ + if (s_atFCSpiInfo[eInst].tFCSpiStat.u16BytesCntFrameNeed <= + (s_atFCSpiInfo[eInst].tFCSpiStat.u16RxGetByteCntOfCurFrame + (uint16_t)4)) + { + u16ByteCount = (uint16_t)(s_atFCSpiInfo[eInst].tFCSpiStat.u16BytesCntFrameNeed - + s_atFCSpiInfo[eInst].tFCSpiStat.u16RxGetByteCntOfCurFrame); + } + else + { + u16ByteCount = (uint16_t)4; + } + + /* Generate the word which will be write in buffer. */ + for (u8ByteIndex = (uint8_t)0; u8ByteIndex < u16ByteCount; ++u8ByteIndex) + { + (s_atFCSpiInfo[eInst].tFCSpiStat.pbyRxBuff)[s_atFCSpiInfo[eInst].tFCSpiStat.u16RxIndex] = + (uint8_t)((u32RxWordData >> (uint32_t)((uint32_t)u8ByteIndex * (uint32_t)8)) & (uint8_t)0xFF); + (s_atFCSpiInfo[eInst].tFCSpiStat.u16RxIndex)++; + } + + s_atFCSpiInfo[eInst].tFCSpiStat.u16RxGetByteCntOfCurFrame = + (uint16_t)((s_atFCSpiInfo[eInst].tFCSpiStat.u16RxGetByteCntOfCurFrame + + u16ByteCount) % s_atFCSpiInfo[eInst].tFCSpiStat.u16BytesCntFrameNeed); + + /* Update internal variable used in transmission. */ + s_atFCSpiInfo[eInst].tFCSpiStat.u16RxByteCntRemainToGet = + (uint16_t)(s_atFCSpiInfo[eInst].tFCSpiStat.u16RxByteCntRemainToGet - u16ByteCount); + /* Verify if all bytes were sent. */ + if ((uint16_t)0 == s_atFCSpiInfo[eInst].tFCSpiStat.u16RxByteCntRemainToGet) + { + break; + } + + u8WordCntInRxFifo--; + } +} + +static void fcspi_write_tx_fifo(FCSPI_InstanceType eInst) +{ + uint32_t u32DataToSend = 0U; + uint16_t u16ThisSendByteCnt = (uint16_t)0; + uint8_t u8TxFifoFreeWordCnt = (uint8_t)(s_atFCSpiInfo[eInst].tFCSpiStat.u8TxFifoSize - + (uint8_t)FCSPI_HWA_GetTxFifoStoredCount(s_atFCSpiInfo[eInst].tFCSpiInstance)); + uint16_t u16BytesTxLeft = s_atFCSpiInfo[eInst].tFCSpiStat.u16TxByteCntRemainToSend; + + while ((u8TxFifoFreeWordCnt != (uint8_t)0) && ((uint16_t)0 != u16BytesTxLeft)) + { + if (FCSPI_TRUE == s_atFCSpiInfo[eInst].tFCSpiStat.eIsPcsContinuous) + { + if((uint16_t)1 == s_atFCSpiInfo[eInst].tFCSpiStat.u16TxByteCntRemainToSend) + { + /* Disable continuous PCS */ + FCSpi_Hw_SetContinuousCommand(eInst, FCSPI_FALSE); + s_atFCSpiInfo[eInst].tFCSpiStat.u16TxByteCntRemainToSend = (uint16_t)0; + u16BytesTxLeft = (uint16_t)0; + break; + } + } + + /* Get the number of bytes which can be written in a single 32 bits word. */ + if ((s_atFCSpiInfo[eInst].tFCSpiStat.u16BytesCntFrameNeed - + s_atFCSpiInfo[eInst].tFCSpiStat.u16TxSendByteCntOfCurFrame) <= (uint16_t)4) + { + u16ThisSendByteCnt = (uint16_t)(s_atFCSpiInfo[eInst].tFCSpiStat.u16BytesCntFrameNeed - + s_atFCSpiInfo[eInst].tFCSpiStat.u16TxSendByteCntOfCurFrame); + } + else + { + u16ThisSendByteCnt = (uint16_t)4; + } + + u32DataToSend = 0U; + + if (NULL != s_atFCSpiInfo[eInst].tFCSpiStat.pbyTxBuff) + { + switch(s_atFCSpiInfo[eInst].tFCSpiStat.u16BytesCntFrameNeed) + { + case 1: + u32DataToSend = *((const uint8_t *)&(s_atFCSpiInfo[eInst].tFCSpiStat.pbyTxBuff[s_atFCSpiInfo[eInst].tFCSpiStat.u16TxIndex])); + s_atFCSpiInfo[eInst].tFCSpiStat.u16TxIndex += sizeof(uint8_t); + break; + + case 2: + u32DataToSend = *((const uint16_t *)&(s_atFCSpiInfo[eInst].tFCSpiStat.pbyTxBuff[s_atFCSpiInfo[eInst].tFCSpiStat.u16TxIndex])); + s_atFCSpiInfo[eInst].tFCSpiStat.u16TxIndex += sizeof(uint16_t); + break; + + default: + u32DataToSend = *((const uint32_t *)&(s_atFCSpiInfo[eInst].tFCSpiStat.pbyTxBuff[s_atFCSpiInfo[eInst].tFCSpiStat.u16TxIndex])); + s_atFCSpiInfo[eInst].tFCSpiStat.u16TxIndex += sizeof(uint32_t); + break; + } + + s_atFCSpiInfo[eInst].tFCSpiStat.u16TxSendByteCntOfCurFrame = + (uint16_t)((s_atFCSpiInfo[eInst].tFCSpiStat.u16TxSendByteCntOfCurFrame + u16ThisSendByteCnt) % + s_atFCSpiInfo[eInst].tFCSpiStat.u16BytesCntFrameNeed); + } + + FCSPI_HWA_WriteData(s_atFCSpiInfo[eInst].tFCSpiInstance, u32DataToSend); + /* Update internal variable used in transmission. */ + s_atFCSpiInfo[eInst].tFCSpiStat.u16TxByteCntRemainToSend -= u16ThisSendByteCnt; + u16BytesTxLeft = s_atFCSpiInfo[eInst].tFCSpiStat.u16TxByteCntRemainToSend; + u8TxFifoFreeWordCnt -= (uint8_t)1; + } +} + +/* MASTER side API */ +/*----------------------------------------------------------------------------*/ +/** + * @brief Init the FCSpi instance as spi master side + * + * @param eInst Which FCSpi Hardware instance + * @param pCfg Configuration of the FCSpi, MUST NOT NULL + * @return FCSPI_StatusType FCSPI_STATUS_SUCCESS when configure successfully. Others, some error occur. + */ +FCSPI_StatusType FCSPI_Master_Init(const FCSPI_InstanceType eInst, const FCSPI_MasterCfgType *pCfg) +{ + uint32_t u32BaudRate = 0U; + uint32_t u32PrescaleRegVal = 0U; + uint32_t u32SckDiv = 0U; + FCSPI_TxRxCtrlType tTxRxCtrlCfg; + FCSPI_StatusType eRet = FCSPI_STATUS_SUCCESS; + + if (NULL != pCfg) + { + if ((pCfg->u16BitCountPerFrame >= (uint16_t)8) && + (pCfg->u16BitCountPerFrame <= (uint16_t)4096)) /* TR_CTRL[FRM_SZ] 12bits */ + { + u32BaudRate = FCSpi_Hw_Master_CalcBaudRate(pCfg, &u32PrescaleRegVal, &u32SckDiv); + if (0U != u32BaudRate) + { + FCSpi_Hw_Reset(eInst, FCSPI_FALSE, FCSPI_FALSE, FCSPI_TRUE); + FCSPI_HWA_SetMasterMode(s_atFCSpiInfo[eInst].tFCSpiInstance); + FCSpi_Hw_SetPcs_2_3_Mode(eInst, PCS2_3_PCS); + FCSpi_Hw_SetPin(eInst, SIN_INPUT_SOUT_OUTPUT, PINOUT_RETAIN_LAST); + + /* set internal state parameters for spi */ + s_atFCSpiInfo[eInst].tFCSpiStat.u8TxFifoSize = (uint8_t)FCSPI_DRV_TX_FIFO_WORD_CNT; + s_atFCSpiInfo[eInst].tFCSpiStat.u8RxFifoSize = (uint8_t)FCSPI_DRV_RX_FIFO_WORD_CNT; + s_atFCSpiInfo[eInst].tFCSpiStat.u32DmaDummyData = 0U; + s_atFCSpiInfo[eInst].tFCSpiStat.u16BitsPerFrame = pCfg->u16BitCountPerFrame; + s_atFCSpiInfo[eInst].tFCSpiStat.u16BytesCntFrameNeed = (uint16_t)(((pCfg->u16BitCountPerFrame + (uint16_t)7)) >> (uint16_t)3); + s_atFCSpiInfo[eInst].tFCSpiStat.eIsPcsContinuous = pCfg->eIsPcsContinuous; + s_atFCSpiInfo[eInst].tFCSpiStat.u32FCSpiSrcClk = pCfg->u32FCSpiSrcClk; + s_atFCSpiInfo[eInst].tFCSpiStat.eIsInTransfer = FCSPI_FALSE; + s_atFCSpiInfo[eInst].tFCSpiStat.eBitFirstOrder = pCfg->eBitFirstOrder; + s_atFCSpiInfo[eInst].tFCSpiStat.eTransferTriggerSrc = pCfg->eTransferTriggerSrc; + s_atFCSpiInfo[eInst].tFCSpiStat.eSckPolarity = pCfg->eSckPolarity; + s_atFCSpiInfo[eInst].tFCSpiStat.eSckSamplePhase = pCfg->eSckSamplePhase; + s_atFCSpiInfo[eInst].tFCSpiStat.ePcs = pCfg->ePcs; + s_atFCSpiInfo[eInst].tFCSpiStat.ePcsPolarity = pCfg->ePcsPolarity; + s_atFCSpiInfo[eInst].tFCSpiStat.u32Baundrate = u32BaudRate; + + /* DMA require frames of 3 bytes per frame handled as 4 bytes per frame. */ + if (s_atFCSpiInfo[eInst].tFCSpiStat.u16BytesCntFrameNeed == (uint16_t)3) + { + s_atFCSpiInfo[eInst].tFCSpiStat.u16BytesCntFrameNeed = (uint16_t)4; + } + /* 4 bytes align requirement when > 32bits */ + if (s_atFCSpiInfo[eInst].tFCSpiStat.u16BytesCntFrameNeed > (uint16_t)4) + { + s_atFCSpiInfo[eInst].tFCSpiStat.u16BytesCntFrameNeed = + ((((s_atFCSpiInfo[eInst].tFCSpiStat.u16BytesCntFrameNeed + (uint16_t)3)) >> (uint16_t)2)) << (uint16_t)2; + } + + s_atFCSpiInfo[eInst].tFCSpiStat.tTriggerDmaInf = pCfg->tTriggerDmaInf; + s_atFCSpiInfo[eInst].tFCSpiStat.pStopNotifyCb = pCfg->pStopNotifyCb; + s_atFCSpiInfo[eInst].tFCSpiStat.pSemaResetCb = pCfg->pSemaResetCb; + s_atFCSpiInfo[eInst].tFCSpiStat.pSemaTakeCb = pCfg->pSemaTakeCb; + s_atFCSpiInfo[eInst].tFCSpiStat.pSemaPostCb = pCfg->pSemaPostCb; + + /* Configure the desired PCS polarity */ + FCSpi_Hw_SetOnePcsPolarity(eInst, pCfg->ePcs, pCfg->ePcsPolarity); + + /* enable sample delay */ + FCSpi_Hw_Master_SetSckLoopbackSample(eInst, FCSPI_TRUE); + + /* set up the baudrate */ + FCSpi_Hw_Set_SCK_PCS_DIV_Hold(eInst, + (uint8_t)(u32SckDiv >> 2U), + (uint8_t)(u32SckDiv >> 2U), + (uint8_t)(u32SckDiv >> 2U), + (uint8_t)u32SckDiv); /* write best baudrate scaler to SCKDIV */ + + /* Write the TCR for this transfer. */ + tTxRxCtrlCfg.eSckPolarity = pCfg->eSckPolarity; + tTxRxCtrlCfg.eSckPhase = pCfg->eSckSamplePhase; + tTxRxCtrlCfg.ePrescalerValue = (FCSPI_PrescaleValueType)u32PrescaleRegVal; + tTxRxCtrlCfg.ePCSSelect = pCfg->ePcs; + tTxRxCtrlCfg.eBitFirstOrder = pCfg->eBitFirstOrder; + tTxRxCtrlCfg.eByteSwap = FCSPI_FALSE; + tTxRxCtrlCfg.eContTransEnable = pCfg->eIsPcsContinuous; + tTxRxCtrlCfg.eContCmdEnable = FCSPI_FALSE; + tTxRxCtrlCfg.eRxDisable = FCSPI_FALSE; + tTxRxCtrlCfg.eTxDisable = FCSPI_FALSE; + tTxRxCtrlCfg.eTransferWidth = FCSPI_TRANSFER_1_BIT; + tTxRxCtrlCfg.u16FrameBitCnt = pCfg->u16BitCountPerFrame; + eRet = FCSpi_Hw_SetTRCR(eInst, &tTxRxCtrlCfg); + + if (FCSPI_STATUS_SUCCESS == eRet) + { + if (FCSPI_TRANSFER_TRIGGER_SRC_USER_POLL != pCfg->eTransferTriggerSrc) + { + IntMgr_EnableInterrupt(s_atFCSpiInfo[eInst].eFCSpiIrq); + } + + FCSPI_HWA_ModuleEnable(s_atFCSpiInfo[eInst].tFCSpiInstance); + } + else + { + eRet = FCSPI_STATUS_ERROR; + } + } + else + { + eRet = FCSPI_STATUS_ERROR; + } + } + else + { + eRet = FCSPI_STATUS_PARAM_ERR; + } + } + else + { + eRet = FCSPI_STATUS_PARAM_ERR; + } + + return eRet; +} + +/** + * @brief Deinit the FCSpi + * + * @param eInst Which FCSpi Hardware instance + * @return FCSPI_StatusType FCSPI_STATUS_SUCCESS when deinit the FCSpi successfully. Others, the hardware is busy now. + */ +FCSPI_StatusType FCSPI_Deinit(const FCSPI_InstanceType eInst) +{ + FCSPI_StatusType eRet = FCSPI_STATUS_SUCCESS; + + if (FCSPI_TRUE != s_atFCSpiInfo[eInst].tFCSpiStat.eIsInTransfer) + { + /* reset registers, disabling spi module */ + FCSpi_Hw_Reset(eInst, FCSPI_FALSE, FCSPI_FALSE, FCSPI_TRUE); + } + else + { + eRet = FCSPI_STATUS_BUSY; + } + + return eRet; +} + +/** + * @brief Configure the holding time (in us) between PCS and SCK + * + * @param eInst Which FCSpi Hardware instance + * @param pCfg Configure the delay parameters between PCS and SCK, MUST NOT null + * @return FCSPI_StatusType FCSPI_STATUS_SUCCESS when configure successfully. Others, the hardware is busy now. + */ +FCSPI_StatusType FCSPI_Master_SetSckPcsHoldTime(const FCSPI_InstanceType eInst, + const FCSPI_MasterSckPcsHoldTimeType *pCfg) +{ + FCSPI_StatusType eStat = FCSPI_STATUS_SUCCESS; + uint32_t u32PCSPCSCycle, + u32SCKPCSCycle, + u32PCSSCKCycle; + FCSPI_PrescaleValueType ePrescaler; + uint32_t u32PrescaleValue; + uint32_t u32ClkAfterScalePerUs; + + if (NULL != pCfg) + { + /* disable FCSPI first */ + eStat = FCSpi_Hw_Disable(eInst); + if (FCSPI_STATUS_SUCCESS == eStat) + { + ePrescaler = FCSpi_Hw_GetRegPrescalerVal(eInst); + u32PrescaleValue = FCSpi_Hw_PrescalerRegToActualVal(ePrescaler); + if (0U != u32PrescaleValue) /* actually unreachable */ + { + u32ClkAfterScalePerUs = (uint32_t)(s_atFCSpiInfo[eInst].tFCSpiStat.u32FCSpiSrcClk / + u32PrescaleValue / (uint32_t)1000000); + u32PCSPCSCycle = pCfg->u32PCStoPCSHoldUs * u32ClkAfterScalePerUs; + u32SCKPCSCycle = pCfg->u32SCKtoPCSHoldUs * u32ClkAfterScalePerUs; + u32PCSSCKCycle = pCfg->u32PCStoSCKHoldUs * u32ClkAfterScalePerUs; + + if (u32PCSPCSCycle > (uint32_t)257U) + { + u32PCSPCSCycle = (uint32_t)257U; + } + + if(u32SCKPCSCycle > (uint32_t)256U) + { + u32SCKPCSCycle = (uint32_t)256U; + } + + if(u32PCSSCKCycle > (uint32_t)256U) + { + u32PCSSCKCycle = (uint32_t)256U; + } + + if (u32PCSPCSCycle < (uint32_t)2U) + { + u32PCSPCSCycle = (uint32_t)2U; + } + + if(u32SCKPCSCycle == (uint32_t)0) + { + u32SCKPCSCycle = (uint32_t)1U; + } + + if(u32PCSSCKCycle == (uint32_t)0U) + { + u32PCSSCKCycle = (uint32_t)1U; + } + + FCSpi_Hw_Set_SCK_PCS_Hold(eInst, + (uint8_t)(u32SCKPCSCycle - 1U), + (uint8_t)(u32PCSSCKCycle - 1U), + (uint8_t)(u32PCSPCSCycle - 2U)); + /* Enable module */ + FCSPI_HWA_ModuleEnable(s_atFCSpiInfo[eInst].tFCSpiInstance); + } + else + { + eStat = FCSPI_STATUS_ERROR; + } + } + else + { + eStat = FCSPI_STATUS_BUSY; + } + } + else + { + eStat = FCSPI_STATUS_PARAM_ERR; + } + + return eStat; +} + +/** + * @brief Configure the holding time (in SCK/100) between PCS and SCK + * + * @param eInst Which FCSpi Hardware instance + * @param pCfg Configure the delay parameters between PCS and SCK, MUST NOT null + * @return FCSPI_StatusType FCSPI_STATUS_SUCCESS when configure successfully. Others, the hardware is busy now. + */ +FCSPI_StatusType FCSPI_Master_SetSckPcsHoldSckPercentage( + const FCSPI_InstanceType eInst, const FCSPI_MasterSckPcsHoldSckCycleType *pCfg) +{ + uint8_t u8PCSPCSCycle; + uint8_t u8SCKPCSCycle; + uint8_t u8PCSSCKCycle; + uint8_t u8SckDiv; + FCSPI_StatusType eRet = FCSPI_STATUS_SUCCESS; + + if (NULL != pCfg) + { + /* disable FCSPI first */ + eRet = FCSpi_Hw_Disable(eInst); + if (FCSPI_STATUS_SUCCESS == eRet) + { + FCSpi_Hw_Get_SCK_PCS_DIV_Hold(eInst, NULL, NULL, NULL, &u8SckDiv); + + u8PCSPCSCycle = (uint8_t)((uint32_t)pCfg->u32PCStoPCSHoldPercentage * + (uint32_t)u8SckDiv / (uint32_t)100); + u8SCKPCSCycle = (uint8_t)((uint32_t)pCfg->u32SCKtoPCSHoldPercentage * + (uint32_t)u8SckDiv / (uint32_t)100); + u8PCSSCKCycle = (uint8_t)((uint32_t)pCfg->u32PCStoSCKHoldPercentage * + (uint32_t)u8SckDiv / (uint32_t)100); + + if (u8PCSPCSCycle < (uint8_t)2) + { + u8PCSPCSCycle = (uint8_t)2; + } + + if(u8SCKPCSCycle == (uint8_t)0) + { + u8SCKPCSCycle = (uint8_t)1; + } + + if(u8PCSSCKCycle == (uint8_t)0) + { + u8PCSSCKCycle = (uint8_t)1; + } + + FCSpi_Hw_Set_SCK_PCS_Hold(eInst, + (uint8_t)(u8SCKPCSCycle - (uint8_t)1), + (uint8_t)(u8PCSSCKCycle - (uint8_t)1), + (uint8_t)(u8PCSPCSCycle - (uint8_t)2)); + /* Enable module */ + FCSPI_HWA_ModuleEnable(s_atFCSpiInfo[eInst].tFCSpiInstance); + } + else + { + eRet = FCSPI_STATUS_BUSY; + } + } + else + { + eRet = FCSPI_STATUS_PARAM_ERR; + } + + return eRet; +} + +/** + * @brief Select the PCS to use and configure + * + * @param eInst Which FCSpi Hardware instance + * @param pCfg Parameters about PCS configuration, MUST NOT null + * @return FCSPI_StatusType FCSPI_STATUS_SUCCESS when configure successfully. Others, the hardware is busy now. + */ +FCSPI_StatusType FCSPI_Master_SelectPcs( + const FCSPI_InstanceType eInst, const FCSPI_MasterPcsConfType *pCfg) +{ + FCSPI_StatusType eRet = FCSPI_STATUS_SUCCESS; + + if (pCfg) + { + eRet = FCSpi_Hw_Disable(eInst); + if (FCSPI_STATUS_SUCCESS == eRet) + { + FCSpi_Hw_SetOnePcsPolarity(eInst, pCfg->ePcs, pCfg->ePolarity); + FCSPI_HWA_ModuleEnable(s_atFCSpiInfo[eInst].tFCSpiInstance); + FCSpi_Hw_SelectUsePcs(eInst, pCfg->ePcs); + } + else + { + eRet = FCSPI_STATUS_BUSY; + } + } + else + { + eRet = FCSPI_STATUS_PARAM_ERR; + } + + return eRet; +} + +static void fcspi_master_clean_transfer(FCSPI_InstanceType eInst, FCSPI_AtomicBoolType bIsInInterrupt) +{ + s_atFCSpiInfo[eInst].tFCSpiStat.eIsInTransfer = FCSPI_FALSE; + + if (FCSPI_TRANSFER_TRIGGER_SRC_DMA_ISR == s_atFCSpiInfo[eInst].tFCSpiStat.eTransferTriggerSrc) + { + FCSpi_Hw_SetRxTxDmaEnableStatus(eInst, FCSPI_FALSE, FCSPI_FALSE); + } + else + { + FCSpi_Hw_DisableSomeInterrupts(eInst, + FCSPI_INT_EN_RFIE(1) | FCSPI_INT_EN_TFIE(1)); + } + + FCSpi_Hw_DisableSomeInterrupts(eInst, + FCSPI_INT_EN_RFOIE(1) | FCSPI_INT_EN_TFUIE(1) | FCSPI_INT_EN_TCIE(1)); + FCSpi_Hw_ClearSomeStatusW1CFlag(eInst, + FCSPI_STATUS_RX_FO(1) | FCSPI_STATUS_TX_FU(1) | FCSPI_STATUS_TCF(1)); + + if (FCSPI_TRUE == bIsInInterrupt) + { + if (NULL != s_atFCSpiInfo[eInst].tFCSpiStat.pStopNotifyCb) + { + s_atFCSpiInfo[eInst].tFCSpiStat.pStopNotifyCb(eInst, FCSPI_TRUE); + } + + if (s_atFCSpiInfo[eInst].tFCSpiStat.u8WaitSemaphore) + { + s_atFCSpiInfo[eInst].tFCSpiStat.pSemaPostCb(eInst, FCSPI_TRUE); + s_atFCSpiInfo[eInst].tFCSpiStat.u8WaitSemaphore = (uint8_t)0; + } + } + else + { + if (NULL != s_atFCSpiInfo[eInst].tFCSpiStat.pStopNotifyCb) + { + s_atFCSpiInfo[eInst].tFCSpiStat.pStopNotifyCb(eInst, FCSPI_FALSE); + } + + if (s_atFCSpiInfo[eInst].tFCSpiStat.u8WaitSemaphore) + { + s_atFCSpiInfo[eInst].tFCSpiStat.pSemaPostCb(eInst, FCSPI_FALSE); + s_atFCSpiInfo[eInst].tFCSpiStat.u8WaitSemaphore = (uint8_t)0; + } + } +} + +static void fcspi_master_abort_transfer(FCSPI_InstanceType eInst, FCSPI_AtomicBoolType bIsInISR) +{ + fcspi_master_clean_transfer(eInst, bIsInISR); + + /* clean the fifo */ + FCSpi_Hw_Reset(eInst, FCSPI_TRUE, FCSPI_TRUE, FCSPI_FALSE); + FCSpi_Hw_Reset(eInst, FCSPI_TRUE, FCSPI_TRUE, FCSPI_FALSE); /* for shifter */ +} + +static void fcspi_master_dma_rx_err_interrupt(FCSPI_InstanceType eInst) +{ + s_atFCSpiInfo[eInst].tFCSpiStat.eTransferStat = FCSPI_TRANSFER_RX_FAIL; + fcspi_master_abort_transfer(eInst, FCSPI_TRUE); +} + +static void fcspi_0_master_dma_rx_err_interrupt(void) +{ + fcspi_master_dma_rx_err_interrupt(FCSPI_0); +} + +static void fcspi_1_master_dma_rx_err_interrupt(void) +{ + fcspi_master_dma_rx_err_interrupt(FCSPI_1); +} + +static void fcspi_2_master_dma_rx_err_interrupt(void) +{ + fcspi_master_dma_rx_err_interrupt(FCSPI_2); +} + +static void fcspi_3_master_dma_rx_err_interrupt(void) +{ + fcspi_master_dma_rx_err_interrupt(FCSPI_3); +} + +static void fcspi_4_master_dma_rx_err_interrupt(void) +{ + fcspi_master_dma_rx_err_interrupt(FCSPI_4); +} + +static void fcspi_5_master_dma_rx_err_interrupt(void) +{ + fcspi_master_dma_rx_err_interrupt(FCSPI_5); +} + +static void fcspi_master_dma_rx_finish_interrupt(void) +{ + ; /* in master mode, the tx trigger the sclk output, so when rx finish, ignore. */ +} + +static void fcspi_master_dma_tx_err_interrupt(FCSPI_InstanceType eInst) +{ + s_atFCSpiInfo[eInst].tFCSpiStat.eTransferStat = FCSPI_TRANSFER_TX_FAIL; + fcspi_master_abort_transfer(eInst, FCSPI_TRUE); +} + +static void fcspi_0_master_dma_tx_err_interrupt(void) +{ + fcspi_master_dma_tx_err_interrupt(FCSPI_0); +} + +static void fcspi_1_master_dma_tx_err_interrupt(void) +{ + fcspi_master_dma_tx_err_interrupt(FCSPI_1); +} + +static void fcspi_2_master_dma_tx_err_interrupt(void) +{ + fcspi_master_dma_tx_err_interrupt(FCSPI_2); +} + +static void fcspi_3_master_dma_tx_err_interrupt(void) +{ + fcspi_master_dma_tx_err_interrupt(FCSPI_3); +} + +static void fcspi_4_master_dma_tx_err_interrupt(void) +{ + fcspi_master_dma_tx_err_interrupt(FCSPI_4); +} + +static void fcspi_5_master_dma_tx_err_interrupt(void) +{ + fcspi_master_dma_tx_err_interrupt(FCSPI_5); +} + +static void fcspi_master_dma_tx_finish_interrupt(FCSPI_InstanceType eInst) +{ + if (FCSPI_TRUE == s_atFCSpiInfo[eInst].tFCSpiStat.eIsPcsContinuous) + { + FCSpi_Hw_SetContinuousCommand(eInst, FCSPI_FALSE); + } + + s_atFCSpiInfo[eInst].tFCSpiStat.u16TxByteCntRemainToSend = (uint16_t)0; + s_atFCSpiInfo[eInst].tFCSpiStat.u16RxByteCntRemainToGet = (uint16_t)0; + + /* DMA -> TX FIFO -> PIN, DMA send to tx fifo finish, enable tx fifo finish interrupt */ + FCSpi_Hw_EnableTransmitCompleteInterrupt(eInst); +} + +static void fcspi_0_master_dma_tx_finish_interrupt(void) +{ + fcspi_master_dma_tx_finish_interrupt(FCSPI_0); +} + +static void fcspi_1_master_dma_tx_finish_interrupt(void) +{ + fcspi_master_dma_tx_finish_interrupt(FCSPI_1); +} + +static void fcspi_2_master_dma_tx_finish_interrupt(void) +{ + fcspi_master_dma_tx_finish_interrupt(FCSPI_2); +} + +static void fcspi_3_master_dma_tx_finish_interrupt(void) +{ + fcspi_master_dma_tx_finish_interrupt(FCSPI_3); +} + +static void fcspi_4_master_dma_tx_finish_interrupt(void) +{ + fcspi_master_dma_tx_finish_interrupt(FCSPI_4); +} + +static void fcspi_5_master_dma_tx_finish_interrupt(void) +{ + fcspi_master_dma_tx_finish_interrupt(FCSPI_5); +} + +/* if enter transfer state, return success, others, not start tranfer */ +static FCSPI_StatusType fcspi_master_async_transfer_bytes(FCSPI_InstanceType eInst, + const uint8_t *pSendBuffer, uint8_t *pReceiveBuffer, + uint16_t u16TransferByteCnt) +{ + DMA_InterruptCfgType tDmaTxInterruptCfg = {0}; + DMA_ChannelCfgType tDmaTxChnlCfg = {0}; + uint8_t u8DmaTxBlkByteCnt = (uint8_t)1; + DMA_InterruptCfgType tDmaRxInterruptCfg = {0}; + DMA_ChannelCfgType tDmaRxChnlCfg = {0}; + uint8_t u8DmaRxBlkByteCnt = (uint8_t)1; + FCSPI_StatusType eRet = FCSPI_STATUS_SUCCESS; + uint32_t u32StatRegVal = 0u; + + if ((uint16_t)0 != s_atFCSpiInfo[eInst].tFCSpiStat.u16BytesCntFrameNeed) + { + if ((uint16_t)0 != u16TransferByteCnt) + { + if ((u16TransferByteCnt % s_atFCSpiInfo[eInst].tFCSpiStat.u16BytesCntFrameNeed) == (uint16_t)0) + { + u32StatRegVal = FCSPI_HWA_GetStatus(s_atFCSpiInfo[eInst].tFCSpiInstance); + if ((FCSPI_TRUE != s_atFCSpiInfo[eInst].tFCSpiStat.eIsInTransfer) && + (!FCSpi_Hw_ChkBusy(u32StatRegVal))) + { + if (!FCSpi_Hw_ChkBusy(FCSPI_HWA_GetStatus(s_atFCSpiInfo[eInst].tFCSpiInstance))) + { + FCSpi_Hw_Reset(eInst, FCSPI_TRUE, FCSPI_TRUE, FCSPI_FALSE); + FCSpi_Hw_Reset(eInst, FCSPI_TRUE, FCSPI_TRUE, FCSPI_FALSE); /* ensure clear data in shifter */ + + /* if pcs need continuous, set command continuous bit */ + if (s_atFCSpiInfo[eInst].tFCSpiStat.eIsPcsContinuous) + { + FCSpi_Hw_SetContinuousCommand(eInst, FCSPI_TRUE); + } + + s_atFCSpiInfo[eInst].tFCSpiStat.eTransferStat = FCSPI_TRANSFER_OK; + + FCSPI_HWA_SetWatermark(s_atFCSpiInfo[eInst].tFCSpiInstance, (uint8_t)0, (uint8_t)2); + + FCSpi_Hw_ClearSomeStatusW1CFlag(eInst, FCSPI_DRV_STATUS_REG_W1C_U32); + FCSpi_Hw_EnableMoreInterrupts(eInst, FCSPI_INT_EN_TFUIE(1)); + + /* if rx needed, enable overflow interrupt and rx */ + if (NULL != pReceiveBuffer) + { + FCSpi_Hw_EnableMoreInterrupts(eInst, FCSPI_INT_EN_RFOIE(1)); + s_atFCSpiInfo[eInst].tFCSpiStat.u16RxByteCntRemainToGet = u16TransferByteCnt; + FCSPI_HWA_EnableRxDataMask(s_atFCSpiInfo[eInst].tFCSpiInstance, FCSPI_TRUE); + } + else + { + s_atFCSpiInfo[eInst].tFCSpiStat.u16RxByteCntRemainToGet = (uint16_t)0; + FCSPI_HWA_EnableRxDataMask(s_atFCSpiInfo[eInst].tFCSpiInstance, FCSPI_FALSE); + } + + if (FCSPI_TRANSFER_TRIGGER_SRC_DMA_ISR == s_atFCSpiInfo[eInst].tFCSpiStat.eTransferTriggerSrc) + { + /* TX */ + tDmaTxChnlCfg.u8ChannelPriority = s_atFCSpiInfo[eInst].tFCSpiStat.tTriggerDmaInf.u8TxDMAChannelPriority; + tDmaTxChnlCfg.bDestAddrLoopbackEn = false; + tDmaTxChnlCfg.bSrcAddrLoopbackEn = false; + tDmaTxChnlCfg.bAutoStop = true; /* auto stop dma after send finish */ + tDmaTxChnlCfg.bSrcCircularBufferEn = false; + tDmaTxChnlCfg.bDestCircularBufferEn = false; + + switch (s_atFCSpiInfo[eInst].tFCSpiStat.u16BytesCntFrameNeed) + { + case 1: + tDmaTxChnlCfg.eSrcDataSize = DMA_TRANSFER_SIZE_1B; + tDmaTxChnlCfg.eDestDataSize = DMA_TRANSFER_SIZE_1B; + tDmaTxChnlCfg.bSrcBlockOffsetEn = true; + tDmaTxChnlCfg.s32BlockOffset = (int32_t)1; + u8DmaTxBlkByteCnt = (uint8_t)1; + break; + + case 2: + tDmaTxChnlCfg.eSrcDataSize = DMA_TRANSFER_SIZE_2B; + tDmaTxChnlCfg.eDestDataSize = DMA_TRANSFER_SIZE_2B; + tDmaTxChnlCfg.bSrcBlockOffsetEn = true; + tDmaTxChnlCfg.s32BlockOffset = (int32_t)2; + u8DmaTxBlkByteCnt = (uint8_t)2; + break; + + default: + tDmaTxChnlCfg.eSrcDataSize = DMA_TRANSFER_SIZE_4B; + tDmaTxChnlCfg.eDestDataSize = DMA_TRANSFER_SIZE_4B; + tDmaTxChnlCfg.bSrcBlockOffsetEn = true; + tDmaTxChnlCfg.s32BlockOffset = (int32_t)4; + u8DmaTxBlkByteCnt = (uint8_t)4; + break; + } + + tDmaTxChnlCfg.u16BlockCount = u16TransferByteCnt / u8DmaTxBlkByteCnt; + tDmaTxChnlCfg.bDestBlockOffsetEn = false; + + tDmaTxInterruptCfg.bTransferCompleteIntEn = true; + tDmaTxInterruptCfg.bTransferErrorIntEn = true; + switch (eInst) + { + case FCSPI_0: + tDmaTxChnlCfg.eTriggerSrc = DMA_REQ_FCSPI0_TX; + tDmaTxInterruptCfg.pTransferCompleteNotify = fcspi_0_master_dma_tx_finish_interrupt; + tDmaTxInterruptCfg.pTransferErrorNotify = fcspi_0_master_dma_tx_err_interrupt; + break; + + case FCSPI_1: + tDmaTxChnlCfg.eTriggerSrc = DMA_REQ_FCSPI1_TX; + tDmaTxInterruptCfg.pTransferCompleteNotify = fcspi_1_master_dma_tx_finish_interrupt; + tDmaTxInterruptCfg.pTransferErrorNotify = fcspi_1_master_dma_tx_err_interrupt; + break; + + case FCSPI_2: + tDmaTxChnlCfg.eTriggerSrc = DMA_REQ_FCSPI2_TX; + tDmaTxInterruptCfg.pTransferCompleteNotify = fcspi_2_master_dma_tx_finish_interrupt; + tDmaTxInterruptCfg.pTransferErrorNotify = fcspi_2_master_dma_tx_err_interrupt; + break; + + case FCSPI_3: + tDmaTxChnlCfg.eTriggerSrc = DMA_REQ_FCSPI3_TX; + tDmaTxInterruptCfg.pTransferCompleteNotify = fcspi_3_master_dma_tx_finish_interrupt; + tDmaTxInterruptCfg.pTransferErrorNotify = fcspi_3_master_dma_tx_err_interrupt; + break; + + case FCSPI_4: + tDmaTxChnlCfg.eTriggerSrc = DMA_REQ_FCSPI4_TX; + tDmaTxInterruptCfg.pTransferCompleteNotify = fcspi_4_master_dma_tx_finish_interrupt; + tDmaTxInterruptCfg.pTransferErrorNotify = fcspi_4_master_dma_tx_err_interrupt; + break; + + case FCSPI_5: + tDmaTxChnlCfg.eTriggerSrc = DMA_REQ_FCSPI5_TX; + tDmaTxInterruptCfg.pTransferCompleteNotify = fcspi_5_master_dma_tx_finish_interrupt; + tDmaTxInterruptCfg.pTransferErrorNotify = fcspi_5_master_dma_tx_err_interrupt; + break; + + default: + tDmaTxChnlCfg.eTriggerSrc = DMA_REQ_FCSPI3_TX; + tDmaTxInterruptCfg.pTransferCompleteNotify = fcspi_3_master_dma_tx_finish_interrupt; + tDmaTxInterruptCfg.pTransferErrorNotify = fcspi_3_master_dma_tx_err_interrupt; + break; + } + + tDmaTxChnlCfg.eDestIncMode = DMA_INCREMENT_DISABLE; + tDmaTxChnlCfg.eSrcIncMode = DMA_INCREMENT_DISABLE; + tDmaTxChnlCfg.pDestBuffer = FCSPI_HWA_GetTxDataAddr(s_atFCSpiInfo[eInst].tFCSpiInstance); + tDmaTxChnlCfg.u32BlockSize = (uint32_t)u8DmaTxBlkByteCnt; + + if (NULL != pSendBuffer) + { + tDmaTxChnlCfg.pSrcBuffer = pSendBuffer; + } + else + { + tDmaTxChnlCfg.pSrcBuffer = &(s_atFCSpiInfo[eInst].tFCSpiStat.u32DmaDummyData); + tDmaTxChnlCfg.bSrcBlockOffsetEn = false; /* if send buffer is NULL, just send dummy data, MUST fix the source to the dummy variable */ + tDmaTxChnlCfg.s32BlockOffset = (int32_t)0; + } + + DMA_InitChannel(s_atFCSpiInfo[eInst].tFCSpiStat.tTriggerDmaInf.eDMAInstance, (DMA_ChannelType)s_atFCSpiInfo[eInst].tFCSpiStat.tTriggerDmaInf.u8TxDMAChannel, &tDmaTxChnlCfg); + + /* RX */ + /* if needed, configure the DMA Rx function */ + if (NULL != pReceiveBuffer) + { + tDmaRxChnlCfg.u8ChannelPriority = s_atFCSpiInfo[eInst].tFCSpiStat.tTriggerDmaInf.u8RxDMAChannelPriority; + tDmaRxChnlCfg.bDestAddrLoopbackEn = false; + tDmaRxChnlCfg.bSrcAddrLoopbackEn = false; + tDmaRxChnlCfg.bAutoStop = true; /* auto stop dma after send finish */ + tDmaRxChnlCfg.bSrcCircularBufferEn = false; + tDmaRxChnlCfg.bDestCircularBufferEn = false; + + switch (s_atFCSpiInfo[eInst].tFCSpiStat.u16BytesCntFrameNeed) + { + case 1: + tDmaRxChnlCfg.eDestDataSize = DMA_TRANSFER_SIZE_1B; + tDmaRxChnlCfg.eSrcDataSize = DMA_TRANSFER_SIZE_1B; + tDmaRxChnlCfg.bDestBlockOffsetEn = true; + tDmaRxChnlCfg.s32BlockOffset = (int32_t)1; + u8DmaRxBlkByteCnt = (uint8_t)1; + break; + + case 2: + tDmaRxChnlCfg.eDestDataSize = DMA_TRANSFER_SIZE_2B; + tDmaRxChnlCfg.eSrcDataSize = DMA_TRANSFER_SIZE_2B; + tDmaRxChnlCfg.bDestBlockOffsetEn = true; + tDmaRxChnlCfg.s32BlockOffset = (int32_t)2; + u8DmaRxBlkByteCnt = (uint8_t)2; + break; + + default: + tDmaRxChnlCfg.eDestDataSize = DMA_TRANSFER_SIZE_4B; + tDmaRxChnlCfg.eSrcDataSize = DMA_TRANSFER_SIZE_4B; + tDmaRxChnlCfg.bDestBlockOffsetEn = true; + tDmaRxChnlCfg.s32BlockOffset = (int32_t)4; + u8DmaRxBlkByteCnt = (uint8_t)4; + break; + } + + tDmaRxChnlCfg.u16BlockCount = u16TransferByteCnt / u8DmaRxBlkByteCnt; + tDmaRxChnlCfg.bSrcBlockOffsetEn = false; + + tDmaRxInterruptCfg.bTransferCompleteIntEn = true; + tDmaRxInterruptCfg.bTransferErrorIntEn = true; + switch (eInst) + { + case FCSPI_0: + tDmaRxChnlCfg.eTriggerSrc = DMA_REQ_FCSPI0_RX; + tDmaRxInterruptCfg.pTransferCompleteNotify = fcspi_master_dma_rx_finish_interrupt; + tDmaRxInterruptCfg.pTransferErrorNotify = fcspi_0_master_dma_rx_err_interrupt; + break; + + case FCSPI_1: + tDmaRxChnlCfg.eTriggerSrc = DMA_REQ_FCSPI1_RX; + tDmaRxInterruptCfg.pTransferCompleteNotify = fcspi_master_dma_rx_finish_interrupt; + tDmaRxInterruptCfg.pTransferErrorNotify = fcspi_1_master_dma_rx_err_interrupt; + break; + + case FCSPI_2: + tDmaRxChnlCfg.eTriggerSrc = DMA_REQ_FCSPI2_RX; + tDmaRxInterruptCfg.pTransferCompleteNotify = fcspi_master_dma_rx_finish_interrupt; + tDmaRxInterruptCfg.pTransferErrorNotify = fcspi_2_master_dma_rx_err_interrupt; + break; + + case FCSPI_3: + tDmaRxChnlCfg.eTriggerSrc = DMA_REQ_FCSPI3_RX; + tDmaRxInterruptCfg.pTransferCompleteNotify = fcspi_master_dma_rx_finish_interrupt; + tDmaRxInterruptCfg.pTransferErrorNotify = fcspi_3_master_dma_rx_err_interrupt; + break; + + case FCSPI_4: + tDmaRxChnlCfg.eTriggerSrc = DMA_REQ_FCSPI4_RX; + tDmaRxInterruptCfg.pTransferCompleteNotify = fcspi_master_dma_rx_finish_interrupt; + tDmaRxInterruptCfg.pTransferErrorNotify = fcspi_4_master_dma_rx_err_interrupt; + break; + + case FCSPI_5: + tDmaRxChnlCfg.eTriggerSrc = DMA_REQ_FCSPI5_RX; + tDmaRxInterruptCfg.pTransferCompleteNotify = fcspi_master_dma_rx_finish_interrupt; + tDmaRxInterruptCfg.pTransferErrorNotify = fcspi_5_master_dma_rx_err_interrupt; + break; + + default: + tDmaRxChnlCfg.eTriggerSrc = DMA_REQ_FCSPI3_RX; + tDmaRxInterruptCfg.pTransferCompleteNotify = fcspi_master_dma_rx_finish_interrupt; + tDmaRxInterruptCfg.pTransferErrorNotify = fcspi_3_master_dma_rx_err_interrupt; + break; + } + + tDmaRxChnlCfg.eDestIncMode = DMA_INCREMENT_DISABLE; + tDmaRxChnlCfg.eSrcIncMode = DMA_INCREMENT_DISABLE; + tDmaRxChnlCfg.pSrcBuffer = FCSPI_HWA_GetRxDataAddr(s_atFCSpiInfo[eInst].tFCSpiInstance); + tDmaRxChnlCfg.u32BlockSize = (uint32_t)u8DmaRxBlkByteCnt; + tDmaRxChnlCfg.pDestBuffer = pReceiveBuffer; + + DMA_InitChannel(s_atFCSpiInfo[eInst].tFCSpiStat.tTriggerDmaInf.eDMAInstance, + (DMA_ChannelType)s_atFCSpiInfo[eInst].tFCSpiStat.tTriggerDmaInf.u8RxDMAChannel, &tDmaRxChnlCfg); + DMA_InitChannelInterrupt(s_atFCSpiInfo[eInst].tFCSpiStat.tTriggerDmaInf.eDMAInstance, + (DMA_ChannelType)s_atFCSpiInfo[eInst].tFCSpiStat.tTriggerDmaInf.u8RxDMAChannel, &tDmaRxInterruptCfg); + DMA_StartChannel(s_atFCSpiInfo[eInst].tFCSpiStat.tTriggerDmaInf.eDMAInstance, + (DMA_ChannelType)s_atFCSpiInfo[eInst].tFCSpiStat.tTriggerDmaInf.u8RxDMAChannel); + } + + DMA_InitChannelInterrupt(s_atFCSpiInfo[eInst].tFCSpiStat.tTriggerDmaInf.eDMAInstance, + (DMA_ChannelType)s_atFCSpiInfo[eInst].tFCSpiStat.tTriggerDmaInf.u8TxDMAChannel, &tDmaTxInterruptCfg); + + DMA_StartChannel(s_atFCSpiInfo[eInst].tFCSpiStat.tTriggerDmaInf.eDMAInstance, + (DMA_ChannelType)s_atFCSpiInfo[eInst].tFCSpiStat.tTriggerDmaInf.u8TxDMAChannel); + + s_atFCSpiInfo[eInst].tFCSpiStat.eIsInTransfer = FCSPI_TRUE; + + if (pReceiveBuffer) + { + FCSpi_Hw_SetRxTxDmaEnableStatus(eInst, FCSPI_TRUE, FCSPI_TRUE); + } + else + { + /* only enable TX DMA */ + FCSpi_Hw_SetRxTxDmaEnableStatus(eInst, FCSPI_FALSE, FCSPI_TRUE); + } + } + else + { + s_atFCSpiInfo[eInst].tFCSpiStat.pbyTxBuff = pSendBuffer; + s_atFCSpiInfo[eInst].tFCSpiStat.pbyRxBuff = pReceiveBuffer; + s_atFCSpiInfo[eInst].tFCSpiStat.u16TxIndex = (uint16_t)0; + s_atFCSpiInfo[eInst].tFCSpiStat.u16RxIndex = (uint16_t)0; + s_atFCSpiInfo[eInst].tFCSpiStat.u16TxSendByteCntOfCurFrame = (uint16_t)0; + s_atFCSpiInfo[eInst].tFCSpiStat.u16RxGetByteCntOfCurFrame = (uint16_t)0; + s_atFCSpiInfo[eInst].tFCSpiStat.u16TxByteCntRemainToSend = u16TransferByteCnt; + if (FCSPI_TRUE == s_atFCSpiInfo[eInst].tFCSpiStat.eIsPcsContinuous) + { + /* continuous transfer need an extra word to negate PCS */ + s_atFCSpiInfo[eInst].tFCSpiStat.u16TxByteCntRemainToSend++; + } + s_atFCSpiInfo[eInst].tFCSpiStat.eIsInTransfer = FCSPI_TRUE; + + if (NULL != pReceiveBuffer) /* need rx fifo */ + { + FCSpi_Hw_EnableMoreInterrupts(eInst, FCSPI_INT_EN_RFIE(1) | FCSPI_INT_EN_TFIE(1)); + } + else + { + FCSpi_Hw_EnableMoreInterrupts(eInst, FCSPI_INT_EN_TFIE(1)); + } + } + eRet = FCSPI_STATUS_SUCCESS; + } + else + { + eRet = FCSPI_STATUS_BUSY; + } + } + else + { + eRet = FCSPI_STATUS_BUSY; + } + } + else + { + eRet = FCSPI_STATUS_ERROR; + } + } + else + { + eRet = FCSPI_STATUS_NO_DATA; + } + } + else + { + eRet = FCSPI_STATUS_ERROR; + } + + return eRet; +} + +/** + * @brief Send and receive asynchronously + * 1) If the trigger source is driver user poll, this api not support this mode. + * 2) If the trigger source is interrupt or DMA, this api will start the transmission, then return immediately. + * After transmission stop, it will trigger an interrupt. + * During the transmission, the send data buffer and receive data buffer + * should keep valid until the transmission stop. + * @param eInst Which FCSpi Hardware instance + * @param pCfg the data information, MUST NOT null + * @return FCSPI_StatusType FCSPI_STATUS_SUCCESS when start transfer successfully. Others, some error occur. + */ +FCSPI_StatusType FCSPI_AsyncTransfer(const FCSPI_InstanceType eInst, const FCSPI_AsyncDataInfType *pCfg) +{ + FCSPI_StatusType eRet = FCSPI_STATUS_SUCCESS; + + if (NULL != pCfg) + { + if (FCSPI_TRANSFER_TRIGGER_SRC_USER_POLL != s_atFCSpiInfo[eInst].tFCSpiStat.eTransferTriggerSrc) + { + if (FCSPI_MODE_MASTER == FCSPI_HWA_CheckMode(s_atFCSpiInfo[eInst].tFCSpiInstance)) + { + eRet = fcspi_master_async_transfer_bytes(eInst, + pCfg->pSendBuffer, pCfg->pReceiveBuffer, + pCfg->u16FrameCount * s_atFCSpiInfo[eInst].tFCSpiStat.u16BytesCntFrameNeed); + } + else + { + eRet = fcspi_slave_async_transfer_bytes(eInst, pCfg->pSendBuffer, pCfg->pReceiveBuffer, + s_atFCSpiInfo[eInst].tFCSpiStat.u16BytesCntFrameNeed * pCfg->u16FrameCount); + } + } + else + { + eRet = FCSPI_STATUS_ERROR; + } + } + else + { + eRet = FCSPI_STATUS_PARAM_ERR; + } + + return eRet; +} + +/** + * @brief Send and receive synchronously + * 1) If the semaphore callbacks are configured, + * and the driver is configured transmitting triggered by interrupt, or by DMA, + * the driver will use semaphore to wait the transmission stopped. + * In this case, the timeout value is passed to semaphore callback directly. + * 2) If the semaphore callbacks are not configured, + * this api will poll the status when triggered by interrupt or DMA, + * or poll to trigger the transmission when the mode is "FCSPI_TRANSFER_TRIGGER_SRC_USER_POLL". + * In this case, the timeout value has different meaning for different trigger mode. + * Read the source code for detail. + * @param eInst Which FCSpi Hardware instance + * @param pCfg the data information, MUST NOT null + * @return FCSPI_StatusType FCSPI_STATUS_SUCCESS when transfer successfully. Others, some error occur. + */ +FCSPI_StatusType FCSPI_SyncTransfer(const FCSPI_InstanceType eInst, const FCSPI_SyncDataInfType *pCfg) +{ + FCSPI_StatusType tStatus; + FCSPI_SemaphoreStatType tSemaStat; + FCSPI_StatusType eRet = FCSPI_STATUS_SUCCESS; + FCSPI_AtomicBoolType bIsMaster; + uint32_t u32MonitorTimeout = 0xFFFFFFFFu; + uint16_t u16RxRemain = (uint16_t)0; + uint16_t u16TxRemain = (uint16_t)0; + uint16_t u16PreRxRemain = (uint16_t)0; + uint16_t u16PreTxRemain = (uint16_t)0; + uint32_t u32TryTimeout = 0xFFFFFFFFu; + FCSPI_AtomicBoolType bIsBlockType = FCSPI_TRUE; + bIsMaster = (FCSPI_MODE_MASTER == FCSPI_HWA_CheckMode(s_atFCSpiInfo[eInst].tFCSpiInstance)) ? FCSPI_TRUE : FCSPI_FALSE; + FCSPI_AtomicBoolType bNeedExitLoop = FCSPI_FALSE; + + if (NULL != pCfg) + { + if ((uint16_t)0 != pCfg->u16FrameCount) + { + if ((NULL != s_atFCSpiInfo[eInst].tFCSpiStat.pSemaResetCb) && + (NULL != s_atFCSpiInfo[eInst].tFCSpiStat.pSemaTakeCb) && + (NULL != s_atFCSpiInfo[eInst].tFCSpiStat.pSemaPostCb) && + ((FCSPI_TRANSFER_TRIGGER_SRC_ISR == s_atFCSpiInfo[eInst].tFCSpiStat.eTransferTriggerSrc) || + (FCSPI_TRANSFER_TRIGGER_SRC_DMA_ISR == s_atFCSpiInfo[eInst].tFCSpiStat.eTransferTriggerSrc))) + { + if (FCSPI_SEMAPHORE_SUCCESS == s_atFCSpiInfo[eInst].tFCSpiStat.pSemaResetCb(eInst)) + { + s_atFCSpiInfo[eInst].tFCSpiStat.u8WaitSemaphore = (uint8_t)1; + + if (FCSPI_TRUE == bIsMaster) + { + tStatus = fcspi_master_async_transfer_bytes(eInst, pCfg->pSendBuffer, pCfg->pReceiveBuffer, + s_atFCSpiInfo[eInst].tFCSpiStat.u16BytesCntFrameNeed * pCfg->u16FrameCount); + } + else + { + tStatus = fcspi_slave_async_transfer_bytes(eInst, pCfg->pSendBuffer, pCfg->pReceiveBuffer, + s_atFCSpiInfo[eInst].tFCSpiStat.u16BytesCntFrameNeed * pCfg->u16FrameCount); + } + + if (FCSPI_STATUS_SUCCESS == tStatus) + { + tSemaStat = s_atFCSpiInfo[eInst].tFCSpiStat.pSemaTakeCb(eInst, pCfg->u32Timeout); + if (FCSPI_SEMAPHORE_FAIL == tSemaStat) + { + s_atFCSpiInfo[eInst].tFCSpiStat.u8WaitSemaphore = (uint8_t)0; + s_atFCSpiInfo[eInst].tFCSpiStat.eTransferStat = FCSPI_TRANSFER_ABORT; + if (FCSPI_TRUE == bIsMaster) + { + fcspi_master_abort_transfer(eInst, FCSPI_FALSE); + } + else + { + fcspi_slave_abort_transfer(eInst, FCSPI_FALSE); + } + + eRet = FCSPI_STATUS_ERROR; + } + else if (FCSPI_SEMAPHORE_TIMEOUT == tSemaStat) + { + s_atFCSpiInfo[eInst].tFCSpiStat.u8WaitSemaphore = (uint8_t)0; + s_atFCSpiInfo[eInst].tFCSpiStat.eTransferStat = FCSPI_TRANSFER_ABORT; + if (FCSPI_TRUE == bIsMaster) + { + fcspi_master_abort_transfer(eInst, FCSPI_FALSE); + } + else + { + fcspi_slave_abort_transfer(eInst, FCSPI_FALSE); + } + eRet = FCSPI_STATUS_SYNC_TIMEOUT; + } + else + { + s_atFCSpiInfo[eInst].tFCSpiStat.u8WaitSemaphore = (uint8_t)0; + if (FCSPI_TRANSFER_OK != s_atFCSpiInfo[eInst].tFCSpiStat.eTransferStat) + { + eRet = FCSPI_STATUS_TRANSFER_FAIL; + } + else + { + eRet = FCSPI_STATUS_SUCCESS; + } + } + } + else + { + s_atFCSpiInfo[eInst].tFCSpiStat.u8WaitSemaphore = (uint8_t)0; + eRet = tStatus; + } + } + else + { + eRet = FCSPI_STATUS_ERROR; + } + } + else + { + if (FCSPI_TRUE == bIsMaster) + { + tStatus = fcspi_master_async_transfer_bytes(eInst, pCfg->pSendBuffer, pCfg->pReceiveBuffer, + s_atFCSpiInfo[eInst].tFCSpiStat.u16BytesCntFrameNeed * pCfg->u16FrameCount); + } + else + { + tStatus = fcspi_slave_async_transfer_bytes(eInst, pCfg->pSendBuffer, pCfg->pReceiveBuffer, + s_atFCSpiInfo[eInst].tFCSpiStat.u16BytesCntFrameNeed * pCfg->u16FrameCount); + } + + if (FCSPI_STATUS_SUCCESS == tStatus) + { + if (pCfg->u32Timeout > 0u) + { + u32TryTimeout = pCfg->u32Timeout; + bIsBlockType = FCSPI_FALSE; + } + else + { + bIsBlockType = FCSPI_TRUE; + } + + if (FCSPI_TRANSFER_TRIGGER_SRC_USER_POLL == s_atFCSpiInfo[eInst].tFCSpiStat.eTransferTriggerSrc) + { + if (FCSPI_TRUE == bIsMaster) + { + do { + eRet = fcspi_master_trigger(eInst, FCSPI_FALSE); + if (FCSPI_FALSE == bIsBlockType) + { + u32TryTimeout--; + if (0u == u32TryTimeout) + { + break; + } + } + } while (FCSPI_STATUS_TRIGGER_OK == eRet); + } + else + { + do { + eRet = fcspi_slave_trigger(eInst, FCSPI_FALSE); + + if (FCSPI_FALSE == bIsBlockType) + { + u32TryTimeout--; + if (0u == u32TryTimeout) + { + break; + } + } + } while (FCSPI_STATUS_TRIGGER_OK == eRet); + } + + if (FCSPI_STATUS_TRIGGER_FINISH == eRet) + { + eRet = FCSPI_STATUS_SUCCESS; + } + else if ((FCSPI_FALSE == bIsBlockType) && (0u == u32TryTimeout)) + { + s_atFCSpiInfo[eInst].tFCSpiStat.eTransferStat = FCSPI_TRANSFER_ABORT; + if (FCSPI_TRUE == bIsMaster) + { + fcspi_master_abort_transfer(eInst, FCSPI_FALSE); + } + else + { + fcspi_slave_abort_transfer(eInst, FCSPI_FALSE); + } + eRet = FCSPI_STATUS_SYNC_TIMEOUT; + } + else + { + eRet = FCSPI_STATUS_TRANSFER_FAIL; + } + } + else if ((FCSPI_TRANSFER_TRIGGER_SRC_ISR == s_atFCSpiInfo[eInst].tFCSpiStat.eTransferTriggerSrc) || + (FCSPI_TRANSFER_TRIGGER_SRC_DMA_ISR == s_atFCSpiInfo[eInst].tFCSpiStat.eTransferTriggerSrc)) + { + u32MonitorTimeout = 0xfffff00u; /* ensure 1s */ + + u16PreRxRemain = s_atFCSpiInfo[eInst].tFCSpiStat.u16RxByteCntRemainToGet; + u16PreTxRemain = s_atFCSpiInfo[eInst].tFCSpiStat.u16TxByteCntRemainToSend; + + while (FCSPI_TRUE == s_atFCSpiInfo[eInst].tFCSpiStat.eIsInTransfer) + { + u32MonitorTimeout--; + if (0u == u32MonitorTimeout) + { + bNeedExitLoop = FCSPI_FALSE; + u16RxRemain = s_atFCSpiInfo[eInst].tFCSpiStat.u16RxByteCntRemainToGet; + u16TxRemain = s_atFCSpiInfo[eInst].tFCSpiStat.u16TxByteCntRemainToSend; + if (((u16PreRxRemain == u16RxRemain) && ((uint16_t)0 != u16RxRemain)) || + ((u16PreTxRemain == u16TxRemain) && ((uint16_t)0 != u16TxRemain))) + { + s_atFCSpiInfo[eInst].tFCSpiStat.eTransferStat = FCSPI_TRANSFER_ABORT; + if (FCSPI_TRUE == bIsMaster) + { + fcspi_master_abort_transfer(eInst, FCSPI_FALSE); + } + else + { + fcspi_slave_abort_transfer(eInst, FCSPI_FALSE); + } + + bNeedExitLoop = FCSPI_TRUE; + } + else + { + u16PreRxRemain = u16RxRemain; + u16PreTxRemain = u16TxRemain; + u32MonitorTimeout = 0xfffff00u; + + if (FCSPI_FALSE == bIsBlockType) + { + u32TryTimeout--; + if (0u == u32TryTimeout) + { + bNeedExitLoop = FCSPI_TRUE; + } + } + } + + if (FCSPI_TRUE == bNeedExitLoop) + { + break; + } + } + } + + if ((FCSPI_FALSE == bIsBlockType) && (0u == u32TryTimeout)) + { + s_atFCSpiInfo[eInst].tFCSpiStat.eTransferStat = FCSPI_TRANSFER_ABORT; + if (FCSPI_TRUE == bIsMaster) + { + fcspi_master_abort_transfer(eInst, FCSPI_FALSE); + } + else + { + fcspi_slave_abort_transfer(eInst, FCSPI_FALSE); + } + eRet = FCSPI_STATUS_SYNC_TIMEOUT; + } + else if (FCSPI_TRANSFER_OK == s_atFCSpiInfo[eInst].tFCSpiStat.eTransferStat) + { + eRet = FCSPI_STATUS_SUCCESS; + } + else + { + eRet = FCSPI_STATUS_TRANSFER_FAIL; + } + } + else + { + s_atFCSpiInfo[eInst].tFCSpiStat.eTransferStat = FCSPI_TRANSFER_ABORT; + if (FCSPI_TRUE == bIsMaster) + { + fcspi_master_abort_transfer(eInst, FCSPI_FALSE); + } + else + { + fcspi_slave_abort_transfer(eInst, FCSPI_FALSE); + } + + eRet = FCSPI_STATUS_TRANSFER_FAIL; + } + } + else + { + eRet = tStatus; + } + } + } + else + { + eRet = FCSPI_STATUS_SUCCESS; + } + } + else + { + eRet = FCSPI_STATUS_PARAM_ERR; + } + + return eRet; +} + +static FCSPI_StatusType fcspi_master_trigger( + FCSPI_InstanceType eInst, FCSPI_AtomicBoolType bIsInIsr) +{ + uint32_t u32StatusRegValue; + FCSPI_StatusType eRet = FCSPI_STATUS_TRIGGER_OK; + + /* if an error is detected the transfer will be aborted */ + u32StatusRegValue = FCSPI_HWA_GetStatus(s_atFCSpiInfo[eInst].tFCSpiInstance); + + /* if tx need more data but hungry, and has data, sth wrong */ + if (FCSpi_Hw_ChkTxFifoUnderrun(u32StatusRegValue) && + (NULL != s_atFCSpiInfo[eInst].tFCSpiStat.pbyTxBuff)) + { + s_atFCSpiInfo[eInst].tFCSpiStat.eTransferStat = FCSPI_TRANSFER_TX_FAIL; + fcspi_master_abort_transfer(eInst, bIsInIsr); + eRet = FCSPI_STATUS_TRIGGER_ABORT_TX_FAIL; + } + /* if rx need more space but overflow, and has space to store, sth wrong */ + else if (FCSpi_Hw_ChkRxFifoOverflow(u32StatusRegValue) && + (NULL != s_atFCSpiInfo[eInst].tFCSpiStat.pbyRxBuff)) + { + s_atFCSpiInfo[eInst].tFCSpiStat.eTransferStat = FCSPI_TRANSFER_RX_FAIL; + fcspi_master_abort_transfer(eInst, bIsInIsr); + eRet = FCSPI_STATUS_TRIGGER_ABORT_RX_FAIL; + } + /* rx data ready */ + else + { + if (FCSpi_Hw_ChkRxGreaterThanWater(u32StatusRegValue)) + { + if ((uint16_t)0 != s_atFCSpiInfo[eInst].tFCSpiStat.u16RxByteCntRemainToGet) + { + fcspi_read_rx_fifo(eInst); + } + } + + /* transmit some, need add more */ + if (FCSpi_Hw_ChkTxEqualOrLessThanWater(u32StatusRegValue)) + { + if ((uint16_t)0 != s_atFCSpiInfo[eInst].tFCSpiStat.u16TxByteCntRemainToSend) + { + fcspi_write_tx_fifo(eInst); + } + } + + if ((uint16_t)0 == s_atFCSpiInfo[eInst].tFCSpiStat.u16TxByteCntRemainToSend) + { + /* disable tx interrupt. enable tx completion interrupt.*/ + FCSpi_Hw_DisableTransmitDataInterrupt(eInst); + FCSpi_Hw_EnableTransmitCompleteInterrupt(eInst); + + /* tx finish first, if rx also finish, just check completion */ + if ((uint16_t)0 == s_atFCSpiInfo[eInst].tFCSpiStat.u16RxByteCntRemainToGet) + { + u32StatusRegValue = FCSPI_HWA_GetStatus(s_atFCSpiInfo[eInst].tFCSpiInstance); + if (FCSpi_Hw_ChkTransferComplete(u32StatusRegValue)) + { + fcspi_master_clean_transfer(eInst, bIsInIsr); + eRet = FCSPI_STATUS_TRIGGER_FINISH; + } + } + } + } + return eRet; +} + +/******************************************************************************/ + +static void fcspi_slave_clean_transfer(FCSPI_InstanceType eInst, FCSPI_AtomicBoolType bIsInInterrupt) +{ + s_atFCSpiInfo[eInst].tFCSpiStat.eIsInTransfer = FCSPI_FALSE; + + if (FCSPI_TRANSFER_TRIGGER_SRC_DMA_ISR == s_atFCSpiInfo[eInst].tFCSpiStat.eTransferTriggerSrc) + { + FCSpi_Hw_SetRxTxDmaEnableStatus(eInst, FCSPI_FALSE, FCSPI_FALSE); + } + else + { + FCSpi_Hw_DisableSomeInterrupts(eInst, FCSPI_INT_EN_RFIE(1) | FCSPI_INT_EN_TFIE(1)); + } + + FCSpi_Hw_DisableSomeInterrupts(eInst, FCSPI_INT_EN_RFOIE(1) | FCSPI_INT_EN_TFUIE(1)); + FCSpi_Hw_ClearSomeStatusW1CFlag(eInst, FCSPI_STATUS_RX_FO(1) | FCSPI_STATUS_TX_FU(1)); + + if (FCSPI_TRUE == bIsInInterrupt) + { + if (NULL != s_atFCSpiInfo[eInst].tFCSpiStat.pStopNotifyCb) + { + s_atFCSpiInfo[eInst].tFCSpiStat.pStopNotifyCb(eInst, FCSPI_TRUE); + } + + if (s_atFCSpiInfo[eInst].tFCSpiStat.u8WaitSemaphore) + { + s_atFCSpiInfo[eInst].tFCSpiStat.pSemaPostCb(eInst, FCSPI_TRUE); + s_atFCSpiInfo[eInst].tFCSpiStat.u8WaitSemaphore = (uint8_t)0; + } + } + else + { + if (NULL != s_atFCSpiInfo[eInst].tFCSpiStat.pStopNotifyCb) + { + s_atFCSpiInfo[eInst].tFCSpiStat.pStopNotifyCb(eInst, FCSPI_FALSE); + } + + if (s_atFCSpiInfo[eInst].tFCSpiStat.u8WaitSemaphore) + { + s_atFCSpiInfo[eInst].tFCSpiStat.pSemaPostCb(eInst, FCSPI_FALSE); + s_atFCSpiInfo[eInst].tFCSpiStat.u8WaitSemaphore = (uint8_t)0; + } + } +} + +static void fcspi_slave_abort_transfer(FCSPI_InstanceType eInst, FCSPI_AtomicBoolType bIsInInterrupt) +{ + fcspi_slave_clean_transfer(eInst, bIsInInterrupt); + FCSpi_Hw_Reset(eInst, FCSPI_TRUE, FCSPI_TRUE, FCSPI_FALSE); + FCSpi_Hw_Reset(eInst, FCSPI_TRUE, FCSPI_TRUE, FCSPI_FALSE); /* for shifter */ +} + +/** + * @brief Init the FCSpi instance as spi slave side + * + * @param eInst Which FCSpi Hardware instance + * @param pCfg Configuration of the FCSpi + * @return FCSPI_StatusType FCSPI_STATUS_SUCCESS when configure successfully. Others, some error occur. + */ +FCSPI_StatusType FCSPI_Slave_Init(const FCSPI_InstanceType eInst, const FCSPI_SlaveCfgType * pCfg) +{ + FCSPI_TxRxCtrlType tTxRxCtrlCfg; + FCSPI_StatusType eRet = FCSPI_STATUS_SUCCESS; + + s_atFCSpiInfo[eInst].tFCSpiStat.eBitFirstOrder = pCfg->eBitFirstOrder; + s_atFCSpiInfo[eInst].tFCSpiStat.u16BitsPerFrame = pCfg->u16BitCountPerFrame; + s_atFCSpiInfo[eInst].tFCSpiStat.eTransferTriggerSrc = pCfg->eTransferTriggerSrc; + s_atFCSpiInfo[eInst].tFCSpiStat.tTriggerDmaInf = pCfg->tTriggerDmaInf; + s_atFCSpiInfo[eInst].tFCSpiStat.pStopNotifyCb = pCfg->pStopNotifyCb; + s_atFCSpiInfo[eInst].tFCSpiStat.pSemaResetCb = pCfg->pSemaResetCb; + s_atFCSpiInfo[eInst].tFCSpiStat.pSemaTakeCb = pCfg->pSemaTakeCb; + s_atFCSpiInfo[eInst].tFCSpiStat.pSemaPostCb = pCfg->pSemaPostCb; + s_atFCSpiInfo[eInst].tFCSpiStat.eSckPolarity = pCfg->eSckPolarity; + s_atFCSpiInfo[eInst].tFCSpiStat.eSckSamplePhase = pCfg->eSckSamplePhase; + s_atFCSpiInfo[eInst].tFCSpiStat.ePcs = pCfg->ePcs; + s_atFCSpiInfo[eInst].tFCSpiStat.ePcsPolarity = pCfg->ePcsPolarity; + + s_atFCSpiInfo[eInst].tFCSpiStat.u16BytesCntFrameNeed = + (uint16_t)((s_atFCSpiInfo[eInst].tFCSpiStat.u16BitsPerFrame + (uint16_t)7) >> (uint16_t)3); + + /* DMA use 4 bytes/frame. */ + if ((uint16_t)3 == s_atFCSpiInfo[eInst].tFCSpiStat.u16BytesCntFrameNeed) + { + s_atFCSpiInfo[eInst].tFCSpiStat.u16BytesCntFrameNeed = (uint16_t)4; + } + + /* FCSPI require 4 bytes align when > 32bits. */ + if (s_atFCSpiInfo[eInst].tFCSpiStat.u16BytesCntFrameNeed > (uint16_t)4) + { + s_atFCSpiInfo[eInst].tFCSpiStat.u16BytesCntFrameNeed = (uint16_t) + ((((s_atFCSpiInfo[eInst].tFCSpiStat.u16BytesCntFrameNeed + (uint16_t)3)) >> (uint16_t)2) << (uint16_t)2); + } + + s_atFCSpiInfo[eInst].tFCSpiStat.eIsInTransfer = FCSPI_FALSE; + + FCSpi_Hw_Reset(eInst, FCSPI_FALSE, FCSPI_FALSE, FCSPI_TRUE); + FCSPI_HWA_SetSlaveMode(s_atFCSpiInfo[eInst].tFCSpiInstance); + FCSpi_Hw_SetPcs_2_3_Mode(eInst, PCS2_3_PCS); + FCSpi_Hw_SetPin(eInst, SIN_INPUT_SOUT_OUTPUT, PINOUT_RETAIN_LAST); + /* set fifo size param */ + s_atFCSpiInfo[eInst].tFCSpiStat.u8TxFifoSize = (uint8_t)FCSPI_DRV_TX_FIFO_WORD_CNT; + s_atFCSpiInfo[eInst].tFCSpiStat.u8RxFifoSize = (uint8_t)FCSPI_DRV_RX_FIFO_WORD_CNT; + s_atFCSpiInfo[eInst].tFCSpiStat.u32DmaDummyData = 0xFFu; + + /* Set polarity */ + FCSpi_Hw_SetOnePcsPolarity(eInst, pCfg->ePcs, pCfg->ePcsPolarity); + + /* Write the TCR for this transfer */ + tTxRxCtrlCfg.eSckPolarity = pCfg->eSckPolarity; + tTxRxCtrlCfg.eSckPhase = pCfg->eSckSamplePhase; + tTxRxCtrlCfg.ePrescalerValue = FCSPI_PRESCALE_1; /* not use */ + tTxRxCtrlCfg.ePCSSelect = pCfg->ePcs; + tTxRxCtrlCfg.eBitFirstOrder = pCfg->eBitFirstOrder; + tTxRxCtrlCfg.eByteSwap = FCSPI_FALSE; + tTxRxCtrlCfg.eContTransEnable = FCSPI_FALSE; /* not use */ + tTxRxCtrlCfg.eContCmdEnable = FCSPI_FALSE; /* not use */ + tTxRxCtrlCfg.eRxDisable = FCSPI_FALSE; + tTxRxCtrlCfg.eTxDisable = FCSPI_FALSE; + tTxRxCtrlCfg.eTransferWidth = FCSPI_TRANSFER_1_BIT; + tTxRxCtrlCfg.u16FrameBitCnt = pCfg->u16BitCountPerFrame; + + eRet = FCSpi_Hw_SetTRCR(eInst, &tTxRxCtrlCfg); + if (FCSPI_STATUS_SUCCESS == eRet) + { + FCSPI_HWA_ModuleEnable(s_atFCSpiInfo[eInst].tFCSpiInstance); + + if (FCSPI_TRANSFER_TRIGGER_SRC_USER_POLL != pCfg->eTransferTriggerSrc) + { + IntMgr_EnableInterrupt(s_atFCSpiInfo[eInst].eFCSpiIrq); + } + } + else + { + eRet = FCSPI_STATUS_ERROR; + } + + return eRet; +} + +static void fcspi_slave_dma_rx_err_interrupt(FCSPI_InstanceType eInst) +{ + s_atFCSpiInfo[eInst].tFCSpiStat.eTransferStat = FCSPI_TRANSFER_RX_FAIL; + fcspi_slave_abort_transfer(eInst, FCSPI_TRUE); +} + +static void fcspi_0_slave_dma_rx_err_interrupt(void) +{ + fcspi_slave_dma_rx_err_interrupt(FCSPI_0); +} + +static void fcspi_1_slave_dma_rx_err_interrupt(void) +{ + fcspi_slave_dma_rx_err_interrupt(FCSPI_1); +} + +static void fcspi_2_slave_dma_rx_err_interrupt(void) +{ + fcspi_slave_dma_rx_err_interrupt(FCSPI_2); +} + +static void fcspi_3_slave_dma_rx_err_interrupt(void) +{ + fcspi_slave_dma_rx_err_interrupt(FCSPI_3); +} + +static void fcspi_4_slave_dma_rx_err_interrupt(void) +{ + fcspi_slave_dma_rx_err_interrupt(FCSPI_4); +} + +static void fcspi_5_slave_dma_rx_err_interrupt(void) +{ + fcspi_slave_dma_rx_err_interrupt(FCSPI_5); +} + +static void fcspi_slave_dma_rx_finish_interrupt(FCSPI_InstanceType eInst) +{ + fcspi_slave_abort_transfer(eInst, FCSPI_TRUE); +} + +static void fcspi_0_slave_dma_rx_finish_interrupt(void) +{ + fcspi_slave_dma_rx_finish_interrupt(FCSPI_0); +} + +static void fcspi_1_slave_dma_rx_finish_interrupt(void) +{ + fcspi_slave_dma_rx_finish_interrupt(FCSPI_1); +} + +static void fcspi_2_slave_dma_rx_finish_interrupt(void) +{ + fcspi_slave_dma_rx_finish_interrupt(FCSPI_2); +} + +static void fcspi_3_slave_dma_rx_finish_interrupt(void) +{ + fcspi_slave_dma_rx_finish_interrupt(FCSPI_3); +} + +static void fcspi_4_slave_dma_rx_finish_interrupt(void) +{ + fcspi_slave_dma_rx_finish_interrupt(FCSPI_4); +} + +static void fcspi_5_slave_dma_rx_finish_interrupt(void) +{ + fcspi_slave_dma_rx_finish_interrupt(FCSPI_5); +} + +static void fcspi_slave_dma_tx_err_interrupt(FCSPI_InstanceType eInst) +{ + s_atFCSpiInfo[eInst].tFCSpiStat.eTransferStat = FCSPI_TRANSFER_TX_FAIL; + fcspi_slave_abort_transfer(eInst, FCSPI_TRUE); +} + +static void fcspi_0_slave_dma_tx_err_interrupt(void) +{ + fcspi_slave_dma_tx_err_interrupt(FCSPI_0); +} + +static void fcspi_1_slave_dma_tx_err_interrupt(void) +{ + fcspi_slave_dma_tx_err_interrupt(FCSPI_1); +} + +static void fcspi_2_slave_dma_tx_err_interrupt(void) +{ + fcspi_slave_dma_tx_err_interrupt(FCSPI_2); +} + +static void fcspi_3_slave_dma_tx_err_interrupt(void) +{ + fcspi_slave_dma_tx_err_interrupt(FCSPI_3); +} + +static void fcspi_4_slave_dma_tx_err_interrupt(void) +{ + fcspi_slave_dma_tx_err_interrupt(FCSPI_4); +} + +static void fcspi_5_slave_dma_tx_err_interrupt(void) +{ + fcspi_slave_dma_tx_err_interrupt(FCSPI_5); +} + +static void fcspi_slave_dma_tx_finish_interrupt(FCSPI_InstanceType eInst) +{ + fcspi_slave_abort_transfer(eInst, FCSPI_TRUE); +} + +static void fcspi_0_slave_dma_tx_finish_interrupt(void) +{ + fcspi_slave_dma_tx_finish_interrupt(FCSPI_0); +} + +static void fcspi_1_slave_dma_tx_finish_interrupt(void) +{ + fcspi_slave_dma_tx_finish_interrupt(FCSPI_1); +} + +static void fcspi_2_slave_dma_tx_finish_interrupt(void) +{ + fcspi_slave_dma_tx_finish_interrupt(FCSPI_2); +} + +static void fcspi_3_slave_dma_tx_finish_interrupt(void) +{ + fcspi_slave_dma_tx_finish_interrupt(FCSPI_3); +} + +static void fcspi_4_slave_dma_tx_finish_interrupt(void) +{ + fcspi_slave_dma_tx_finish_interrupt(FCSPI_4); +} + +static void fcspi_5_slave_dma_tx_finish_interrupt(void) +{ + fcspi_slave_dma_tx_finish_interrupt(FCSPI_5); +} + +static FCSPI_StatusType fcspi_slave_async_transfer_bytes(FCSPI_InstanceType eInst, + const uint8_t *pSendBuffer, uint8_t *pReceiveBuffer, uint16_t u16TransferByteCnt) +{ + DMA_InterruptCfgType tDmaTxInterruptCfg = {0}; + DMA_ChannelCfgType tDmaTxChnlCfg = {0}; + uint8_t u8DmaTxBlkByteCnt = (uint8_t)1; + DMA_InterruptCfgType tDmaRxInterruptCfg = {0}; + DMA_ChannelCfgType tDmaRxChnlCfg = {0}; + uint8_t u8DmaRxBlkByteCnt = (uint8_t)1; + FCSPI_StatusType eRet = FCSPI_STATUS_SUCCESS; + + if ((NULL == pSendBuffer) && (NULL == pReceiveBuffer)) + { + eRet = FCSPI_STATUS_ERROR; + } + else if ((uint16_t)0 == s_atFCSpiInfo[eInst].tFCSpiStat.u16BytesCntFrameNeed) + { + eRet = FCSPI_STATUS_ERROR; + } + else if ((uint16_t)0 == u16TransferByteCnt) + { + eRet = FCSPI_STATUS_NO_DATA; + } + else if ((uint16_t)0 != (u16TransferByteCnt % s_atFCSpiInfo[eInst].tFCSpiStat.u16BytesCntFrameNeed)) + { + eRet = FCSPI_STATUS_ERROR; + } + else if (FCSPI_TRUE == s_atFCSpiInfo[eInst].tFCSpiStat.eIsInTransfer) + { + eRet = FCSPI_STATUS_BUSY; + } + else + { + s_atFCSpiInfo[eInst].tFCSpiStat.eTransferStat = FCSPI_TRANSFER_OK; + FCSpi_Hw_Reset(eInst, FCSPI_TRUE, FCSPI_TRUE, FCSPI_FALSE); + FCSpi_Hw_Reset(eInst, FCSPI_TRUE, FCSPI_TRUE, FCSPI_FALSE); /* for shifter */ + + FCSpi_Hw_ClearSomeStatusW1CFlag(eInst, FCSPI_DRV_STATUS_REG_W1C_U32); + + /* in slave mode, rx and tx all enabled */ + FCSpi_Hw_EnableMoreInterrupts(eInst, FCSPI_INT_EN_TFUIE(1) | FCSPI_INT_EN_RFOIE(1)); + + s_atFCSpiInfo[eInst].tFCSpiStat.pbyTxBuff = pSendBuffer; + s_atFCSpiInfo[eInst].tFCSpiStat.pbyRxBuff = pReceiveBuffer; + s_atFCSpiInfo[eInst].tFCSpiStat.u16TxIndex = (uint16_t)0; + s_atFCSpiInfo[eInst].tFCSpiStat.u16RxIndex = (uint16_t)0; + + if (FCSPI_TRANSFER_TRIGGER_SRC_DMA_ISR == s_atFCSpiInfo[eInst].tFCSpiStat.eTransferTriggerSrc) + { + FCSPI_HWA_SetWatermark(s_atFCSpiInfo[eInst].tFCSpiInstance, (uint8_t)0, (uint8_t)3); + + /* TX */ + tDmaTxChnlCfg.u8ChannelPriority = s_atFCSpiInfo[eInst].tFCSpiStat.tTriggerDmaInf.u8TxDMAChannelPriority; + tDmaTxChnlCfg.bDestAddrLoopbackEn = false; + tDmaTxChnlCfg.bSrcAddrLoopbackEn = false; + tDmaTxChnlCfg.bAutoStop = true; /* auto stop dma after send finish */ + tDmaTxChnlCfg.bSrcCircularBufferEn = false; + tDmaTxChnlCfg.bDestCircularBufferEn = false; + + switch (s_atFCSpiInfo[eInst].tFCSpiStat.u16BytesCntFrameNeed) + { + case 1: + tDmaTxChnlCfg.eSrcDataSize = DMA_TRANSFER_SIZE_1B; + tDmaTxChnlCfg.eDestDataSize = DMA_TRANSFER_SIZE_1B; + tDmaTxChnlCfg.bSrcBlockOffsetEn = true; + tDmaTxChnlCfg.s32BlockOffset = (int32_t)1; + u8DmaTxBlkByteCnt = (uint8_t)1; + break; + + case 2: + tDmaTxChnlCfg.eSrcDataSize = DMA_TRANSFER_SIZE_2B; + tDmaTxChnlCfg.eDestDataSize = DMA_TRANSFER_SIZE_2B; + tDmaTxChnlCfg.bSrcBlockOffsetEn = true; + tDmaTxChnlCfg.s32BlockOffset = (int32_t)2; + u8DmaTxBlkByteCnt = (uint8_t)2; + break; + + default: + tDmaTxChnlCfg.eSrcDataSize = DMA_TRANSFER_SIZE_4B; + tDmaTxChnlCfg.eDestDataSize = DMA_TRANSFER_SIZE_4B; + tDmaTxChnlCfg.bSrcBlockOffsetEn = true; + tDmaTxChnlCfg.s32BlockOffset = (int32_t)4; + u8DmaTxBlkByteCnt = (uint8_t)4; + break; + } + + tDmaTxChnlCfg.u16BlockCount = u16TransferByteCnt / u8DmaTxBlkByteCnt; + tDmaTxChnlCfg.bDestBlockOffsetEn = false; + tDmaTxInterruptCfg.bTransferCompleteIntEn = true; + tDmaTxInterruptCfg.bTransferErrorIntEn = true; + switch (eInst) + { + case FCSPI_0: + tDmaTxChnlCfg.eTriggerSrc = DMA_REQ_FCSPI0_TX; + tDmaTxInterruptCfg.pTransferCompleteNotify = fcspi_0_slave_dma_tx_finish_interrupt; + tDmaTxInterruptCfg.pTransferErrorNotify = fcspi_0_slave_dma_tx_err_interrupt; + break; + + case FCSPI_1: + tDmaTxChnlCfg.eTriggerSrc = DMA_REQ_FCSPI1_TX; + tDmaTxInterruptCfg.pTransferCompleteNotify = fcspi_1_slave_dma_tx_finish_interrupt; + tDmaTxInterruptCfg.pTransferErrorNotify = fcspi_1_slave_dma_tx_err_interrupt; + break; + + case FCSPI_2: + tDmaTxChnlCfg.eTriggerSrc = DMA_REQ_FCSPI2_TX; + tDmaTxInterruptCfg.pTransferCompleteNotify = fcspi_2_slave_dma_tx_finish_interrupt; + tDmaTxInterruptCfg.pTransferErrorNotify = fcspi_2_slave_dma_tx_err_interrupt; + break; + + case FCSPI_3: + tDmaTxChnlCfg.eTriggerSrc = DMA_REQ_FCSPI3_TX; + tDmaTxInterruptCfg.pTransferCompleteNotify = fcspi_3_slave_dma_tx_finish_interrupt; + tDmaTxInterruptCfg.pTransferErrorNotify = fcspi_3_slave_dma_tx_err_interrupt; + break; + + case FCSPI_4: + tDmaTxChnlCfg.eTriggerSrc = DMA_REQ_FCSPI4_TX; + tDmaTxInterruptCfg.pTransferCompleteNotify = fcspi_4_slave_dma_tx_finish_interrupt; + tDmaTxInterruptCfg.pTransferErrorNotify = fcspi_4_slave_dma_tx_err_interrupt; + break; + + case FCSPI_5: + tDmaTxChnlCfg.eTriggerSrc = DMA_REQ_FCSPI5_TX; + tDmaTxInterruptCfg.pTransferCompleteNotify = fcspi_5_slave_dma_tx_finish_interrupt; + tDmaTxInterruptCfg.pTransferErrorNotify = fcspi_5_slave_dma_tx_err_interrupt; + break; + + default: + tDmaTxChnlCfg.eTriggerSrc = DMA_REQ_FCSPI3_TX; + tDmaTxInterruptCfg.pTransferCompleteNotify = fcspi_3_slave_dma_tx_finish_interrupt; + tDmaTxInterruptCfg.pTransferErrorNotify = fcspi_3_slave_dma_tx_err_interrupt; + break; + } + + tDmaTxChnlCfg.eDestIncMode = DMA_INCREMENT_DISABLE; + tDmaTxChnlCfg.eSrcIncMode = DMA_INCREMENT_DISABLE; + tDmaTxChnlCfg.pDestBuffer = FCSPI_HWA_GetTxDataAddr(s_atFCSpiInfo[eInst].tFCSpiInstance); + tDmaTxChnlCfg.u32BlockSize = (uint32_t)u8DmaTxBlkByteCnt; + + if (NULL != pSendBuffer) + { + s_atFCSpiInfo[eInst].tFCSpiStat.u16TxByteCntRemainToSend = u16TransferByteCnt; + tDmaTxChnlCfg.pSrcBuffer = pSendBuffer; + } + else + { + s_atFCSpiInfo[eInst].tFCSpiStat.u16TxByteCntRemainToSend = (uint16_t)0; + tDmaTxChnlCfg.bSrcBlockOffsetEn = false; /* if send buffer is NULL, just send dummy data, MUST fix the source to the dummy variable */ + tDmaTxChnlCfg.s32BlockOffset = (int32_t)0; + tDmaTxChnlCfg.pSrcBuffer = &(s_atFCSpiInfo[eInst].tFCSpiStat.u32DmaDummyData); + } + + DMA_InitChannel(s_atFCSpiInfo[eInst].tFCSpiStat.tTriggerDmaInf.eDMAInstance, + (DMA_ChannelType)s_atFCSpiInfo[eInst].tFCSpiStat.tTriggerDmaInf.u8TxDMAChannel, &tDmaTxChnlCfg); + + /* RX */ + tDmaRxChnlCfg.u8ChannelPriority = s_atFCSpiInfo[eInst].tFCSpiStat.tTriggerDmaInf.u8RxDMAChannelPriority; + tDmaRxChnlCfg.bDestAddrLoopbackEn = false; + tDmaRxChnlCfg.bSrcAddrLoopbackEn = false; + tDmaRxChnlCfg.bAutoStop = true; /* auto stop dma after send finish */ + tDmaRxChnlCfg.bSrcCircularBufferEn = false; + tDmaRxChnlCfg.bDestCircularBufferEn = false; + + switch (s_atFCSpiInfo[eInst].tFCSpiStat.u16BytesCntFrameNeed) + { + case 1: + tDmaRxChnlCfg.eDestDataSize = DMA_TRANSFER_SIZE_1B; + tDmaRxChnlCfg.eSrcDataSize = DMA_TRANSFER_SIZE_1B; + tDmaRxChnlCfg.bDestBlockOffsetEn = true; + tDmaRxChnlCfg.s32BlockOffset = (int32_t)1; + u8DmaRxBlkByteCnt = (uint8_t)1; + break; + + case 2: + tDmaRxChnlCfg.eDestDataSize = DMA_TRANSFER_SIZE_2B; + tDmaRxChnlCfg.eSrcDataSize = DMA_TRANSFER_SIZE_2B; + tDmaRxChnlCfg.bDestBlockOffsetEn = true; + tDmaRxChnlCfg.s32BlockOffset = (int32_t)2; + u8DmaRxBlkByteCnt = (uint8_t)2; + break; + + default: + tDmaRxChnlCfg.eDestDataSize = DMA_TRANSFER_SIZE_4B; + tDmaRxChnlCfg.eSrcDataSize = DMA_TRANSFER_SIZE_4B; + tDmaRxChnlCfg.bDestBlockOffsetEn = true; + tDmaRxChnlCfg.s32BlockOffset = (int32_t)4; + u8DmaRxBlkByteCnt = (uint8_t)4; + break; + } + + tDmaRxChnlCfg.u16BlockCount = u16TransferByteCnt / u8DmaRxBlkByteCnt; + tDmaRxChnlCfg.bSrcBlockOffsetEn = false; + tDmaRxInterruptCfg.bTransferCompleteIntEn = true; + tDmaRxInterruptCfg.bTransferErrorIntEn = true; + switch (eInst) + { + case FCSPI_0: + tDmaRxChnlCfg.eTriggerSrc = DMA_REQ_FCSPI0_RX; + tDmaRxInterruptCfg.pTransferCompleteNotify = fcspi_0_slave_dma_rx_finish_interrupt; + tDmaRxInterruptCfg.pTransferErrorNotify = fcspi_0_slave_dma_rx_err_interrupt; + break; + + case FCSPI_1: + tDmaRxChnlCfg.eTriggerSrc = DMA_REQ_FCSPI1_RX; + tDmaRxInterruptCfg.pTransferCompleteNotify = fcspi_1_slave_dma_rx_finish_interrupt; + tDmaRxInterruptCfg.pTransferErrorNotify = fcspi_1_slave_dma_rx_err_interrupt; + break; + + case FCSPI_2: + tDmaRxChnlCfg.eTriggerSrc = DMA_REQ_FCSPI2_RX; + tDmaRxInterruptCfg.pTransferCompleteNotify = fcspi_2_slave_dma_rx_finish_interrupt; + tDmaRxInterruptCfg.pTransferErrorNotify = fcspi_2_slave_dma_rx_err_interrupt; + break; + + case FCSPI_3: + tDmaRxChnlCfg.eTriggerSrc = DMA_REQ_FCSPI3_RX; + tDmaRxInterruptCfg.pTransferCompleteNotify = fcspi_3_slave_dma_rx_finish_interrupt; + tDmaRxInterruptCfg.pTransferErrorNotify = fcspi_3_slave_dma_rx_err_interrupt; + break; + + case FCSPI_4: + tDmaRxChnlCfg.eTriggerSrc = DMA_REQ_FCSPI4_RX; + tDmaRxInterruptCfg.pTransferCompleteNotify = fcspi_4_slave_dma_rx_finish_interrupt; + tDmaRxInterruptCfg.pTransferErrorNotify = fcspi_4_slave_dma_rx_err_interrupt; + break; + + case FCSPI_5: + tDmaRxChnlCfg.eTriggerSrc = DMA_REQ_FCSPI5_RX; + tDmaRxInterruptCfg.pTransferCompleteNotify = fcspi_5_slave_dma_rx_finish_interrupt; + tDmaRxInterruptCfg.pTransferErrorNotify = fcspi_5_slave_dma_rx_err_interrupt; + break; + + default: + tDmaRxChnlCfg.eTriggerSrc = DMA_REQ_FCSPI3_RX; + tDmaRxInterruptCfg.pTransferCompleteNotify = fcspi_3_slave_dma_rx_finish_interrupt; + tDmaRxInterruptCfg.pTransferErrorNotify = fcspi_3_slave_dma_rx_err_interrupt; + break; + } + + tDmaRxChnlCfg.eSrcIncMode = DMA_INCREMENT_DISABLE; + tDmaRxChnlCfg.eDestIncMode = DMA_INCREMENT_DISABLE; + tDmaRxChnlCfg.pSrcBuffer = FCSPI_HWA_GetRxDataAddr(s_atFCSpiInfo[eInst].tFCSpiInstance); + tDmaRxChnlCfg.u32BlockSize = (uint32_t)u8DmaRxBlkByteCnt; + + if (NULL != pReceiveBuffer) + { + s_atFCSpiInfo[eInst].tFCSpiStat.u16RxByteCntRemainToGet = u16TransferByteCnt; + tDmaRxChnlCfg.pDestBuffer = pReceiveBuffer; + } + else + { + s_atFCSpiInfo[eInst].tFCSpiStat.u16RxByteCntRemainToGet = (uint16_t)0; + tDmaRxChnlCfg.bDestBlockOffsetEn = false; + tDmaRxChnlCfg.s32BlockOffset = (int32_t)0; + tDmaRxChnlCfg.pDestBuffer = &(s_atFCSpiInfo[eInst].tFCSpiStat.u32DmaDummyData); + } + + DMA_InitChannel(s_atFCSpiInfo[eInst].tFCSpiStat.tTriggerDmaInf.eDMAInstance, + (DMA_ChannelType)s_atFCSpiInfo[eInst].tFCSpiStat.tTriggerDmaInf.u8RxDMAChannel, &tDmaRxChnlCfg); + + s_atFCSpiInfo[eInst].tFCSpiStat.eIsInTransfer = FCSPI_TRUE; + + DMA_InitChannelInterrupt(s_atFCSpiInfo[eInst].tFCSpiStat.tTriggerDmaInf.eDMAInstance, + (DMA_ChannelType)s_atFCSpiInfo[eInst].tFCSpiStat.tTriggerDmaInf.u8RxDMAChannel, &tDmaRxInterruptCfg); + DMA_InitChannelInterrupt(s_atFCSpiInfo[eInst].tFCSpiStat.tTriggerDmaInf.eDMAInstance, + (DMA_ChannelType)s_atFCSpiInfo[eInst].tFCSpiStat.tTriggerDmaInf.u8TxDMAChannel, &tDmaTxInterruptCfg); + DMA_StartChannel(s_atFCSpiInfo[eInst].tFCSpiStat.tTriggerDmaInf.eDMAInstance, + (DMA_ChannelType)s_atFCSpiInfo[eInst].tFCSpiStat.tTriggerDmaInf.u8RxDMAChannel); + DMA_StartChannel(s_atFCSpiInfo[eInst].tFCSpiStat.tTriggerDmaInf.eDMAInstance, + (DMA_ChannelType)s_atFCSpiInfo[eInst].tFCSpiStat.tTriggerDmaInf.u8TxDMAChannel); + FCSpi_Hw_SetRxTxDmaEnableStatus(eInst, FCSPI_TRUE, FCSPI_TRUE); + } + else + { + FCSPI_HWA_SetWatermark(s_atFCSpiInfo[eInst].tFCSpiInstance, (uint8_t)0, (uint8_t)2); + + if (NULL == s_atFCSpiInfo[eInst].tFCSpiStat.pbyTxBuff) + { + s_atFCSpiInfo[eInst].tFCSpiStat.u16TxByteCntRemainToSend = (uint16_t)0; + FCSPI_HWA_EnableTxDataMask(s_atFCSpiInfo[eInst].tFCSpiInstance, FCSPI_FALSE); + } + else + { + s_atFCSpiInfo[eInst].tFCSpiStat.u16TxByteCntRemainToSend = u16TransferByteCnt; + FCSPI_HWA_EnableTxDataMask(s_atFCSpiInfo[eInst].tFCSpiInstance, FCSPI_TRUE); + } + + if (NULL == s_atFCSpiInfo[eInst].tFCSpiStat.pbyRxBuff) + { + s_atFCSpiInfo[eInst].tFCSpiStat.u16RxByteCntRemainToGet = (uint16_t)0; + FCSPI_HWA_EnableRxDataMask(s_atFCSpiInfo[eInst].tFCSpiInstance, FCSPI_FALSE); + } + else + { + s_atFCSpiInfo[eInst].tFCSpiStat.u16RxByteCntRemainToGet = u16TransferByteCnt; + FCSPI_HWA_EnableRxDataMask(s_atFCSpiInfo[eInst].tFCSpiInstance, FCSPI_TRUE); + } + + s_atFCSpiInfo[eInst].tFCSpiStat.u16RxGetByteCntOfCurFrame = (uint16_t)0; + s_atFCSpiInfo[eInst].tFCSpiStat.u16TxSendByteCntOfCurFrame = (uint16_t)0; + s_atFCSpiInfo[eInst].tFCSpiStat.eIsPcsContinuous = FCSPI_FALSE; + s_atFCSpiInfo[eInst].tFCSpiStat.eIsInTransfer = FCSPI_TRUE; + + if (NULL != pReceiveBuffer) /* need rx fifo */ + { + FCSpi_Hw_EnableMoreInterrupts(eInst, FCSPI_INT_EN_RFIE(1)); + } + + if (NULL != pSendBuffer) + { + FCSpi_Hw_EnableMoreInterrupts(eInst, FCSPI_INT_EN_TFIE(1)); + } + } + } + + return eRet; +} + +static FCSPI_StatusType fcspi_slave_trigger( + FCSPI_InstanceType eInst, FCSPI_AtomicBoolType bIsInISR) +{ + uint32_t u32StatusRegValue; + uint16_t u16RemainTx = (uint16_t)0; + uint16_t u16RemainRx = (uint16_t)0; + FCSPI_StatusType eRet = FCSPI_STATUS_TRIGGER_OK; + + /* If an error is detected the transfer will be aborted */ + u32StatusRegValue = FCSPI_HWA_GetStatus(s_atFCSpiInfo[eInst].tFCSpiInstance); + if (FCSpi_Hw_ChkTxFifoUnderrun(u32StatusRegValue) && + (NULL != s_atFCSpiInfo[eInst].tFCSpiStat.pbyTxBuff)) + { + s_atFCSpiInfo[eInst].tFCSpiStat.eTransferStat = FCSPI_TRANSFER_TX_FAIL; + fcspi_slave_abort_transfer(eInst, bIsInISR); + eRet = FCSPI_STATUS_TRIGGER_ABORT_TX_FAIL; + } + else if (FCSpi_Hw_ChkRxFifoOverflow(u32StatusRegValue) && + (NULL != s_atFCSpiInfo[eInst].tFCSpiStat.pbyRxBuff)) + { + s_atFCSpiInfo[eInst].tFCSpiStat.eTransferStat = FCSPI_TRANSFER_RX_FAIL; + fcspi_slave_abort_transfer(eInst, bIsInISR); + eRet = FCSPI_STATUS_TRIGGER_ABORT_RX_FAIL; + } + /* rx data ready */ + else + { + if (FCSpi_Hw_ChkRxGreaterThanWater(u32StatusRegValue)) + { + if ((uint16_t)0 != s_atFCSpiInfo[eInst].tFCSpiStat.u16RxByteCntRemainToGet) + { + fcspi_read_rx_fifo(eInst); + } + } + + /* transmit some, need add more */ + if (FCSpi_Hw_ChkTxEqualOrLessThanWater(u32StatusRegValue)) + { + if ((uint16_t)0 != s_atFCSpiInfo[eInst].tFCSpiStat.u16TxByteCntRemainToSend) + { + fcspi_write_tx_fifo(eInst); + } + } + + if ((uint16_t)0 == s_atFCSpiInfo[eInst].tFCSpiStat.u16TxByteCntRemainToSend) + { + /* Disable TX flag. Software buffer is empty.*/ + FCSpi_Hw_DisableTransmitDataInterrupt(eInst); + } + + if ((uint16_t)0 == s_atFCSpiInfo[eInst].tFCSpiStat.u16RxByteCntRemainToGet) + { + FCSpi_Hw_DisableReceiveDataInterrupt(eInst); + } + + u16RemainTx = s_atFCSpiInfo[eInst].tFCSpiStat.u16TxByteCntRemainToSend; + u16RemainRx = s_atFCSpiInfo[eInst].tFCSpiStat.u16RxByteCntRemainToGet; + if (((uint16_t)0 == u16RemainTx) && ((uint16_t)0 == u16RemainRx)) + { + FCSpi_Hw_DisableSomeInterrupts(eInst, FCSPI_INT_EN_RFOIE(1) | FCSPI_INT_EN_TFUIE(1)); + + if (s_atFCSpiInfo[eInst].tFCSpiStat.pStopNotifyCb) + { + s_atFCSpiInfo[eInst].tFCSpiStat.pStopNotifyCb(eInst, bIsInISR); + } + + if (s_atFCSpiInfo[eInst].tFCSpiStat.u8WaitSemaphore) + { + s_atFCSpiInfo[eInst].tFCSpiStat.pSemaPostCb(eInst, bIsInISR); + s_atFCSpiInfo[eInst].tFCSpiStat.u8WaitSemaphore = (uint8_t)0; + } + + s_atFCSpiInfo[eInst].tFCSpiStat.eIsInTransfer = FCSPI_FALSE; + eRet = FCSPI_STATUS_TRIGGER_FINISH; + } + } + + return eRet; +} + +/*----------------------------------------------------------------------------*/ +/** + * @brief If it's in transfer, get its stat, or get the last transfer's stat. + * + * @param eInst Which FCSpi Hardware instance + * @param pCfg the transfer information, can be null + * @return FCSPI_StatusType FCSPI_STATUS_SUCCESS when the last transfer is finish successfully. Others, busy or error occur. + */ +FCSPI_StatusType FCSPI_GetLatestTransferStat(const FCSPI_InstanceType eInst, FCSPI_TransferRemainInfType *pCfg) +{ + FCSPI_StatusType eRet = FCSPI_STATUS_SUCCESS; + + if (NULL != pCfg) + { + pCfg->u32ByteCountReceiveRemained = s_atFCSpiInfo[eInst].tFCSpiStat.u16RxByteCntRemainToGet; + pCfg->u32ByteCountSendRemained = s_atFCSpiInfo[eInst].tFCSpiStat.u16TxByteCntRemainToSend; + } + + if (FCSPI_TRANSFER_OK != s_atFCSpiInfo[eInst].tFCSpiStat.eTransferStat) + { + eRet = FCSPI_STATUS_ERROR; + } + else if (FCSPI_TRUE == s_atFCSpiInfo[eInst].tFCSpiStat.eIsInTransfer) + { + eRet = FCSPI_STATUS_BUSY; + } + else + { + eRet = FCSPI_STATUS_SUCCESS; + } + + return eRet; +} + +#ifdef FCSPI_DRV_INTERNAL_FUNC_EN +/** + * @brief Trigger the driver to transfer data when select FCSPI_TRANSFER_TRIGGER_SRC_USER_POLL + * + * @param eInst Which FCSpi Hardware instance + * @return FCSPI_StatusType FCSPI_STATUS_TRIGGER_OK when api trigger successfully, FCSPI_STATUS_TRIGGER_FINISH when all data transfer finish. Others, error happen. + */ +FCSPI_StatusType FCSPI_PollTrigger(FCSPI_InstanceType eInst) +{ + FCSPI_StatusType eRet = FCSPI_STATUS_TRIGGER_OK; + + if (FCSPI_TRANSFER_TRIGGER_SRC_USER_POLL == s_atFCSpiInfo[eInst].tFCSpiStat.eTransferTriggerSrc) + { + if (FCSPI_TRUE == s_atFCSpiInfo[eInst].tFCSpiStat.eIsInTransfer) + { + if (FCSPI_MODE_MASTER == FCSPI_HWA_CheckMode(s_atFCSpiInfo[eInst].tFCSpiInstance)) + { + eRet = fcspi_master_trigger(eInst, FCSPI_FALSE); + } + else + { + eRet = fcspi_slave_trigger(eInst, FCSPI_FALSE); + } + } + else + { + eRet = FCSPI_STATUS_ERROR; + } + } + else + { + eRet = FCSPI_STATUS_ERROR; + } + + return eRet; +} +#endif + +/** + * @brief Select the trigger source(DMA with interrupt / interrupt / user poll) + * + * @param eInst Which FCSpi Hardware instance + * @param eSrc three source, 1) DMA move data between memory and registers, notified when finish by interrupt; 2) purely by interrupt; 3) purely by user poll. + * @return FCSPI_StatusType FCSPI_STATUS_SUCCESS when successfully. Others, error. + */ +FCSPI_StatusType FCSPI_SelectTriggerSrc( + FCSPI_InstanceType eInst, FCSPI_TriggerSrcType eSrc) +{ + FCSPI_StatusType eRet = FCSPI_STATUS_SUCCESS; + uint32_t u32StatRegVal = 0u; + + u32StatRegVal = FCSPI_HWA_GetStatus(s_atFCSpiInfo[eInst].tFCSpiInstance); + if ((FCSPI_TRUE != s_atFCSpiInfo[eInst].tFCSpiStat.eIsInTransfer) && + (!FCSpi_Hw_ChkBusy(u32StatRegVal))) + { + switch (eSrc) + { + case FCSPI_TRANSFER_TRIGGER_SRC_ISR: + s_atFCSpiInfo[eInst].tFCSpiStat.eTransferTriggerSrc = eSrc; + break; + case FCSPI_TRANSFER_TRIGGER_SRC_DMA_ISR: + s_atFCSpiInfo[eInst].tFCSpiStat.eTransferTriggerSrc = eSrc; + break; + case FCSPI_TRANSFER_TRIGGER_SRC_USER_POLL: + s_atFCSpiInfo[eInst].tFCSpiStat.eTransferTriggerSrc = eSrc; + break; + default: + s_atFCSpiInfo[eInst].tFCSpiStat.eTransferTriggerSrc = eSrc; + break; + } + } + else + { + eRet = FCSPI_STATUS_BUSY; + } + + return eRet; +} + +/** + * @brief Abort current transfer if exist, or just recovery the hardware. + * + * @param eInst Which FCSpi Hardware instance + */ +void FCSPI_AbortTransfer(const FCSPI_InstanceType eInst) +{ + s_atFCSpiInfo[eInst].tFCSpiStat.eTransferStat = FCSPI_TRANSFER_ABORT; + + if (FCSPI_MODE_MASTER == FCSPI_HWA_CheckMode(s_atFCSpiInfo[eInst].tFCSpiInstance)) + { + fcspi_master_abort_transfer(eInst, FCSPI_FALSE); + } + else + { + fcspi_slave_abort_transfer(eInst, FCSPI_FALSE); + } +} + +static void fcspi_irq_handler(FCSPI_InstanceType eInst) +{ + if (FCSPI_MODE_MASTER == FCSPI_HWA_CheckMode(s_atFCSpiInfo[eInst].tFCSpiInstance)) + { + fcspi_master_trigger(eInst, FCSPI_TRUE); + } + else + { + fcspi_slave_trigger(eInst, FCSPI_TRUE); + } +} + +/** + * @brief fcspi 0 interrupt handler + * + * @note This function should be called as/in FCSPI 0 interrupt handler + */ +void FCSPI0_IRQHandler(void) +{ + fcspi_irq_handler(FCSPI_0); +} + +/** + * @brief fcspi 1 interrupt handler + * + * @note This function should be called as/in FCSPI 1 interrupt handler + */ +void FCSPI1_IRQHandler(void) +{ + fcspi_irq_handler(FCSPI_1); +} + +/** + * @brief fcspi 2 interrupt handler + * + * @note This function should be called as/in FCSPI 2 interrupt handler + */ +void FCSPI2_IRQHandler(void) +{ + fcspi_irq_handler(FCSPI_2); +} + +/** + * @brief fcspi 3 interrupt handler + * + * @note This function should be called as/in FCSPI 3 interrupt handler + */ +void FCSPI3_IRQHandler(void) +{ + fcspi_irq_handler(FCSPI_3); +} + +/** + * @brief fcspi 4 interrupt handler + * + * @note This function should be called as/in FCSPI 4 interrupt handler + */ +void FCSPI4_IRQHandler(void) +{ + fcspi_irq_handler(FCSPI_4); +} + +/** + * @brief fcspi 5 interrupt handler + * + * @note This function should be called as/in FCSPI 5 interrupt handler + */ +void FCSPI5_IRQHandler(void) +{ + fcspi_irq_handler(FCSPI_5); +} diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_fcuart.c b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_fcuart.c new file mode 100644 index 0000000..a74d1cd --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_fcuart.c @@ -0,0 +1,1768 @@ +/** + * @file fc7xxx_driver_fcuart.c + * @author Flagchip + * @brief FC7xxx FCUart driver type definition and API + * @version 0.1.0 + * @date 2024-01-14 + * + * @copyright Copyright (c) 2022 Flagchip Semiconductors Co., Ltd. + * + */ + +/******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-01-14 Flagchip0122 N/A FC7xxx internal release version + ********************************************************************************/ + +#include "fc7xxx_driver_fcuart.h" + + + + +/********* Macro ************/ + +/********* Local typedef ************/ + +typedef enum { + UART_PRINT_RADIX_BIN = 2U, + UART_PRINT_RADIX_OCT = 8U, + UART_PRINT_RADIX_DEC = 10U, + UART_PRINT_RADIX_HEX = 16U +} UART_PrintIntType; + +/** + * @brief FCUART Operation Sequence + * + */ +typedef enum { + FCUART_SEQUENCE_VAR_NOINIT, /**< FCUART_SEQUENCE_DEINIT means fcuart variables data is not initialed */ + FCUART_SEQUENCE_DEINIT, /**< FCUART_SEQUENCE_DEINIT means fcuart driver is not initialed */ + FCUART_SEQUENCE_NOTSTART_RECEIVE, /**< FCUART_SEQUENCE_NOTSTART_RECEIVE means fcuart driver initialed and write/erase is allowed */ + FCUART_SEQUENCE_START_RECEIVE /**< FCUART_SEQUENCE_START_RECEIVE means fcuart driver started received */ +} FCUART_SequenceType; + +/********* Local Variables ************/ +/* UART instance array */ +static FCUART_Type *const s_aFCUART_InstanceTable[FCUART_INSTANCE_COUNT] = FCUART_BASE_PTRS; + +/* sequence table */ +static FCUART_SequenceType s_aCurrentSequence[FCUART_INSTANCE_COUNT] = {FCUART_SEQUENCE_VAR_NOINIT}; + +/* error notify callback function point */ +static FCUART_ErrorInterrupt_CallBackType s_aFCUART_ErrorNotifyTable[FCUART_INSTANCE_COUNT]; + +/* receive notify callback function point */ +static FCUART_TxRxInterrupt_CallBackType s_aFCUART_RxNotifyTable[FCUART_INSTANCE_COUNT]; + +/* Transfer empty notify callback function point */ +static FCUART_TxRxInterrupt_CallBackType s_aFCUART_TxEmptyNotifyTable[FCUART_INSTANCE_COUNT]; + +/* Transfer complete notify callback function point */ +static FCUART_TxRxInterrupt_CallBackType s_aFCUART_TxCompleteNotifyTable[FCUART_INSTANCE_COUNT]; + +/* Idle notify callback function point */ +static FCUART_IdleInterrupt_CallBackType s_aFCUART_IdleNotifyTable[FCUART_INSTANCE_COUNT]; + +/* check every pUart instance whether is used */ +static uint8_t s_aFCUART_UartUsed[FCUART_INSTANCE_COUNT]; + +/* check every pUart instance transmit timeout */ +static uint32_t s_aFCUART_TransmitTimeout[FCUART_INSTANCE_COUNT]; + +/* pUart instance receive buffer */ +static FCUART_DataType *s_aFCUART_RxMsg[FCUART_INSTANCE_COUNT]; + +/* pUart instance transfer buffer */ +static FCUART_DataType *s_aFCUART_TxMsg[FCUART_INSTANCE_COUNT]; + +/********* Local Prototype Functions ************/ + +static FCUART_ErrorType FCUART_LL_CheckInstance(uint8_t u8UartIndex); + +static uint32_t FCUART_LL_Error(uint8_t u8UartIndex); + +static FCUART_ErrorType FCUART_LL_ProcessBaud(uint32_t u32Smb, uint32_t *u32OverSamp, uint32_t *u32Sbr); + +static FCUART_ErrorType FCUART_LL_Transmit_Char(FCUART_Type *pUart, uint8_t u8Data, uint32_t u32TimeoutTick); + +static FCUART_ErrorType FCUART_LL_Receive(uint8_t u8UartIndex, FCUART_DataType *pUartData); + +static FCUART_ErrorType FCUART_LL_Transmit_Empty(uint8_t u8UartIndex, FCUART_DataType *pUartData); + +static FCUART_ErrorType FCUART_LL_Transmit_Complete(uint8_t u8UartIndex); + +static FCUART_ErrorType FCUART_LL_Idle(uint8_t u8UartIndex); + +static uint8_t FCUART_Float2Char(double Value, char *pOutStr, uint32_t u32Eps); + +static uint8_t FCUART_Int2Char(int i32Value, char *pOutStr, UART_PrintIntType eRadix, bool bHexUpper); + +/********* Global Prototype Functions ************/ + +/********* Local Functions ************/ +/** + * @brief Check UART instance + * + * @param u8UartIndex UART instance number + * @return + */ +static FCUART_ErrorType FCUART_LL_CheckInstance(uint8_t u8UartIndex) { + FCUART_ErrorType tRetVal; + + if (u8UartIndex < FCUART_INSTANCE_COUNT) { + tRetVal = (FCUART_ErrorType) FCUART_ERROR_OK; + } else { + tRetVal = (FCUART_ErrorType) FCUART_ERROR_INVALID_PARAM; + } + + return tRetVal; +} + +/** + * @brief Process get OverSamp and SBR + * + * @param u32Smb the value OverSame*SBR + * @param u32OverSamp out OverSampe + * @param u32Sbr out + * @return FCUART_ERROR_OK is ok, others are not ok + */ +static FCUART_ErrorType FCUART_LL_ProcessBaud(uint32_t u32Smb, uint32_t *u32OverSamp, uint32_t *u32Sbr) { + FCUART_ErrorType tRetVal; + uint32_t u32SbrTemp; + uint32_t u32OverSampTemp; + uint32_t u32TempSmbDiff; + uint32_t u32SmbDiff; + uint32_t u32CalcSmb; + uint32_t u32OverSamp1; + uint32_t u32Sbr1; + uint32_t u32OriginDiff; + + u32OverSamp1 = 4U; /* 4..32 */ + + /* sbr = smb / oversamp */ + u32Sbr1 = (uint16_t) (u32Smb / (u32OverSamp1)); + u32CalcSmb = (u32OverSamp1) * (u32Sbr1); + + if (u32CalcSmb > u32Smb) { + u32SmbDiff = u32CalcSmb - u32Smb; + } else { + u32SmbDiff = u32Smb - u32CalcSmb; + } + u32OriginDiff = u32SmbDiff; + + if (u32SmbDiff != 0U) { + + /* loop to find the best u32OverSamp1 value possible, one that generates minimum u32SmbDiff + * iterate through the rest of the supported values of u32OverSamp */ + for (u32OverSampTemp = 5U; u32OverSampTemp <= 32U; u32OverSampTemp++) { + /* calculate the temporary u32Sbr value */ + u32SbrTemp = (uint32_t) (u32Smb / u32OverSampTemp); + /* calculate the baud rate based on the temporary u32OverSamp and u32Sbr values */ + u32CalcSmb = (uint32_t) (u32OverSampTemp * u32SbrTemp); + + if (u32CalcSmb > u32Smb) { + u32TempSmbDiff = u32CalcSmb - u32Smb; + } else { + u32TempSmbDiff = u32Smb - u32CalcSmb; + } + + if (u32TempSmbDiff < u32SmbDiff) { + u32SmbDiff = u32TempSmbDiff; + u32OverSamp1 = u32OverSampTemp; /* update and store the best u32OverSamp value calculated */ + u32Sbr1 = u32SbrTemp; /* update store the best u32Sbr value calculated */ + } + + /* when differ is 0U, break */ + if (u32SmbDiff == 0U) { + break; + } + } + } + + /* check differ */ + if (u32SmbDiff <= u32OriginDiff) { + tRetVal = (FCUART_ErrorType) FCUART_ERROR_OK; + + /* out the calculated value */ + *u32Sbr = u32Sbr1; + *u32OverSamp = u32OverSamp1; + } else { + tRetVal = (FCUART_ErrorType) FCUART_ERROR_FAILED; + } + + return tRetVal; +} + +/** + * @brief Function to Transmit single Char + * + * @param pUart UART Instance point + * @param u8Data UART data + * @return FCUART_ERROR_OK is ok, others are not ok + */ +static FCUART_ErrorType FCUART_LL_Transmit_Char(FCUART_Type *pUart, uint8_t u8Data, uint32_t u32TimeoutTick) { + uint32_t u32Result; + uint32_t u32TryCount; + + /* check transmit ready flag */ + u32Result = FCUART_HWA_GetStatus(pUart, FCUART_STAT_TDREF); + + if (u32Result != 0U) { + FCUART_HWA_SetData(pUart, (uint32_t) u8Data); /* Send data */ + FCUART_HWA_SetTxTransfer(pUart, true); /* start transmit */ + + u32Result = 0U; + u32TryCount = 0U; + + while ((u32Result == 0U) && (u32TryCount < u32TimeoutTick)) { + /* check transmit flag */ + u32Result = FCUART_HWA_GetStatus(pUart, FCUART_STAT_TCF); + u32TryCount++; + } + + /* after transmit completed, close TE */ + FCUART_HWA_SetTxTransfer(pUart, false); + } + + return (u32Result == 0U) ? (FCUART_ErrorType) FCUART_ERROR_FAILED : (FCUART_ErrorType) FCUART_ERROR_OK; +} + +/** + * @brief Function to Transmit single Char by interrupt + * + * @param u8UartIndex UART Instance + * @param pUartData UART receive buffer + * @return FCUART_ERROR_OK is ok, others are not ok + */ +static FCUART_ErrorType FCUART_LL_Transmit_Empty(uint8_t u8UartIndex, FCUART_DataType *pUartData) { + FCUART_ErrorType tRetVal = (FCUART_ErrorType) FCUART_ERROR_INVALID_PARAM; + FCUART_Type *pUart; + uint32_t u32TempStats; + uint32_t u32Index; + uint8_t u8Index; + uint8_t u8TxWaterMark; + + pUart = (FCUART_Type *) s_aFCUART_InstanceTable[u8UartIndex]; + if ((pUartData != NULL) && (pUartData->pDatas != NULL)) { + /* get and clear receive flag */ + u32TempStats = FCUART_HWA_GetStatus(pUart, FCUART_STAT_TDREF); + if (u32TempStats > 0U) { + /* TDRFF Flag has been got */ + tRetVal = (FCUART_ErrorType) FCUART_ERROR_OK; + if (pUartData->u32DataLen > 0U) { + if (true == FCUART_HWA_GetEnStatusTxFifo(pUart)) { + /* Tx fifo enable */ + u8TxWaterMark = FCUART_HWA_GetTxWaterMark(pUart); + + if (((pUartData->u32DataLen) >= (uint32_t) (FCUART_FIFO_DEPTH - u8TxWaterMark))) { + for (u8Index = 0U; u8Index < (FCUART_FIFO_DEPTH - u8TxWaterMark); u8Index++) { + FCUART_HWA_SetData(pUart, (uint8_t) (pUartData->pDatas[0U])); /* Send data */ + + /* Update pointer position */ + (pUartData->pDatas)++; + (pUartData->u32DataLen)--; + } + } else { + for (u32Index = 0U; u32Index < (pUartData->u32DataLen); u32Index++) { + FCUART_HWA_SetData(pUart, (uint8_t) (pUartData->pDatas[0U])); /* Send data */ + + /* Update pointer position */ + (pUartData->pDatas)++; + (pUartData->u32DataLen)--; + } + } + } else { + /* Tx fifo disable */ + FCUART_HWA_SetData(pUart, (uint8_t) (pUartData->pDatas[0U])); /* Send data */ + + /* Update pointer position */ + (pUartData->pDatas)++; + (pUartData->u32DataLen)--; + } + + if (0U == pUartData->u32DataLen) { + /* There's no new data, disable transmit empty interrupt and enable transmit complete interrupt */ + FCUART_HWA_DisableInterrupt(pUart, (uint32_t) FCUART_INT_CTRL_TIE); + FCUART_HWA_EnableInterrupt(pUart, (uint32_t) FCUART_INT_CTRL_TCIE); + } + } + } + } + + return tRetVal; +} + +/** + * @brief Function to deal transmit complete + * + * @param u8UartIndex UART Instance + * @return FCUART_ERROR_OK is ok, others are not ok + */ +static FCUART_ErrorType FCUART_LL_Transmit_Complete(uint8_t u8UartIndex) { + FCUART_ErrorType tRetVal = (FCUART_ErrorType) FCUART_ERROR_INVALID_PARAM; + FCUART_Type *pUart; + uint32_t u32TempStats; + + /* No need to check instance */ + pUart = (FCUART_Type *) s_aFCUART_InstanceTable[u8UartIndex]; + /* get and clear receive flag */ + u32TempStats = FCUART_HWA_GetStatus(pUart, FCUART_STAT_TCF); + + if (u32TempStats > 0U) { + /* TCF Flag has been got */ + tRetVal = (FCUART_ErrorType) FCUART_ERROR_OK; + + FCUART_HWA_DisableInterrupt(pUart, (uint32_t) (FCUART_INT_CTRL_TE | FCUART_INT_CTRL_TCIE)); + } + return tRetVal; +} + +/** + * @brief Function to deal idle line + * + * @param u8UartIndex UART Instance + * @return FCUART_ERROR_OK is ok, others are not ok + */ +static FCUART_ErrorType FCUART_LL_Idle(uint8_t u8UartIndex) { + FCUART_ErrorType tRetVal = (FCUART_ErrorType) FCUART_ERROR_INVALID_PARAM; + FCUART_Type *pUart; + uint32_t u32TempStats; + + /* get and clear receive flag */ + pUart = (FCUART_Type *) s_aFCUART_InstanceTable[u8UartIndex]; + /* No need to check instance */ + u32TempStats = FCUART_HWA_GetStatus(pUart, FCUART_STAT_IDLEF); + + if (u32TempStats > 0U) { + /* IDLF Flag has been got */ + tRetVal = (FCUART_ErrorType) FCUART_ERROR_OK; + FCUART_HWA_ClearStatus(pUart, (uint32_t) FCUART_STAT_IDLEF); + } + return tRetVal; +} + +/** + * @brief Receive UART data + * + * @param u8UartIndex UART Instance + * @param pUartData UART receive buffer + * @return FCUART_ERROR_OK is ok, others are not ok + */ +static FCUART_ErrorType FCUART_LL_Receive(uint8_t u8UartIndex, FCUART_DataType *pUartData) { + FCUART_ErrorType tRetVal = (FCUART_ErrorType) FCUART_ERROR_INVALID_PARAM; + FCUART_Type *pUart; + uint8_t u8ReadData; + uint32_t u32TempStats; + uint8_t u8RxCount; + uint8_t u8Index; + + pUart = (FCUART_Type *) s_aFCUART_InstanceTable[u8UartIndex]; + + if ((pUartData != NULL) && (pUartData->pDatas != NULL)) { + /* get and clear receive flag */ + u32TempStats = FCUART_HWA_GetStatus(pUart, FCUART_STAT_RDRFF); + + if (u32TempStats > 0U) { + /* RDRFF Flag has been got */ + tRetVal = (FCUART_ErrorType) FCUART_ERROR_OK; + + pUartData->u32DataLen = 0U; + if (true == FCUART_HWA_GetEnStatusRxFifo(pUart)) { + /* Rx fifo enable */ + u8RxCount = FCUART_HWA_GetFifoRxCount(pUart); + for (u8Index = 0U; u8Index < u8RxCount; u8Index++) { + u8ReadData = FCUART_HWA_GetData(pUart); + pUartData->pDatas[u8Index] = u8ReadData; + pUartData->u32DataLen++; + } + } else { + /* Rx fifo disable */ + u8ReadData = FCUART_HWA_GetData(pUart); + pUartData->pDatas[0U] = u8ReadData; + pUartData->u32DataLen++; + } + } + } + + return tRetVal; +} + +/** + * @brief Get Error Status + * + * @param u8UartIndex + * @return All Error Combine, 0U is no error + */ +static uint32_t FCUART_LL_Error(uint8_t u8UartIndex) { + uint32_t u32RetVal; + uint32_t u32ErrorValue; + FCUART_Type *pUart; + + u32ErrorValue = 0U; + + pUart = (FCUART_Type *) s_aFCUART_InstanceTable[u8UartIndex]; + + /* receive overrun */ + u32RetVal = FCUART_HWA_GetStatus(pUart, FCUART_STAT_RORF); + + /* FCUART_HWA_ClearStatus(pUart, FCUART_STAT_RORF); */ + if (u32RetVal != 0U) { + u32ErrorValue = (uint32_t) FCUART_ERROR_RORF; + } + + /* noise flag */ + u32RetVal = FCUART_HWA_GetStatus(pUart, FCUART_STAT_NF); + + /*FCUART_HWA_ClearStatus(pUart, FCUART_STAT_NF);*/ + if (u32RetVal != 0U) { + u32ErrorValue |= (uint32_t) FCUART_ERROR_NF; + } + + /* Frame Error flag */ + u32RetVal = FCUART_HWA_GetStatus(pUart, FCUART_STAT_FEF); + + /*FCUART_HWA_ClearStatus(pUart, FCUART_STAT_FEF);*/ + if (u32RetVal != 0U) { + u32ErrorValue |= (uint32_t) FCUART_ERROR_FEF; + } + + /* Parity Error Flag */ + u32RetVal = FCUART_HWA_GetStatus(pUart, FCUART_STAT_PEF); + + /*FCUART_HWA_ClearStatus(pUart, FCUART_STAT_PEF);*/ + if (u32RetVal != 0U) { + u32ErrorValue |= (uint32_t) FCUART_ERROR_PEF; + } + + /* Receive Data Parity Error Flag */ + u32RetVal = FCUART_HWA_GetStatus(pUart, FCUART_STAT_RPEF); + + /*FCUART_HWA_ClearStatus(pUart, FCUART_STAT_RPEF);*/ + if (u32RetVal != 0U) { + u32ErrorValue |= (uint32_t) FCUART_ERROR_RPEF; + } + + /* Transmit Data Parity Error Flag */ + u32RetVal = FCUART_HWA_GetStatus(pUart, FCUART_STAT_TPEF); + + /*FCUART_HWA_ClearStatus(pUart, FCUART_STAT_TPEF);*/ + if (u32RetVal != 0U) { + u32ErrorValue |= (uint32_t) FCUART_ERROR_TPEF; + } + + /* clear error flags */ + FCUART_HWA_ClearStatus(pUart, u32ErrorValue); + + return u32ErrorValue; +} + +/********************* Global Functions *********************/ + +/** + * @brief Initial UART variables Memory + * + */ +void FCUART_InitMemory(uint8_t u8UartIndex) { + + s_aFCUART_ErrorNotifyTable[u8UartIndex] = NULL; + + s_aFCUART_RxNotifyTable[u8UartIndex] = NULL; + + s_aFCUART_TxEmptyNotifyTable[u8UartIndex] = NULL; + + s_aFCUART_TxCompleteNotifyTable[u8UartIndex] = NULL; + + s_aFCUART_IdleNotifyTable[u8UartIndex] = NULL; + + s_aFCUART_UartUsed[u8UartIndex] = 0U; + + /* set first state */ + s_aCurrentSequence[u8UartIndex] = FCUART_SEQUENCE_DEINIT; + +} + +/** + * @brief This Function is used to initial UART instance + * + * @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U) + * @param pInitCfg contains clock, baud-rate, Bit Mode, parity and so on. + * @return FCUART_ERROR_OK is ok, others are not ok + */ +FCUART_ErrorType FCUART_Init(uint8_t u8UartIndex, FCUART_InitType *pInitCfg) { + FCUART_ErrorType tRetVal; + uint32_t u32TempBaudReg; + uint32_t u32TempCtrlReg; + uint32_t u32TempFifoReg; + uint32_t u32TempWatermarkReg; + uint32_t u32TempStat; + uint32_t u32TempModir; + FCUART_Type *pUart; + uint32_t u32Sbr = 0U; + uint32_t u32OverSamp = 0U; + uint32_t u32Smb = 0U; + + /* check parameter */ + tRetVal = FCUART_LL_CheckInstance(u8UartIndex); + + if ((tRetVal == (FCUART_ErrorType) FCUART_ERROR_OK) && + (s_aCurrentSequence[u8UartIndex] == FCUART_SEQUENCE_DEINIT)) { + + tRetVal = (FCUART_ErrorType) FCUART_ERROR_OK; + } else { + tRetVal |= (FCUART_ErrorType) FCUART_ERROR_INVALID_SEQUENCE; + } + + if (pInitCfg != NULL) { + if (tRetVal == (FCUART_ErrorType) FCUART_ERROR_OK) { + + /* set not start state */ + s_aCurrentSequence[u8UartIndex] = FCUART_SEQUENCE_NOTSTART_RECEIVE; + + if (0U != pInitCfg->u32Baudrate) { + u32Smb = pInitCfg->u32ClkSrcHz / pInitCfg->u32Baudrate; + } else { + u32Smb = 0; + tRetVal = (FCUART_ErrorType) FCUART_ERROR_INVALID_PARAM; + } + + pUart = (FCUART_Type *) s_aFCUART_InstanceTable[u8UartIndex]; + + /* process for baud-rate */ + if ((FCUART_ErrorType) FCUART_ERROR_OK == FCUART_LL_ProcessBaud(u32Smb, &u32OverSamp, &u32Sbr)) { + /* temporary BAUD register */ + u32TempBaudReg = (uint32_t) 0U | + /* initial value */ + FCUART_BAUD_MAEN0(0U) | + /* Match mode enable 0 */ + FCUART_BAUD_MAEN1(0U) | + /* Match mode enable 1 */ + FCUART_BAUD_10BIT_MODE(0U) | + /* 10bit mode select */ + FCUART_BAUD_OVR_SAMP(u32OverSamp - 1U) | + /* Over sampling Ratio, n+1 */ + FCUART_BAUD_TDMAEN(pInitCfg->bEnTxEmptyDma) | + /* Transmitter DMA Enable */ + FCUART_BAUD_RDMAEN(pInitCfg->bEnRxFullDma) | + /* Receiver Full DMA Enable */ + FCUART_BAUD_RIDMAEN(0U) | + /* Receiver Idle DMA Enable */ + FCUART_BAUD_MATCH_CFG(0U) | + /* Match Configuration */ + FCUART_BAUD_BEDGE_SAMP(1U) | + /* Both Edge Sampling */ + FCUART_BAUD_RESYNC_DIS(0U) | + /* Re-synchronization Disable */ + FCUART_BAUD_LBKDIE(0U) | + /* LIN Break Detect Interrupt Enable */ + FCUART_BAUD_RIAEIE(0U) | + /* RX Input Active Edge Interrupt Enable */ + FCUART_BAUD_SBNS(pInitCfg->eStopBit) | + /* Stop Bit Number Select */ + FCUART_BAUD_SBR( + u32Sbr); /* Baud Rate Modulo Divisor. baud-rate = baud clock / ((OVR_SAMP+1) * SBR) */ + + /* temporary CTRL register */ + u32TempCtrlReg = (uint32_t) 0U |/* initial value */ + FCUART_CTRL_R8T9(0U) | + /* Receive Bit 8 / Transmit Bit 9 */ + FCUART_CTRL_R9T8(0U) | + /* Receive Bit 9 / Transmit Bit 8 */ + FCUART_CTRL_TXDIR(0U) | + /* TXD Pin Direction in Single-Wire Mode */ + FCUART_CTRL_TXINV(0U) | + /* Transmit Data Inversion */ + FCUART_CTRL_ORIE(0U) | + /* Overrun Interrupt Enable */ + FCUART_CTRL_NEIE(0U) | + /* Noise Error Interrupt Enable */ + FCUART_CTRL_FEIE(0U) | + /* Frame Error Interrupt Enable */ + FCUART_CTRL_PEIE(0U) | + /* Parity Error Interrupt Enable */ + FCUART_CTRL_TIE(0U) | + /* Transmit Interrupt Enable */ + FCUART_CTRL_TCIE(0U) | + /* Transmission Complete Interrupt Enable */ + FCUART_CTRL_RIE(0U) | + /* Receiver Interrupt Enable */ + FCUART_CTRL_IIE(0U) | + /* Idle Line Interrupt Enable */ + FCUART_CTRL_TE(0U) | + /* Transmitter Enable */ + FCUART_CTRL_RE(0U) | + /* Receiver Enable */ + FCUART_CTRL_RWC(0U) | + /* Receiver WakeUp Control */ + FCUART_CTRL_SBK(0U) | + /* Send Break */ + FCUART_CTRL_M0IE(0U) | + /* Match address 0 Interrupt Enable */ + FCUART_CTRL_M1IE(0U) | + /* Match address 1 Interrupt Enable */ + FCUART_CTRL_7BMS(0U) | + /* 7-Bit Mode Select */ + FCUART_CTRL_IDLECFG(pInitCfg->eIdleCharNum) | + /* Idle Configuration 2^n bytes time no data entry IDLE */ + FCUART_CTRL_LOOPMS(0U) | + /* Loop Mode Select */ + FCUART_CTRL_WAITEN(0U) | + /* WAIT Enable */ + FCUART_CTRL_RXSRC(0U) | + /* Receiver Source Select */ + FCUART_CTRL_BMSEL(pInitCfg->eBitMode) | + /* 9-Bit or 8-Bit Mode Select */ + FCUART_CTRL_RSWMS(0U) | + /* Receiver WakeUp Method Select */ + FCUART_CTRL_ITS(pInitCfg->eIdleStart) | + /* Idle Line Type Select */ + FCUART_CTRL_PE(pInitCfg->bParityEnable) | + /* Parity Enable */ + FCUART_CTRL_PT( + pInitCfg->eParityType); /* Parity Type */ + + /* temporary FIFO register */ + u32TempFifoReg = + (uint32_t) 0U | /* initial value */ + FCUART_FIFO_TXEMPTY(0U) | /* Transmit Buffer/FIFO Empty */ + FCUART_FIFO_RXEMPTY(0U) | /* Receive Buffer/FIFO Empty */ + FCUART_FIFO_TXOF(0U) | /* Transmitter Buffer Overflow Flag */ + FCUART_FIFO_RXUF(0U) | /* Receiver Buffer Underflow Flag */ + FCUART_FIFO_TXFLUSH(1U) | /* Transmit FIFO/Buffer Flush */ + FCUART_FIFO_RXFLUSH(1U) | /* Receive FIFO/Buffer Flush */ + FCUART_FIFO_RXIDEN(pInitCfg->eFifoRxIdleCharNum) | + /* Receiver Idle Empty Enable */ + FCUART_FIFO_TXOFIE(0U) | /* Transmit FIFO Overflow Interrupt Enable */ + FCUART_FIFO_RXUFIE(0U) | /* Receive FIFO Underflow Interrupt Enable */ + FCUART_FIFO_TXFEN(pInitCfg->bEnTxFifo) | /* Transmit FIFO Enable */ + FCUART_FIFO_TXFIFODEP(1U) | /* Transmit FIFO Buffer Depth */ + FCUART_FIFO_RXFEN(pInitCfg->bEnRxFifo) | /* Receive FIFO Enable, enable RX FIFO */ + FCUART_FIFO_RXFIFODEP(1U); /* Receive FIFO Buffer Depth */ + + /* temporary WATERMARK register */ + u32TempWatermarkReg = (uint32_t) 0U |/* initial value */ + FCUART_WATERMARK_RXCOUNT(0U) | + /* Receive Counter */ + FCUART_WATERMARK_RXWATER(pInitCfg->u8RxFifoWaterMark) | + /* Receive WaterMark, receive n-1 request interrupt or DMA */ + FCUART_WATERMARK_TXCOUNT(0U) | + /* Transmit Counter */ + FCUART_WATERMARK_TXWATER( + pInitCfg->u8TxFifoWaterMark); /* Transmit WaterMark */ + + /* temporary MODIR register */ + u32TempModir = (uint32_t) 0U | /* initial value */ + FCUART_MODIR_RXRTSCFG(0U) | + /* Receive RTS Configuration */ + FCUART_MODIR_TXCTSSRC(0U) | + /* Transmit CTS Source */ + FCUART_MODIR_TXCTSCFG(0U) | + /* Transmit CTS Configuration */ + FCUART_MODIR_RXRTSEN(0U) | /* Receiver Request-to-Send Enable */ + FCUART_MODIR_TXRTSPOL(0U) | + /* Transmitter Request-to-Send Polarity */ + FCUART_MODIR_TXRTSEN(0U) | /* Transmitter Request-to-Send Enable */ + FCUART_MODIR_TXCTSEN( + 0U); /* Transmitter Clear-to-Send Enable */ + + /* write register with temporary data */ + FCUART_HWA_SetBaud(pUart, u32TempBaudReg); /* 0x19000008; */ + FCUART_HWA_SetFifo(pUart, u32TempFifoReg); + FCUART_HWA_SetWaterMark(pUart, u32TempWatermarkReg); + FCUART_HWA_SetModir(pUart, u32TempModir); + + FCUART_HWA_SetCtrl(pUart, u32TempCtrlReg); + + /* clear all status */ + u32TempStat = FCUART_HWA_GetSTAT(pUart); + FCUART_HWA_WriteClearSTAT(pUart, u32TempStat); + FCUART_HWA_ClearFIFOErrorFlag(pUart); + + /* instance used */ + s_aFCUART_UartUsed[u8UartIndex] = 1U; + s_aFCUART_TransmitTimeout[u8UartIndex] = + pInitCfg->u32TransmitTimeout > 0U ? pInitCfg->u32TransmitTimeout : 3000U; + } else { + tRetVal |= (FCUART_ErrorType) FCUART_ERROR_FAILED; + } + } + } else { + tRetVal |= (FCUART_ErrorType) FCUART_ERROR_INVALID_PARAM; + } + + return tRetVal; +} + +/** + * @brief This Function is used to de-initial UART instance + * + * @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U) + * @return FCUART_ERROR_OK is ok, others are not ok + */ +FCUART_ErrorType FCUART_DeInit(uint8_t u8UartIndex) { + FCUART_ErrorType tRetVal; + FCUART_Type *pUart; + + /* check parameter */ + tRetVal = FCUART_LL_CheckInstance(u8UartIndex); + + if ((tRetVal == (FCUART_ErrorType) FCUART_ERROR_OK) && (s_aCurrentSequence[u8UartIndex] > FCUART_SEQUENCE_DEINIT)) { + + tRetVal = (FCUART_ErrorType) FCUART_ERROR_OK; + } else { + tRetVal |= (FCUART_ErrorType) FCUART_ERROR_INVALID_SEQUENCE; + } + + if (tRetVal == (FCUART_ErrorType) FCUART_ERROR_OK) { + /* set deinit state */ + s_aCurrentSequence[u8UartIndex] = FCUART_SEQUENCE_DEINIT; + pUart = (FCUART_Type *) s_aFCUART_InstanceTable[u8UartIndex]; + + FCUART_HWA_SetSoftWareReset(pUart); + } + + return tRetVal; +} + +FCUART_ErrorType FCUART_BufTransmitted(uint8_t u8UartIndex, FCUART_InterruptType *pInterruptCfg) { + FCUART_ErrorType tRetVal; + + /* check parameter */ + tRetVal = FCUART_LL_CheckInstance(u8UartIndex); + + if ((tRetVal == (FCUART_ErrorType) FCUART_ERROR_OK) && + (s_aCurrentSequence[u8UartIndex] == FCUART_SEQUENCE_NOTSTART_RECEIVE)) { + tRetVal = (FCUART_ErrorType) FCUART_ERROR_OK; + } else { + tRetVal |= (FCUART_ErrorType) FCUART_ERROR_INVALID_SEQUENCE; + } + + s_aFCUART_TxMsg[u8UartIndex] = pInterruptCfg->pTxBuf; + s_aFCUART_TxEmptyNotifyTable[u8UartIndex] = pInterruptCfg->pTxEmptyNotify; + s_aFCUART_TxCompleteNotifyTable[u8UartIndex] = pInterruptCfg->pTxCompleteNotify; + + return tRetVal; +} + +/** + * @brief This Function is used to set UART interrupt + * + * @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U) + * @param pIntCfg contains callback functions + * @return FCUART_ERROR_OK is ok, others are not ok + */ +FCUART_ErrorType FCUART_SetInterrupt(uint8_t u8UartIndex, FCUART_InterruptType *pInterruptCfg) { + FCUART_ErrorType tRetVal; + FCUART_Type *pUart; + + /* check parameter */ + tRetVal = FCUART_LL_CheckInstance(u8UartIndex); + + if ((tRetVal == (FCUART_ErrorType) FCUART_ERROR_OK) && + (s_aCurrentSequence[u8UartIndex] == FCUART_SEQUENCE_NOTSTART_RECEIVE)) { + tRetVal = (FCUART_ErrorType) FCUART_ERROR_OK; + } else { + tRetVal |= (FCUART_ErrorType) FCUART_ERROR_INVALID_SEQUENCE; + } + + if (tRetVal == (FCUART_ErrorType) FCUART_ERROR_OK) { + if (pInterruptCfg != NULL) { + pUart = (FCUART_Type *) s_aFCUART_InstanceTable[u8UartIndex]; + + /* error interrupt */ + if (true == pInterruptCfg->bEnErrorInterrupt) { + FCUART_HWA_EnableInterrupt(pUart, (uint32_t) (FCUART_INT_CTRL_ORIE | FCUART_INT_CTRL_NEIE | + FCUART_INT_CTRL_FEIE | FCUART_INT_CTRL_PEIE)); + + s_aFCUART_ErrorNotifyTable[u8UartIndex] = pInterruptCfg->pErrorNotify; + } else { + FCUART_HWA_DisableInterrupt(pUart, (uint32_t) (FCUART_INT_CTRL_ORIE | FCUART_INT_CTRL_NEIE | + FCUART_INT_CTRL_FEIE | FCUART_INT_CTRL_PEIE)); + } + + /* receive interrupt */ + if (true == pInterruptCfg->bEnRxInterrupt) { + /* check buffer point if it is null */ + if (pInterruptCfg->pRxBuf != NULL) { + FCUART_HWA_EnableInterrupt(pUart, (uint32_t) FCUART_INT_CTRL_RIE); + + s_aFCUART_RxMsg[u8UartIndex] = pInterruptCfg->pRxBuf; + s_aFCUART_RxNotifyTable[u8UartIndex] = pInterruptCfg->pRxNotify; + } else { + tRetVal |= (FCUART_ErrorType) FCUART_ERROR_INVALID_PARAM; + } + + } else { + FCUART_HWA_DisableInterrupt(pUart, (uint32_t) FCUART_INT_CTRL_RIE); + } + + /* Transfer interrupt */ + if (true == pInterruptCfg->bEnTxInterrupt) { + /* check buffer point if it is null */ + if (pInterruptCfg->pTxBuf != NULL) { + FCUART_HWA_EnableInterrupt(pUart, (uint32_t) FCUART_INT_CTRL_TIE); + s_aFCUART_TxMsg[u8UartIndex] = pInterruptCfg->pTxBuf; + s_aFCUART_TxEmptyNotifyTable[u8UartIndex] = pInterruptCfg->pTxEmptyNotify; + s_aFCUART_TxCompleteNotifyTable[u8UartIndex] = pInterruptCfg->pTxCompleteNotify; + } else { + tRetVal |= (FCUART_ErrorType) FCUART_ERROR_INVALID_PARAM; + } + + } else { + FCUART_HWA_DisableInterrupt(pUart, (uint32_t) FCUART_INT_CTRL_TIE); + } + + /* Idle interrupt */ + if (true == pInterruptCfg->bEnIdleInterrupt) { + FCUART_HWA_EnableInterrupt(pUart, (uint32_t) FCUART_INT_CTRL_IIE); + s_aFCUART_IdleNotifyTable[u8UartIndex] = pInterruptCfg->pIdleNotify; + } else { + FCUART_HWA_DisableInterrupt(pUart, (uint32_t) FCUART_INT_CTRL_IIE); + } + } else { + tRetVal |= (FCUART_ErrorType) FCUART_ERROR_INVALID_PARAM; + } + } else { + /* No deal with */ + } + + return tRetVal; +} + +/** + * @brief This Function is used to set UART WakeUp + * + * @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U) + * @param pWakeupCfg contains UART wake-up parameters + * @return FCUART_ERROR_OK is ok, others are not ok + */ +FCUART_ErrorType FCUART_SetWakeup(uint8_t u8UartIndex, FCUART_WakeupType *pWakeupCfg) { + FCUART_ErrorType tRetVal; + FCUART_Type *pUart; + + /* check parameter */ + tRetVal = FCUART_LL_CheckInstance(u8UartIndex); + + if ((tRetVal == (FCUART_ErrorType) FCUART_ERROR_OK) && + (s_aCurrentSequence[u8UartIndex] == FCUART_SEQUENCE_NOTSTART_RECEIVE)) { + tRetVal = (FCUART_ErrorType) FCUART_ERROR_OK; + } else { + tRetVal |= (FCUART_ErrorType) FCUART_ERROR_INVALID_SEQUENCE; + } + + if (pWakeupCfg != NULL) { + if (tRetVal == (FCUART_ErrorType) FCUART_ERROR_OK) { + pUart = (FCUART_Type *) s_aFCUART_InstanceTable[u8UartIndex]; + + /* + * RWC MATCH0|MATCH1 MATCH_CFG [RSWMS,RWUID] Receiver Wakeup + 0 0 X X Normal operation + 1 0 00 00 Receiver wakeup on idle line, IDLE flag not set + 1 0 00 01 Receiver wakeup on idle line, IDLE flag set + 1 0 00 10 Receiver wakeup on address mark + 1 1 11 10 Receiver wakeup on address match + 0 1 00 X0 Address mark address match, IDLE flag not set for discarded characters + 0 1 00 X1 Address mark address match, IDLE flag set for discarded characters + 0 1 01 X0 Idle line address match + 0 1 10 X0 Address match on and address match off, IDLE flag not set for discarded characters + 0 1 10 X1 Address match on and address match off, IDLE flag set for discarded characters + * + */ + + FCUART_HWA_AttachCtrl(pUart, FCUART_CTRL_RWC_MASK | + FCUART_CTRL_RSWMS_MASK); /* WakeUp enable and method select address-mark */ + FCUART_HWA_AttachBaud(pUart, FCUART_BAUD_MATCH_CFG(3U) | + FCUART_BAUD_MAEN0(1U)); /* match0 data */ + FCUART_HWA_AttachMatch(pUart, FCUART_MATCH_MATCH0(pWakeupCfg->u32WakeUpData)); /* set wake-up data*/ + } + } else { + tRetVal |= (FCUART_ErrorType) FCUART_ERROR_INVALID_PARAM; + } + + return tRetVal; +} + +/** + * @brief This Function is used to start receiving + * + * @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U) + * @return FCUART_ERROR_OK is ok, others are not ok + */ +FCUART_ErrorType FCUART_StartReceive(uint8_t u8UartIndex) { + FCUART_ErrorType tRetVal; + FCUART_Type *pUart; + + tRetVal = FCUART_LL_CheckInstance(u8UartIndex); + + if ((FCUART_ErrorType) FCUART_ERROR_OK == tRetVal) { + if (s_aCurrentSequence[u8UartIndex] == FCUART_SEQUENCE_NOTSTART_RECEIVE) { + tRetVal = (FCUART_ErrorType) FCUART_ERROR_OK; + /* set started receive state */ + s_aCurrentSequence[u8UartIndex] = FCUART_SEQUENCE_START_RECEIVE; + + pUart = (FCUART_Type *) s_aFCUART_InstanceTable[u8UartIndex]; + + /* start receive */ + FCUART_HWA_SetRxTransfer(pUart, true); + } else { + tRetVal = (FCUART_ErrorType) FCUART_ERROR_INVALID_SEQUENCE; + } + } else { + tRetVal = (FCUART_ErrorType) FCUART_ERROR_INVALID_PARAM; + } + + return tRetVal; +} + +/** + * @brief This Function is used to stop receiving + * + * @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U) + * @return FCUART_ERROR_OK is ok, others are not ok + */ +FCUART_ErrorType FCUART_StopReceive(uint8_t u8UartIndex) { + FCUART_ErrorType tRetVal; + FCUART_Type *pUart; + + /* check parameter */ + tRetVal = FCUART_LL_CheckInstance(u8UartIndex); + + if ((tRetVal == (FCUART_ErrorType) FCUART_ERROR_OK) && + ((s_aCurrentSequence[u8UartIndex] == FCUART_SEQUENCE_START_RECEIVE) || + (s_aCurrentSequence[u8UartIndex] == FCUART_SEQUENCE_NOTSTART_RECEIVE))) { + + tRetVal = (FCUART_ErrorType) FCUART_ERROR_OK; + } else { + tRetVal |= (FCUART_ErrorType) FCUART_ERROR_INVALID_SEQUENCE; + } + + if (tRetVal == (FCUART_ErrorType) FCUART_ERROR_OK) { + /* set stop state */ + s_aCurrentSequence[u8UartIndex] = FCUART_SEQUENCE_NOTSTART_RECEIVE; + pUart = (FCUART_Type *) s_aFCUART_InstanceTable[u8UartIndex]; + + /* stop receive */ + FCUART_HWA_SetRxTransfer(pUart, false); + } + + return tRetVal; +} + +/** + * @brief This Function is used to start transmit through interrupt + * + * @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U) + * @return FCUART_ERROR_OK is ok, others are not ok + */ +FCUART_ErrorType FCUART_StartTransmit(uint8_t u8UartIndex) { + FCUART_ErrorType tRetVal; + FCUART_Type *pUart; + + tRetVal = FCUART_LL_CheckInstance(u8UartIndex); + + if ((FCUART_ErrorType) FCUART_ERROR_OK == tRetVal) { + + tRetVal = (FCUART_ErrorType) FCUART_ERROR_OK; + + pUart = (FCUART_Type *) s_aFCUART_InstanceTable[u8UartIndex]; + + /* start transmit */ + FCUART_HWA_SetTxTransfer(pUart, true); + + if (false == FCUART_GetInterruptMode(u8UartIndex, (uint32_t) FCUART_INT_CTRL_TIE)) { + FCUART_HWA_EnableInterrupt(pUart, (uint32_t) FCUART_INT_CTRL_TIE); + } + } else { + tRetVal = (FCUART_ErrorType) FCUART_ERROR_INVALID_PARAM; + } + + return tRetVal; +} + +/** + * @brief This Function is used to stop transmitting + * + * @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U) + * @return FCUART_ERROR_OK is ok, others are not ok + */ +FCUART_ErrorType FCUART_StopTransmit(uint8_t u8UartIndex) { + FCUART_ErrorType tRetVal; + FCUART_Type *pUart; + + /* check parameter */ + tRetVal = FCUART_LL_CheckInstance(u8UartIndex); + + if (tRetVal == (FCUART_ErrorType) FCUART_ERROR_OK) { + + tRetVal = (FCUART_ErrorType) FCUART_ERROR_OK; + pUart = (FCUART_Type *) s_aFCUART_InstanceTable[u8UartIndex]; + + /* stop receive */ + FCUART_HWA_SetTxTransfer(pUart, false); + } else { + /* No deal with */ + } + + return tRetVal; +} + +/** + * @brief This Function is used to transmit UART data + * + * @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U) + * @param pUartData contains UART data and length + * @return FCUART_ERROR_OK is ok, others are not ok + */ +FCUART_ErrorType FCUART_Transmit(uint8_t u8UartIndex, FCUART_DataType *pUartData) { + FCUART_ErrorType tRetVal; + + FCUART_Type *pUart; + uint8_t *pData; + uint32_t u32DataLen; + uint8_t u8Index; + + /* check parameter */ + tRetVal = FCUART_LL_CheckInstance(u8UartIndex); + + if ((tRetVal == (FCUART_ErrorType) FCUART_ERROR_OK) && + ((s_aCurrentSequence[u8UartIndex] == FCUART_SEQUENCE_START_RECEIVE) || + (s_aCurrentSequence[u8UartIndex] == FCUART_SEQUENCE_NOTSTART_RECEIVE))) { + + tRetVal = (FCUART_ErrorType) FCUART_ERROR_OK; + } else { + tRetVal |= (FCUART_ErrorType) FCUART_ERROR_INVALID_SEQUENCE; + } + + if (pUartData != NULL) { + if (pUartData->pDatas != NULL) { + if (tRetVal == (FCUART_ErrorType) FCUART_ERROR_OK) { + pData = pUartData->pDatas; + u32DataLen = pUartData->u32DataLen; + pUart = (FCUART_Type *) s_aFCUART_InstanceTable[u8UartIndex]; + + for (u8Index = 0U; u8Index < u32DataLen; u8Index++) { + tRetVal |= FCUART_LL_Transmit_Char(pUart, pData[u8Index], s_aFCUART_TransmitTimeout[u8UartIndex]); + + if (tRetVal != (FCUART_ErrorType) FCUART_ERROR_OK) { + break; + } + } + } + } else { + tRetVal |= (FCUART_ErrorType) FCUART_ERROR_INVALID_PARAM; + } + } else { + tRetVal |= (FCUART_ErrorType) FCUART_ERROR_INVALID_PARAM; + } + + return tRetVal; +} + +/** + * @brief Get Stat Flag + * + * @param u8UartIndex UART instance + * @param eStatusType stat type + * @return FCUART STAT status flag + */ +uint32_t FCUART_GetStatus(uint8_t u8UartIndex, FCUART_StatType eStatusType) { + FCUART_ErrorType tRetVal; + FCUART_Type *pUart; + uint32_t u32RetVal; + + /* check parameter */ + tRetVal = FCUART_LL_CheckInstance(u8UartIndex); + + if (tRetVal == (FCUART_ErrorType) FCUART_ERROR_OK) { + pUart = (FCUART_Type *) s_aFCUART_InstanceTable[u8UartIndex]; + u32RetVal = FCUART_HWA_GetStatus(pUart, eStatusType); + } else { + u32RetVal = 0U; + } + + return u32RetVal; +} + +/** + * @brief This Function is used to receive data when polling (not used when rx interrupt enabled) + * + * @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U) + * @param pRxMsg is data buffer address, and pDatas need to be initialed with external buffer + * @return FCUART_ERROR_OK is ok, others are not ok + */ +FCUART_ErrorType FCUART_Receive_Polling(uint8_t u8UartIndex, FCUART_DataType *pRxMsg) { + FCUART_ErrorType tRetVal; + + /* check parameter */ + tRetVal = FCUART_LL_CheckInstance(u8UartIndex); + + if ((tRetVal == (FCUART_ErrorType) FCUART_ERROR_OK) && + (s_aCurrentSequence[u8UartIndex] == FCUART_SEQUENCE_START_RECEIVE)) { + + tRetVal = (FCUART_ErrorType) FCUART_ERROR_OK; + } else { + tRetVal |= (FCUART_ErrorType) FCUART_ERROR_INVALID_SEQUENCE; + } + + if (pRxMsg != NULL) { + if (pRxMsg->pDatas != NULL) { + if (s_aFCUART_UartUsed[u8UartIndex] == 1U) { + tRetVal = FCUART_LL_Receive(u8UartIndex, pRxMsg); + } + } else { + tRetVal |= (FCUART_ErrorType) FCUART_ERROR_INVALID_PARAM; + } + } else { + tRetVal |= (FCUART_ErrorType) FCUART_ERROR_INVALID_PARAM; + } + + return tRetVal; +} + +/** + * @brief This Function is used to get error when polling (not used when error interrupt enabled) + * + * @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U) + * @param pErrorValue is error value + * @return FCUART_ERROR_OK is ok, others are not ok + */ +FCUART_ErrorType FCUART_Error_Polling(uint8_t u8UartIndex, uint32_t *pErrorValue) { + FCUART_ErrorType tRetVal; + + /* check parameter */ + tRetVal = FCUART_LL_CheckInstance(u8UartIndex); + + if ((tRetVal == (FCUART_ErrorType) FCUART_ERROR_OK) && + (s_aCurrentSequence[u8UartIndex] >= FCUART_SEQUENCE_NOTSTART_RECEIVE)) { + + tRetVal = (FCUART_ErrorType) FCUART_ERROR_OK; + } else { + tRetVal |= (FCUART_ErrorType) FCUART_ERROR_INVALID_SEQUENCE; + } + + if (tRetVal == (FCUART_ErrorType) FCUART_ERROR_OK) { + if (s_aFCUART_UartUsed[u8UartIndex] == 1U) { + /* check error */ + *pErrorValue = FCUART_LL_Error(u8UartIndex); + } else { + tRetVal = (FCUART_ErrorType) FCUART_ERROR_FAILED; + } + } + + return tRetVal; +} + +/** + * @brief This Function is used to enable fcuart loop mode + * + * @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U) + * @param bStatus enable/disable status of loop mode + * @return FCUART_ERROR_OK is ok, others are not ok + * + */ +FCUART_ErrorType FCUART_SetLoopMode(uint8_t u8UartIndex, bool bStatus) { + FCUART_Type *pUart; + FCUART_ErrorType tRetVal; + + /* check parameter */ + tRetVal = FCUART_LL_CheckInstance(u8UartIndex); + + if (tRetVal == (FCUART_ErrorType) FCUART_ERROR_OK) { + pUart = (FCUART_Type *) s_aFCUART_InstanceTable[u8UartIndex]; + + if (true == bStatus) { + FCUART_HWA_EnableLoopMode(pUart); + } else { + FCUART_HWA_DisableLoopMode(pUart); + } + } else { + /* No deal with */ + } + return tRetVal; +} + +/** + * @brief This Function is used to send 9 bits data + * + * @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U) + * @param u16Data data to send + * @return FCUART_ERROR_OK is ok, others are not ok + * + */ +FCUART_ErrorType FCUART_SendData_9Bits(uint8_t u8UartIndex, uint16_t u16Data) { + FCUART_Type *pUart; + FCUART_ErrorType tRetVal; + uint8_t u8SingleBit_8; + + /* check parameter */ + tRetVal = FCUART_LL_CheckInstance(u8UartIndex); + if (tRetVal == (FCUART_ErrorType) FCUART_ERROR_OK) { + pUart = (FCUART_Type *) s_aFCUART_InstanceTable[u8UartIndex]; + + u8SingleBit_8 = (uint8_t) ((u16Data >> 8U) & 1U); + + /* Set bit8 */ + FCUART_HWA_SetR9T8(pUart, u8SingleBit_8); + /* Set 0 ~ 7 bits */ + FCUART_HWA_SetData(pUart, (uint8_t) u16Data); + } else { + /* No deal with */ + } + return tRetVal; + +} + +/** + * @brief This Function is used to Get 9 bits data + * + * @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U) + * @param pData pointer to data + * @return FCUART_ERROR_OK is ok, others are not ok + * + */ +FCUART_ErrorType FCUART_GetData_9Bits(uint8_t u8UartIndex, uint16_t *pData) { + FCUART_Type *pUart; + FCUART_ErrorType tRetVal; + uint8_t u8SingleBit_8; + uint8_t u8Temp; + + /* check parameter */ + tRetVal = FCUART_LL_CheckInstance(u8UartIndex); + if (tRetVal == (FCUART_ErrorType) FCUART_ERROR_OK) { + pUart = (FCUART_Type *) s_aFCUART_InstanceTable[u8UartIndex]; + /* Get bit8 */ + u8SingleBit_8 = FCUART_HWA_GetR8T9(pUart); + /* Get 0 ~ 7 bits */ + u8Temp = FCUART_HWA_GetData(pUart); + /* Get 0 ~ 8 bits */ + *pData = (((uint16_t) u8SingleBit_8 << 8U) | (uint16_t) u8Temp); + } else { + /* No deal with */ + } + return tRetVal; + +} + +/** + * @brief This Function is used to send 10 bits data + * + * @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U) + * @param u16Data data to send + * @return FCUART_ERROR_OK is ok, others are not ok + * + */ +FCUART_ErrorType FCUART_SendData_10Bits(uint8_t u8UartIndex, uint16_t u16Data) { + FCUART_Type *pUart; + FCUART_ErrorType tRetVal; + uint8_t u8SingleBit_8; + uint8_t u8SingleBit_9; + + /* check parameter */ + tRetVal = FCUART_LL_CheckInstance(u8UartIndex); + if (tRetVal == (FCUART_ErrorType) FCUART_ERROR_OK) { + pUart = (FCUART_Type *) s_aFCUART_InstanceTable[u8UartIndex]; + + u8SingleBit_8 = (uint8_t) ((u16Data >> 8U) & 1U); + u8SingleBit_9 = (uint8_t) ((u16Data >> 9U) & 1U); + + /* Set bit8 */ + FCUART_HWA_SetR9T8(pUart, u8SingleBit_8); + /* Set bit9 */ + FCUART_HWA_SetR8T9(pUart, u8SingleBit_9); + /* Set 0 ~ 7 bits */ + FCUART_HWA_SetData(pUart, (uint8_t) u16Data); + } else { + /* No deal with */ + } + return tRetVal; + +} + +/** + * @brief This Function is used to Get 10 bits data + * + * @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U) + * @param pData pointer to data + * @return FCUART_ERROR_OK is ok, others are not ok + * + */ +FCUART_ErrorType FCUART_GetData_10Bits(uint8_t u8UartIndex, uint16_t *pData) { + FCUART_Type *pUart; + FCUART_ErrorType tRetVal; + uint8_t u8SingleBit_8; + uint8_t u8SingleBit_9; + uint8_t u8Temp; + + /* check parameter */ + tRetVal = FCUART_LL_CheckInstance(u8UartIndex); + if (tRetVal == (FCUART_ErrorType) FCUART_ERROR_OK) { + pUart = (FCUART_Type *) s_aFCUART_InstanceTable[u8UartIndex]; + /* Get bit8 */ + u8SingleBit_8 = FCUART_HWA_GetR8T9(pUart); + /* Get bit9 */ + u8SingleBit_9 = FCUART_HWA_GetR9T8(pUart); + /* Get 0 ~ 7 bits */ + u8Temp = FCUART_HWA_GetData(pUart); + /* Get 0 ~ 9 bits */ + *pData = (((uint16_t) u8SingleBit_8 << 8U) | ((uint16_t) u8SingleBit_9 << 9U) | (uint16_t) u8Temp); + } else { + /* No deal with */ + } + return tRetVal; + +} + +/** + * @brief This Function is used to set bit mode,parity and stop bit + * + * @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U) + * @param pData pointer to data + * @return FCUART_ERROR_OK is ok, others are not ok + * + */ +FCUART_ErrorType FCUART_SetBitModeAndParity(uint8_t u8UartIndex, + FCUART_BitModeType eBitMode, + FCUART_StopBitNumType eStopBit, + FCUART_ParityType eParityType, + bool bParityEnable +) { + FCUART_Type *pUart; + FCUART_ErrorType tRetVal; + + /* check parameter */ + tRetVal = FCUART_LL_CheckInstance(u8UartIndex); + if (tRetVal == (FCUART_ErrorType) FCUART_ERROR_OK) { + pUart = (FCUART_Type *) s_aFCUART_InstanceTable[u8UartIndex]; + + FCUART_HWA_SetBitMode(pUart, eBitMode); + FCUART_HWA_SetStopBit(pUart, eStopBit); + FCUART_HWA_SetParity(pUart, eParityType, bParityEnable); + } else { + /* No deal with */ + } + return tRetVal; +} + +/** + * @brief This Function is used to Get current interrupt mode + * + * @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U) + * @param u32Data Interrupt type to get + * @return true/false + * + */ +bool FCUART_GetInterruptMode(uint8_t u8UartIndex, uint32_t u32Data) { + FCUART_ErrorType tTempVal; + bool bRetVal; + FCUART_Type *pUart; + uint32_t u32CtrlRegData; + + /* check parameter */ + tTempVal = FCUART_LL_CheckInstance(u8UartIndex); + if (tTempVal == (FCUART_ErrorType) FCUART_ERROR_OK) { + pUart = (FCUART_Type *) s_aFCUART_InstanceTable[u8UartIndex]; + + u32CtrlRegData = FCUART_HWA_GetCtrl(pUart); + bRetVal = ((u32CtrlRegData & u32Data) > 0U) ? true : false; + } else { + bRetVal = false; + } + + return bRetVal; +} + +/** + * @brief This Function is used to assign data to send through interrupt + * + * @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U) + * @param pData data pointer + * @param u32Length data length to send + * @return FCUART_ERROR_OK is ok, others are not ok + * + */ +FCUART_ErrorType FCUART_AssignTxInterruptData(uint8_t u8UartIndex, uint8_t *pData, uint32_t u32Length) { + FCUART_ErrorType tTempVal; + /* check parameter */ + tTempVal = FCUART_LL_CheckInstance(u8UartIndex); + if (tTempVal == (FCUART_ErrorType) FCUART_ERROR_OK) { + if (pData != NULL) { + s_aFCUART_TxMsg[u8UartIndex]->pDatas = pData; + s_aFCUART_TxMsg[u8UartIndex]->u32DataLen = u32Length; + } else { + tTempVal = (FCUART_ErrorType) FCUART_ERROR_INVALID_PARAM; + } + } else { + /* No deal with */ + } + + return tTempVal; +} + + +/* ################################################################################## */ +/* ############################## Interrupt Services ################################ */ +/** + * @brief This Function is used to deal with FCUART TxRx interrupt + * + * @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U) + * + */ +void FCUARTN_RxTx_IRQHandler(uint8_t u8UartIndex) { + FCUART_ErrorType tTempVal; + FCUART_DataType *pRxMsgList; + FCUART_DataType *pTxMsgList; + uint32_t u32ErrorValue; + uint32_t u32CtrlRegData; + + //Do not check instance because it should be checked before + u32CtrlRegData = FCUART_HWA_GetCtrl((FCUART_Type *) s_aFCUART_InstanceTable[u8UartIndex]); + + /* Handle receive interrupt */ + if (((uint32_t) FCUART_INT_CTRL_RIE) == (u32CtrlRegData & ((uint32_t) FCUART_INT_CTRL_RIE))) { + /* get buffer point and it stored when called SetInterrupt */ + pRxMsgList = s_aFCUART_RxMsg[u8UartIndex]; + /* check pUart receive data */ + tTempVal = FCUART_LL_Receive(u8UartIndex, pRxMsgList); + + /* check buffer valid */ + if ((tTempVal == (FCUART_ErrorType) FCUART_ERROR_OK) && (pRxMsgList != NULL)) { + if (s_aFCUART_RxNotifyTable[u8UartIndex] != NULL) { + s_aFCUART_RxNotifyTable[u8UartIndex](u8UartIndex, pRxMsgList); + } + } + } + + /* Handle transmit interrupt */ + if (((uint32_t) FCUART_INT_CTRL_TIE) == (u32CtrlRegData & ((uint32_t) FCUART_INT_CTRL_TIE))) { + /* get buffer point and it stored when called SetInterrupt */ + pTxMsgList = s_aFCUART_TxMsg[u8UartIndex]; + /* transfer data */ + tTempVal = FCUART_LL_Transmit_Empty(u8UartIndex, pTxMsgList); + + if ((tTempVal == (FCUART_ErrorType) FCUART_ERROR_OK) && (pTxMsgList != NULL)) { + if (s_aFCUART_TxEmptyNotifyTable[u8UartIndex] != NULL) { + s_aFCUART_TxEmptyNotifyTable[u8UartIndex](u8UartIndex, pTxMsgList); + } + } + } + + /* Handle transmit complete interrupt */ + if (((uint32_t) FCUART_INT_CTRL_TCIE) == (u32CtrlRegData & ((uint32_t) FCUART_INT_CTRL_TCIE))) { + tTempVal = FCUART_LL_Transmit_Complete(u8UartIndex); + + if ((tTempVal == (FCUART_ErrorType) FCUART_ERROR_OK) && + (s_aFCUART_TxCompleteNotifyTable[u8UartIndex] != NULL)) { + s_aFCUART_TxCompleteNotifyTable[u8UartIndex](u8UartIndex, NULL); + } + } + + /* Handle idle interrupt */ + if (((uint32_t) FCUART_INT_CTRL_IIE) == (u32CtrlRegData & ((uint32_t) FCUART_INT_CTRL_IIE))) { + tTempVal = FCUART_LL_Idle(u8UartIndex); + if ((tTempVal == (FCUART_ErrorType) FCUART_ERROR_OK) && (s_aFCUART_IdleNotifyTable[u8UartIndex] != NULL)) { + s_aFCUART_IdleNotifyTable[u8UartIndex](u8UartIndex); + } + } + + /* Handle error interrupt */ + if (0U != (u32CtrlRegData & ((uint32_t) (FCUART_INT_CTRL_ORIE | FCUART_INT_CTRL_NEIE | FCUART_INT_CTRL_FEIE | + FCUART_INT_CTRL_PEIE)))) { + /* check error */ + u32ErrorValue = FCUART_LL_Error(u8UartIndex); + + if ((u32ErrorValue != 0U) && (s_aFCUART_ErrorNotifyTable[u8UartIndex] != NULL)) { + s_aFCUART_ErrorNotifyTable[u8UartIndex](u8UartIndex, u32ErrorValue); + } + + PROCESS_UNUSED_VAR(u32ErrorValue) + } +} + +/************************ Uart Print Library ************************/ + +/** + * @brief This Function is used to print ASCII char from UART + * + * @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U) + * @param fmt is char format + * @return FCUART_ERROR_OK is ok, others are not ok + */ +FCUART_ErrorType FCUART_Printf(uint8_t u8UartIndex, char *fmt, ...) { + FCUART_Type *pUart; + FCUART_ErrorType tRetVal; + const char *pStr; + int i32Temp; + unsigned char TxData; + uint8_t u8Number; + uint8_t u8LenthNumber = 4U; + char TempBuffer[16]; + va_list ap; + + va_start(ap, fmt); + /* check parameter */ + tRetVal = FCUART_LL_CheckInstance(u8UartIndex); + + if ((tRetVal == (FCUART_ErrorType) FCUART_ERROR_OK) && + ((s_aCurrentSequence[u8UartIndex] == FCUART_SEQUENCE_START_RECEIVE) || + (s_aCurrentSequence[u8UartIndex] == FCUART_SEQUENCE_NOTSTART_RECEIVE))) { + + tRetVal = (FCUART_ErrorType) FCUART_ERROR_OK; + } else { + tRetVal |= (FCUART_ErrorType) FCUART_ERROR_INVALID_SEQUENCE; + } + + if (tRetVal == (FCUART_ErrorType) FCUART_ERROR_OK) { + pUart = (FCUART_Type *) s_aFCUART_InstanceTable[u8UartIndex]; + + while (*fmt != (char) 0) { + /* Escape character */ + if ((*fmt) == ESCAPE_CHARACTER) { + switch (*(++fmt)) { + case 'r': { + TxData = ENTER; + tRetVal = FCUART_LL_Transmit_Char(pUart, TxData, s_aFCUART_TransmitTimeout[u8UartIndex]); + fmt++; + } + break; + + case 'n': { + TxData = NEW_LINE; + tRetVal = FCUART_LL_Transmit_Char(pUart, TxData, s_aFCUART_TransmitTimeout[u8UartIndex]); + fmt++; + } + break; + + default: + fmt++; + break; + } + } else if ((*fmt) == (char) '%') { + switch (*(++fmt)) { + case 's': { + pStr = va_arg(ap, const char *); + for (; *pStr; pStr++) { + tRetVal = FCUART_LL_Transmit_Char(pUart, *((unsigned char *) pStr), + s_aFCUART_TransmitTimeout[u8UartIndex]); + } + fmt++; + } + break; + + case 'd': { + i32Temp = va_arg(ap, int); + if (0U == FCUART_Int2Char(i32Temp, TempBuffer, UART_PRINT_RADIX_DEC, false)) { + for (pStr = TempBuffer; *pStr; pStr++) { + tRetVal = FCUART_LL_Transmit_Char(pUart, *((unsigned char *) pStr), + s_aFCUART_TransmitTimeout[u8UartIndex]); + } + } + fmt++; + } + break; + + case 'x': { + i32Temp = va_arg(ap, int); + if (0U == FCUART_Int2Char(i32Temp, TempBuffer, UART_PRINT_RADIX_HEX, false)) { + for (pStr = TempBuffer; *pStr; pStr++) { + tRetVal = FCUART_LL_Transmit_Char(pUart, *((unsigned char *) pStr), + s_aFCUART_TransmitTimeout[u8UartIndex]); + } + } + fmt++; + } + break; + + case 'X': { + i32Temp = va_arg(ap, int); + if (0U == FCUART_Int2Char(i32Temp, TempBuffer, UART_PRINT_RADIX_HEX, true)) { + for (pStr = TempBuffer; *pStr; pStr++) { + tRetVal = FCUART_LL_Transmit_Char(pUart, *((unsigned char *) pStr), + s_aFCUART_TransmitTimeout[u8UartIndex]); + } + } + fmt++; + } + break; + + case '.': { + u8Number = (uint8_t) (*(++fmt) - '0'); + if ((*(++fmt)) == 'f') { + double num = va_arg(ap, double); + if (0U == FCUART_Float2Char(num, TempBuffer, u8Number)) { + for (pStr = TempBuffer; *pStr; pStr++) { + tRetVal = FCUART_LL_Transmit_Char(pUart, *((unsigned char *) pStr), + s_aFCUART_TransmitTimeout[u8UartIndex]); + } + } + fmt++; + } + } + break; + + case 'f': { + double num = va_arg(ap, double); + if (0U == FCUART_Float2Char(num, TempBuffer, u8LenthNumber)) { + for (pStr = TempBuffer; *pStr; pStr++) { + tRetVal = FCUART_LL_Transmit_Char(pUart, *((unsigned char *) pStr), + s_aFCUART_TransmitTimeout[u8UartIndex]); + } + } + fmt++; + } + break; + + default: + fmt++; + break; + } + } else { + tRetVal = FCUART_LL_Transmit_Char(pUart, *((unsigned char *) fmt), + s_aFCUART_TransmitTimeout[u8UartIndex]); + + if (tRetVal != FCUART_ERROR_OK) { + break; + } + + fmt++; + } + } + } + + va_end(ap); + + return tRetVal; +} + +/** + * @brief Convert integer to char + * + * @param i32Value + * @param pOutStr + * @param eRadix + * @return 0 is ok + */ +static uint8_t FCUART_Int2Char(int i32Value, char *pOutStr, UART_PrintIntType eRadix, bool bHexUpper) { + uint8_t u8Retval; + char aCharListUpper[] = "0123456789ABCDEF"; + char aCharListLower[] = "0123456789abcdef"; + char aNumList[] = "0123456789"; + char *pCharList; + uint32_t u32Temp; + uint8_t u8Index = 0U; + uint8_t u8ValueStart = 0U; + char Temp = 0; + uint32_t j; + + if (NULL == pOutStr) { + u8Retval = 1U; + } else { + u8Retval = 0U; + if ((UART_PRINT_RADIX_DEC == eRadix) && (i32Value < 0)) { + // Decimal and negative + u32Temp = (uint32_t) (0 - i32Value); + pOutStr[u8Index++] = '-'; + u8ValueStart = 1U; + pCharList = aNumList; + } else { + if (true == bHexUpper) { + pCharList = aCharListUpper; + } else { + pCharList = aCharListLower; + } + u32Temp = (uint32_t) i32Value; + } + + // Data is converted to a string and stored in reverse order + do { + pOutStr[u8Index++] = pCharList[u32Temp % (uint8_t) eRadix]; + u32Temp /= (uint8_t) eRadix; + } while (u32Temp); + + pOutStr[u8Index] = '\0'; + + // Convert the string with reverse order to positive + for (j = u8ValueStart; j < (u8Index + u8ValueStart) / 2U; j++) { + Temp = pOutStr[j]; + pOutStr[j] = pOutStr[u8Index - j - 1U + u8ValueStart]; + pOutStr[u8Index - j - 1U + u8ValueStart] = Temp; + } + } + return u8Retval; +} + +/** + * @brief Convert float to char + * + * @param Value + * @param pOutStr + * @param U32Eps + * @return 0 is ok + */ +static uint8_t FCUART_Float2Char(double Value, char *pOutStr, uint32_t u32Eps) { + uint32_t u32Integer; + double Decimal; + char aCharList[] = "0123456789"; + uint8_t u8ValueStart = 0U; + uint32_t u32TempCnt = 1U; + char Temp = 0; + double TempFactor = 0.1; + uint8_t u8Index = 0U; + uint32_t u32TempDecimal; + uint8_t u8Retval; + uint32_t j; + + if (NULL == pOutStr) { + u8Retval = 1U; + } else { + u8Retval = 0U; + // Extract integer and decimal from the input number + if (Value < FLOAT_ZERO) { + Decimal = (double) ((int32_t) Value - Value); + u32Integer = (uint32_t) (0.0 - Value); + pOutStr[u8Index++] = '-'; + u8ValueStart = 1U; + } else { + u32Integer = (uint32_t) Value; + Decimal = (double) (Value - u32Integer); + } + // The integer part of the data is converted into a string and stored in reverse order + do { + pOutStr[u8Index++] = aCharList[u32Integer % 10U]; + u32Integer /= 10U; + } while (0U != u32Integer); + + pOutStr[u8Index] = '\0'; + + // Convert the string with reverse order to positive + for (j = u8ValueStart; j < (u8Index + u8ValueStart) / 2U; j++) { + Temp = pOutStr[j]; + pOutStr[j] = pOutStr[u8Index - j - 1U + u8ValueStart]; + pOutStr[u8Index - j - 1U + u8ValueStart] = Temp; + } + + // Accuracy problem, preventing input 1.2 and output 1.19 + for (j = 0U; j <= u32Eps; j++) { + TempFactor *= 0.1; + } + Decimal += TempFactor; + + for (j = 0; j < u32Eps; j++) { + Decimal *= (double) 10.0; + u32TempCnt *= 10U; + } + + u32TempDecimal = (uint32_t) Decimal; + pOutStr[u8Index++] = '.'; + for (j = 0; j < u32Eps; j++) { + u32TempCnt /= 10U; + if (0U != u32TempCnt) { + pOutStr[u8Index++] = u32TempDecimal / u32TempCnt + '0'; + u32TempDecimal %= u32TempCnt; + } + } + pOutStr[u8Index] = '\0'; + } + return u8Retval; +} diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_flash.c b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_flash.c new file mode 100644 index 0000000..8f8e08f --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_flash.c @@ -0,0 +1,998 @@ +/** + * @file fc7xxx_driver_flash.c + * @author Flagchip + * @brief FC7xxx Flash driver source code + * @version 0.1.0 + * @date 2024-01-11 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-01-11 Flagchip054 N/A First version for FC7240 + ******************************************************************************** */ + +#include "fc7xxx_driver_flash.h" + +/* ################################################################################## */ +/* ####################################### Macro #################################### */ + +#define STATUS_SUCCESS 0x001UL +#define STATUS_HVOP 0x8001UL +#define FLASH_API_DISABLE 0x0UL +#define FLASH_API_ENABLE 0x1UL +#define FLASH_API_SIZE_8M 0x0UL +#define WDG_TUNE_DISABLE 0x1u +#define FLASH_AUTO_HOLD_ENABLE 0x1UL +#define FLASH_AUTO_HOLD_DISABLE 0x0UL +#define FLASH_REG_BIT_CFG_DISABLE 0x0UL +#define FLASH_REG_BIT_CFG_ENABLE 0x1UL +#define FLASH_REG_BIT_CFG_HOLD 0x2UL + +#define INVAILD_ADDR ((void*)0xFFFFFFFFU) + +#define FLS_MAX_ERASE_BLANK_CHECK (256U) + +#define FLS_ABT_TIMEOUT_VALUE (1000000U) +#define FLS_ASYNC_WRITE_TIMEOUT_VALUE (1000U) +#define FLS_ASYNC_ERASE_TIMEOUT_VALUE (500000U) +/*================================================================================================= +* LOCAL TYPEDEFS (STRUCTURES, UNIONS, ENUMS) +=================================================================================================*/ + +typedef uint32_t status_t; + +typedef struct { + uint32_t blk_sel; + uint32_t dest; +} FLASH_DRV_ERASESECTOR_CFG_T; + +typedef struct { + uint32_t dest; + uint32_t size; + uint32_t *pData; + uint32_t wdg_tune; + uint32_t pgff; +} FLASH_DRV_PRGM_CFG_T; + + +typedef struct +{ + uint16 u16FlashRomApiMajorVersion; + uint16 u16FlashRomApiMinorVersion; + + status_t (*FLASH_DRV_EraseBlock)(FLASH_API_BLOCK_SELECT_TYPE blk_se, uint32_t int_en, uint32_t type); + status_t (*FLASH_DRV_EraseBlock_Clear)(void); + status_t (*FLASH_DRV_EraseSector)(FLASH_DRV_ERASESECTOR_CFG_T * flash_api_cfg, uint32_t int_en, uint32_t type); + status_t (*FLASH_DRV_EraseSector_Clear)(void); + uint32_t RESERVED2[2U]; + status_t (*FLASH_DRV_Program)(FLASH_DRV_PRGM_CFG_T * flash_api_cfg, uint32_t int_en, uint32_t type); + status_t (*FLASH_DRV_Program_Clear)(void); + uint32_t RESERVED3[6U]; + status_t (*FLASH_DRV_HV_Status_Check)(void); + uint32_t RESERVED4[8U]; + status_t (*FLASH_DRV_ENABLE_HOLD_CFG)(uint32_t flash_api_cfg); +}FLASH_ROM_API_ENTRY_T; + + +/** flash driver header for finding function in special address */ +#define FLASHAPI_IN_ROM_ADDR 0x04810200U /* flash api address in rom */ +const FLASH_ROM_API_ENTRY_T *s_pFlashDriver_RomApiHeader; + +/* ################################################################################## */ +/* ################################ Local Variables ################################# */ + + +/* ################################################################################## */ +/* ########################### Local Prototype Functions ############################ */ + + +/* ################################################################################## */ +/* ########################### Global Prototype Functions ########################### */ + + + + +/* ################################################################################## */ +/* ################################ Local Functions ################################# */ + + +/** + * \brief PFlash Driver Function for Erasing Address Check + * + * \param pFlashParam flash driver erase parameter + */ +static FLASH_StatusType FLASHDRIVER_LL_PFlashEraseCheck(FLASH_DRIVER_ParamType *pFlashParam) +{ + FLASH_StatusType tRetVal; + + if (s_pFlashDriver_RomApiHeader != (FLASH_ROM_API_ENTRY_T *)FLASHAPI_IN_ROM_ADDR) + { + tRetVal = FLASH_ERROR_NO_INIT; + } + else + { + tRetVal = FLASH_ERROR_OK; + /* check address align */ + if (pFlashParam->u32Address & (PFLASH_ERASE_SECTOR_SIZE - 1U)) + { + tRetVal = FLASH_ERROR_INVALID_ADDR; + pFlashParam->u32ErrorAddress = pFlashParam->u32Address; + + } + else + { + /* check length align */ + if (pFlashParam->u32Length & (PFLASH_ERASE_SECTOR_SIZE - 1U)) + { + tRetVal = FLASH_ERROR_INVALID_SIZE; + pFlashParam->u32ErrorAddress = pFlashParam->u32Address; + } + + } + } + return tRetVal; +} + +/** + * \brief DFlash Driver Function for Erasing Address Check + * + * \param pFlashParam flash driver erase parameter + */ +static FLASH_StatusType FLASHDRIVER_LL_DFlashEraseCheck(FLASH_DRIVER_ParamType *pFlashParam) +{ + FLASH_StatusType tRetVal; + + if (s_pFlashDriver_RomApiHeader != (FLASH_ROM_API_ENTRY_T *)FLASHAPI_IN_ROM_ADDR) + { + tRetVal = FLASH_ERROR_NO_INIT; + } + else + { + + tRetVal = FLASH_ERROR_OK; + + /* check address align */ + if (pFlashParam->u32Address & (DFLASH_ERASE_SECTOR_SIZE - 1U)) + { + tRetVal = FLASH_ERROR_INVALID_ADDR; + pFlashParam->u32ErrorAddress = pFlashParam->u32Address; + + } + else + { + /* check length align */ + if (pFlashParam->u32Length & (DFLASH_ERASE_SECTOR_SIZE - 1U)) + { + tRetVal = FLASH_ERROR_INVALID_SIZE; + pFlashParam->u32ErrorAddress = pFlashParam->u32Address; + } + + } + + } + return tRetVal; +} + +/** + * \brief PFlash Driver Function for Writing address Check + * + * \param pFlashParam flash driver write parameter + */ +static FLASH_StatusType FLASHDRIVER_PFlashWriteCheck(FLASH_DRIVER_ParamType *pFlashParam) +{ + FLASH_StatusType tRetVal; + + if (s_pFlashDriver_RomApiHeader != (FLASH_ROM_API_ENTRY_T *)FLASHAPI_IN_ROM_ADDR) + { + tRetVal = FLASH_ERROR_NO_INIT; + } + else + { + tRetVal = FLASH_ERROR_OK; + + /* check address align */ + if (pFlashParam->u32Address & (PFLASH_PROGRAM_PAGE_MIN_SIZE - 1U)) + { + tRetVal = FLASH_ERROR_INVALID_ADDR; + pFlashParam->u32ErrorAddress = pFlashParam->u32Address; + } + + else + { + /* check length align */ + if (pFlashParam->u32Length & (PFLASH_PROGRAM_PAGE_MIN_SIZE - 1U)) + { + tRetVal = FLASH_ERROR_INVALID_SIZE; + pFlashParam->u32ErrorAddress = pFlashParam->u32Address; + } + } + } + return tRetVal; +} + +/** + * \brief DFlash Driver Function for Writing address Check + * + * \param pFlashParam flash driver write parameter + */ +static FLASH_StatusType FLASHDRIVER_DFlashWriteCheck(FLASH_DRIVER_ParamType *pFlashParam) +{ + FLASH_StatusType tRetVal; + + if (s_pFlashDriver_RomApiHeader != (FLASH_ROM_API_ENTRY_T *)FLASHAPI_IN_ROM_ADDR) + { + tRetVal = FLASH_ERROR_NO_INIT; + } + else + { + tRetVal = FLASH_ERROR_OK; + + /* check address align */ + if (pFlashParam->u32Address & (DFLASH_PROGRAM_PAGE_MIN_SIZE - 1U)) + { + tRetVal = FLASH_ERROR_INVALID_ADDR; + pFlashParam->u32ErrorAddress = pFlashParam->u32Address; + } + + else + { + /* check length align */ + if (pFlashParam->u32Length & (DFLASH_PROGRAM_PAGE_MIN_SIZE - 1U)) + { + tRetVal = FLASH_ERROR_INVALID_SIZE; + pFlashParam->u32ErrorAddress = pFlashParam->u32Address; + } + } + } + return tRetVal; +} + +/** + * \brief PFlash Driver Function for lock/unlock sector + * + * \param u32Address sector address + * \param bLock 0U-unlock, 1U-lock + */ +static void FLASHDRIVER_PFlashLockBlock(FLASH_API_BLOCK_SELECT_TYPE blk_sel, uint8_t bLock) +{ + uint32_t u32Index; + uint32_t u32Temp; + + u32Index = (uint32_t)blk_sel; + /* 1 bank contains more than 256KB, used FB_CPELCK for first and last 256KB used FB_FPELCK */ + /* PFLASH bank index */ + u32Temp = bLock ? 0xFFFFFFFFUL : 0x0UL; + if(blk_sel < FLASH_DATA_BLOCK_SELECT0) + { + FMC1->FB_CPELCK[u32Index] = u32Temp; + FMC1->FB_FPELCK[u32Index] = u32Temp; + } + else + { + FMC1->FB_FPELCK[u32Index] = u32Temp; + } +} + +/** + * \brief PFlash Driver Function for lock/unlock sector + * + * \param u32Address sector address + * \param bLock 0U-unlock, 1U-lock + */ +static FLASH_StatusType FLASHDRIVER_PFlashLockSector(uint32_t u32Address, uint8_t bLock) +{ + FLASH_StatusType tRetVal; + uint32_t u32Index; + uint32_t u32Length; + uint32_t u32Temp; + + tRetVal = FLASH_ERROR_OK; + + /* 1 bank contains more than 256KB, used FB_CPELCK for first and last 256KB used FB_FPELCK */ + if ((u32Address >= PFLASH_ADDR_START) && (u32Address <= PFLASH_ADDR_END)) + { + /* PFLASH bank index */ + u32Index = (u32Address - PFLASH_ADDR_START) / PFLASH_BANK_SIZE; + u32Length = ((u32Address - PFLASH_ADDR_START) % PFLASH_BANK_SIZE) ; + if (u32Length < (PFLASH_BANK_SIZE - FLASH_256KB_SIZE)) /* first 1792KB */ + { + u32Temp = ((uint32_t)1UL << ((u32Address - PFLASH_ADDR_START - PFLASH_BANK_SIZE * u32Index) >> 16)); + u32Temp = bLock ? 0xFFFFFFFFUL : (0xFFFFFFFFUL ^ u32Temp); + FMC1->FB_CPELCK[u32Index] = u32Temp; + } + else /* last 256KB */ + { + u32Temp = ((u32Address - PFLASH_ADDR_START - PFLASH_BANK_SIZE * u32Index - PFLASH_LAST256K_OFFSET) >> 13); + u32Temp = ((uint32_t)1UL << u32Temp); + u32Temp = bLock ? 0xFFFFFFFFUL : (0xFFFFFFFFUL ^ u32Temp); + /* 0x1C0000UL */ + FMC1->FB_FPELCK[u32Index] = u32Temp; + } + } + else + { + tRetVal = FLASH_ERROR_INVALID_ADDR; + } + return tRetVal; +} + +/** + * \brief DFlash Driver Function for lock/unlock sector + * + * \param u32Address sector address + * \param bLock 0U-unlock, 1U-lock + */ +static FLASH_StatusType FLASHDRIVER_DFlashLockSector(uint32_t u32Address, uint8_t bLock) +{ + FLASH_StatusType tRetVal; + uint32_t u32Index; + uint32_t u32Temp; + tRetVal = FLASH_ERROR_OK; + + /* 1 bank contains only 256KB, only used FB_FPELCK */ + u32Index = 2U; + if ((u32Address >= DFLASH_ADDR_START) && (u32Address <= DFLASH_ADDR_END)) + { + u32Temp = 0xFFFFFFFFUL ^ (1UL << ((u32Address - DFLASH_ADDR_START - DFLASH_BANK0_SIZE * (u32Index - 2U)) >> 13)); + FMC1->FB_FPELCK[u32Index] = bLock ? 0xFFFFFFFFUL : u32Temp ; + } + else + { + tRetVal = FLASH_ERROR_INVALID_ADDR; + } + return tRetVal; +} + +/** + * \brief Get Flash Configuration + * + * \param u32Address the flash address + * \param pFlash_api_cfg out flash parameter + */ +static FLASH_StatusType FLASHDRIVER_GetFlashConfig(uint32_t u32Address, FLASH_DRV_ERASESECTOR_CFG_T *pFlash_api_cfg) +{ + FLASH_StatusType tRetVal; + tRetVal = FLASH_ERROR_OK; + + if ((u32Address >= PFLASH_ADDR_START) && (u32Address < PFLASH_ADDR_START + PFLASH_BANK_SIZE)) + { + pFlash_api_cfg->blk_sel = FLASH_BLOCK_SELECT0; + pFlash_api_cfg->dest = u32Address; + + } + else if ((u32Address >= PFLASH_ADDR_START) && (u32Address < PFLASH_ADDR_START + PFLASH_BANK_SIZE*2U)) + { + pFlash_api_cfg->blk_sel = FLASH_BLOCK_SELECT1; + pFlash_api_cfg->dest = u32Address; + } + else if ((u32Address >= DFLASH_ADDR_START) && (u32Address < DFLASH_ADDR_START + DFLASH_BANK0_SIZE)) + { + pFlash_api_cfg->blk_sel = FLASH_DATA_BLOCK_SELECT0; + pFlash_api_cfg->dest = u32Address; + } + else + { + tRetVal = FLASH_ERROR_INVALID_ADDR; + } + return tRetVal; +} + +/* ################################################################################## */ +/* ################################# Global Functions ############################### */ + +void FLASHDRIVER_Init(void) +{ + s_pFlashDriver_RomApiHeader = (FLASH_ROM_API_ENTRY_T *)FLASHAPI_IN_ROM_ADDR; +} + +/** + * \brief PFlash Driver Function for Erasing + * + * \param pFlashParam flash driver erase parameter + * \return ErrorType + */ +FLASH_StatusType FLASHDRIVER_FlashEraseBlock(FLASH_API_BLOCK_SELECT_TYPE blk_sel) +{ + uint32_t u32TryCount; + + FLASH_StatusType tRetVal; + uint32_t u32Temp; + + tRetVal = FLASH_ERROR_OK; + + if(blk_sel > FLASH_DATA_BLOCK_SELECT0) + { + tRetVal = FLASH_ERROR_INVALID_PARAM; + } + else + { + s_pFlashDriver_RomApiHeader->FLASH_DRV_ENABLE_HOLD_CFG(FLASH_AUTO_HOLD_ENABLE); + FLASHDRIVER_PFlashLockBlock(blk_sel, 0); + __asm(" cpsid i"); + u32Temp = s_pFlashDriver_RomApiHeader-> FLASH_DRV_EraseBlock(blk_sel, FLASH_API_DISABLE, 0); + __asm(" cpsie i"); + tRetVal = (u32Temp == STATUS_SUCCESS) ? FLASH_ERROR_OK : FLASH_ERROR_FAILED; + /* check erase operation valid */ + if (tRetVal != FLASH_ERROR_OK) + { + + } + else + { + /* check erasing still in progress */ + tRetVal = FLASH_ERROR_FAILED; + u32TryCount = 0; + while ((tRetVal != FLASH_ERROR_OK) && (u32TryCount++ < 1000000)) + { + u32Temp = s_pFlashDriver_RomApiHeader->FLASH_DRV_HV_Status_Check(); + /* check if finished */ + if (u32Temp == STATUS_HVOP) + { + tRetVal = FLASH_ERROR_FAILED; + } + else + { + tRetVal = FLASH_ERROR_OK; + } + } + + if (tRetVal != FLASH_ERROR_OK) + { + /* erasing timeout, exit */ + *(uint32_t*)(0x00000014U) = *((uint32_t*)0x40020004U); + } + else + { + /* check erasing result */ + u32Temp = s_pFlashDriver_RomApiHeader-> FLASH_DRV_EraseBlock_Clear(); + tRetVal = (u32Temp == STATUS_SUCCESS) ? FLASH_ERROR_OK : FLASH_ERROR_FAILED; + } + } + } + return tRetVal; +} + +/** + * \brief PFlash Driver Function for Erasing + * + * \param pFlashParam flash driver erase parameter + * \return ErrorType + */ +FLASH_StatusType FLASHDRIVER_PFlashEraseSector(FLASH_DRIVER_ParamType *pFlashParam) +{ + uint32_t u32Addr, u32Length; + uint32_t u32TryCount; + FLASH_DRV_ERASESECTOR_CFG_T tFlash_api_cfg; + + FLASH_StatusType tRetVal; + uint32_t u32Temp; + + tRetVal = FLASH_ERROR_OK; + + /* FLASH_DRV_WDG_CFG_T tFlash_wdg_cfg; */ + + u32Addr = pFlashParam->u32Address; + u32Length = pFlashParam->u32Length; + + tRetVal = FLASH_ERROR_OK; + pFlashParam->u32ErrorAddress = 0x0U; + + tRetVal = FLASHDRIVER_LL_PFlashEraseCheck(pFlashParam); + + if (tRetVal == FLASH_ERROR_OK) + { + /* config flash wdog */ + //ConfigFlashWdog(); + + s_pFlashDriver_RomApiHeader->FLASH_DRV_ENABLE_HOLD_CFG(FLASH_AUTO_HOLD_ENABLE); + + + pFlashParam->u32Length = PFLASH_ERASE_SECTOR_SIZE; + + /* loop erase */ + for (pFlashParam->u32Address = u32Addr; pFlashParam->u32Address < u32Addr + u32Length; + pFlashParam->u32Address += PFLASH_ERASE_SECTOR_SIZE) + { + + FLASHDRIVER_PFlashLockSector(pFlashParam->u32Address, 0U); + FLASHDRIVER_GetFlashConfig(pFlashParam->u32Address, &tFlash_api_cfg); + /* start erase */ + __asm(" cpsid i"); + u32Temp = s_pFlashDriver_RomApiHeader->FLASH_DRV_EraseSector(&tFlash_api_cfg, FLASH_API_DISABLE, 0); + __asm(" cpsie i"); + tRetVal = (u32Temp == STATUS_SUCCESS) ? FLASH_ERROR_OK : FLASH_ERROR_FAILED; + + + /* check erase operation valid */ + if (tRetVal != FLASH_ERROR_OK) + { + /* erase operation failed, exit */ + pFlashParam->u32ErrorAddress = pFlashParam->u32Address; + break; + } + else + { + /* check erasing still in progress */ + tRetVal = FLASH_ERROR_FAILED; + u32TryCount = 0; + while ((tRetVal != FLASH_ERROR_OK) && (u32TryCount++ < 100000)) + { + u32Temp = s_pFlashDriver_RomApiHeader->FLASH_DRV_HV_Status_Check(); + /* check if finished */ + if (u32Temp == STATUS_HVOP) + { + tRetVal = FLASH_ERROR_FAILED; + } + else + { + tRetVal = FLASH_ERROR_OK; + } + } + + if (tRetVal != FLASH_ERROR_OK) + { + /* erasing timeout, exit */ + *(uint32_t*)(0x00000014U) = *((uint32_t*)0x40020004U); + break; + } + else + { + /* check erasing result */ + u32Temp = s_pFlashDriver_RomApiHeader->FLASH_DRV_EraseSector_Clear(); + tRetVal = (u32Temp == STATUS_SUCCESS) ? FLASH_ERROR_OK : FLASH_ERROR_FAILED; + + if (tRetVal != FLASH_ERROR_OK) + { + /* erasing failed, exit */ + pFlashParam->u32ErrorAddress = pFlashParam->u32Address; + break; + } + else + { + + if (tRetVal != FLASH_ERROR_OK) + { + /* erasing failed, exit */ + pFlashParam->u32ErrorAddress = pFlashParam->u32Address; + break; + } + else + { + + /* trigger watchdog function */ + if (pFlashParam->wdTriggerFct != ((void *)0)) + { + pFlashParam->wdTriggerFct(pFlashParam->wdTriggerFct_env); + } + } + + + } + } + } + /* lock sector */ + FLASHDRIVER_PFlashLockSector(pFlashParam->u32Address, 1U); + } + } + return tRetVal; +} + +/** + * \brief PFlash Driver Function for Writing + * + * \param pFlashParam flash driver write parameter + * \return ErrorType + */ +FLASH_StatusType FLASHDRIVER_PFlashWrite(FLASH_DRIVER_ParamType *pFlashParam) +{ + uint32_t u32Addr, u32Length, u32DataAddr, u32AlignLen, u32TempLen; + /* uint8_t *pTempBuf; */ + uint32_t u32AlignOffset, u32Index, u32Count; + uint32_t u32TryCount; + FLASH_DRV_PRGM_CFG_T tFlash_api_cfg; + + FLASH_StatusType tRetVal; + uint32_t u32Temp; + + + tRetVal = FLASH_ERROR_OK; + + u32Addr = pFlashParam->u32Address; + u32Length = pFlashParam->u32Length; + + pFlashParam->u32ErrorAddress = 0x0U; + + + tRetVal = FLASHDRIVER_PFlashWriteCheck(pFlashParam); + + if (tRetVal == FLASH_ERROR_OK) + { + /* config flash wdog */ + //ConfigFlashWdog(); + + s_pFlashDriver_RomApiHeader->FLASH_DRV_ENABLE_HOLD_CFG(FLASH_AUTO_HOLD_ENABLE); + + /* align address, write must align to FLASH_PROGRAM_PAGE_MAX_SIZE */ + u32AlignOffset = u32Addr & (PFLASH_PROGRAM_PAGE_MAX_SIZE - 1U); + u32AlignLen = u32Length + u32AlignOffset; + + u32Count = u32AlignLen & (PFLASH_PROGRAM_PAGE_MAX_SIZE - 1U); + + u32Count = u32Count > 0U ? 1U : 0U; + + u32Count += u32AlignLen / PFLASH_PROGRAM_PAGE_MAX_SIZE; + + u32DataAddr = (uint32_t)pFlashParam->pData; + u32TempLen = u32AlignLen; + + for (u32Index = 0U; u32Index < u32Count; u32Index++) + { + /* real write length in this cycle */ + u32TempLen = u32Length + u32AlignOffset; + u32TempLen = u32TempLen >= PFLASH_PROGRAM_PAGE_MAX_SIZE ? PFLASH_PROGRAM_PAGE_MAX_SIZE : u32TempLen; + u32TempLen -= u32AlignOffset; + + pFlashParam->u32Address = u32Addr; + pFlashParam->u32Length = u32TempLen; + + /* unlock sector */ + FLASHDRIVER_PFlashLockSector(pFlashParam->u32Address, 0U); + tFlash_api_cfg.pgff = FLASH_REG_BIT_CFG_DISABLE; + tFlash_api_cfg.dest = pFlashParam->u32Address; + tFlash_api_cfg.size = (pFlashParam->u32Length / 4); /* one data is 4 bytes */ + tFlash_api_cfg.pData = (uint32_t *)u32DataAddr; + tFlash_api_cfg.wdg_tune = WDG_TUNE_DISABLE; + + /* next address and length */ + u32Addr += u32TempLen; + u32DataAddr += u32TempLen; + u32Length -= u32TempLen; + + u32AlignOffset = 0U; + + /* start write */ + __asm(" cpsid i"); + u32Temp = s_pFlashDriver_RomApiHeader->FLASH_DRV_Program(&tFlash_api_cfg, FLASH_API_DISABLE, 0); + __asm(" cpsie i"); + tRetVal = u32Temp == STATUS_SUCCESS ? FLASH_ERROR_OK : FLASH_ERROR_FAILED; + + /* check erase operation valid */ + if (tRetVal != FLASH_ERROR_OK) + { + /* write operation failed, exit */ + pFlashParam->u32ErrorAddress = pFlashParam->u32Address; + break; + } + else + { + /* FLASHDRIVER_LL_Delay(); */ + + /* check write still in progress */ + tRetVal = FLASH_ERROR_FAILED; + u32TryCount = 0; + while ((tRetVal != FLASH_ERROR_OK) && (u32TryCount++ < 10000)) + { + u32Temp = s_pFlashDriver_RomApiHeader->FLASH_DRV_HV_Status_Check(); + /* check if finished */ + if (u32Temp == STATUS_HVOP) + { + tRetVal = FLASH_ERROR_FAILED; + } + else + { + tRetVal = FLASH_ERROR_OK; + } + } + + + if (tRetVal != FLASH_ERROR_OK) + { + /* erasing timeout, exit */ + pFlashParam->u32ErrorAddress = pFlashParam->u32Address; + break; + } + else + { + + /* check write result */ + u32Temp = s_pFlashDriver_RomApiHeader->FLASH_DRV_Program_Clear(); + tRetVal = (u32Temp == STATUS_SUCCESS) ? FLASH_ERROR_OK : FLASH_ERROR_FAILED; + + if (tRetVal != FLASH_ERROR_OK) + { + /* write failed, exit */ + pFlashParam->u32ErrorAddress = pFlashParam->u32Address; + break; + } + else + { + /* trigger watchdog function */ + if (pFlashParam->wdTriggerFct != ((void *)0)) + { + pFlashParam->wdTriggerFct(pFlashParam->wdTriggerFct_env); + } + + } + } + } + + /* lock sector */ + FLASHDRIVER_PFlashLockSector(pFlashParam->u32Address, 1U); + } + } + return tRetVal; +} + +/** + * \brief DFlash Driver Function for Erasing + * + * \param pFlashParam flash driver erase parameter + * \return ErrorType + */ +FLASH_StatusType FLASHDRIVER_DFlashEraseSector(FLASH_DRIVER_ParamType *pFlashParam) +{ + uint32_t u32Addr, u32Length; + uint32_t u32TryCount; + FLASH_DRV_ERASESECTOR_CFG_T tFlash_api_cfg; + FLASH_StatusType tRetVal; + uint32_t u32Temp; + + tRetVal = FLASH_ERROR_OK; + + + u32Addr = pFlashParam->u32Address; + u32Length = pFlashParam->u32Length; + + tRetVal = FLASH_ERROR_OK; + pFlashParam->u32ErrorAddress = 0x0U; + + tRetVal = FLASHDRIVER_LL_DFlashEraseCheck(pFlashParam); + + if (tRetVal == FLASH_ERROR_OK) + { + /* config flash wdog */ + //ConfigFlashWdog(); + + s_pFlashDriver_RomApiHeader->FLASH_DRV_ENABLE_HOLD_CFG(FLASH_AUTO_HOLD_ENABLE); + + + pFlashParam->u32Length = DFLASH_ERASE_SECTOR_SIZE; + + /* loop erase */ + for (pFlashParam->u32Address = u32Addr; pFlashParam->u32Address < u32Addr + u32Length; + pFlashParam->u32Address += DFLASH_ERASE_SECTOR_SIZE) + { + /* unlock data flash */ + FLASHDRIVER_DFlashLockSector(pFlashParam->u32Address, 0U); + + FLASHDRIVER_GetFlashConfig(pFlashParam->u32Address, &tFlash_api_cfg); + /* start erase */ + __asm(" cpsid i"); + u32Temp = s_pFlashDriver_RomApiHeader->FLASH_DRV_EraseSector(&tFlash_api_cfg, FLASH_API_DISABLE, 0); + __asm(" cpsie i"); + tRetVal = (u32Temp == STATUS_SUCCESS) ? FLASH_ERROR_OK : FLASH_ERROR_FAILED; + + + /* check erase operation valid */ + if (tRetVal != FLASH_ERROR_OK) + { + /* erase operation failed, exit */ + pFlashParam->u32ErrorAddress = pFlashParam->u32Address; + break; + } + else + { + /* check erasing still in progress */ + tRetVal = FLASH_ERROR_FAILED; + u32TryCount = 0; + while ((tRetVal != FLASH_ERROR_OK) && (u32TryCount++ < 100000)) + { + u32Temp = s_pFlashDriver_RomApiHeader->FLASH_DRV_HV_Status_Check(); + /* check if finished */ + if (u32Temp == STATUS_HVOP) + { + tRetVal = FLASH_ERROR_FAILED; + } + else + { + tRetVal = FLASH_ERROR_OK; + } + } + + if (tRetVal != FLASH_ERROR_OK) + { + /* erasing timeout, exit */ + pFlashParam->u32ErrorAddress = pFlashParam->u32Address; + break; + } + else + { + /* check erasing result */ + u32Temp = s_pFlashDriver_RomApiHeader->FLASH_DRV_EraseSector_Clear(); + tRetVal = (u32Temp == STATUS_SUCCESS) ? FLASH_ERROR_OK : FLASH_ERROR_FAILED; + + if (tRetVal != FLASH_ERROR_OK) + { + /* erasing failed, exit */ + pFlashParam->u32ErrorAddress = pFlashParam->u32Address; + break; + } + else + { + + if (tRetVal != FLASH_ERROR_OK) + { + /* erasing failed, exit */ + pFlashParam->u32ErrorAddress = pFlashParam->u32Address; + break; + } + else + { + + /* trigger watchdog function */ + if (pFlashParam->wdTriggerFct != ((void *)0)) + { + pFlashParam->wdTriggerFct(pFlashParam->wdTriggerFct_env); + } + } + + + } + } + } + + /* lock data flash */ + FLASHDRIVER_DFlashLockSector(pFlashParam->u32Address, 1U); + } + } + return tRetVal; +} + +/** + * \brief DFlash Driver Function for Writing + * + * \param pFlashParam flash driver write parameter + * \return ErrorType + */ +FLASH_StatusType FLASHDRIVER_DFlashWrite(FLASH_DRIVER_ParamType *pFlashParam) +{ + uint32_t u32Addr, u32Length, u32DataAddr, u32AlignLen, u32TempLen; + /* uint8_t *pTempBuf; */ + uint32_t u32AlignOffset, u32Index, u32Count; + uint32_t u32TryCount; + FLASH_DRV_PRGM_CFG_T tFlash_api_cfg; + + FLASH_StatusType tRetVal; + uint32_t u32Temp; + + tRetVal = FLASH_ERROR_OK; + + u32Addr = pFlashParam->u32Address; + u32Length = pFlashParam->u32Length; + + pFlashParam->u32ErrorAddress = 0x0U; + + + tRetVal = FLASHDRIVER_DFlashWriteCheck(pFlashParam); + + if (tRetVal == FLASH_ERROR_OK) + { + /* config flash wdog */ + //ConfigFlashWdog(); + + s_pFlashDriver_RomApiHeader->FLASH_DRV_ENABLE_HOLD_CFG(FLASH_AUTO_HOLD_ENABLE); + + /* align address, write must align to FLASH_PROGRAM_PAGE_MAX_SIZE */ + u32AlignOffset = u32Addr & (DFLASH_PROGRAM_PAGE_MAX_SIZE - 1U); + u32AlignLen = u32Length + u32AlignOffset; + + u32Count = u32AlignLen & (DFLASH_PROGRAM_PAGE_MAX_SIZE - 1U); + + u32Count = u32Count > 0U ? 1U : 0U; + + u32Count += u32AlignLen / DFLASH_PROGRAM_PAGE_MAX_SIZE; + + u32DataAddr = (uint32_t)pFlashParam->pData; + u32TempLen = u32AlignLen; + + for (u32Index = 0U; u32Index < u32Count; u32Index++) + { + /* real write length in this cycle */ + u32TempLen = u32Length + u32AlignOffset; + u32TempLen = u32TempLen >= DFLASH_PROGRAM_PAGE_MAX_SIZE ? DFLASH_PROGRAM_PAGE_MAX_SIZE : u32TempLen; + u32TempLen -= u32AlignOffset; + + pFlashParam->u32Address = u32Addr; + pFlashParam->u32Length = u32TempLen; + + /* unlock sector */ + FLASHDRIVER_DFlashLockSector(pFlashParam->u32Address, 0U); + tFlash_api_cfg.pgff = FLASH_REG_BIT_CFG_DISABLE; + tFlash_api_cfg.dest = pFlashParam->u32Address; + tFlash_api_cfg.size = (pFlashParam->u32Length / 4); /* one data is 4 bytes */ + tFlash_api_cfg.pData = (uint32_t *)u32DataAddr; + tFlash_api_cfg.wdg_tune = WDG_TUNE_DISABLE; + + /* next address and length */ + u32Addr += u32TempLen; + u32DataAddr += u32TempLen; + u32Length -= u32TempLen; + + u32AlignOffset = 0U; + + /* start write */ + __asm(" cpsid i"); + u32Temp = s_pFlashDriver_RomApiHeader->FLASH_DRV_Program(&tFlash_api_cfg, FLASH_API_DISABLE, 0); + __asm(" cpsie i"); + tRetVal = u32Temp == STATUS_SUCCESS ? FLASH_ERROR_OK : FLASH_ERROR_FAILED; + + /* check erase operation valid */ + if (tRetVal != FLASH_ERROR_OK) + { + /* write operation failed, exit */ + pFlashParam->u32ErrorAddress = pFlashParam->u32Address; + break; + } + else + { + /* FLASHDRIVER_LL_Delay(); */ + + /* check write still in progress */ + tRetVal = FLASH_ERROR_FAILED; + u32TryCount = 0; + while ((tRetVal != FLASH_ERROR_OK) && (u32TryCount++ < 10000)) + { + u32Temp = s_pFlashDriver_RomApiHeader->FLASH_DRV_HV_Status_Check(); + /* check if finished */ + if (u32Temp == STATUS_HVOP) + { + tRetVal = FLASH_ERROR_FAILED; + } + else + { + tRetVal = FLASH_ERROR_OK; + } + } + + + if (tRetVal != FLASH_ERROR_OK) + { + /* erasing timeout, exit */ + pFlashParam->u32ErrorAddress = pFlashParam->u32Address; + break; + } + else + { + /* check write result */ + u32Temp = s_pFlashDriver_RomApiHeader->FLASH_DRV_Program_Clear(); + tRetVal = (u32Temp == STATUS_SUCCESS) ? FLASH_ERROR_OK : FLASH_ERROR_FAILED; + + if (tRetVal != FLASH_ERROR_OK) + { + /* write failed, exit */ + pFlashParam->u32ErrorAddress = pFlashParam->u32Address; + break; + } + else + { + /* trigger watchdog function */ + if (pFlashParam->wdTriggerFct != ((void *)0)) + { + pFlashParam->wdTriggerFct(pFlashParam->wdTriggerFct_env); + } + + } + } + } + /* lock data flash */ + FLASHDRIVER_DFlashLockSector(pFlashParam->u32Address, 1U); + + } + } + return tRetVal; +} diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_flexcan.c b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_flexcan.c new file mode 100644 index 0000000..13df2c6 --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_flexcan.c @@ -0,0 +1,2994 @@ +/** + * @file fc7xxx_driver_flexcan.h + * @author Flagchip + * @brief FC7xxx CAN driver type definition and API + * @version 0.1.0 + * @date 2022-02-20 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + */ + +/* ******************************************************************************** + * Revision History: + * + * Version Date Author Descriptions + * --------- ---------- ------------ --------------- + * 0.1.0 2024-1-13 Flagchip0112 First version for FC7240 + ******************************************************************************** */ + + + +#include "fc7xxx_driver_flexcan.h" /* include peripheral declarations */ + +#include "interrupt_manager.h" + + +/* ################################################################################## */ +/* ####################################### Macro #################################### */ + + +#ifndef NULL + #define NULL ((void *)0) +#endif + +#define FLEXCAN_FD_INSTANCE_COUNT FLEXCAN_INSTANCE_COUNT /** all support can fd */ + +#define FLEXCAN_MB_NUM 32U /** Every CAN contains message buffer number */ + + +#define FLEXCAN_RX_FIFO_ENABLE STD_OFF +#define FLEXCAN_DMA_ENABLE STD_OFF + +#define FLEXCAN_DET_ERROR_REPORT STD_OFF + + +#define FLEXCAN_DET_ERROR_ID_FUNC_INIT 0x01U +#define FLEXCAN_DET_ERROR_ID_FUNC_MSGCFG 0x02U +#define FLEXCAN_DET_ERROR_ID_FUNC_SETINTERRUPT 0x03U +#define FLEXCAN_DET_ERROR_ID_FUNC_START 0x04U +#define FLEXCAN_DET_ERROR_ID_FUNC_STOP 0x05U +#define FLEXCAN_DET_ERROR_ID_FUNC_TRANSMIT 0x06U +#define FLEXCAN_DET_ERROR_ID_FUNC_RECEIVE 0x07U + + +#define FLEXCAN_DET_ERROR_ID_PARAM_POINTCHECK 0x01U +#define FLEXCAN_DET_ERROR_ID_PARAM_INDEXCHECK 0x02U + + + +/* register word num */ +#define FLEXCAN_MEM_WORD_LEN 0x04U + + +#define MB_RAM_OFFSET 0x80U +#define RXIMR_OFFSET 0x880U +#define RXFIR_TEST_OFFSET 0xA80U +#define MASK_OFFSET 0xAA0U +#define SMBTX_OFFSET 0xAB0U +#define SMBRX0_OFFSET 0xAC0U +#define SMBRX1_OFFSET 0xAD0U +#define FD_SMBTX_OFFSET 0xF28U +#define FD_SMBRX0_OFFSET 0xF70U +#define FD_SMBRX1_OFFSET 0xFB8U +#define ERX_FIFO_OFFSET 0x2000U +#define ERFFEL_OFFSET 0x3000U + + +#define MB_RAM_WORD_NUM 128U +#define RXIMR_WORD_NUM 32U +#define RXFIR_TEST_WORD_NUM 8U +#define MASK_WORD_NUM 4U +#define SMBTX_WORD_NUM 4U +#define SMBRX0_WORD_NUM 4U +#define SMBRX1_WORD_NUM 4U +#define FD_SMBTX_WORD_NUM 18U +#define FD_SMBRX0_WORD_NUM 18U +#define FD_SMBRX1_WORD_NUM 18U +#define ERX_FIFO_WORD_NUM 240U +#define ERFFEL_WORD_NUM 32U + + + +#define USE_CBT_NORMAL + + + +#define TQ_NUM_IPT 2U + +#define TQ_SYNC_NUM 1U + +/* Ctrl1 */ +#define TQ_NUM_CTRL1_MAX 25U +#define TQ_NUM_CTRL1_MIN 8U + +#define CTRL1_PRESDIV_MAX 256U +#define CTRL1_PRESDIV_MIN 1U + +#define CTRL1_RJW_MAX 4U +#define CTRL1_RJW_MIN 1U + +#define CTRL1_PROPSEG_MAX 8U +#define CTRL1_PROPSEG_MIN 1U + +#define CTRL1_PSEG1_MAX 8U +#define CTRL1_PSEG1_MIN 1U + +#define CTRL1_TIMERSEGMENT1_MAX 16U +#define CTRL1_TIMERSEGMENT1_MIN 2U + +#define CTRL1_PSEG2_MAX 8U +#define CTRL1_PSEG2_MIN 2U + + +/* CBT */ +#define TQ_NUM_CBT_MAX 25U /* 80U */ +#define TQ_NUM_CBT_MIN 8U + +#define CBT_PRESDIV_MAX 1024U +#define CBT_PRESDIV_MIN 1U + +#define CBT_RJW_MAX 32U +#define CBT_RJW_MIN 1U + +#define CBT_PROPSEG_MAX 64U +#define CBT_PROPSEG_MIN 1U + +#define CBT_PSEG1_MAX 32U +#define CBT_PSEG1_MIN 1U + +#define CBT_TIMERSEGMENT1_MAX 96U +#define CBT_TIMERSEGMENT1_MIN 2U + +#define CBT_PSEG2_MAX 32U +#define CBT_PSEG2_MIN 2U + + +/* FDCBT */ +#define TQ_NUM_FDCBT_MAX 25U +#define TQ_NUM_FDCBT_MIN 5U + +#define FDCBT_PRESDIV_MAX 1024U +#define FDCBT_PRESDIV_MIN 1U + +#define FDCBT_RJW_MAX 8U +#define FDCBT_RJW_MIN 1U + +#define FDCBT_PROPSEG_MAX 31U +#define FDCBT_PROPSEG_MIN 0U + +#define FDCBT_PSEG1_MAX 8U +#define FDCBT_PSEG1_MIN 1U + +#define FDCBT_TIMERSEGMENT1_MAX 39U +#define FDCBT_TIMERSEGMENT1_MIN 2U + +#define FDCBT_PSEG2_MAX 8U +#define FDCBT_PSEG2_MIN 2U + + + +/* ################################################################################## */ +/* ################################### Type define ################################## */ + + + + + + + +typedef enum +{ + /* RXIDA=0: bitIDE=29-19,EXT=29-1; */ + RXFIFO_FILTERFORMATA = 0, + /* RXIDB_0: bitIDE=29-19,EXT=29-16; RXIDB_1: bitIDE=13-3,EXT=13-0; */ + RXFIFO_FILTERFORMATB = 1, + /* RXIDC_0: bitIDE/EXT=31-24; RXIDC_1: bitIDE/EXT=23-16; RXIDC_2: bitIDE/EXT=15-8; RXIDC_3: bitIDE/EXT=7-0 */ + RXFIFO_FILTERFORMATC = 2 + +} FLEXCAN_RxFifoFilterFormatType; + +typedef struct +{ + FLEXCAN_RxFifoFilterFormatType eFilterFormat; + uint32_t u32RxElementNum; + uint32_t *pRxElementList; +} FLEXCAN_RxFifoFilterType; + + + +/** + * @brief CAN Baudrate setting + * + */ +typedef struct +{ + uint8_t bEnFd; /**< if enable can FD, set 1U */ + uint8_t bEnBrs; /**< if enable can BRS, set 1U */ + FLEXCAN_DataWidthType eMbDataWidth; /**< Message Buffer Data Width */ + + FLEXCAN_BaudClkType eClkSrcHz; /**< clock source HZ */ + FLEXCAN_BaudType eBaudrate; /**< normal bit rate */ + FLEXCAN_BaudType eDataBaud; /**< can fd data bit rate */ + + uint32_t u32Ctrl1; /**< ctrl1 register value */ + uint32_t u32Cbt; /**< cbt register value */ + uint32_t u32FdCtrl; /**< fdctrl register value */ + uint32_t u32FdCbt; /**< fdcbt register value */ + +} FLEXCAN_BaudCfgType; + + + +/** + * @brief CAN setting configuration + * + */ +typedef struct +{ + uint8_t bEnableFd; /**< if enable can FD, set 1U */ + uint8_t bEnableFifo; /**< if enable can fifo, set 1U */ + uint8_t bEnableDMA; /**< if enable can dma, set 1U */ + uint8_t bEnableErrInt; /**< if enable can error interrupt, set 1U */ + uint8_t bEnableFifoInt; /**< if enable can fifo interrupt, set 1U */ + uint8_t bEnableTxMBInt; /**< if enable can Tx MB interrupt, set 1U */ + uint8_t bEnableRxMBInt; /**< if enable can Rx MB interrupt, set 1U */ + uint8_t u8EnhancedFifoDmaWM;/**< The watermark for DMA in CANFD FIFO mode */ + uint8_t u8RxFifoCnt; /**< can receive start message buffer index */ + uint8_t u8RxMbStart1; /**< can receive start message buffer index */ + uint8_t u8RxMbCnt1; /**< can receive message buffer count */ + uint8_t u8TxMbStart1; /**< can transmit start message buffer index */ + uint8_t u8TxMbCnt1; /**< can receive message buffer count */ + FLEXCAN_DataWidthType eMbDataWidth; /**< Message Buffer Data Width */ + FLEXCAN_RxMsgType *pRxBuf; /**< receive buffer address, length same to u8RxFilterCnt, must global array */ +} FLEXCAN_SettingType; + +/** + * @brief CAN Operation Sequence + * + */ +typedef enum +{ + FLEXCAN_SEQUENCE_VAR_NOINIT, /**< FLEXCAN_SEQUENCE_DEINIT means CAN variables data is not initialed */ + FLEXCAN_SEQUENCE_DEINIT, /**< FLEXCAN_SEQUENCE_DEINIT means CAN driver is not initialed */ + FLEXCAN_SEQUENCE_NOTSTART, /**< FLEXCAN_SEQUENCE_NOTSTART means can driver initialed and not start */ + FLEXCAN_SEQUENCE_STARTED /**< FLEXCAN_SEQUENCE_STARTED means can driver started */ +} FLEXCAN_SequenceType; + + +/** + * @brief Baud-rate clock and divider + * + */ +typedef struct +{ + FLEXCAN_BaudClkType eClkHz; /**< Clock Hz for baudrate */ + FLEXCAN_BaudType eBaudrate; /**< Normal bit baudrate */ + uint32_t u32Presdiv; /**< Presdiv for can */ + uint32_t u32Propseg; /**< Propseg for can */ + uint32_t u32Pseg1; /**< Pseg1 for can */ + uint32_t u32Pseg2; /**< Pseg2 for can */ + uint32_t u32Rjw; /**< RJW for can */ +} FLEXCAN_BaudRegType; + + +/* ################################################################################## */ +/* ############################# Local Const Variables ############################## */ + +/* CAN Instance */ +static FLEXCAN_Type *const s_aFlexCan_InstanceTable[FLEXCAN_INSTANCE_COUNT] = +{ + FLEXCAN0, + FLEXCAN1, + FLEXCAN2, + FLEXCAN3 +}; + +/* Normal bit table */ +static const FLEXCAN_BaudRegType s_aFlexCan_NormalBaudDividerTable[] = +{ + /* clock source hz baudrate presdiv propseg pseg1 pseg2 rjw */ + { FLEXCAN_BAUDCLK_HZ_16M, FLEXCAN_BAUD_500K, 2, 8, 4, 3, 2 }, + { FLEXCAN_BAUDCLK_HZ_24M, FLEXCAN_BAUD_100K, 12, 7, 6, 6, 1 }, + { FLEXCAN_BAUDCLK_HZ_24M, FLEXCAN_BAUD_125K, 12, 5, 5, 5, 1 }, + { FLEXCAN_BAUDCLK_HZ_24M, FLEXCAN_BAUD_250K, 8, 5, 3, 3, 1 }, + { FLEXCAN_BAUDCLK_HZ_24M, FLEXCAN_BAUD_500K, 4, 5, 3, 3, 1 }, + { FLEXCAN_BAUDCLK_HZ_24M, FLEXCAN_BAUD_800K, 3, 5, 2, 2, 1 }, + { FLEXCAN_BAUDCLK_HZ_24M, FLEXCAN_BAUD_1M, 2, 5, 3, 3, 1 }, + { FLEXCAN_BAUDCLK_HZ_24M, FLEXCAN_BAUD_2M, 1, 5, 3, 3, 1 }, + { FLEXCAN_BAUDCLK_HZ_48M, FLEXCAN_BAUD_100K, 32, 8, 3, 3, 1 }, + { FLEXCAN_BAUDCLK_HZ_48M, FLEXCAN_BAUD_125K, 24, 7, 4, 4, 1 }, + { FLEXCAN_BAUDCLK_HZ_48M, FLEXCAN_BAUD_250K, 24, 3, 2, 2, 1 }, + { FLEXCAN_BAUDCLK_HZ_48M, FLEXCAN_BAUD_500K, 6, 7, 4, 4, 1 }, + { FLEXCAN_BAUDCLK_HZ_48M, FLEXCAN_BAUD_800K, 4, 8, 3, 3, 1 }, + { FLEXCAN_BAUDCLK_HZ_48M, FLEXCAN_BAUD_1M, 3, 7, 4, 4, 1 }, + { FLEXCAN_BAUDCLK_HZ_48M, FLEXCAN_BAUD_2M, 2, 5, 3, 3, 1 }, + { FLEXCAN_BAUDCLK_HZ_120M, FLEXCAN_BAUD_100K, 80, 8, 3, 3, 1 }, + { FLEXCAN_BAUDCLK_HZ_120M, FLEXCAN_BAUD_125K, 64, 8, 3, 3, 1 }, + { FLEXCAN_BAUDCLK_HZ_120M, FLEXCAN_BAUD_250K, 32, 8, 3, 3, 1 }, + { FLEXCAN_BAUDCLK_HZ_120M, FLEXCAN_BAUD_500K, 16, 8, 3, 3, 3 }, + { FLEXCAN_BAUDCLK_HZ_120M, FLEXCAN_BAUD_800K, 15, 5, 2, 2, 1 }, + { FLEXCAN_BAUDCLK_HZ_120M, FLEXCAN_BAUD_1M, 8, 8, 3, 3, 1 }, + { FLEXCAN_BAUDCLK_HZ_120M, FLEXCAN_BAUD_2M, 4, 8, 3, 3, 1 }, + { FLEXCAN_BAUDCLK_HZ_150M, FLEXCAN_BAUD_500K, 20, 8, 3, 3, 1 }, + { FLEXCAN_BAUDCLK_HZ_150M, FLEXCAN_BAUD_1M, 10, 8, 3, 3, 1 }, + { FLEXCAN_BAUDCLK_HZ_150M, FLEXCAN_BAUD_2M, 5, 8, 3, 3, 1 }, + +}; + +/* Data bit table */ +static const FLEXCAN_BaudRegType s_aFlexCan_DataBaudDividerTable[] = +{ + /* clock source hz baudrate presdiv propseg pseg1 pseg2 rjw */ + { FLEXCAN_BAUDCLK_HZ_16M, FLEXCAN_BAUD_2M, 1, 3, 2, 2, 1 }, + { FLEXCAN_BAUDCLK_HZ_24M, FLEXCAN_BAUD_1M, 2, 5, 3, 3, 1 }, + { FLEXCAN_BAUDCLK_HZ_24M, FLEXCAN_BAUD_2M, 1, 5, 3, 3, 1 }, + { FLEXCAN_BAUDCLK_HZ_24M, FLEXCAN_BAUD_3M, 1, 3, 2, 2, 1 }, + { FLEXCAN_BAUDCLK_HZ_48M, FLEXCAN_BAUD_1M, 3, 7, 4, 4, 1 }, + { FLEXCAN_BAUDCLK_HZ_48M, FLEXCAN_BAUD_2M, 2, 5, 3, 3, 1 }, + { FLEXCAN_BAUDCLK_HZ_48M, FLEXCAN_BAUD_3M, 1, 7, 4, 4, 1 }, + { FLEXCAN_BAUDCLK_HZ_48M, FLEXCAN_BAUD_4M, 1, 5, 3, 3, 1 }, + { FLEXCAN_BAUDCLK_HZ_48M, FLEXCAN_BAUD_6M, 1, 3, 2, 2, 1 }, + { FLEXCAN_BAUDCLK_HZ_120M, FLEXCAN_BAUD_1M, 8, 8, 3, 3, 1 }, + { FLEXCAN_BAUDCLK_HZ_120M, FLEXCAN_BAUD_2M, 4, 8, 3, 3, 1 }, + { FLEXCAN_BAUDCLK_HZ_120M, FLEXCAN_BAUD_3M, 4, 5, 2, 2, 1 }, + { FLEXCAN_BAUDCLK_HZ_120M, FLEXCAN_BAUD_4M, 3, 5, 2, 2, 1 }, + { FLEXCAN_BAUDCLK_HZ_120M, FLEXCAN_BAUD_5M, 2, 5, 3, 3, 1 }, + { FLEXCAN_BAUDCLK_HZ_120M, FLEXCAN_BAUD_6M, 2, 5, 2, 2, 1 }, + { FLEXCAN_BAUDCLK_HZ_120M, FLEXCAN_BAUD_8M, 1, 8, 3, 3, 1 }, + { FLEXCAN_BAUDCLK_HZ_150M, FLEXCAN_BAUD_1M, 10, 8, 3, 3, 1 }, + { FLEXCAN_BAUDCLK_HZ_150M, FLEXCAN_BAUD_2M, 5, 8, 3, 3, 1 }, + { FLEXCAN_BAUDCLK_HZ_150M, FLEXCAN_BAUD_3M, 5, 5, 2, 2, 1 }, + { FLEXCAN_BAUDCLK_HZ_150M, FLEXCAN_BAUD_5M, 2, 8, 3, 3, 1 } + +}; + + +/* ################################################################################## */ +/* ################################ Local Variables ################################# */ + + +/* sequence var */ +static FLEXCAN_SequenceType s_aCurrentSequence[FLEXCAN_INSTANCE_COUNT] = {FLEXCAN_SEQUENCE_VAR_NOINIT}; + + +/* message buffer word length, default pCan is 16bytes, 4words */ +/* static uint8_t s_aFlexCan_DataLen[FLEXCAN_INSTANCE_COUNT]; */ + +/* pCan message buffer used count stored */ +/* static FLEXCAN_MBConfigType s_aFlexCan_MBCfg_Table[FLEXCAN_INSTANCE_COUNT]; */ + +/* can setting */ +static FLEXCAN_SettingType s_aFlexCan_Setting_Table[FLEXCAN_INSTANCE_COUNT]; + + +/* store notify callback function point */ +static FLEXCAN_ErrorInterruptCallBackType s_aFlexCan_ErrorNotifyTable[FLEXCAN_INSTANCE_COUNT]; +static FLEXCAN_TxInterruptCallBackType s_aFlexCan_TxNotifyTable[FLEXCAN_INSTANCE_COUNT]; +static FLEXCAN_RxInterruptCallBackType s_aFlexCan_RxNotifyTable[FLEXCAN_INSTANCE_COUNT]; +static FLEXCAN_RxInterruptCallBackType s_aFlexCan_RxFifoNotifyTable[FLEXCAN_INSTANCE_COUNT]; + +/* check every pCan instance whether is used */ +/* static FLEXCAN_RxMsgType const * s_aFlexCan_RxBufList[FLEXCAN_INSTANCE_COUNT]; */ + +/* check every pCan instance whether is used */ +static uint8_t s_aFlexCan_CanUsed[FLEXCAN_INSTANCE_COUNT]; + +#if FLEXCAN_DET_ERROR_REPORT == STD_ON +typedef struct +{ + uint8_t u8FunctionID; + uint8_t u8ParameterID; +} FLEXCAN_DetErrorType; + +static FLEXCAN_DetErrorType s_tFlexCan_DetErrorId; +#endif + + +/* ################################################################################## */ +/* ########################### Local Prototype Functions ############################ */ + + + + +/* ################################################################################## */ +/* ########################### Global Prototype Functions ########################### */ + + +/* ################################################################################## */ +/* ################################ Local Functions ################################# */ + +#if FLEXCAN_DET_ERROR_REPORT == STD_ON +static void FLEXCAN_ReportDet(uint8_t funcId, uint8_t paramId) +{ + s_tFlexCan_DetErrorId.u8FunctionID = funcId; + s_tFlexCan_DetErrorId.u8ParameterID = paramId; + + while (1) + { + + } + +} + +#endif + + +#if FLEXCAN_CHECK_PARAMETERS == STD_ON +/** + * @brief Check FLEXCAN instance + * + * @param u8CanIndex Can Index, must less than FLEXCAN_INSTANCE_COUNT + * @return FLEXCAN_ERROR_OK is OK + */ +LOCAL_INLINE FLEXCAN_ErrorType FLEXCAN_LL_CheckInstance(uint8_t u8CanIndex) +{ + FLEXCAN_ErrorType tRetVal; + + if (u8CanIndex < FLEXCAN_INSTANCE_COUNT) + { + tRetVal = FLEXCAN_ERROR_OK; + } + else + { + tRetVal = FLEXCAN_ERROR_INVALID_PARAM; + } + + return tRetVal; +} + +#endif + +/** + * @brief Check FLEXCAN Fd Support instance + * + * @param u8CanIndex Can Index, must less than FLEXCAN_INSTANCE_COUNT + * @return FLEXCAN_ERROR_OK is OK + */ +LOCAL_INLINE FLEXCAN_ErrorType FLEXCAN_LL_CheckFdInstance(uint8_t u8CanIndex) +{ + FLEXCAN_ErrorType tRetVal; + + if (u8CanIndex < FLEXCAN_FD_INSTANCE_COUNT) + { + tRetVal = FLEXCAN_ERROR_OK; + } + else + { + tRetVal = FLEXCAN_ERROR_INVALID_PARAM; + } + + return tRetVal; +} + + +/** + * @brief Initial embedded can ram area + * + * @param u8CanIndex CanIndex, Must less than FLEXCAN_INSTANCE_COUNT + */ +/* Every CAN contains message buffer number */ +#define FLEXCAN_MB_NUM_PTRS {32U,32U,32U,32U} +/* Number of instances of the FLEXCAN FD module. */ +#define FLEXCAN_FD_SUPPORT_PTRS {1U,1U,1U,1U} +/* Support Gate */ +#define FLEXCAN_GATE_BUFNUM_PTRS {0U,0U,0U,0U} +/* Support pretend network */ +#define FLEXCAN_PNET_SUPPORT_PTRS {1U,1U,1U,1U} + +/* IFlag1...IFlagn, IMask1...IMaskn */ +#define FLEXCAN_IFLAGMASK_NUM_PTRS {1U,1U,1U,1U} +#define FLEXCAN_IFLAGMASK_NUM_MAX 1U + +/* MBDSR0..MBDSRn */ +#define FLEXCAN_FD_DATALEN_RANGE_NUM_PTRS {1U,1U,1U,1U} +#define FLEXCAN_FD_DATALEN_RANGE_NUM_MAX 1U + +/* Enhanced Rx FIFO */ +#define FLEXCAN_ENHANCED_FIFO_ELEMENT_MAX_PTRS {32U,32U,32U,32U} +#define FLEXCAN_ENHANCED_FIFO_DEPTH_PTRS {12U,12U,12U,12U} + +static const uint8_t s_aFlexCanFd_SupportTable[FLEXCAN_INSTANCE_COUNT] = FLEXCAN_FD_SUPPORT_PTRS; +static const uint8_t s_aFlexCanEnhancedElementNums[FLEXCAN_INSTANCE_COUNT] = FLEXCAN_ENHANCED_FIFO_ELEMENT_MAX_PTRS; +static const uint8_t s_aFlexCanMbNums[FLEXCAN_INSTANCE_COUNT] = FLEXCAN_MB_NUM_PTRS; +static const uint8_t s_aFlexCanDataLenNums[FLEXCAN_INSTANCE_COUNT] = FLEXCAN_FD_DATALEN_RANGE_NUM_PTRS; +static const uint8_t s_aFlexCanEnhancedDepthp[FLEXCAN_INSTANCE_COUNT] = FLEXCAN_ENHANCED_FIFO_DEPTH_PTRS; +static const uint8_t s_aFlexCanGateNumSizes[FLEXCAN_INSTANCE_COUNT] = FLEXCAN_GATE_BUFNUM_PTRS; +static const uint8_t s_aFlexCanIflagMaskSizes[FLEXCAN_INSTANCE_COUNT] = FLEXCAN_IFLAGMASK_NUM_PTRS; +static const uint8_t s_aFlexCanPnetSupportTable[FLEXCAN_INSTANCE_COUNT]=FLEXCAN_PNET_SUPPORT_PTRS; + +#define FLEXCAN_MB_RAM_OFFSET 0x80U /* length is MB_Num*4*4 */ +#define FLEXCAN_RXIMR_OFFSET 0x880U /* Length is MB_Num*4 */ +#define FLEXCAN_RXFIR_TEST_OFFSET 0xA80U +#define FLEXCAN_RXFIR_TEST_LEN 0x18U /* Length is 0x18 */ +#define FLEXCAN_MASK_OFFSET 0xAA0U +#define FLEXCAN_MASK_LEN 0x10U /* Length is 0x10, RX14MASK, RX15MASK,RXMGMAXK, and RSFGMASK */ +#define FLEXCAN_SMBTX_OFFSET 0xAB0U +#define FLEXCAN_SMBTX_LEN 0x10U /* Length is 0x10 */ +#define FLEXCAN_SMBRX0_OFFSET 0xAC0U +#define FLEXCAN_SMBRX0_LEN 0x10U /* Length is 0x10 */ +#define FLEXCAN_SMBRX1_OFFSET 0xAD0U +#define FLEXCAN_SMBRX1_LEN 0x10U /* Length is 0x10 */ +#define FLEXCAN_FD_SMBTX_OFFSET 0xF28U +#define FLEXCAN_FD_SMBTX_LEN 0x48U /* Length is 0x48 */ +#define FLEXCAN_FD_SMBRX0_OFFSET 0xF70U +#define FLEXCAN_FD_SMBRX0_LEN 0x48U /* Length is 0x48 */ +#define FLEXCAN_FD_SMBRX1_OFFSET 0xFB8U +#define FLEXCAN_FD_SMBRX1_LEN 0x48U /* Length is 0x48 */ +#define FLEXCAN_ERX_FIFO_OFFSET 0x2000U /* Length is Depth*20(fd) or Depth*6(non-fd) */ +#define FLEXCAN_ERX_FIFO_FD_WIDTH 20U +#define FLEXCAN_ERX_FIFO_NONFD_WIDTH 6U +#define FLEXCAN_ERFFEL_OFFSET 0x3000U /* Length is element_num*4 */ +#define FLEXCAN_GATEBUF_OFFSET 0x1A10U /* Length is gatebuf_num*2*4 */ + + + +static void FLEXCAN_LL_EmbededRam_Init(uint8_t u8CanIndex) +{ + volatile uint32_t u32Index ; + volatile uint32_t ramAddr; + FLEXCAN_Type *pCan; + + pCan = (FLEXCAN_Type *)s_aFlexCan_InstanceTable[(uint8_t)u8CanIndex]; + + for (u32Index = 0U; u32Index < s_aFlexCanMbNums[u8CanIndex]*4U; u32Index++) + { + ramAddr = FLEXCAN_REGISTER_WITHOFFSET(pCan, FLEXCAN_MB_RAM_OFFSET, u32Index * 4U); + FLEXCAN_REG32_CONTENT(ramAddr) = 0U; + } + + for (u32Index = 0U; u32Index < s_aFlexCanMbNums[u8CanIndex]; u32Index++) + { + ramAddr = FLEXCAN_REGISTER_WITHOFFSET(pCan, FLEXCAN_RXIMR_OFFSET, u32Index * 4U); + FLEXCAN_REG32_CONTENT(ramAddr) = 0U; + } + + for (u32Index = 0U; u32Index < FLEXCAN_RXFIR_TEST_LEN; u32Index+=4U) + { + ramAddr = FLEXCAN_REGISTER_WITHOFFSET(pCan, FLEXCAN_RXFIR_TEST_OFFSET, u32Index); + FLEXCAN_REG32_CONTENT(ramAddr) = 0U; + } + + for (u32Index = 0U; u32Index < FLEXCAN_MASK_LEN; u32Index+=4U) + { + ramAddr = FLEXCAN_REGISTER_WITHOFFSET(pCan, FLEXCAN_MASK_OFFSET, u32Index); + FLEXCAN_REG32_CONTENT(ramAddr) = 0U; + } + + for (u32Index = 0U; u32Index < FLEXCAN_SMBTX_LEN; u32Index+=4U) + { + ramAddr = FLEXCAN_REGISTER_WITHOFFSET(pCan, FLEXCAN_SMBTX_OFFSET, u32Index); + FLEXCAN_REG32_CONTENT(ramAddr) = 0U; + } + + for (u32Index = 0U; u32Index < FLEXCAN_SMBRX0_LEN; u32Index+=4U) + { + ramAddr = FLEXCAN_REGISTER_WITHOFFSET(pCan, FLEXCAN_SMBRX0_OFFSET, u32Index); + FLEXCAN_REG32_CONTENT(ramAddr) = 0U; + } + + for (u32Index = 0U; u32Index < FLEXCAN_SMBRX1_LEN; u32Index+=4U) + { + ramAddr = FLEXCAN_REGISTER_WITHOFFSET(pCan, FLEXCAN_SMBRX1_OFFSET, u32Index); + FLEXCAN_REG32_CONTENT(ramAddr) = 0U; + } + + /* only can fd support these memory */ + if(s_aFlexCanFd_SupportTable[u8CanIndex]) + { + for (u32Index = 0U; u32Index < FLEXCAN_FD_SMBTX_LEN; u32Index+=4U) + { + ramAddr = FLEXCAN_REGISTER_WITHOFFSET(pCan, FLEXCAN_FD_SMBTX_OFFSET, u32Index); + FLEXCAN_REG32_CONTENT(ramAddr) = 0U; + } + + for (u32Index = 0U; u32Index < FLEXCAN_FD_SMBRX0_LEN; u32Index+=4U) + { + ramAddr = FLEXCAN_REGISTER_WITHOFFSET(pCan, FLEXCAN_FD_SMBRX0_OFFSET, u32Index); + FLEXCAN_REG32_CONTENT(ramAddr) = 0U; + } + + for (u32Index = 0U; u32Index < FLEXCAN_FD_SMBRX1_LEN; u32Index+=4U) + { + ramAddr = FLEXCAN_REGISTER_WITHOFFSET(pCan, FLEXCAN_FD_SMBRX1_OFFSET, u32Index); + FLEXCAN_REG32_CONTENT(ramAddr) = 0U; + } + } + + /* only enhanced rx fifo support these memory */ + if(s_aFlexCanEnhancedDepthp[u8CanIndex]) + { + /** initial rx fifo with fd */ + for (u32Index = 0U; u32Index < s_aFlexCanEnhancedDepthp[u8CanIndex]*4U*FLEXCAN_ERX_FIFO_FD_WIDTH; u32Index+=4U) + { + ramAddr = FLEXCAN_REGISTER_WITHOFFSET(pCan, FLEXCAN_ERX_FIFO_OFFSET, u32Index ); + FLEXCAN_REG32_CONTENT(ramAddr) = 0U; + } + + /* enhanced fifo elements */ + for (u32Index = 0U; u32Index < s_aFlexCanEnhancedElementNums[u8CanIndex]; u32Index++) + { + ramAddr = FLEXCAN_REGISTER_WITHOFFSET(pCan, FLEXCAN_ERFFEL_OFFSET, u32Index * 4U); + FLEXCAN_REG32_CONTENT(ramAddr) = 0U; + } + } + + /* gate buffer */ + if(s_aFlexCanGateNumSizes[u8CanIndex]) + { + for (u32Index = 0U; u32Index < s_aFlexCanGateNumSizes[u8CanIndex]*2U; u32Index++) + { + ramAddr = FLEXCAN_REGISTER_WITHOFFSET(pCan, FLEXCAN_GATEBUF_OFFSET, u32Index * 4U); + FLEXCAN_REG32_CONTENT(ramAddr) = 0U; + } + } +} + +/* +static void FLEXCAN_LL_EmbededRam_Init(uint8_t u8CanIndex) +{ + volatile uint32_t u8Index ; + volatile uint32_t ramAddr; + FLEXCAN_Type *pCan; + + pCan = (FLEXCAN_Type *)s_aFlexCan_InstanceTable[u8CanIndex]; + + for (u8Index = 0U; u8Index < MB_RAM_WORD_NUM; u8Index++) + { + ramAddr = FLEXCAN_REGISTER_WITHOFFSET(pCan, MB_RAM_OFFSET, u8Index * FLEXCAN_MEM_WORD_LEN); + FLEXCAN_REG32_CONTENT(ramAddr) = 0U; + } + + for (u8Index = 0U; u8Index < RXIMR_WORD_NUM; u8Index++) + { + ramAddr = FLEXCAN_REGISTER_WITHOFFSET(pCan, RXIMR_OFFSET, u8Index * FLEXCAN_MEM_WORD_LEN); + FLEXCAN_REG32_CONTENT(ramAddr) = 0U; + } + + for (u8Index = 0U; u8Index < RXFIR_TEST_WORD_NUM; u8Index++) + { + ramAddr = FLEXCAN_REGISTER_WITHOFFSET(pCan, RXFIR_TEST_OFFSET, u8Index * FLEXCAN_MEM_WORD_LEN); + FLEXCAN_REG32_CONTENT(ramAddr) = 0U; + } + + + for (u8Index = 0U; u8Index < MASK_WORD_NUM; u8Index++) + { + ramAddr = FLEXCAN_REGISTER_WITHOFFSET(pCan, MASK_OFFSET, u8Index * FLEXCAN_MEM_WORD_LEN); + FLEXCAN_REG32_CONTENT(ramAddr) = 0U; + } + + for (u8Index = 0U; u8Index < SMBTX_WORD_NUM; u8Index++) + { + ramAddr = FLEXCAN_REGISTER_WITHOFFSET(pCan, SMBTX_OFFSET, u8Index * FLEXCAN_MEM_WORD_LEN); + FLEXCAN_REG32_CONTENT(ramAddr) = 0U; + } + + for (u8Index = 0U; u8Index < SMBRX0_WORD_NUM; u8Index++) + { + ramAddr = FLEXCAN_REGISTER_WITHOFFSET(pCan, SMBRX0_OFFSET, u8Index * FLEXCAN_MEM_WORD_LEN); + FLEXCAN_REG32_CONTENT(ramAddr) = 0U; + } + + for (u8Index = 0U; u8Index < SMBRX1_WORD_NUM; u8Index++) + { + ramAddr = FLEXCAN_REGISTER_WITHOFFSET(pCan, SMBRX1_OFFSET, u8Index * FLEXCAN_MEM_WORD_LEN); + FLEXCAN_REG32_CONTENT(ramAddr) = 0U; + } + + // can fd only + if (FLEXCAN_LL_CheckFdInstance(u8CanIndex) == FLEXCAN_ERROR_OK) + { + for (u8Index = 0U; u8Index < FD_SMBTX_WORD_NUM; u8Index++) + { + ramAddr = FLEXCAN_REGISTER_WITHOFFSET(pCan, FD_SMBTX_OFFSET, u8Index * FLEXCAN_MEM_WORD_LEN); + FLEXCAN_REG32_CONTENT(ramAddr) = 0U; + } + + for (u8Index = 0U; u8Index < FD_SMBRX0_WORD_NUM; u8Index++) + { + ramAddr = FLEXCAN_REGISTER_WITHOFFSET(pCan, FD_SMBRX0_OFFSET, u8Index * FLEXCAN_MEM_WORD_LEN); + FLEXCAN_REG32_CONTENT(ramAddr) = 0U; + } + + for (u8Index = 0U; u8Index < FD_SMBRX1_WORD_NUM; u8Index++) + { + ramAddr = FLEXCAN_REGISTER_WITHOFFSET(pCan, FD_SMBRX1_OFFSET, u8Index * FLEXCAN_MEM_WORD_LEN); + FLEXCAN_REG32_CONTENT(ramAddr) = 0U; + } + + + // initial rx fifo + for (u8Index = 0U; u8Index < ERX_FIFO_WORD_NUM; u8Index++) + { + ramAddr = FLEXCAN_REGISTER_WITHOFFSET(pCan, ERX_FIFO_OFFSET, u8Index * FLEXCAN_MEM_WORD_LEN); + FLEXCAN_REG32_CONTENT(ramAddr) = 0U; + } + + for (u8Index = 0U; u8Index < ERFFEL_WORD_NUM; u8Index++) + { + ramAddr = FLEXCAN_REGISTER_WITHOFFSET(pCan, ERFFEL_OFFSET, u8Index * FLEXCAN_MEM_WORD_LEN); + FLEXCAN_REG32_CONTENT(ramAddr) = 0U; + } + + } + +} +*/ + + +/** + * @brief This Function is used to receive Special Message Buffer data + * + * @param u8CanIndex Can Index, Must less than FLEXCAN_INSTANCE_COUNT + * @param u8RealMbIndex, message buffer index 0...31, if fifo enable, always 0 + * @param u8MbDataLen, message buffer data length + * @param pRxMsg, received data buffer + * @return 0 means no data, others means received data + */ +static uint8_t FLEXCAN_LL_ReceiveMb(uint8_t u8CanIndex, uint8_t u8RealMbIndex, uint8 bEnFifo, uint8_t u8MbDataLen, FLEXCAN_RxMsgType *const pRxMsg) +{ + + FLEXCAN_Type *pCan; + uint32_t u32Status; + + uint32_t *pSrc; + uint32_t *pDest; + uint8_t u8Index; + + uint32_t u32TempAddr; + uint32_t u32WordLen; + uint8 u8IflagIndex; + + pCan = (FLEXCAN_Type *)s_aFlexCan_InstanceTable[u8CanIndex]; + + if (bEnFifo != 0U) + { + u8IflagIndex = 5U; /* IFLAG1[BIT5] (Frames available in Rx FIFO) is asserted when there is at least one frame available to be read from the FIFO */ + u8RealMbIndex = 0U; /* fifo received always in MB0 */ + } + else + { + u8IflagIndex = u8RealMbIndex; + } + + pRxMsg->u32DataLen = 0U; + + u32Status = FLEXCAN_HWA_GetFlag1NoFifoFlag(pCan, (uint32_t)u8IflagIndex); + + if (u32Status != 0U) + { + pRxMsg->u8CanIndex = u8CanIndex; + pRxMsg->u8MbIndex = u8RealMbIndex; + + /* message buffer 1th word */ + u32TempAddr = (uint32_t)FLEXCAN_MB_WORDN_ADDR(&(pCan->RAM[0U]), u8RealMbIndex, u8MbDataLen, 0U); + + pRxMsg->bEnFd = (uint8_t)((FLEXCAN_MB_EDL_GET(u32TempAddr) == 0U) ? 0U : 1U); + pRxMsg->bEnBrs = (uint8_t)((FLEXCAN_MB_BRS_GET(u32TempAddr) == 0U) ? 0U : 1U); + + + pRxMsg->u32DataLen = FLEXCAN_MB_DLC_GET(u32TempAddr); + pRxMsg->u32DataLen = FLEXCAN_DlcToDataLen(pRxMsg->u32DataLen); + pRxMsg->eFrameType = (FLEXCAN_IdType)(FLEXCAN_MB_IDE_GET(u32TempAddr)); + + /* message buffer 2th word */ + u32TempAddr = (uint32_t)FLEXCAN_MB_WORDN_ADDR(&(pCan->RAM[0U]), u8RealMbIndex, u8MbDataLen, 4U); + + if (pRxMsg->eFrameType) + { + pRxMsg->u32CanId = FLEXCAN_MB_EXTID_GET(u32TempAddr); + } + else + { + pRxMsg->u32CanId = FLEXCAN_MB_STDID_GET(u32TempAddr); + } + + + + pDest = (uint32_t *)pRxMsg->aData; + /* message buffer 3th word */ + pSrc = (uint32_t *)FLEXCAN_MB_WORDN_ADDR(&(pCan->RAM[0U]), u8RealMbIndex, u8MbDataLen, 8U); + + + u32WordLen = pRxMsg->u32DataLen / 4U + (pRxMsg->u32DataLen % 4U > 0U ? 1U : 0U); + + for (u8Index = 0U; u8Index < u32WordLen; u8Index++) + { + /* big endian to little endian */ + REV_BYTES_32(pSrc[u8Index], pDest[u8Index]); + } + + FLEXCAN_HWA_UnlockMbNoFifoFlag(pCan, (uint32_t)u8IflagIndex); + + } + else + { + } + + return pRxMsg->u32DataLen > 0U; +} + + +/** + * @brief This Function is used to receive Enhance FIFO Buffer data + * + * @param u8CanIndex Can Index, Must less than FLEXCAN_INSTANCE_COUNT + * @param pRxMsg, received data buffer + * @return 0 means no data, others means received data + */ +static uint8_t FLEXCAN_LL_ReceiveEnhanceFifo(uint8_t u8CanIndex, FLEXCAN_RxMsgType *const pRxMsg) +{ + uint32_t u32Status; + + volatile uint32_t *pSrc; + volatile uint32_t *pDest; + uint8_t u8Index; + FLEXCAN_Type *pCan; + + pRxMsg->u32DataLen = 0U; + + #if FLEXCAN_CHECK_PARAMETERS == STD_ON + if (FLEXCAN_LL_CheckFdInstance(u8CanIndex) == FLEXCAN_ERROR_OK) + { + #endif + pCan = (FLEXCAN_Type *)s_aFlexCan_InstanceTable[u8CanIndex]; + + /* The enhanced Rx FIFO has a watermark that is configured by setting EFRCR[ERFWM]. + * If EFRCR[ERFWM] is set, the CPU is notified only if a minimum number of messages is stored in the FIFO. + * When the number of stored messages is greater than the value in EFRCR[ERFWM], ERFSR[ERFWMI] is set by the hardware. */ + + /* check fd fifo data available */ + u32Status = FLEXCAN_HWA_ERFSRGetEnhancedFifoFlag(pCan, FLEXCAN_ERFSR_ERFDA_SHIFT, FLEXCAN_ERFSR_ERFDA_MASK); + + if (u32Status != 0U) + { + + pRxMsg->u8CanIndex = u8CanIndex; + pRxMsg->u8MbIndex = 0U; + + pRxMsg->bEnFd = (uint8_t)(FLEXCAN_EFIFOMB_EDL_GET()); + pRxMsg->bEnBrs = (uint8_t)(FLEXCAN_EFIFOMB_BRS_GET()); + + + pRxMsg->u32DataLen = FLEXCAN_EFIFOMB_DLC_GET(); + pRxMsg->u32DataLen = (uint8_t)(FLEXCAN_DlcToDataLen(pRxMsg->u32DataLen)); + pRxMsg->eFrameType = (FLEXCAN_IdType)(FLEXCAN_EFIFOMB_IDE_GET()); + + + if (pRxMsg->eFrameType) + { + pRxMsg->u32CanId = FLEXCAN_EFIFOMB_EXTID_GET(); + } + else + { + pRxMsg->u32CanId = FLEXCAN_EFIFOMB_STDID_GET(); + } + + pDest = (uint32_t *)pRxMsg->aData; + /* message buffer 3th word */ + pSrc = (volatile uint32_t *)FLEXCAN_EFIFOMB_DATAADDR_GET(0U); + + + //u32WordLen = pRxMsg->u32DataLen / 4U + (pRxMsg->u32DataLen % 4U > 0U ? 1U : 0U); + + for (u8Index = 0U; u8Index < 18U; u8Index++) + { + /* big endian to little endian */ + REV_BYTES_32(pSrc[u8Index], pDest[u8Index]); + } + + //u32WordLen = FLEXCAN_EFIFOMB_HRTIMESTAMP_GET(u32WordLen); /* Read TIMER to unlock message buffers */ + + /* clear fifo data available status */ + FLEXCAN_HWA_ERFSRClearEnhancedFifoFlag(pCan, FLEXCAN_ERFSR_ERFDA_MASK); + + /* get fifo data available status */ + u32Status = FLEXCAN_HWA_ERFSRGetEnhancedFifoFlag(pCan, FLEXCAN_ERFSR_ERFDA_SHIFT, FLEXCAN_ERFSR_ERFDA_MASK); + + } + #if FLEXCAN_CHECK_PARAMETERS == STD_ON + } + #endif + + return pRxMsg->u32DataLen > 0U; +} + + +/** + * @brief Polling Message Buffer Received Data + * + * @param u8CanIndex Can Index, Must less than FLEXCAN_INSTANCE_COUNT + * @param pRxMsgList Message Stored buffer point + * @return Received message count + */ +static uint8_t FLEXCAN_LL_PollingMb(uint8_t u8CanIndex, FLEXCAN_RxMsgType *const pRxMsgList) +{ + uint8_t u8MsgNum; + uint32_t u32Status; + uint8_t u8RealMbIndex; + + FLEXCAN_SettingType *pCurSetting; + + uint8_t u8MBindex; + uint8_t u8MbDataWidth; + + pCurSetting = &s_aFlexCan_Setting_Table[u8CanIndex]; + + u8MsgNum = 0U; + + /* loop check all receive message buffer */ + for (u8MBindex = 0U; u8MBindex < pCurSetting->u8RxMbCnt1; u8MBindex++) + { + u8RealMbIndex = (uint8_t)(pCurSetting->u8RxMbStart1 + u8MBindex); + u8MbDataWidth = pCurSetting->eMbDataWidth; + + u32Status = FLEXCAN_LL_ReceiveMb(u8CanIndex, u8RealMbIndex, 0U, u8MbDataWidth, &pRxMsgList[u8MsgNum]); + + if (u32Status != 0U) + { + u8MsgNum ++; + } + else + { + } + } + + return u8MsgNum; +} + +/** + * @brief Polling Legacy Rx FIFO + * + * @param u8CanIndex CanIndex, Must less than FLEXCAN_INSTANCE_COUNT + * @param u8MbDataWidth Message Buffer Data Width + * @param pRxMsgList received data buffer + * @return receive message count + */ +static uint8_t FLEXCAN_LL_PollingLegacyFifo(uint8_t u8CanIndex, uint8_t u8MbDataWidth, FLEXCAN_RxMsgType *pRxMsgList) +{ + uint8_t u8MsgNum; + uint32_t u32Status; + uint8_t u8MBindex; + + u8MsgNum = 0U; + pRxMsgList[u8MsgNum].u32DataLen = 0U; + + /* legacy fifo only receive in MB 0 */ + u8MBindex = 0U; + + /* IFLAG1[BIT5] (Frames available in Rx FIFO) is asserted when there is at least one frame available to be read from the FIFO. */ + u32Status = 1U; + + while (u32Status != 0U) + { + u32Status = FLEXCAN_LL_ReceiveMb(u8CanIndex, u8MBindex, 1U, u8MbDataWidth, &pRxMsgList[u8MsgNum]); + + if (u32Status != 0U) + { + u8MsgNum ++; + } + else + { + } + + } + + return u8MsgNum; +} + +/** + * @brief Polling Enhanced Rx FIFO Data + * + * @param u8CanIndex Can Index, must less than FLEXCAN_INSTANCE_COUNT + * @param pRxMsgList received data buffer + * @return receive message count + */ +static uint8_t FLEXCAN_LL_PollingEnhancedFifo(uint8_t u8CanIndex, FLEXCAN_RxMsgType *pRxMsgList) +{ + uint8_t u8MsgNum; + uint32_t u32Status; + + /* The enhanced Rx FIFO has a watermark that is configured by setting EFRCR[ERFWM]. + * If EFRCR[ERFWM] is set, the CPU is notified only if a minimum number of messages is stored in the FIFO. + * When the number of stored messages is greater than the value in EFRCR[ERFWM], ERFSR[ERFWMI] is set by the hardware. */ + + /* check fd fifo data available */ + u8MsgNum = 0U; + u32Status = 1U; + while (u32Status != 0U) + { + u32Status = FLEXCAN_LL_ReceiveEnhanceFifo(u8CanIndex, &pRxMsgList[u8MsgNum]); + if (u32Status > 0U) + { + u8MsgNum ++; + } + } + + return u8MsgNum; +} + + +/** + * @brief Receive Can FIFO Data + * + * @param u8CanIndex Can Index, must less than FLEXCAN_INSTANCE_COUNT + * @param bEnableFd if it is CAN FD Fifo + * @param pRxMsgList received data buffer + * @return receive message count + */ +static uint8_t FLEXCAN_LL_ReceiveFifo(uint8_t u8CanIndex, uint8_t bEnableFd, FLEXCAN_RxMsgType *pRxMsgList) +{ + + uint8_t u8MsgNum; + + FLEXCAN_SettingType *pCurSetting; + + pCurSetting = &s_aFlexCan_Setting_Table[u8CanIndex]; + + + if (bEnableFd) /* can fd fifo receive */ + { + u8MsgNum = FLEXCAN_LL_PollingEnhancedFifo(u8CanIndex, pRxMsgList); + + } + else /* legacy fifo receive */ + { + u8MsgNum = FLEXCAN_LL_PollingLegacyFifo(u8CanIndex, pCurSetting->eMbDataWidth, pRxMsgList); + + } + + return u8MsgNum; +} + + +/** + * @brief Process CAN Baudrate from table + * + * @param pBaudCfg baudrate configuration + * @return 0 is ok + */ +static uint8_t FLEXCAN_LL_ProcessBaud(FLEXCAN_BaudCfgType *pBaudCfg) +{ + uint32_t u32Mod; + uint8_t u8RetVal; + uint32_t u32Index; + + + u8RetVal = 1U; + + if (pBaudCfg->bEnFd) + { + u32Mod = (uint32_t)pBaudCfg->eClkSrcHz % (uint32_t)pBaudCfg->eBaudrate; + if (u32Mod != 0U) + { + u8RetVal = 1U; + } + else + { + + /* loop check for normal bit rate */ + for (u32Index = 0U; u32Index < sizeof(s_aFlexCan_NormalBaudDividerTable) / sizeof(s_aFlexCan_NormalBaudDividerTable[0]); u32Index++) + { + if ((pBaudCfg->eClkSrcHz == s_aFlexCan_NormalBaudDividerTable[u32Index].eClkHz) && (pBaudCfg->eBaudrate == s_aFlexCan_NormalBaudDividerTable[u32Index].eBaudrate)) + { + /* when pCan fd enabled, pCan normal bit set by CBT !!!! */ + pBaudCfg->u32Cbt = FLEXCAN_CBT_EPRESDIV(s_aFlexCan_NormalBaudDividerTable[u32Index].u32Presdiv - 1U) | + FLEXCAN_CBT_ERJW(s_aFlexCan_NormalBaudDividerTable[u32Index].u32Rjw - 1U) | + FLEXCAN_CBT_EPSEG1(s_aFlexCan_NormalBaudDividerTable[u32Index].u32Pseg1 - 1U) | + FLEXCAN_CBT_EPSEG2(s_aFlexCan_NormalBaudDividerTable[u32Index].u32Pseg2 - 1U) | + FLEXCAN_CBT_EPROPSEG(s_aFlexCan_NormalBaudDividerTable[u32Index].u32Propseg - 1U) | + FLEXCAN_CBT_BTF(1U); /* SMP = 1: use 3 bits per CAN sample */ + + u8RetVal = 0U; + break; + } + } + + + if (u8RetVal == 0U) + { + u8RetVal = 1U; + + /* loop for fd data bit rate */ + for (u32Index = 0U; u32Index < sizeof(s_aFlexCan_DataBaudDividerTable) / sizeof(s_aFlexCan_DataBaudDividerTable[0]); u32Index++) + { + if ((pBaudCfg->eClkSrcHz == s_aFlexCan_DataBaudDividerTable[u32Index].eClkHz) && (pBaudCfg->eDataBaud == s_aFlexCan_DataBaudDividerTable[u32Index].eBaudrate)) + { + pBaudCfg->u32FdCtrl = FLEXCAN_FDCTRL_FDRATE(pBaudCfg->bEnBrs) | + /* MBDSR0, pMb 0-31 data length, 8-0,16-1,32-2,64-3 */ + FLEXCAN_FDCTRL_MBDSR0(pBaudCfg->eMbDataWidth == FLEXCAN_DATAWIDTH_8 ? 0U : (pBaudCfg->eMbDataWidth == FLEXCAN_DATAWIDTH_16 ? 1U : + (pBaudCfg->eMbDataWidth == FLEXCAN_DATAWIDTH_32 ? 2U : 3U))) + | FLEXCAN_FDCTRL_TDCOFF(1U); + + + /* when pCan fd enabled, pCan normal bit set by CBT !!!! */ + pBaudCfg->u32FdCbt = FLEXCAN_FDCBT_FPRESDIV(s_aFlexCan_DataBaudDividerTable[u32Index].u32Presdiv - 1U) | + FLEXCAN_FDCBT_FRJW(s_aFlexCan_DataBaudDividerTable[u32Index].u32Rjw - 1U) | + FLEXCAN_FDCBT_FPSEG1(s_aFlexCan_DataBaudDividerTable[u32Index].u32Pseg1 - 1U) | + FLEXCAN_FDCBT_FPSEG2(s_aFlexCan_DataBaudDividerTable[u32Index].u32Pseg2 - 1U) | + FLEXCAN_FDCBT_FPROPSEG(s_aFlexCan_DataBaudDividerTable[u32Index].u32Propseg); + + u8RetVal = 0U; + break; + } + } + } + + + } + } + else + { + u32Mod = (uint32_t)pBaudCfg->eClkSrcHz % (uint32_t)pBaudCfg->eBaudrate; + if (u32Mod != 0U) + { + u8RetVal = 1U; + } + + else + { + u8RetVal = 1U; + /* loop check for normal bit rate */ + for (u32Index = 0U; u32Index < sizeof(s_aFlexCan_NormalBaudDividerTable) / sizeof(s_aFlexCan_NormalBaudDividerTable[0]); u32Index++) + { + if ((pBaudCfg->eClkSrcHz == s_aFlexCan_NormalBaudDividerTable[u32Index].eClkHz) && (pBaudCfg->eBaudrate == s_aFlexCan_NormalBaudDividerTable[u32Index].eBaudrate)) + { + /* when pCan fd enabled, pCan normal bit set by CBT !!!! */ + pBaudCfg->u32Ctrl1 = FLEXCAN_CTRL1_PRESDIV(s_aFlexCan_NormalBaudDividerTable[u32Index].u32Presdiv - 1U) | + FLEXCAN_CTRL1_RJW(s_aFlexCan_NormalBaudDividerTable[u32Index].u32Rjw - 1U) | + FLEXCAN_CTRL1_PSEG1(s_aFlexCan_NormalBaudDividerTable[u32Index].u32Pseg1 - 1U) | + FLEXCAN_CTRL1_PSEG2(s_aFlexCan_NormalBaudDividerTable[u32Index].u32Pseg2 - 1U) | + FLEXCAN_CTRL1_PROPSEG(s_aFlexCan_NormalBaudDividerTable[u32Index].u32Propseg - 1U); + + u8RetVal = 0U; + } + } + + + } + } + + + return u8RetVal; + +} + +/** + * @brief Set Legacy Rx FIFO + * + * @param u8CanIndex Can Index, must less than FLEXCAN_INSTANCE_COUNT + * @param pRxFilterList Filter id list + * @param u32RxFilterCnt Filter id list length + * @return FLEXCAN_ERROR_OK is ok + */ +static FLEXCAN_ErrorType FLEXCAN_LL_SetLegacyFifo(uint8_t u8CanIndex, FLEXCAN_RxMbFilterType *pRxFilterList, uint32_t u32RxFilterCnt) +{ + FLEXCAN_ErrorType tRetVal; + uint32_t u32FilterNum; + uint32_t u32FilterNumLeft; + uint32_t u32Index; + + FLEXCAN_Type *pCan; + + #if FLEXCAN_CHECK_PARAMETERS == STD_ON + tRetVal = FLEXCAN_LL_CheckFdInstance(u8CanIndex); + + if (tRetVal == FLEXCAN_ERROR_OK) + { + #else + tRetVal = FLEXCAN_ERROR_OK; + #endif + pCan = (FLEXCAN_Type *)s_aFlexCan_InstanceTable[u8CanIndex]; + + /* set legacy fifo */ + FLEXCAN_HWA_EnableLegacyFifo(pCan); + + + /* 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 */ + /* Format A: RTR IDE | RXIDA (standard =29-19, extended = 29-1) | */ + /* Format B: RTR IDE | RXIDB_0 (standart = 29-19, extended = 29-16) MSB compare | RTR IDE|RXIDB_1 (standart = 13-3, extended = 13-0) MSB compare */ + /* Format C: RXIDC_0 (std/ext = 31-24) MSB compare | RXIDC_1 (std/ext = 23-16) MSB compare | RXIDC_2 (std/ext =15-8) MSB compare | RXIDC_3 (std/ext =7-0) MSB compare */ + + /* set always format A */ + + + u32FilterNum = 0U; + + /* filter start from MB 6 */ + for (u32Index = 0U; u32Index < u32RxFilterCnt; u32Index++) + { + /* extended id */ + if (pRxFilterList[u32Index].eRxFrameType == FLEXCAN_ID_EXT) + { + FLEXCAN_HWA_MbRam(pCan, 4U * 6U + u32FilterNum, (1U << 30) | (pRxFilterList[u32Index].u32RxCanId << 1)); /* id */ + FLEXCAN_HWA_SetIndividualMask(pCan, u32FilterNum, (1U << 30) | pRxFilterList[u32Index].u32RxCanIdMask) ; /* mask */ + } + else /* standard id */ + { + FLEXCAN_HWA_MbRam(pCan, 4U * 6U + u32FilterNum, pRxFilterList[u32Index].u32RxCanId << 19); /* id */ + FLEXCAN_HWA_SetIndividualMask(pCan, u32FilterNum, (1U << 30) | (pRxFilterList[u32Index].u32RxCanIdMask << 19)) ; /* mask */ + } + + u32FilterNum++; + } + + /* filter elements number are multiple of 8 */ + u32FilterNumLeft = 8U - u32RxFilterCnt % 8U; + /* set left same to last filter */ + for (u32Index = 0U; u32Index < u32FilterNumLeft; u32Index++) + { + /* extended id */ + if (pRxFilterList[u32FilterNum - 1U].eRxFrameType == FLEXCAN_ID_EXT) + { + FLEXCAN_HWA_MbRam(pCan, 4U * 6U + u32FilterNum + u32Index, (1U << 30) | (pRxFilterList[u32FilterNum - 1U].u32RxCanId << 1)); /* id */ + FLEXCAN_HWA_SetIndividualMask(pCan, u32FilterNum + u32Index, (1U << 30) | pRxFilterList[u32FilterNum - 1U].u32RxCanIdMask); /* mask */ + } + else /* standard id */ + { + FLEXCAN_HWA_MbRam(pCan, 4U * 6U + u32FilterNum + u32Index, pRxFilterList[u32FilterNum - 1U].u32RxCanId << 19); /* id */ + FLEXCAN_HWA_SetIndividualMask(pCan, u32FilterNum + u32Index, (1U << 30) | (pRxFilterList[u32FilterNum - 1U].u32RxCanIdMask << 19)); /* mask */ + + } + } + + /* set fifo filter, 1 group filter contains 8 filter elements (2MBs) */ + /* left for tx = MaxMb-6 - (RFFN+1)*2 */ + u32FilterNum = u32FilterNum / 8U + (u32FilterNum % 8U > 0U ? 1U : 0U); + FLEXCAN_HWA_SetLegacyFifoFilterNum(pCan, u32FilterNum); + #if FLEXCAN_CHECK_PARAMETERS == STD_ON + } + #endif + + return tRetVal; +} + +/** + * @brief Set Enhanced Rx FIFO + * + * @param u8CanIndex Can Index, must less than FLEXCAN_INSTANCE_COUNT + * @param pRxFilterList Filter id list + * @param u32RxFilterCnt Filter id list length + * @param u8WaterMark DMA Wartmark + * @return FLEXCAN_ERROR_OK is ok + */ +static FLEXCAN_ErrorType FLEXCAN_LL_SetEnhancedFifo(uint8_t u8CanIndex, FLEXCAN_RxMbFilterType *pRxFilterList, uint32_t u32RxFilterCnt, uint8_t u8WaterMark) +{ + FLEXCAN_ErrorType tRetVal; + uint32_t u32FilterERFCRNum; + uint32_t u32Index; + FLEXCAN_Type *pCan; + + #if FLEXCAN_CHECK_PARAMETERS == STD_ON + tRetVal = FLEXCAN_LL_CheckFdInstance(u8CanIndex); + + if (tRetVal == FLEXCAN_ERROR_OK) + { + #else + tRetVal = FLEXCAN_ERROR_OK; + #endif + + uint32_t u32ExtIDFilterNum; + uint32_t u32StdIDFilterNum; + uint32_t u32TempERFCR; + + /* current pCan instance */ + pCan = (FLEXCAN_Type *)s_aFlexCan_InstanceTable[u8CanIndex]; + + /* Configure the filter elements by writing in the ERFFELn registers (ERFFELn registers are implemented in RAM; thus, they must be explicitly initialized prior to any reception). */ + + /* standard id filter */ + /* 31-30 29-28 27 26-16 15-12 11 10-0 */ + /* FSCH=b00 Reserved RTR filter STD ID filter Reserved RTR mask STD ID mask id_filter&id_mask */ + /* FSCH=b01 Reserved RTR filter STD ID filter2 Reserved RTR mask STD ID filter1 id filter1<=id<= id filter2 */ + /* FSCH=b10 Reserved RTR filter2 STD ID filter2 Reserved RTR filter1 STD ID filter1 id filter1= id = id filter2 */ + + /* extended id filter */ + /* 31-30 29 28-0 */ + /* FSCH=00b RTR filter EXT ID filter */ + /* Reserved RTR mask EXT ID mask */ + /* FSCH=01b RTR filter EXT ID filter2 */ + /* Reserved RTR mask EXT ID filter1 */ + /* FSCH=10b RTR filter2 EXT ID filter2 */ + /* Reserved RTR filter1 EXT ID filter1 */ + + u32ExtIDFilterNum = 0U; + u32StdIDFilterNum = 0U; + + /* get extended id count and standard id count */ + for (u32Index = 0U; u32Index < u32RxFilterCnt; u32Index++) + { + if (pRxFilterList[u32Index].eRxFrameType == FLEXCAN_ID_EXT) + { + /* extended id first */ + /* pCan->ERFFEL[u32Index] &= 0xFFFFFFFU; */ + FLEXCAN_HWA_EnhancedFifoFilter(pCan, u32ExtIDFilterNum * 2U, pRxFilterList[u32Index].u32RxCanId); /* id */ + FLEXCAN_HWA_EnhancedFifoFilter(pCan, u32ExtIDFilterNum * 2U + 1U, pRxFilterList[u32Index].u32RxCanIdMask); /* mask */ + + u32ExtIDFilterNum++; + } + } + + for (u32Index = 0U; u32Index < u32RxFilterCnt; u32Index++) + { + /* standard id */ + if (pRxFilterList[u32Index].eRxFrameType == FLEXCAN_ID_STD) + { + FLEXCAN_HWA_EnhancedFifoFilter(pCan, u32ExtIDFilterNum * 2U + u32StdIDFilterNum, (pRxFilterList[u32Index].u32RxCanId << 16) | pRxFilterList[u32Index].u32RxCanIdMask); + u32StdIDFilterNum++; + } + } + + /* standard id number must multiple of 2 */ + tRetVal = (FLEXCAN_ErrorType)(tRetVal | ((u32StdIDFilterNum % 2U == 1U) ? FLEXCAN_ERROR_INVALID_PARAM : FLEXCAN_ERROR_OK)); + + if (tRetVal == FLEXCAN_ERROR_OK) + { + /* total id filter number in ERFCR, two std */ + u32FilterERFCRNum = u32StdIDFilterNum / 2U + u32ExtIDFilterNum - 1U; + + + + /* Write one to ERFSR[ERFCLR] to reset Enhanced Rx FIFO engine */ + FLEXCAN_HWA_ERFSRResetEnhancedFifo(pCan); + /* Clear EFRSR[ERFUFW], EFRSR[ERFOVF], EFRSR[ERFWMI], and EFRSR[ERFDA], if they are set. */ + FLEXCAN_HWA_ERFSRClearEnhancedFifoFlag(pCan, FLEXCAN_ERFSR_ERFUFW_MASK | FLEXCAN_ERFSR_ERFWMI_MASK | FLEXCAN_ERFSR_ERFDA_MASK); + /* Write EFRCR[NFE] to configure the total number of enhanced Rx FIFO filter elements to be used in Enhanced Rx FIFO reception. */ + + + /* set rx fifo filter num */ + u32TempERFCR = ((u32FilterERFCRNum) << FLEXCAN_ERFCR_NFE_SHIFT)&FLEXCAN_ERFCR_NFE_MASK; + + /* Write ERFCR[NEXIF] to configure the number of extended ID and standard ID filter elements to be used in Enhanced Rx FIFO reception (NEXIF �� NFE + 1). */ + /* set rx fifo extended id filter num, <= NFE+1 */ + u32TempERFCR |= (u32ExtIDFilterNum << FLEXCAN_ERFCR_NEXIF_SHIFT)&FLEXCAN_ERFCR_NEXIF_MASK; + + u32TempERFCR |= FLEXCAN_ERFCR_ERFWM(u8WaterMark - 1U); /* receive 1 message will indicate to fifo water mark */ + + u32TempERFCR |= FLEXCAN_ERFCR_DMALW(19U); + + u32TempERFCR |= FLEXCAN_ERFCR_ERFEN_MASK; /* enable enhance fifo dma */ + + FLEXCAN_HWA_SetERFCR(pCan, u32TempERFCR); + + /* set enhanced fifo */ + FLEXCAN_HWA_EnableFDFifo(pCan); + + /* Configure the Enhanced Rx FIFO watermark by writing ERFCR[ERFWM]. */ + + /* If interrupts will be used, set the interrupt enables in the ERIER register */ + + /* If DMA will be used, set MCR[DMA] to enable DMA operation and write ERFCR[DMALW] to configure the number of words to transfer for each Enhanced Rx FIFO data element */ + + } + #if FLEXCAN_CHECK_PARAMETERS == STD_ON + } + #endif + + return tRetVal; + +} + + + +/** + * @brief Process Tx Iflag and return result + * + * @param u8CanIndex Can Index, must less than FLEXCAN_INSTANCE_COUNT + * @param u8Handler Transmit Handler + * @return 1 means process successfully and can transmit next time, 0 means no active flag, 0xff means out of range + */ +static uint8_t FLEXCAN_LL_ProcessTx(uint8_t u8CanIndex, uint8_t u8Handler) +{ + uint8_t u8Index; + FLEXCAN_Type *pCan; + FLEXCAN_SettingType *pCurSetting; + uint32_t u32Iflag; + uint32_t u32HandlerMask; + + pCurSetting = &s_aFlexCan_Setting_Table[u8CanIndex]; + +#if FLEXCAN_CHECK_PARAMETERS == STD_ON + if(u8Handler < pCurSetting->u8TxMbCnt1) + { +#endif + pCan = (FLEXCAN_Type *)s_aFlexCan_InstanceTable[u8CanIndex]; + + u32Iflag = FLEXCAN_HWA_GetFlag1(pCan);; + u32HandlerMask = (1U << (pCurSetting->u8TxMbStart1+u8Handler)); + + u32Iflag = u32Iflag & u32HandlerMask; + + if(u32Iflag>0U) + FLEXCAN_HWA_SetFlag1(pCan, u32Iflag); + + u8Index = ((u32Iflag>0U)?1U:0U); +#if FLEXCAN_CHECK_PARAMETERS == STD_ON + } + else + { + u8Index = 0xFFU; + } +#endif + + return u8Index; +} + + +/* ################################################################################## */ +/* ################################ Global Functions ################################ */ + + + +/** + * @brief Initial FLEXCAN variables Memory + * + * @param u8CanIndex Can Index, must less than FLEXCAN_INSTANCE_COUNT + */ +void FLEXCAN_InitMemory(uint8_t u8CanIndex) +{ + + #if FLEXCAN_CHECK_PARAMETERS == STD_ON + FLEXCAN_ErrorType tRetVal; + /* check parameter */ + tRetVal = FLEXCAN_LL_CheckInstance(u8CanIndex); + if (tRetVal == FLEXCAN_ERROR_OK) + { + #endif + + s_aFlexCan_Setting_Table[u8CanIndex].bEnableFd = 0U; + s_aFlexCan_Setting_Table[u8CanIndex].bEnableFifo = 0U; + s_aFlexCan_Setting_Table[u8CanIndex].bEnableDMA = 0U; + s_aFlexCan_Setting_Table[u8CanIndex].pRxBuf = NULL; + s_aFlexCan_Setting_Table[u8CanIndex].u8RxMbCnt1 = 0U; + s_aFlexCan_Setting_Table[u8CanIndex].u8RxMbStart1 = 0U; + s_aFlexCan_Setting_Table[u8CanIndex].u8TxMbCnt1 = 0U; + s_aFlexCan_Setting_Table[u8CanIndex].u8TxMbStart1 = 0U; + s_aFlexCan_Setting_Table[u8CanIndex].u8RxFifoCnt = 0U; + s_aFlexCan_Setting_Table[u8CanIndex].eMbDataWidth = FLEXCAN_DATAWIDTH_8; + s_aFlexCan_Setting_Table[u8CanIndex].u8EnhancedFifoDmaWM = 0U; + s_aFlexCan_ErrorNotifyTable[u8CanIndex] = NULL; + s_aFlexCan_TxNotifyTable[u8CanIndex] = NULL; + s_aFlexCan_RxNotifyTable[u8CanIndex] = NULL; + + s_aFlexCan_CanUsed[u8CanIndex] = 0U; + + /* set first state */ + s_aCurrentSequence[u8CanIndex] = FLEXCAN_SEQUENCE_DEINIT; + #if FLEXCAN_CHECK_PARAMETERS == STD_ON + } + #endif + +} + + +/** + * @brief Initial CAN + * + * @param u8CanIndex Can Index, must less than FLEXCAN_INSTANCE_COUNT + * @param pInitCfg clock, baud-rate, canfd, data length and so on. + * @return 0 is ok, others are not ok + */ +FLEXCAN_ErrorType FLEXCAN_Init(uint8_t u8CanIndex, const FLEXCAN_InitType *const pInitCfg) +{ + FLEXCAN_ErrorType tRetVal; + uint32_t u32TempCtrl1; + uint32_t u32TempMcr; + uint8_t u8Result; + FLEXCAN_Type *pCan; + FLEXCAN_BaudCfgType tBaudCfg; + + #if FLEXCAN_CHECK_PARAMETERS == STD_ON + /* check parameter */ + tRetVal = FLEXCAN_LL_CheckInstance(u8CanIndex); + + if ((tRetVal == FLEXCAN_ERROR_OK) && (s_aCurrentSequence[u8CanIndex] == FLEXCAN_SEQUENCE_DEINIT)) + { + tRetVal = FLEXCAN_ERROR_OK; + } + else + { + tRetVal |= FLEXCAN_ERROR_INVALID_SEQUENCE; + } + + + if (pInitCfg == NULL || (pInitCfg->u8EnhancedFifoDmaWM > 12U)) + { + tRetVal |= FLEXCAN_ERROR_INVALID_PARAM; + } + else + { + /* DMA only support in Legacy Rx FIFO and Enhance Rx FIFO */ + if (pInitCfg->bEnDma != 0U) + { + if ((pInitCfg->bEnRxFifo == 0U)) + { + tRetVal |= FLEXCAN_ERROR_INVALID_PARAM; + } + } + } + + if ((pInitCfg->bEnFd == 0U) && (pInitCfg->bEnBrs == 1U)) + { + tRetVal |= FLEXCAN_ERROR_INVALID_PARAM; + } + + if ((pInitCfg->bEnFd == 1U) && (u8CanIndex >= FLEXCAN_FD_INSTANCE_COUNT)) + { + tRetVal |= FLEXCAN_ERROR_INVALID_PARAM; + } + + if (tRetVal == FLEXCAN_ERROR_OK) + { + #endif + /* set not start state */ + s_aCurrentSequence[u8CanIndex] = FLEXCAN_SEQUENCE_NOTSTART; + + pCan = (FLEXCAN_Type *)s_aFlexCan_InstanceTable[u8CanIndex]; + + u8Result = 0U; + tRetVal = FLEXCAN_ERROR_OK; + + FLEXCAN_HWA_SetMcrDisable(pCan, TRUE); + FLEXCAN_HWA_SetCtrl1(pCan, 0U); + FLEXCAN_HWA_SetCtrl1BaudSrc(pCan, pInitCfg->eClkSrcSel); + + FLEXCAN_HWA_SetMcrDisable(pCan, FALSE); + + /* mcr->B.bitMDIS = 0; */ + + FLEXCAN_HWA_SetHaltFreeze(pCan); + + /* wait for bitFRZACK=1 on freeze mode entry/exit */ + if (FLEXCAN_HWA_WaitMcrFreezen(pCan, 10000U) != 0U) + { + tRetVal |= FLEXCAN_ERROR_TIMEOUT; + } + else + { +// FLEXCAN_HWA_SetCtrl2(pCan, +// FLEXCAN_CTRL2_WRMFRZ(1U) | /* initial ram ecc */ +// FLEXCAN_CTRL2_TASD(20U) | +// FLEXCAN_CTRL2_DIRECT_EN(((pInitCfg->eDirect) & FLEXCAN_CTRL2_DIRECT_EN_MASK) ? 1U : 0U) | +// FLEXCAN_CTRL2_DIRECT_TRIG(((pInitCfg->eDirect) & FLEXCAN_CTRL2_DIRECT_TRIG_MASK) ? 1U : 0U) | +// FLEXCAN_CTRL2_ISOCANFDEN(1U)); + FLEXCAN_HWA_SetCtrl2(pCan, + FLEXCAN_CTRL2_WRMFRZ(1U) | /* initial ram ecc */ + FLEXCAN_CTRL2_TASD(20U) | + FLEXCAN_CTRL2_ISOCANFDEN(1U)); + + + + tBaudCfg.bEnFd = pInitCfg->bEnFd; + tBaudCfg.bEnBrs = pInitCfg->bEnBrs; + tBaudCfg.eMbDataWidth = pInitCfg->eMbDataWidth; + + tBaudCfg.eClkSrcHz = pInitCfg->eClkSrcHz; + tBaudCfg.eBaudrate = pInitCfg->eBaudrate; + tBaudCfg.eDataBaud = pInitCfg->eDataBaud; + + + u8Result = FLEXCAN_LL_ProcessBaud(&tBaudCfg); + + + if (u8Result) + { + tRetVal = FLEXCAN_ERROR_INVALID_PARAM; + } + else + { + /* when pCan fd disabled, pCan normal bit set by CTRL1 !!!! */ + u32TempCtrl1 = FLEXCAN_CTRL1_CLKSRC(pInitCfg->eClkSrcSel) | FLEXCAN_CTRL1_LOM(pInitCfg->bListenOnly); + + if (!tBaudCfg.bEnFd) + { + u32TempCtrl1 |= tBaudCfg.u32Ctrl1; /* SMP = 1: use 3 bits per CAN sample */ + } + else + { + FLEXCAN_HWA_SetCBT(pCan, tBaudCfg.u32Cbt); + + FLEXCAN_HWA_SetFDCTRL(pCan, tBaudCfg.u32FdCtrl); + FLEXCAN_HWA_SetFDCBT(pCan, tBaudCfg.u32FdCbt); + } + + + FLEXCAN_HWA_SetCtrl1(pCan, u32TempCtrl1); + + /* initial RAM to avoid ECC error CFIFCFIF*/ + FLEXCAN_LL_EmbededRam_Init(u8CanIndex); + + u32TempMcr = FLEXCAN_MCR_MDIS(0) | /* enable pCan module */ + FLEXCAN_MCR_FRZ(1) | /* not frozen */ + FLEXCAN_MCR_RFEN(((!pInitCfg->bEnFd) && pInitCfg->bEnRxFifo) ? 1U : 0U) | /* Legacy RX FIFO, only when canfd not enable */ + FLEXCAN_MCR_HALT(1) | /* not halt */ + FLEXCAN_MCR_SOFTRST(0) | /* not reset */ + FLEXCAN_MCR_SUPV(1) | /* supervisor mode */ + FLEXCAN_MCR_WRNEN(0) | /* wake up disable */ + FLEXCAN_MCR_SRXDIS(1) | /* self reception disable */ + FLEXCAN_MCR_IRMQ(0) | /* individual Rx masking */ + FLEXCAN_MCR_DMA(pInitCfg->bEnDma) | /* DMA enable */ + FLEXCAN_MCR_PNET_EN(0) | /* Pretended Networking Enable */ + FLEXCAN_MCR_LPRIOEN(0) | /* Local Priority disable */ + FLEXCAN_MCR_AEN(0) | /* abort disable */ + FLEXCAN_MCR_FDEN(pInitCfg->bEnFd) | /* CAN FD enable */ + FLEXCAN_MCR_IDAM(0) | /* ID Acceptance Mode for Rx FIFO, format A */ + FLEXCAN_MCR_MAXMB(0); /* Max number of Message Buffer, num 31 is the 32th MB */ + + FLEXCAN_HWA_SetMCR(pCan, u32TempMcr); /* Negate FlexCAN 1 halt state for 32 MBs */ + + /* store setting value */ + s_aFlexCan_Setting_Table[u8CanIndex].bEnableFd = pInitCfg->bEnFd; + s_aFlexCan_Setting_Table[u8CanIndex].bEnableFifo = pInitCfg->bEnRxFifo; + s_aFlexCan_Setting_Table[u8CanIndex].bEnableDMA = pInitCfg->bEnDma; + s_aFlexCan_Setting_Table[u8CanIndex].eMbDataWidth = pInitCfg->eMbDataWidth; + s_aFlexCan_Setting_Table[u8CanIndex].u8EnhancedFifoDmaWM = pInitCfg->u8EnhancedFifoDmaWM; + } + } + #if FLEXCAN_CHECK_PARAMETERS == STD_ON + } + #endif + + return tRetVal; + +} + + +/** + * @brief De-initial can instance + * + * @param u8CanIndex Can Index, must less than FLEXCAN_INSTANCE_COUNT + * @return 0 is ok, others are not ok + */ +FLEXCAN_ErrorType FLEXCAN_DeInit(uint8_t u8CanIndex) +{ + FLEXCAN_ErrorType tRetVal; + uint32_t u32TempMcr; + FLEXCAN_Type *pCan; + + #if FLEXCAN_CHECK_PARAMETERS == STD_ON + /* check parameter */ + tRetVal = FLEXCAN_LL_CheckInstance(u8CanIndex); + + if (tRetVal == FLEXCAN_ERROR_OK) + { + tRetVal = FLEXCAN_ERROR_OK; + } + else + { + tRetVal |= FLEXCAN_ERROR_INVALID_SEQUENCE; + } + + if (tRetVal == FLEXCAN_ERROR_OK) + { + #else + tRetVal = FLEXCAN_ERROR_OK; + #endif + pCan = (FLEXCAN_Type *)s_aFlexCan_InstanceTable[u8CanIndex]; + FLEXCAN_HWA_SetHaltFreeze(pCan); + + /* wait for bitFRZACK=1 on freeze mode entry/exit */ + if (FLEXCAN_HWA_WaitMcrFreezen(pCan, 10000U) != 0U) + { + tRetVal |= FLEXCAN_ERROR_TIMEOUT; + } + else + { + if(u8CanIndex < FLEXCAN_FD_INSTANCE_COUNT) + { + FLEXCAN_HWA_DisableFDFifo(pCan); + } + + + FLEXCAN_HWA_DisableLegacyFifo(pCan); + + u32TempMcr = FLEXCAN_MCR_MDIS(1) | /* enable pCan module */ + FLEXCAN_MCR_FRZ(0) | /* not frozen */ + FLEXCAN_MCR_RFEN(0U) | /* RX FIFO disable */ + FLEXCAN_MCR_HALT(0) | /* not halt */ + FLEXCAN_MCR_SOFTRST(0) | /* not reset */ + FLEXCAN_MCR_SUPV(1) | /* supervisor mode */ + FLEXCAN_MCR_WRNEN(0) | /* wake up disable */ + FLEXCAN_MCR_SRXDIS(1) | /* self reception disable */ + FLEXCAN_MCR_IRMQ(0) | /* individual Rx masking */ + FLEXCAN_MCR_DMA(0) | /* DMA enable */ + FLEXCAN_MCR_PNET_EN(0) | /* Pretended Networking Enable */ + FLEXCAN_MCR_LPRIOEN(0) | /* Local Priority disable */ + FLEXCAN_MCR_AEN(0) | /* abort disable */ + FLEXCAN_MCR_FDEN(0) | /* CAN FD enable */ + FLEXCAN_MCR_IDAM(0) | /* ID Acceptance Mode for Rx FIFO, format A */ + FLEXCAN_MCR_MAXMB(0); /* Max number of Message Buffer, num 31 is the 32th MB */ + + + FLEXCAN_HWA_SetCtrl1(pCan, 0U); + FLEXCAN_HWA_SetMCR(pCan, u32TempMcr); /* Negate FlexCAN 1 halt state for 32 MBs */ + + /* clear setting value */ + FLEXCAN_InitMemory(u8CanIndex); + } + + #if FLEXCAN_CHECK_PARAMETERS == STD_ON + } + #endif + + return tRetVal; +} + + +/** + * @brief Configure can receive message box and id filter + * + * @param u8CanIndex Can Index, must less than FLEXCAN_INSTANCE_COUNT + * @param pRxMbCfg contains CAN Instance, Rx CAN ID and Mask + * @return 0 is ok + */ +FLEXCAN_ErrorType FLEXCAN_RxFilterConfig(uint8_t u8CanIndex, const FLEXCAN_MBConfigType *const pRxMbCfg) +{ + FLEXCAN_ErrorType tRetVal; + FLEXCAN_Type *pCan; + FLEXCAN_RxMbFilterType *pCurRxCfg; + uint32_t u32Mask; + uint8_t u8Index; + FLEXCAN_SettingType *pCurSetting; + uint8_t bIndividualMask; + uint32_t u32TempAddr; + + #if FLEXCAN_CHECK_PARAMETERS == STD_ON + /* check parameter */ + tRetVal = FLEXCAN_LL_CheckInstance(u8CanIndex); + + if ((tRetVal == FLEXCAN_ERROR_OK) && (s_aCurrentSequence[u8CanIndex] == FLEXCAN_SEQUENCE_NOTSTART)) + { + tRetVal = FLEXCAN_ERROR_OK; + } + else + { + tRetVal |= FLEXCAN_ERROR_INVALID_SEQUENCE; + } + + if (pRxMbCfg == NULL) + { + tRetVal |= FLEXCAN_ERROR_INVALID_PARAM; + } + else + { + /* check buffer point if it is null */ + if ((pRxMbCfg->pRxBuf == NULL) || (((pRxMbCfg->u8RxFilterFifoCnt > 0U) && (pRxMbCfg->pRxFilterFifoList == NULL)))) + { + tRetVal |= FLEXCAN_ERROR_INVALID_PARAM; + } + } + + if (tRetVal == FLEXCAN_ERROR_OK) + { + #else + tRetVal = FLEXCAN_ERROR_OK; + #endif + bIndividualMask = 1U; + + /* current pCan instance */ + pCan = (FLEXCAN_Type *)s_aFlexCan_InstanceTable[u8CanIndex]; + + /* current pCan message pMb cnt */ + pCurSetting = &s_aFlexCan_Setting_Table[u8CanIndex]; + + + pCurSetting->pRxBuf = pRxMbCfg->pRxBuf; + + pCurSetting->u8RxMbStart1 = 0U; /* receive message buffer always start from 0 */ + pCurSetting->u8TxMbStart1 = 0U; + pCurSetting->u8RxMbCnt1 = pRxMbCfg->u8RxFilterMBCnt; + pCurSetting->u8TxMbCnt1 = pRxMbCfg->u8TxMsgCnt; + pCurSetting->u8RxFifoCnt = pRxMbCfg->u8RxFilterFifoCnt; + + if (pCurSetting->bEnableFifo) + { + /* only non-fd fifo need rx filter between rx and tx message buffer */ + if (pCurSetting->bEnableFd) + { +#if 0 + /* must multiple of 2 */ + if (pRxMbCfg->u8RxFilterFifoCnt % 2U) + { + tRetVal |= FLEXCAN_ERROR_INVALID_PARAM; + } +#endif + + /* set fifo filter parameter */ + tRetVal = (FLEXCAN_ErrorType)(tRetVal | FLEXCAN_LL_SetEnhancedFifo(u8CanIndex, pRxMbCfg->pRxFilterFifoList, (uint32_t)pRxMbCfg->u8RxFilterFifoCnt, + pCurSetting->u8EnhancedFifoDmaWM)); + } + else + { + /* insert rx filter before tx message buffer, every group filter contains 8 elements(2MBs), at least 2 groups */ + if (pRxMbCfg->u8RxFilterFifoCnt <= 8U) + { + pCurSetting->u8RxMbStart1 = 8U; + } + else + { + pCurSetting->u8RxMbStart1 = (uint8_t)(6U + 2U * (pRxMbCfg->u8RxFilterFifoCnt / 8U + (pRxMbCfg->u8RxFilterFifoCnt % 8U > 0U ? 1U : 0U))); + + } + pCurSetting->u8TxMbStart1 = (uint8_t)(pCurSetting->u8RxMbStart1 + pCurSetting->u8RxMbCnt1); + + + /* set fifo filter parameter */ + tRetVal |= FLEXCAN_LL_SetLegacyFifo(u8CanIndex, pRxMbCfg->pRxFilterFifoList, (uint32_t)pRxMbCfg->u8RxFilterFifoCnt); + } + + + } + else + { + if (pCurSetting->bEnableFd) + { + + /* clear enhanced fifo */ + FLEXCAN_HWA_DisableFDFifo(pCan); + } + else + { + /* clear legacy fifo */ + FLEXCAN_HWA_DisableLegacyFifo(pCan); + } + } + + + /* For normal message buffer. */ + + /* fifo can exist with normal mb */ + /* Receive MB first set */ + + for (u8Index = 0U; u8Index < pCurSetting->u8RxMbCnt1; u8Index++) + { + uint8_t u8MBIndex; + /* ############## current rx pMb #################### */ + u8MBIndex = (uint8_t)(pCurSetting->u8RxMbStart1 + u8Index); + pCurSetting->u8TxMbStart1 ++; + /* current rx filter */ + pCurRxCfg = &(pRxMbCfg->pRxFilterMBList[u8Index]); + /* message buffer 1th word */ + u32TempAddr = (uint32_t)FLEXCAN_MB_WORDN_ADDR(&(pCan->RAM[0U]), u8MBIndex, pCurSetting->eMbDataWidth, 0U); + + FLEXCAN_MB_IDE_SET(u32TempAddr, pCurRxCfg->eRxFrameType); + + /* message buffer 2th word */ + u32TempAddr = (uint32_t)FLEXCAN_MB_WORDN_ADDR(&(pCan->RAM[0U]), u8MBIndex, pCurSetting->eMbDataWidth, 4U); + + /* 1. set filter id */ + if (pCurRxCfg->eRxFrameType == FLEXCAN_ID_STD) + { + FLEXCAN_MB_STDID_SET(u32TempAddr, pCurRxCfg->u32RxCanId); + + u32Mask = pCurRxCfg->u32RxCanIdMask << 18U; /* stardard id left shift 18 bits */ + } + else /* extended id filter */ + { + FLEXCAN_MB_EXTID_SET(u32TempAddr, pCurRxCfg->u32RxCanId); + u32Mask = pCurRxCfg->u32RxCanIdMask; /* stardard id */ + } + + /* message buffer 1th word */ + u32TempAddr = (uint32_t)FLEXCAN_MB_WORDN_ADDR(&(pCan->RAM[0U]), u8MBIndex, pCurSetting->eMbDataWidth, 0U); + /* set code 0x04U to enable rx */ + FLEXCAN_MB_CODE_SET(u32TempAddr, 4U); + + /* 3. set rx filter u32Mask */ + if (bIndividualMask) + { + /* In FRZ mode, init CAN1 16 msg buf filters */ + FLEXCAN_HWA_SetIndividualMask(pCan, (uint32_t)u8MBIndex, u32Mask); + } + else + { + /* global u32Mask */ + /* Global acceptance u32Mask: check all ID bits */ + if (u8MBIndex == 14U) + { + FLEXCAN_HWA_SetRx14Mask(pCan, u32Mask); + } + else if (u8MBIndex == 15U) + { + FLEXCAN_HWA_SetRx15Mask(pCan, u32Mask); + } + else + { + FLEXCAN_HWA_SetGlobalMask(pCan, u32Mask); + } + } + + + } + u8Index = (uint8_t)(pCurSetting->u8TxMbStart1 + pCurSetting->u8TxMbCnt1 - (uint8_t)0x1U); + + /* set max pMb number */ + FLEXCAN_HWA_AttachMCR(pCan, FLEXCAN_MCR_MAXMB(u8Index) /* Maximum pMb index */ + | FLEXCAN_MCR_IRMQ(bIndividualMask)); /* individual Rx masking */ + + #if FLEXCAN_CHECK_PARAMETERS == STD_ON + } + #endif + + return tRetVal; +} + + +/** + * @brief Configure can interrupt + * + * @param u8CanIndex Can Index, must less than FLEXCAN_INSTANCE_COUNT + * @param pIntCfg Contians interrupt enable and call back function points + * @return 0 is ok + */ +FLEXCAN_ErrorType FLEXCAN_SetInterrupt(uint8_t u8CanIndex, const FLEXCAN_InterruptType *const pIntCfg) +{ + FLEXCAN_ErrorType tRetVal; + FLEXCAN_Type *pCan; + uint32_t u32Mask; + uint8_t u8Index; + FLEXCAN_SettingType *pCurSetting; + + #if FLEXCAN_CHECK_PARAMETERS == STD_ON + /* check parameter */ + tRetVal = FLEXCAN_LL_CheckInstance(u8CanIndex); + + if ((tRetVal == FLEXCAN_ERROR_OK) && (s_aCurrentSequence[u8CanIndex] == FLEXCAN_SEQUENCE_NOTSTART)) + { + tRetVal = FLEXCAN_ERROR_OK; + } + else + { + tRetVal |= FLEXCAN_ERROR_INVALID_SEQUENCE; + } + + if (pIntCfg == NULL) + { + tRetVal |= FLEXCAN_ERROR_INVALID_PARAM; + } + else + { + /* check buffer point if it is null */ + if (((pIntCfg->bEnRxFifoInterrupt == 1U) && (pIntCfg->pRxFifoNotify == NULL)) + || ((pIntCfg->bEnRxMBInterrupt == 1U) && (pIntCfg->pRxMBNotify == NULL)) + || ((pIntCfg->bEnErrorInterrupt == 1U) && (pIntCfg->pErrorNotify == NULL))) + { + tRetVal |= FLEXCAN_ERROR_INVALID_PARAM; + } + } + + if (tRetVal == FLEXCAN_ERROR_OK) + { + #else + tRetVal = FLEXCAN_ERROR_OK; + #endif + pCan = (FLEXCAN_Type *)s_aFlexCan_InstanceTable[u8CanIndex]; + + pCurSetting = &s_aFlexCan_Setting_Table[u8CanIndex]; + + if ((pIntCfg->bEnErrorInterrupt) || (pIntCfg->bEnRxFifoInterrupt) || (pIntCfg->bEnRxMBInterrupt)) + { + } + + + if (pIntCfg->bEnErrorInterrupt) + { + FLEXCAN_HWA_AttachCtrl1(pCan, FLEXCAN_CTRL1_ERRMSK(1U) | /* error interrupt u32Mask */ + FLEXCAN_CTRL1_BOFFMSK(1U)); /* busoff interrupt u32Mask */ + + + FLEXCAN_HWA_AttachCtrl2(pCan, FLEXCAN_CTRL2_ERRMSK_FAST(1U) /* fast error */); + + s_aFlexCan_ErrorNotifyTable[u8CanIndex] = pIntCfg->pErrorNotify; + } + + if (pIntCfg->bEnRxFifoInterrupt) + { + /* interrupt for fifo */ + if (pCurSetting->bEnableFifo) + { + /* can fd fifo interrupt */ + if (pCurSetting->bEnableFd) + { + /* enhanced fifo data available interrupt */ + FLEXCAN_HWA_SetERFIERDataInterrupt(pCan); + } + else /* non-fd fifo interrupt */ + { + /* MB 5 at least one message in fifo interrupt */ + FLEXCAN_HWA_SetMaskFifoInterrupt(pCan); + } + s_aFlexCan_RxFifoNotifyTable[u8CanIndex] = pIntCfg->pRxFifoNotify; + } + } + if (pIntCfg->bEnTxMBInterrupt) + { + u32Mask = 0U; + + for (u8Index = 0U; u8Index < pCurSetting->u8TxMbCnt1; u8Index++) + { + u32Mask = (u32Mask << 1U) | (1U << pCurSetting->u8TxMbStart1); + } + + /* MB 31-0 u32Mask */ + FLEXCAN_HWA_AttachMaskMbInterrupt(pCan, u32Mask); + + s_aFlexCan_TxNotifyTable[u8CanIndex] = pIntCfg->pTxMBNotify; + } + + if (pIntCfg->bEnRxMBInterrupt) + { + u32Mask = 0U; + + for (u8Index = 0U; u8Index < pCurSetting->u8RxMbCnt1; u8Index++) + { + u32Mask = (u32Mask << 1U) | (1U << pCurSetting->u8RxMbStart1); + } + + /* MB 31-0 u32Mask */ + FLEXCAN_HWA_AttachMaskMbInterrupt(pCan, u32Mask); + + s_aFlexCan_RxNotifyTable[u8CanIndex] = pIntCfg->pRxMBNotify; + } + s_aFlexCan_Setting_Table[u8CanIndex].bEnableFifoInt = pIntCfg->bEnRxFifoInterrupt; + s_aFlexCan_Setting_Table[u8CanIndex].bEnableTxMBInt = pIntCfg->bEnTxMBInterrupt; + s_aFlexCan_Setting_Table[u8CanIndex].bEnableRxMBInt = pIntCfg->bEnRxMBInterrupt; + s_aFlexCan_Setting_Table[u8CanIndex].bEnableErrInt = pIntCfg->bEnRxMBInterrupt; + #if FLEXCAN_CHECK_PARAMETERS == STD_ON + } + #endif + + return tRetVal; +} + + +/** + * @brief Start can instance + * + * @param u8CanIndex Can Index, must less than FLEXCAN_INSTANCE_COUNT + * @return 0 is ok + */ +FLEXCAN_ErrorType FLEXCAN_Start(uint8_t u8CanIndex) +{ + FLEXCAN_ErrorType tRetVal; + uint32_t u32TempMcr; + FLEXCAN_Type *pCan; + + #if FLEXCAN_CHECK_PARAMETERS == STD_ON + /* check parameter */ + tRetVal = FLEXCAN_LL_CheckInstance(u8CanIndex); + + if ((tRetVal == FLEXCAN_ERROR_OK) && (s_aCurrentSequence[u8CanIndex] == FLEXCAN_SEQUENCE_NOTSTART)) + { + tRetVal = FLEXCAN_ERROR_OK; + } + else + { + tRetVal |= FLEXCAN_ERROR_INVALID_SEQUENCE; + } + + + if (tRetVal == FLEXCAN_ERROR_OK) + { + #else + tRetVal = FLEXCAN_ERROR_OK; + #endif + /* set started state */ + s_aCurrentSequence[u8CanIndex] = FLEXCAN_SEQUENCE_STARTED; + + pCan = (FLEXCAN_Type *)s_aFlexCan_InstanceTable[u8CanIndex]; + + u32TempMcr = FLEXCAN_HWA_GetMCR(pCan); + + u32TempMcr &= ~(FLEXCAN_MCR_FRZ(1U) | /* not frozen */ + FLEXCAN_MCR_HALT(1U) /* not halt */ + /*| FLEXCAN_MCR_SUPV(1) user mode */ + ); /* not reset */ + + FLEXCAN_HWA_SetMCR(pCan, u32TempMcr); + + if (FLEXCAN_HWA_WaitMcrExitFreezen(pCan, 10000U) != 0U) + { + tRetVal |= FLEXCAN_ERROR_TIMEOUT; + } + else + { + + if (FLEXCAN_HWA_WaitMcrReady(pCan, 10000U) != 0U) + { + tRetVal |= FLEXCAN_ERROR_TIMEOUT; + } + else + { + + s_aFlexCan_CanUsed[u8CanIndex] = 1U; + } + } + #if FLEXCAN_CHECK_PARAMETERS == STD_ON + } + #endif + + return tRetVal; +} + + +/** + * @brief Stop can instance + * + * @param u8CanIndex Can Index, must less than FLEXCAN_INSTANCE_COUNT + */ +FLEXCAN_ErrorType FLEXCAN_Stop(uint8_t u8CanIndex) +{ + FLEXCAN_ErrorType tRetVal; + uint32_t u32TempMcr; + FLEXCAN_Type *pCan; + + #if FLEXCAN_CHECK_PARAMETERS == STD_ON + /* check parameter */ + tRetVal = FLEXCAN_LL_CheckInstance(u8CanIndex); + + if ((tRetVal == FLEXCAN_ERROR_OK) && (s_aCurrentSequence[u8CanIndex] >= FLEXCAN_SEQUENCE_DEINIT)) + { + tRetVal = FLEXCAN_ERROR_OK; + } + else + { + tRetVal |= FLEXCAN_ERROR_INVALID_SEQUENCE; + } + + + if (tRetVal == FLEXCAN_ERROR_OK) + { + #else + tRetVal = FLEXCAN_ERROR_OK; + #endif + /* set started state */ + s_aCurrentSequence[u8CanIndex] = FLEXCAN_SEQUENCE_NOTSTART; + + pCan = (FLEXCAN_Type *)s_aFlexCan_InstanceTable[u8CanIndex]; + + u32TempMcr = FLEXCAN_HWA_GetMCR(pCan); + + u32TempMcr |= FLEXCAN_MCR_FRZ(1U) | /* not frozen */ + FLEXCAN_MCR_HALT(1U) /* not halt */ + /*| FLEXCAN_MCR_SUPV(1) user mode */ + ; /* not reset */ + + FLEXCAN_HWA_SetMCR(pCan, u32TempMcr); + + /* must wait */ + if (FLEXCAN_HWA_WaitMcrFreezen(pCan, 10000U) != 0U) + { + tRetVal |= FLEXCAN_ERROR_TIMEOUT; + } + else + { + + /* must wait */ + if (FLEXCAN_HWA_WaitMcrNoReady(pCan, 10000U) != 0U) + { + tRetVal |= FLEXCAN_ERROR_TIMEOUT; + } + else + { + s_aFlexCan_CanUsed[u8CanIndex] = 0U; + } + } + #if FLEXCAN_CHECK_PARAMETERS == STD_ON + } + + #endif + + return tRetVal; +} + + +/** + * @brief Transmit data, if tx disable, must call FLEXCAN_TransmitProcess after transmiting + * + * @param u8CanIndex Can Index, must less than FLEXCAN_INSTANCE_COUNT + * @param pTxMsg contains CAN instance, CAN ID, CAN FD and CAN data. + * @return 0 is ok + */ +FLEXCAN_ErrorType FLEXCAN_TransmitData(uint8_t u8CanIndex, const FLEXCAN_TxMsgType *const pTxMsg) +{ + FLEXCAN_ErrorType tRetVal; + uint32_t *pSrc; + uint32_t *pDest; + uint32_t u32Index; + FLEXCAN_Type *pCan; + FLEXCAN_SettingType *pCurSetting; + uint8_t u8TxRealMbIndex; + uint32_t u32WordLen; + uint32_t u32TempAddr; + uint32_t u32Code; + + #if FLEXCAN_CHECK_PARAMETERS == STD_ON + /* check parameter */ + tRetVal = FLEXCAN_LL_CheckInstance(u8CanIndex); + + if ((tRetVal == FLEXCAN_ERROR_OK) && (s_aCurrentSequence[u8CanIndex] == FLEXCAN_SEQUENCE_STARTED)) + { + tRetVal = FLEXCAN_ERROR_OK; + } + else + { + tRetVal |= FLEXCAN_ERROR_INVALID_SEQUENCE; + } + + if (pTxMsg == NULL) + { + tRetVal |= FLEXCAN_ERROR_INVALID_PARAM; + } + else + { + /* check buffer point if it is null */ + if (&(pTxMsg->aData) == NULL) + { + tRetVal |= FLEXCAN_ERROR_INVALID_PARAM; + } + else + { + if (pTxMsg->u32DataLen > (uint32_t)s_aFlexCan_Setting_Table[u8CanIndex].eMbDataWidth) + { + tRetVal |= FLEXCAN_ERROR_INVALID_PARAM; + } + } + } + + if ((pTxMsg->bEnFd == 1U) && (u8CanIndex >= FLEXCAN_FD_INSTANCE_COUNT)) + { + tRetVal |= FLEXCAN_ERROR_INVALID_PARAM; + } + + + if (tRetVal == FLEXCAN_ERROR_OK) + { + #endif + + pCan = (FLEXCAN_Type *)s_aFlexCan_InstanceTable[u8CanIndex]; + + pCurSetting = &s_aFlexCan_Setting_Table[u8CanIndex]; + if (pTxMsg->u8TxHandler >= pCurSetting->u8TxMbCnt1) + { + tRetVal = FLEXCAN_ERROR_INVALID_PARAM; + } + else + { + u8TxRealMbIndex = (uint8_t)(pTxMsg->u8TxHandler + pCurSetting->u8TxMbStart1); + + /* message buffer 1th word */ + u32TempAddr = (uint32_t)FLEXCAN_MB_WORDN_ADDR(&(pCan->RAM[0U]), u8TxRealMbIndex, pCurSetting->eMbDataWidth, 0U); + u32Code = FLEXCAN_MB_CODE_GET(u32TempAddr); + if((0x8 != u32Code) && (0U != u32Code)) + { + tRetVal = FLEXCAN_ERROR_BUSY; + } + else + { + + /* message buffer 1th word */ + u32TempAddr = (uint32_t)FLEXCAN_MB_WORDN_ADDR(&(pCan->RAM[0U]), u8TxRealMbIndex, pCurSetting->eMbDataWidth, 0U); + /* clear last value */ + FLEXCAN_REG32_CONTENT(u32TempAddr) = 0U; + + FLEXCAN_MB_EDL_SET(u32TempAddr, pTxMsg->bEnFd); + FLEXCAN_MB_BRS_SET(u32TempAddr, pTxMsg->bEnBrs); + + FLEXCAN_MB_IDE_SET(u32TempAddr, pTxMsg->eFrameType); + + /* SRR */ + FLEXCAN_MB_SRR_SET(u32TempAddr, 0U); + /* DLC */ + u32Index = FLEXCAN_DataLenToDlc(pTxMsg->u32DataLen); + FLEXCAN_MB_DLC_SET(u32TempAddr, u32Index); + + /* message buffer 2th word */ + u32TempAddr = (uint32_t)FLEXCAN_MB_WORDN_ADDR(&(pCan->RAM[0U]), u8TxRealMbIndex, pCurSetting->eMbDataWidth, 4U); + /* clear last value */ + FLEXCAN_REG32_CONTENT(u32TempAddr) = 0U; + + /* standard id */ + if (pTxMsg->eFrameType == FLEXCAN_ID_STD) + { + FLEXCAN_MB_STDID_SET(u32TempAddr, pTxMsg->u32CanId); + } + else /* extended id */ + { + FLEXCAN_MB_EXTID_SET(u32TempAddr, pTxMsg->u32CanId); + } + + FLEXCAN_MB_PRIO_SET(u32TempAddr, 0U); + + pSrc = (uint32_t *)(uint32_t)(&(pTxMsg->aData[0])); + /* message buffer 3th word */ + pDest = (uint32_t *)FLEXCAN_MB_WORDN_ADDR(&(pCan->RAM[0U]), u8TxRealMbIndex, pCurSetting->eMbDataWidth, 8U); + + u32WordLen = pTxMsg->u32DataLen / 4U + (pTxMsg->u32DataLen % 4U > 0U ? 1U : 0U); + + /* revert data to little endian */ + for (u32Index = 0U; u32Index < u32WordLen; u32Index++) + { + /* big endian to little endian */ + REV_BYTES_32(pSrc[u32Index], pDest[u32Index]); + } + + + /* message buffer 1th word */ + u32TempAddr = (uint32_t)FLEXCAN_MB_WORDN_ADDR(&(pCan->RAM[0U]), u8TxRealMbIndex, pCurSetting->eMbDataWidth, 0U); + + + /* CODE set 0x0C to transmit */ + FLEXCAN_MB_CODE_SET(u32TempAddr, 0x0CU); + + + if (pTxMsg->bWaitTxCompleted) + { + u32TempAddr = 0U; + u32WordLen = FLEXCAN_HWA_GetFlag1NoFifoFlag(pCan, u8TxRealMbIndex); + while ((u32WordLen == 0U) && (u32TempAddr++ < pTxMsg->u16WaitTxTimeout)) + { + u32WordLen = FLEXCAN_HWA_GetFlag1NoFifoFlag(pCan, u8TxRealMbIndex); + } + + if (u32WordLen == 0U) + { + tRetVal = FLEXCAN_ERROR_TIMEOUT; + } + + } + else + { + u32WordLen = FLEXCAN_HWA_GetFlag1NoFifoFlag(pCan, u8TxRealMbIndex); + if (u32WordLen == 0U) + { + tRetVal = FLEXCAN_ERROR_TIMEOUT; + } + } + + } + } + #if FLEXCAN_CHECK_PARAMETERS == STD_ON + } + #endif + + return tRetVal; +} + + +/** + * @brief Process flag after transmit + * + * @param u8CanIndex Can Index, must less than FLEXCAN_INSTANCE_COUNT + * @param u8Handler Transmit Handler + * @return 1 means process successfully and can transmit next time, 0 means no active flag, 0xff means out of range + */ +uint8_t FLEXCAN_TransmitProcess(uint8_t u8CanIndex, uint8_t u8TxHandler) +{ + #if FLEXCAN_CHECK_PARAMETERS == STD_ON + FLEXCAN_ErrorType tRetVal; + /* check parameter */ + tRetVal = FLEXCAN_LL_CheckInstance(u8CanIndex); + if (tRetVal == FLEXCAN_ERROR_OK) + { + #endif + return FLEXCAN_LL_ProcessTx(u8CanIndex, u8TxHandler); + #if FLEXCAN_CHECK_PARAMETERS == STD_ON + } + else + { + return 0U; + } + #endif +} + + +/** + * @brief Abort transmit with special transmit handler + * + * @param u8CanIndex Can Index, must less than FLEXCAN_INSTANCE_COUNT + * @param u8TxHandler Transmit handler + * @return 0 is ok + */ +FLEXCAN_ErrorType FLEXCAN_TransmitAbort(uint8_t u8CanIndex, uint8_t u8TxHandler) +{ + FLEXCAN_ErrorType tRetVal; + FLEXCAN_SettingType *pCurSetting; + FLEXCAN_Type *pCan; + uint8_t u8TxRealMbIndex; + uint32_t u32TempAddr; + + #if FLEXCAN_CHECK_PARAMETERS == STD_ON + /* check parameter */ + tRetVal = FLEXCAN_LL_CheckInstance(u8CanIndex); + + if ((tRetVal == FLEXCAN_ERROR_OK) && (s_aCurrentSequence[u8CanIndex] == FLEXCAN_SEQUENCE_STARTED)) + { + tRetVal = FLEXCAN_ERROR_OK; + } + else + { + tRetVal |= FLEXCAN_ERROR_INVALID_SEQUENCE; + } + + + if (tRetVal == FLEXCAN_ERROR_OK) + { + + #endif + + pCan = (FLEXCAN_Type *)s_aFlexCan_InstanceTable[u8CanIndex]; + + pCurSetting = &s_aFlexCan_Setting_Table[u8CanIndex]; + if (u8TxHandler >= pCurSetting->u8TxMbCnt1) + { + tRetVal = FLEXCAN_ERROR_INVALID_PARAM; + } + + else + { + u8TxRealMbIndex = (uint8_t)(u8TxHandler + pCurSetting->u8TxMbStart1); + /* message buffer 1th word */ + u32TempAddr = (uint32_t)FLEXCAN_MB_WORDN_ADDR(&(pCan->RAM[0U]), u8TxRealMbIndex, pCurSetting->eMbDataWidth, 0U); + + + /* CODE set 0x09 to aborting transmit */ + FLEXCAN_MB_CODE_SET(u32TempAddr, 0x09U); + } + #if FLEXCAN_CHECK_PARAMETERS == STD_ON + } + #endif + + return tRetVal; +} + + +/** + * @brief Receive data when polling (not used when rx interrupt enabled) + * + * @param u8CanIndex Can Index, must less than FLEXCAN_INSTANCE_COUNT + * @param pRxBufList is FLEXCAN_RxMsgType type point point, and don't need to be initialed + * @return 0 is ok + */ +FLEXCAN_ErrorType FLEXCAN_Receive_Polling(uint8_t u8CanIndex, FLEXCAN_RxMsgListType *const pRxBufList) +{ + FLEXCAN_ErrorType tRetVal; + uint8_t u8RetVal; + + #if FLEXCAN_CHECK_PARAMETERS == STD_ON + /* check parameter */ + tRetVal = FLEXCAN_LL_CheckInstance(u8CanIndex); + + if ((tRetVal == FLEXCAN_ERROR_OK) && (s_aCurrentSequence[u8CanIndex] == FLEXCAN_SEQUENCE_STARTED)) + { + tRetVal = FLEXCAN_ERROR_OK; + } + else + { + tRetVal |= FLEXCAN_ERROR_INVALID_SEQUENCE; + } + + if (pRxBufList == NULL) + { + tRetVal |= FLEXCAN_ERROR_INVALID_PARAM; + } + + + if (tRetVal == FLEXCAN_ERROR_OK) + { + + #else + tRetVal = FLEXCAN_ERROR_OK; + #endif + u8RetVal = 0U; + + pRxBufList->u8RxMsgCnt = 0U; + pRxBufList->pRxMsgBuf = s_aFlexCan_Setting_Table[u8CanIndex].pRxBuf; + + + if (s_aFlexCan_CanUsed[u8CanIndex] == 1U) + { + /* receive from fifo or normal */ + if (s_aFlexCan_Setting_Table[u8CanIndex].bEnableFifo) + { + u8RetVal = FLEXCAN_LL_ReceiveFifo(u8CanIndex, s_aFlexCan_Setting_Table[u8CanIndex].bEnableFd, pRxBufList->pRxMsgBuf); + } + else + { + u8RetVal = FLEXCAN_LL_PollingMb(u8CanIndex, pRxBufList->pRxMsgBuf); + } + pRxBufList->u8RxMsgCnt = u8RetVal; + } + #if FLEXCAN_CHECK_PARAMETERS == STD_ON + } + #endif + + return tRetVal; +} + + + +/** + * @brief Get can error + * + * @param u8CanIndex Can Index, must less than FLEXCAN_INSTANCE_COUNT + * @param pErrorInfo is error information + * @return 0 is no error, others contains error + */ +FLEXCAN_ErrorType FLEXCAN_GetErrorInfo(uint8_t u8CanIndex, FLEXCAN_ErrorInfoType *const pErrorInfo) +{ + FLEXCAN_ErrorType tRetVal; + uint32_t u32ESR1Status, u32ECRStatus; + FLEXCAN_Type *pCan; + + #if FLEXCAN_CHECK_PARAMETERS == STD_ON + /* check parameter */ + tRetVal = FLEXCAN_LL_CheckInstance(u8CanIndex); + + if ((tRetVal == FLEXCAN_ERROR_OK) && (s_aCurrentSequence[u8CanIndex] >= FLEXCAN_SEQUENCE_NOTSTART)) + { + tRetVal = FLEXCAN_ERROR_OK; + } + else + { + tRetVal |= FLEXCAN_ERROR_INVALID_SEQUENCE; + } + + + if (tRetVal == FLEXCAN_ERROR_OK) + { + + #else + tRetVal = FLEXCAN_ERROR_OK; + #endif + pCan = (FLEXCAN_Type *)s_aFlexCan_InstanceTable[u8CanIndex]; + + u32ESR1Status = FLEXCAN_HWA_GetErrorInfo(pCan); + pErrorInfo->u32ErrorValue = u32ESR1Status; + + u32ECRStatus = FLEXCAN_HWA_GetErrorCount(pCan); + pErrorInfo->u32ErrorValue &= FLEXCAN_ESR1_BIT1ERR_FAST_MASK | FLEXCAN_ESR1_BIT0ERR_FAST_MASK | FLEXCAN_ESR1_CRCERR_FAST_MASK | FLEXCAN_ESR1_FRMERR_FAST_MASK | + FLEXCAN_ESR1_STFERR_FAST_MASK | + FLEXCAN_ESR1_ERROVR_MASK | FLEXCAN_ESR1_ERRINT_FAST_MASK | FLEXCAN_ESR1_BOFFDONEINT_MASK | FLEXCAN_ESR1_TWRNINT_MASK | FLEXCAN_ESR1_RWRNINT_MASK | + FLEXCAN_ESR1_BIT1ERR_MASK | FLEXCAN_ESR1_BIT0ERR_MASK | FLEXCAN_ESR1_ACKERR_MASK | FLEXCAN_ESR1_CRCERR_MASK | FLEXCAN_ESR1_FRMERR_MASK | FLEXCAN_ESR1_STFERR_MASK | + FLEXCAN_ESR1_TXWRN_MASK | FLEXCAN_ESR1_RXWRN_MASK | FLEXCAN_ESR1_FLTCONF_MASK | FLEXCAN_ESR1_BOFFINT_MASK | FLEXCAN_ESR1_ERRINT_MASK; + + if(pErrorInfo->u32ErrorValue & FLEXCAN_ESR1_BIT1ERR_FAST_MASK) + pErrorInfo->tErrorDetail.u8Error_FLEXCAN_ESR1_BIT1ERR_FAST = 1U; + else + pErrorInfo->tErrorDetail.u8Error_FLEXCAN_ESR1_BIT1ERR_FAST = 0U; + + if(pErrorInfo->u32ErrorValue & FLEXCAN_ESR1_BIT0ERR_FAST_MASK) + pErrorInfo->tErrorDetail.u8Error_FLEXCAN_ESR1_BIT0ERR_FAST = 1U; + else + pErrorInfo->tErrorDetail.u8Error_FLEXCAN_ESR1_BIT0ERR_FAST = 0U; + + if(pErrorInfo->u32ErrorValue & FLEXCAN_ESR1_CRCERR_FAST_MASK) + pErrorInfo->tErrorDetail.u8Error_FLEXCAN_ESR1_CRCERR_FAST = 1U; + else + pErrorInfo->tErrorDetail.u8Error_FLEXCAN_ESR1_CRCERR_FAST = 0U; + + if(pErrorInfo->u32ErrorValue & FLEXCAN_ESR1_FRMERR_FAST_MASK) + pErrorInfo->tErrorDetail.u8Error_FLEXCAN_ESR1_FRMERR_FAST = 1U; + else + pErrorInfo->tErrorDetail.u8Error_FLEXCAN_ESR1_FRMERR_FAST = 0U; + + if(pErrorInfo->u32ErrorValue & FLEXCAN_ESR1_STFERR_FAST_MASK) + pErrorInfo->tErrorDetail.u8Error_FLEXCAN_ESR1_STFERR_FAST = 1U; + else + pErrorInfo->tErrorDetail.u8Error_FLEXCAN_ESR1_STFERR_FAST = 0U; + + if(pErrorInfo->u32ErrorValue & FLEXCAN_ESR1_ERROVR_MASK) + pErrorInfo->tErrorDetail.u8Error_FLEXCAN_ESR1_ERROVR = 1U; + else + pErrorInfo->tErrorDetail.u8Error_FLEXCAN_ESR1_ERROVR = 0U; + + if(pErrorInfo->u32ErrorValue & FLEXCAN_ESR1_ERRINT_FAST_MASK) + pErrorInfo->tErrorDetail.u8Error_FLEXCAN_ESR1_ERRINT_FAST = 1U; + else + pErrorInfo->tErrorDetail.u8Error_FLEXCAN_ESR1_ERRINT_FAST = 0U; + + if(pErrorInfo->u32ErrorValue & FLEXCAN_ESR1_BOFFDONEINT_MASK) + pErrorInfo->tErrorDetail.u8Error_FLEXCAN_ESR1_BOFFDONEINT = 1U; + else + pErrorInfo->tErrorDetail.u8Error_FLEXCAN_ESR1_BOFFDONEINT = 0U; + + if(pErrorInfo->u32ErrorValue & FLEXCAN_ESR1_TWRNINT_MASK) + pErrorInfo->tErrorDetail.u8Error_FLEXCAN_ESR1_TWRNINT = 1U; + else + pErrorInfo->tErrorDetail.u8Error_FLEXCAN_ESR1_TWRNINT = 0U; + + if(pErrorInfo->u32ErrorValue & FLEXCAN_ESR1_RWRNINT_MASK) + pErrorInfo->tErrorDetail.u8Error_FLEXCAN_ESR1_RWRNINT = 1U; + else + pErrorInfo->tErrorDetail.u8Error_FLEXCAN_ESR1_RWRNINT = 0U; + + if(pErrorInfo->u32ErrorValue & FLEXCAN_ESR1_BIT1ERR_MASK) + pErrorInfo->tErrorDetail.u8Error_FLEXCAN_ESR1_BIT1ERR = 1U; + else + pErrorInfo->tErrorDetail.u8Error_FLEXCAN_ESR1_BIT1ERR = 0U; + + if(pErrorInfo->u32ErrorValue & FLEXCAN_ESR1_BIT0ERR_MASK) + pErrorInfo->tErrorDetail.u8Error_FLEXCAN_ESR1_BIT0ERR = 1U; + else + pErrorInfo->tErrorDetail.u8Error_FLEXCAN_ESR1_BIT0ERR = 0U; + + if(pErrorInfo->u32ErrorValue & FLEXCAN_ESR1_ACKERR_MASK) + pErrorInfo->tErrorDetail.u8Error_FLEXCAN_ESR1_ACKERR = 1U; + else + pErrorInfo->tErrorDetail.u8Error_FLEXCAN_ESR1_ACKERR = 0U; + + if(pErrorInfo->u32ErrorValue & FLEXCAN_ESR1_CRCERR_MASK) + pErrorInfo->tErrorDetail.u8Error_FLEXCAN_ESR1_CRCERR = 1U; + else + pErrorInfo->tErrorDetail.u8Error_FLEXCAN_ESR1_CRCERR = 0U; + + if(pErrorInfo->u32ErrorValue & FLEXCAN_ESR1_FRMERR_MASK) + pErrorInfo->tErrorDetail.u8Error_FLEXCAN_ESR1_FRMERR = 1U; + else + pErrorInfo->tErrorDetail.u8Error_FLEXCAN_ESR1_FRMERR = 0U; + + if(pErrorInfo->u32ErrorValue & FLEXCAN_ESR1_STFERR_MASK) + pErrorInfo->tErrorDetail.u8Error_FLEXCAN_ESR1_STFERR = 1U; + else + pErrorInfo->tErrorDetail.u8Error_FLEXCAN_ESR1_STFERR = 0U; + + if(pErrorInfo->u32ErrorValue & FLEXCAN_ESR1_TXWRN_MASK) + pErrorInfo->tErrorDetail.u8Error_FLEXCAN_ESR1_TXWRN = 1U; + else + pErrorInfo->tErrorDetail.u8Error_FLEXCAN_ESR1_TXWRN = 0U; + + if(pErrorInfo->u32ErrorValue & FLEXCAN_ESR1_RXWRN_MASK) + pErrorInfo->tErrorDetail.u8Error_FLEXCAN_ESR1_RXWRN = 1U; + else + pErrorInfo->tErrorDetail.u8Error_FLEXCAN_ESR1_RXWRN = 0U; + + if(pErrorInfo->u32ErrorValue & FLEXCAN_ESR1_FLTCONF_MASK) + pErrorInfo->tErrorDetail.u8Error_FLEXCAN_ESR1_FLTCONF = 1U; + else + pErrorInfo->tErrorDetail.u8Error_FLEXCAN_ESR1_FLTCONF = 0U; + + if(pErrorInfo->u32ErrorValue & FLEXCAN_ESR1_BOFFINT_MASK) + pErrorInfo->tErrorDetail.u8Error_FLEXCAN_ESR1_BOFFINT = 1U; + else + pErrorInfo->tErrorDetail.u8Error_FLEXCAN_ESR1_BOFFINT = 0U; + + if(pErrorInfo->u32ErrorValue & FLEXCAN_ESR1_ERRINT_MASK) + pErrorInfo->tErrorDetail.u8Error_FLEXCAN_ESR1_ERRINT = 1U; + else + pErrorInfo->tErrorDetail.u8Error_FLEXCAN_ESR1_ERRINT = 0U; + + pErrorInfo->u32RxErrCnt = (u32ECRStatus & FLEXCAN_ECR_RXERRCNT_MASK) >> FLEXCAN_ECR_RXERRCNT_SHIFT; + pErrorInfo->u32RxErrCnt_Fast = (u32ECRStatus & FLEXCAN_ECR_RXERRCNT_FAST_MASK) >> FLEXCAN_ECR_RXERRCNT_FAST_SHIFT; + pErrorInfo->u32TxErrCnt = (u32ECRStatus & FLEXCAN_ECR_TXERRCNT_MASK) >> FLEXCAN_ECR_TXERRCNT_SHIFT; + pErrorInfo->u32TxErrCnt_Fast = (u32ECRStatus & FLEXCAN_ECR_TXERRCNT_FAST_MASK) >> FLEXCAN_ECR_TXERRCNT_FAST_SHIFT; + + #if FLEXCAN_CHECK_PARAMETERS == STD_ON + } + else + { + PROCESS_UNUSED_VAR(u32ESR1Status); + PROCESS_UNUSED_VAR(u32ECRStatus); + } + #endif + + return tRetVal; +} + +/** + * @brief Clear can error + * + * @param u8CanIndex Can Index, must less than FLEXCAN_INSTANCE_COUNT + * @param pErrorInfo is error information + * @return 0 is no error, others contains error + */ +FLEXCAN_ErrorType FLEXCAN_ClrErrorInfo(uint8_t u8CanIndex, const FLEXCAN_ErrorInfoType *const pErrorInfo) +{ + FLEXCAN_ErrorType tRetVal; + FLEXCAN_Type *pCan; + + #if FLEXCAN_CHECK_PARAMETERS == STD_ON + /* check parameter */ + tRetVal = FLEXCAN_LL_CheckInstance(u8CanIndex); + + if ((tRetVal == FLEXCAN_ERROR_OK) && (s_aCurrentSequence[u8CanIndex] >= FLEXCAN_SEQUENCE_NOTSTART)) + { + tRetVal = FLEXCAN_ERROR_OK; + } + else + { + tRetVal |= FLEXCAN_ERROR_INVALID_SEQUENCE; + } + + + if (tRetVal == FLEXCAN_ERROR_OK) + { + #else + tRetVal = FLEXCAN_ERROR_OK; + #endif + pCan = (FLEXCAN_Type *)s_aFlexCan_InstanceTable[u8CanIndex]; + + FLEXCAN_HWA_ClrErrorInfo(pCan, pErrorInfo->u32ErrorValue); + #if FLEXCAN_CHECK_PARAMETERS == STD_ON + } + #endif + + return tRetVal; +} + + + + +/** + * @brief Transfer Data length to DLC + * + * @param u32DataLen data length + * @return DLC + */ +uint32_t FLEXCAN_DataLenToDlc(uint32_t u32DataLen) +{ + uint32_t u32Dlc; + + switch (u32DataLen) + { + case 0U: + case 1U: + case 2U: + case 3U: + case 4U: + case 5U: + case 6U: + case 7U: + case 8U: + { + u32Dlc = u32DataLen; + } + break; + case 12U: + { + u32Dlc = 9U; + } + break; + case 16U: + { + u32Dlc = 10U; + } + break; + case 20U: + { + u32Dlc = 11U; + } + break; + case 24U: + { + u32Dlc = 12U; + } + break; + case 32U: + { + u32Dlc = 13U; + } + break; + case 48U: + { + u32Dlc = 14U; + } + break; + case 64U: + { + u32Dlc = 15U; + + } + break; + + default: + u32Dlc = 0U; + break; + } + + return u32Dlc; +} + + +/** + * @brief Transfer DLC to Data length + * + * @param u32Dlc DLC Data Length + * @return + */ +uint32_t FLEXCAN_DlcToDataLen(uint32_t u32Dlc) +{ + uint32_t u32DataLen; + + + switch (u32Dlc) + { + case 0U: + case 1U: + case 2U: + case 3U: + case 4U: + case 5U: + case 6U: + case 7U: + case 8U: + { + u32DataLen = u32Dlc; + } + break; + case 9U: + { + u32DataLen = 12U; + } + break; + case 10U: + { + u32DataLen = 16U; + } + break; + case 11U: + { + u32DataLen = 20U; + } + break; + case 12U: + { + u32DataLen = 24U; + } + break; + case 13U: + { + u32DataLen = 32U; + } + break; + case 14U: + { + u32DataLen = 48U; + } + break; + case 15U: + { + u32DataLen = 64U; + } + break; + + default: + u32DataLen = 0U; + break; + } + + return u32DataLen; +} + + +/* ################################################################################## */ +/* ############################## Interrupt Services ################################ */ + +/** + * @brief Can interrupt process + * + * @param u8CanIndex Can Index, Must less than FLEXCAN_INSTANCE_COUNT + */ +void FLEXCAN_IRQHandler(uint8_t u8CanIndex) +{ + uint8_t u8RecNum, u8Index; + uint32_t u32Flag1, u32ERFSR; + FLEXCAN_Type *pCan; + FLEXCAN_RxMsgType *pRxMsgList; + uint8_t u8FifoInterrupt; + FLEXCAN_ErrorType tRetVal; + + FLEXCAN_ErrorInfoType pErrorInfo; + + #if FLEXCAN_CHECK_PARAMETERS == STD_ON + /* check parameter */ + tRetVal = FLEXCAN_LL_CheckInstance(u8CanIndex); + if (tRetVal == FLEXCAN_ERROR_OK) + { + #endif + + pCan = (FLEXCAN_Type *)s_aFlexCan_InstanceTable[u8CanIndex]; + + FLEXCAN_GetErrorInfo(u8CanIndex, &pErrorInfo); + + pRxMsgList = s_aFlexCan_Setting_Table[u8CanIndex].pRxBuf; + + u32Flag1 = FLEXCAN_HWA_GetFlag1(pCan); + + + /* check pCan error */ + if (pErrorInfo.u32ErrorValue != 0U) + { + /* error notification */ + if (s_aFlexCan_ErrorNotifyTable[u8CanIndex] != NULL) + { + /* clear can error */ + s_aFlexCan_ErrorNotifyTable[u8CanIndex](u8CanIndex, &pErrorInfo); + } + } + + tRetVal = FLEXCAN_LL_CheckFdInstance(u8CanIndex); + + if (tRetVal == FLEXCAN_ERROR_OK) + { + u32ERFSR = FLEXCAN_HWA_ERFSRGetEnhancedFifoFlag(pCan, FLEXCAN_ERFSR_ERFDA_SHIFT, FLEXCAN_ERFSR_ERFDA_MASK); + u8FifoInterrupt = ((true == s_aFlexCan_Setting_Table[u8CanIndex].bEnableFd) && (0U != u32ERFSR) && (s_aFlexCan_Setting_Table[u8CanIndex].bEnableFifoInt)); + } + else + { + u8FifoInterrupt = 0U; + } + u8FifoInterrupt = (uint8_t)(u8FifoInterrupt | ((false == s_aFlexCan_Setting_Table[u8CanIndex].bEnableFd) && (u32Flag1 & 0x20U) && + (s_aFlexCan_Setting_Table[u8CanIndex].bEnableFifoInt))); + + /* check pCan receive data from fifo or normal */ + if ((s_aFlexCan_Setting_Table[u8CanIndex].bEnableFifo) && u8FifoInterrupt) + { + u8RecNum = FLEXCAN_LL_ReceiveFifo(u8CanIndex, s_aFlexCan_Setting_Table[u8CanIndex].bEnableFd, pRxMsgList); + /* rx notification */ + if ((u8RecNum > 0U) && (s_aFlexCan_RxFifoNotifyTable[u8CanIndex] != NULL)) + { + for (u8Index = 0U; u8Index < u8RecNum; u8Index++) + { + s_aFlexCan_RxFifoNotifyTable[u8CanIndex](u8CanIndex, &pRxMsgList[u8Index]); + } + } + } + + /* check transmit interrupt */ + if (s_aFlexCan_Setting_Table[u8CanIndex].bEnableTxMBInt) + { + for (u8Index = 0U; u8Index < s_aFlexCan_Setting_Table[u8CanIndex].u8TxMbCnt1; u8Index++) + { + u8RecNum = FLEXCAN_LL_ProcessTx(u8CanIndex,u8Index); + if ((u8RecNum == 1U) && (s_aFlexCan_TxNotifyTable[u8CanIndex] != NULL)) + { + s_aFlexCan_TxNotifyTable[u8CanIndex](u8CanIndex, u8Index); + } + } + } + + /* check receive interrupt */ + if (s_aFlexCan_Setting_Table[u8CanIndex].bEnableRxMBInt) + { + u8RecNum = FLEXCAN_LL_PollingMb(u8CanIndex, pRxMsgList); + if ((u8RecNum > 0U) && (s_aFlexCan_RxNotifyTable[u8CanIndex] != NULL)) + { + for (u8Index = 0U; u8Index < u8RecNum; u8Index++) + { + s_aFlexCan_RxNotifyTable[u8CanIndex](u8CanIndex, &pRxMsgList[u8Index]); + } + } + } + + PROCESS_UNUSED_VAR(pCan); + + #if FLEXCAN_CHECK_PARAMETERS == STD_ON + } + #endif +} + +bool IsTxBufferFree_ByCode(uint8_t canIndex, uint8_t handler) { + FLEXCAN_Type *pCan = s_aFlexCan_InstanceTable[canIndex]; + FLEXCAN_SettingType *pCurSetting = &s_aFlexCan_Setting_Table[canIndex]; + + if (handler >= pCurSetting->u8TxMbCnt1) { + return false; // Неверный handler + } + + uint8_t realIndex = pCurSetting->u8TxMbStart1 + handler; + + // Читаем код из первого слова MB + uint32_t addr = (uint32_t)FLEXCAN_MB_WORDN_ADDR( + &(pCan->RAM[0U]), realIndex, pCurSetting->eMbDataWidth, 0U); + + uint32_t code = FLEXCAN_MB_CODE_GET(addr); + + // Коды состояния буфера: + // 0x0 = EMPTY (не использовался) - СВОБОДЕН + // 0x8 = INACTIVE (неактивен) - СВОБОДЕН + // 0xC = TRANSMITTING (передаёт) - ЗАНЯТ + // 0x9 = ABORTING (прерывается) - ЗАНЯТ + + return (code == 0x0 || code == 0x8); +} diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_fmc.c b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_fmc.c new file mode 100644 index 0000000..221194a --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_fmc.c @@ -0,0 +1,231 @@ +/** + * @file fc7xxx_driver_fmc.c + * @author Flagchip + * @brief FC7xxx Fmc driver source code + * @version 0.1.0 + * @date 2024-1-5 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-1-5 Flagchip120 N/A First version for FC7240 + ******************************************************************************** */ + +#include "fc7xxx_driver_fmc.h" + +/* ################################################################################## */ +/* ####################################### Macro #################################### */ + + +/* ################################################################################## */ +/* ################################ Local Variables ################################# */ +static FMC_Type *const s_apFmcBase[FMC_INSTANCE_COUNT] = FMC_BASE_PTRS; + +/* ################################################################################## */ +/* ########################### Local Prototype Functions ############################ */ + + +/** + * \brief FMC PFlash Driver Function for lock/unlock sector + * + * \param pFMC FMC instance + * \param u32Address sector address + * \param bLock 0U-unlock, 1U-lock + */ +static FMC_Lock_StatusType FMCDRIVER_PFlashLockRegion(const FMC_InstanceType eInstance, uint32_t u32Address, uint8_t bLock); + +/** + * \brief FMC DFlash Driver Function for lock/unlock sector + * + * \param pFMC FMC instance + * \param u32Address sector address + * \param bLock 0U-unlock, 1U-lock + */ +static FMC_Lock_StatusType FMCDRIVER_DFlashLockRegion(const FMC_InstanceType eInstance, uint32_t u32Address, uint8_t bLock); + +/* ################################################################################## */ +/* ########################### Global Prototype Functions ########################### */ + + +/* ################################################################################## */ +/* ################################ Local Functions ################################# */ + +/** + * \brief FMC PFlash Driver Function for lock/unlock sector + * + * \param eInstance FMC instance + * \param u32Address sector address + * \param bLock 0U-unlock, 1U-lock + */ +static FMC_Lock_StatusType FMCDRIVER_PFlashLockRegion(const FMC_InstanceType eInstance, uint32_t u32Address, uint8_t bLock) +{ + FMC_Type *const pFMC = s_apFmcBase[eInstance]; + FMC_Lock_StatusType tRetVal; + uint32_t u32Index; + uint32_t u32Length; + uint32_t u32Temp; + + tRetVal = FMC_LOCK_ERROR_OK; + + /* 1 bank contains more than 256KB, used FB_CPELCK for first and last 256KB used FB_FPELCK */ + if ((u32Address >= PFLASH_ADDR_START) && (u32Address <= (PFLASH_ADDR_START + PFLASH_TOTAL_SIZE))) + { + /* PFLASH bank index */ + u32Index = (u32Address - PFLASH_ADDR_START) / PFLASH_BANK_SIZE; + u32Length = ((u32Address - PFLASH_ADDR_START) % PFLASH_BANK_SIZE) ; + if (u32Length < (PFLASH_BANK_SIZE - FLASH_256KB_SIZE)) /* first 768KB */ + { + u32Temp = ((uint32_t)1UL << ((u32Address - PFLASH_ADDR_START - PFLASH_BANK_SIZE * u32Index) >> 16)); + u32Temp = bLock ? (FMC_HWA_GetFBCPELCKValue(pFMC, u32Index) | u32Temp) : (FMC_HWA_GetFBCPELCKValue(pFMC, u32Index) & ~u32Temp); + FMC_HWA_SetFBCPELCKValue(pFMC, u32Index, u32Temp); + } + else /* last 256KB */ + { + u32Temp = ((u32Address - PFLASH_ADDR_START - PFLASH_BANK_SIZE * u32Index - PFLASH_PHANTOM_OFFSET) >> 13); + u32Temp = ((uint32_t)1UL << u32Temp); + u32Temp = bLock ? (FMC_HWA_GetFBFPELCKValue(pFMC, u32Index) | u32Temp) : (FMC_HWA_GetFBFPELCKValue(pFMC, u32Index) & ~u32Temp); + FMC_HWA_SetFBFPELCKValue(pFMC, u32Index, u32Temp); + } + } + else + { + tRetVal = FMC_LOCK_ERROR_INVALID_ADDR; + } + return tRetVal; +} + + +/** + * \brief FMC DFlash Driver Function for lock/unlock sector + * + * \param eInstance FMC instance + * \param u32Address sector address + * \param bLock 0U-unlock, 1U-lock + */ +static FMC_Lock_StatusType FMCDRIVER_DFlashLockRegion(const FMC_InstanceType eInstance, uint32_t u32Address, uint8_t bLock) +{ + FMC_Type *const pFMC = s_apFmcBase[eInstance]; + FMC_Lock_StatusType tRetVal; + uint32_t u32Index; + uint32_t u32Temp; + tRetVal = FMC_LOCK_ERROR_OK; + + /* 1 bank contains only 128KB, only used FB_FPELCK */ + u32Index = 2U; + if ((u32Address >= DFLASH_ADDR_START) && (u32Address <= DFLASH_ADDR_END)) + { + u32Temp = 1UL << ((u32Address - DFLASH_ADDR_START - DFLASH_BANK0_SIZE_ * (u32Index - 2U)) >> 13); + u32Temp = bLock ? (FMC_HWA_GetFBFPELCKValue(pFMC, u32Index) | u32Temp) : (FMC_HWA_GetFBFPELCKValue(pFMC, u32Index) & ~u32Temp); + FMC_HWA_SetFBFPELCKValue(pFMC, u32Index, u32Temp); + } + else + { + tRetVal = FMC_LOCK_ERROR_INVALID_ADDR; + } + return tRetVal; +} + + +/* ################################################################################## */ +/* ################################# Global Functions ############################### */ + +/** + * \brief FMC Driver Function for flash lock + * + * \param pFmcParam FMC driver flash lock parameter + * \return ErrorType + */ +FMC_Lock_StatusType FMCDRIVER_FlashLock(FMC_DRIVER_Lock_ParamType *pFmcParam) +{ + uint32_t u32Addr, u32Length, u32LockSize, u32TempAddr; + + FMC_Lock_StatusType tRetVal; + tRetVal = FMC_LOCK_ERROR_OK; + + u32Addr = pFmcParam->u32Address; + u32Length = pFmcParam->u32Length; + u32LockSize = (pFmcParam->bClass == FMC_Page) ? FLASH_PROGRAM_PAGE_SIZE : FLASH_ERASE_SECTOR_SIZE; + + /* Address and length should aligned by page/sector */ + if (pFmcParam->u32Address & (u32LockSize - 1U)) + { + tRetVal = FMC_LOCK_ERROR_INVALID_ADDR; + pFmcParam->u32ErrorAddress = pFmcParam->u32Address; + } + if (pFmcParam->u32Length & (u32LockSize - 1U)) + { + tRetVal = FMC_LOCK_ERROR_INVALID_SIZE; + pFmcParam->u32ErrorAddress = pFmcParam->u32Address; + } + + if (tRetVal == FMC_LOCK_ERROR_OK) + { + for (u32TempAddr = u32Addr; u32TempAddr < u32Addr + u32Length; u32TempAddr += u32LockSize) + { + if (pFmcParam->bFlash == FMC_PFlash) + { + tRetVal = FMCDRIVER_PFlashLockRegion(pFmcParam->bFMC, u32TempAddr, pFmcParam->bLock); + } + else + { + tRetVal = FMCDRIVER_DFlashLockRegion(pFmcParam->bFMC, u32TempAddr, pFmcParam->bLock); + } + } + } + return tRetVal; +} + +/** + * \brief FMC set ota active block + * + * \param eInstance FMC instance + * \param bLock 0U-active block 0, 1U-active block 1 + */ +void FMCDRIVER_SwapBlock(const FMC_InstanceType eInstance, FMC_API_ACTIVE_BLOCK_TYPE bActive) +{ + FMC_Type *const pFMC = s_apFmcBase[eInstance]; + if (0U == FMC_HWA_GetOTACtrlValue(pFMC, 0)) + { + FMC_HWA_SetOTAActive(pFMC, 0, bActive); + FMC_HWA_SetOTAEnable(pFMC, 0); + } +} + +/** + * \brief Get current active OTA block + * + * \param eInstance FMC instance + * \return Current active block (FMC_Active0 or FMC_Active1) + * Returns FMC_Active0 by default if OTA is not enabled or error + */ +FMC_API_ACTIVE_BLOCK_TYPE FMCDRIVER_GetActiveBlock(const FMC_InstanceType eInstance) +{ + FMC_Type *const pFMC = s_apFmcBase[eInstance]; + + // Validate instance + if ((eInstance >= FMC_INSTANCE_COUNT) || (pFMC == NULL)) + { + return FMC_Active0; + } + + // Read OTA_CTRL register + uint32_t u32OTACtrl = FMC_HWA_GetOTACtrlValue(pFMC, 0U); + + // Check if OTA is enabled (0xA = enabled) + uint32_t u32OTAEn = (u32OTACtrl & FMC_OTA_CTRL_OTA_EN_MASK) >> FMC_OTA_CTRL_OTA_EN_SHIFT; + + if (u32OTAEn != 0xA) + { + // OTA not enabled - no swapping configured, return default Bank 0 + return FMC_Active0; + } + + // OTA is enabled - read which bank is active + uint32_t u32Active = (u32OTACtrl & FMC_OTA_CTRL_OTA_ACTIVE_MASK) >> FMC_OTA_CTRL_OTA_ACTIVE_SHIFT; + + return (FMC_API_ACTIVE_BLOCK_TYPE)u32Active; +} \ No newline at end of file diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_fpu.c b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_fpu.c new file mode 100644 index 0000000..3a76265 --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_fpu.c @@ -0,0 +1,51 @@ +/** + * @file fc7xxx_driver_fpu.c + * @author Flagchip051 + * @brief FC4xxx FPU driver type definition and API + * @version 0.1.0 + * @date 2024-01-11 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-01-11 Flagchip054 N/A First version for FC7240 + ******************************************************************************** */ + +#include "fc7xxx_driver_fpu.h" + +/* Note: library user should add interrupt stack support, add compiler support */ +/* + * @details @verbatim +If only want use FPU, +1) configure FCIDE to enable FPU compiler support, "Properties" -> C/C++ Build -> Settings -> Tool Settings -> Target Processor -> Float ABI -> FP instructions(hard) -> FPU Type set to "fpv5-sp-d16" +2) configure FCIDE to enable FPU compiler support, "Properties" -> C/C++ Build -> Settings -> Tool Settings -> GNU Arm Cross C Compiler -> Preprocessor -> Defined symbols(-D) -> Add "__FPU_PRESENT=1" (without ") +3) and call FPU_Enable to enable FPU at the beginning of program. + +If want to use DSP, +1) configure FCIDE to enable FPU compiler support, Properties -> C/C++ Build -> Settings -> Tool Settings -> Target Processor -> Float ABI -> FP instructions(hard) +2) add MACRO "DRIVER_CM7_DSP_ENABLE" in FCIDE Properties -> C/C++ General -> Paths and Symbols -> Symbols -> GNU C and GNU C++ and Assembly +3) add Include Path to project Properties -> C/C++ General -> Paths and Symbols -> Includes -> GNU C and GNU C++ and Assembly: + ../../../../../../Template/Device/CMSIS5_590/DSP/Include + ../../../../../../Template/Device/CMSIS5_590/Core/Include + ../../../../../../Template/Device/CMSIS5_590/DSP/PrivateInclude +4) and call FPU_Enable to enable FPU at the beginning of program. + @endverbatim + */ + +void FPU_Enable(void) +{ + FPU_HWA_Enable(); /* set CP10 and CP11 Full Access */ + __DSB(); + __ISB(); +} + +void FPU_Disable(void) +{ + FPU_HWA_Disable(); /* Access denied. Any attempted access generates a NOCP UsageFault */ +} + diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_freqm.c b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_freqm.c new file mode 100644 index 0000000..530751a --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_freqm.c @@ -0,0 +1,186 @@ +/** + * @file fc7xxx_driver_freqm.c + * @author Flagchip + * @brief FC7xxx FREQM driver type definition and API + * @version 0.1.0 + * @date 2024-01-14 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + * @details + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-01-14 qxw0100 N/A First version for FC7240 + ******************************************************************************** */ + +#include "fc7xxx_driver_freqm.h" +#include "fc7xxx_driver_pcc.h" +#include "interrupt_manager.h" + +/********* Local variable ************/ +static FREQM_Type * const pFreqmPtrs = FREQM; + +static FREQM_MesCntStartCallBackType s_pMesCntStartCallback = NULL; +static FREQM_MesCntStopCallBackType s_pMesCntStopCallback = NULL; +static FREQM_RefCntStopCallBackType s_pRefCntStopCallback = NULL; +static FREQM_FaultCallBackType s_pFaultCallback = NULL; + + +/********* Global Functions ************/ +/** + * @brief Initialize FREQM configuration + * + * @param pInitStruct the basic configurations of the FREQM + * @return FREQM_StatusType whether the operation is successfully + */ +FREQM_StatusType FREQM_Init(const FREQM_InitType *const pInitStruct) +{ + FREQM_StatusType eRet = FREQM_STATUS_SUCCESS; + if (NULL == pInitStruct) + { + eRet = FREQM_STATUS_PARAM_INVALID; + } + else + { + /* Configure the clock divider value */ + FREQM_HWA_MesClk_PreDiv(pFreqmPtrs,pInitStruct->u8PredivVal); + /* Select the clock source to be measured */ + FREQM_HWA_MesClkSel(pFreqmPtrs,pInitStruct->eClkSel); + /* Set and clear the S/W reset */ + PCC_GenPeripheralReset(PCC_CLK_FREQM); + /* Configure the measure counter targer value */ + FREQM_HWA_SetMesLength(pFreqmPtrs,pInitStruct->u32MesLen); + /* Configure the reference counter target value */ + FREQM_HWA_SetRefTimeout(pFreqmPtrs,pInitStruct->u32RefTo); + } + return eRet; +} + +/** + * @brief De-initialize the FREQM + * + * @param eInstance the selected FREQM + * @return FREQM_StatusType whether the operation is successfully + */ +FREQM_StatusType FREQM_DeInit() +{ + FREQM_StatusType eStatus = FREQM_STATUS_SUCCESS; + /* Set register to reset value */ + FREQM_HWA_MesClk_PreDiv(pFreqmPtrs,0U); + FREQM_HWA_MesClkSel(pFreqmPtrs,(FREQM_MesClkSelType)0); + FREQM_HWA_SetMesLength(pFreqmPtrs,0xFFFFFFFFU); + FREQM_HWA_SetRefTimeout(pFreqmPtrs,0xFFFFFFFFU); + + FREQM_HWA_DisableCntEventInterrupt(pFreqmPtrs); + s_pMesCntStartCallback = NULL; + s_pMesCntStopCallback = NULL; + s_pRefCntStopCallback = NULL; + s_pFaultCallback = NULL; + + return eStatus; +} + +/** + * @brief Clear all FREQM status + * + * @return FREQM_StatusType whether the operation is successfully + */ +FREQM_StatusType FREQM_ClearStatus() +{ + FREQM_StatusType eStatus = FREQM_STATUS_SUCCESS; + uint32_t u32TimeOutVal = 0xffff; + uint32_t u32CntStatus; + + FREQM_HWA_SetRefCnt(pFreqmPtrs,0U); + + do + { + u32CntStatus = FREQM_HWA_GetCntStatus(pFreqmPtrs); + u32TimeOutVal--; + }while(u32CntStatus!=0U); + + if(u32TimeOutVal == 0U) + { + eStatus = FREQM_STATUS_TIMEOUT; + } + return eStatus; +} + +/** + * @brief Start the reference/measure counter + * + */ +void FREQM_StartMeasureCnt() +{ + FREQM_HWA_SetMesCnt(pFreqmPtrs,0U); +} + +/** + * @brief Get saved reference counter value + * + * @return uint32_t saved reference counter value + */ +uint32_t FREQM_GetRefCntSave() +{ + return FREQM_HWA_GetRefCntSave(pFreqmPtrs); +} + +/** + * @brief FREQM initialize interrupt function + * + * @param pIntStruct FREQM interrupt structure + * @return FREQM_StatusType whether the operation is successfully + */ +FREQM_StatusType FREQM_InterruptInit(const FREQM_InterruptType *const pIntrStruct) +{ + FREQM_StatusType eStatus = FREQM_STATUS_SUCCESS; + + FREQM_HWA_EnableCntEventInterrupt(pFreqmPtrs); + /*register callback functions*/ + s_pMesCntStartCallback = pIntrStruct->pMesCntStartCallback; + s_pMesCntStopCallback = pIntrStruct->pMesCntStopCallback; + s_pRefCntStopCallback = pIntrStruct->pRefCntStopCallback; + s_pFaultCallback = pIntrStruct->pFaultCallback; + + return eStatus; +} + +/** + * @brief Interrupt IRQ handle of FREQM + * + */ +void FREQM_IRQHandler(void) +{ + uint32_t u32CntStatus; + bool bIntFlag; + + bIntFlag = FREQM_HWA_GetInterruptFlag(pFreqmPtrs); + if(bIntFlag) + { + FREQM_HWA_ClearInterruptFlag(pFreqmPtrs); + } + + u32CntStatus = FREQM_HWA_GetCntStatus(pFreqmPtrs); + + if(u32CntStatus == FREQM_CNT_STATUS_MES_CNT_START_MASK)//0x4 + { + s_pMesCntStartCallback(); + } + else if(u32CntStatus == (FREQM_CNT_STATUS_MES_CNT_START_MASK|FREQM_CNT_STATUS_MES_CNT_STOP_MASK) )//0x6 + { + + s_pMesCntStopCallback(); + } + else if(u32CntStatus == (FREQM_CNT_STATUS_MES_CNT_START_MASK|FREQM_CNT_STATUS_MES_CNT_STOP_MASK|FREQM_CNT_STATUS_REF_CNT_STOP_MASK) )//0x7 + { + s_pRefCntStopCallback(); + } + else + { + s_pFaultCallback(); + } +} diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_ftu.c b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_ftu.c new file mode 100644 index 0000000..d48df67 --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_ftu.c @@ -0,0 +1,1810 @@ +/** + * @file fc7xxx_driver_ftu.c + * @author Flagchip + * @brief FC7xxx FTU driver type definition and API + * @version 0.1.0 + * @date 2022-11-15 + * + * @copyright Copyright (c) 2022 Flagchip Semiconductors Co., Ltd. + * + * @details + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2022-11-15 Flagchip070 N/A First version for FC7300 + ******************************************************************************** */ + +#include "fc7xxx_driver_ftu.h" +#include "fc7xxx_driver_pcc.h" +#include "interrupt_manager.h" +#include "HwA_scm.h" + +/********* Local variable ************/ +static const uint32_t s_aFtuMaxCounter[FTU_INSTANCE_COUNT] = {0xFFFFu, 0xFFFFFFu, 0xFFFFFFu, 0xFFFFu, 0xFFFFu, 0xFFFFu, 0xFFFFu, 0xFFFFu}; +static FTU_Type * const s_pFtuBasePtrs[FTU_INSTANCE_COUNT] = FTU_BASE_PTRS; +static FTU_ClkSrcType s_eFtuClkSrc[FTU_INSTANCE_COUNT] = {FTU_NO_CLK}; + +static FTU_ChannelCallBackType s_pChannelCallback[FTU_INSTANCE_COUNT] = {NULL}; +static FTU_FaultCallBackType s_pFaultCallback[FTU_INSTANCE_COUNT] = {NULL}; +static FTU_InterruptCallBackType s_pOverflowCallback[FTU_INSTANCE_COUNT] = {NULL}; +static FTU_InterruptCallBackType s_pReloadPointCallback[FTU_INSTANCE_COUNT] = {NULL}; + +/***************** Local Prototype Functions *********************/ +static void enable_sync_flag(FTU_Type *pFtu, uint16_t u16SyncFlag); +static void disable_sync_flag(FTU_Type *pFtu, uint16_t u16SyncFlag); +static void disable_reload_points(FTU_Type *pFtu, uint16_t u16ReloadPoints); +static void enable_reload_points(FTU_Type *pFtu, uint16_t u16ReloadPoints); + +/********* Local Functions ************/ +/** + * @brief Configure the input capture edge of the selected FTU channel + * + * @param pFtu the base address of the FTU instance + * @param u8Channel channel index of the FTU instance + * @param eEdge input capture edge + */ +static void set_ftu_input_edge(FTU_Type *pFtu, uint8_t u8Channel, FTU_InputCapturePinModeType eEdge) +{ + if (FTU_INPUT_RISING_EDGE == eEdge) + { + FTU_HWA_ConfigChannelEdgeLevel(pFtu, u8Channel, FTU_CHANNEL_EDGE_RISING); + } + else if (FTU_INPUT_FALLING_EDGE == eEdge) + { + FTU_HWA_ConfigChannelEdgeLevel(pFtu, u8Channel, FTU_CHANNEL_EDGE_FALLING); + } + else if (FTU_INPUT_BOTH_EDGE == eEdge) + { + FTU_HWA_ConfigChannelEdgeLevel(pFtu, u8Channel, FTU_CHANNEL_EDGE_BOTH); + } + else + { + FTU_HWA_ConfigChannelEdgeLevel(pFtu, u8Channel, FTU_CHANNEL_EDGE_NOT_USED); + } +} +/** + * @brief Enable the synchronization of the selected FTU instance + * + * @param pFtu the base address of the FTU instance + * @param u16SyncFlag The synchronization flag + */ +static void enable_sync_flag(FTU_Type *pFtu, uint16_t u16SyncFlag) +{ + uint32_t u32Loop; + if(0u != (u16SyncFlag & (uint16_t)FTU_SYNC_FLAG_FTUEN)) + { + FTU_HWA_SetModuleUpdateRegBySync(pFtu); + } + if(0u != (u16SyncFlag & (uint16_t)FTU_SYNC_FLAG_LDOK)) + { + FTU_HWA_SetPwmLoadEnable(pFtu); + } + if(0u != (u16SyncFlag & (uint16_t)FTU_SYNC_FLAG_CNTINC)) + { + FTU_HWA_SetCntinSync(pFtu); + } + for(u32Loop = 0; u32Loop < 4u; u32Loop++) + { + if(0u != (u16SyncFlag & (uint16_t)((uint16_t)FTU_SYNC_FLAG_SYNCEN01 << u32Loop))) + { + FTU_HWA_SetChannelSyncEnable(pFtu, u32Loop); + } + } + if(0u != (u16SyncFlag & (uint16_t)FTU_SYNC_FLAG_PWMSYNC)) + { + FTU_HWA_SetPwmSyncMode(pFtu); + } + if(0u != (u16SyncFlag & (uint16_t)FTU_SYNC_FLAG_REINIT)) + { + FTU_HWA_SetReinitBySync(pFtu); + } + if(0u != (u16SyncFlag & (uint16_t)FTU_SYNC_FLAG_SYNCHOM)) + { + FTU_HWA_EnableOutputMaskBySync(pFtu); + } +} + +/** + * @brief Disable the synchronization of the selected FTU instance + * + * @param pFtu the base address of the FTU instance + * @param u16SyncFlag The synchronization flag + */ +static void disable_sync_flag(FTU_Type *pFtu, uint16_t u16SyncFlag) +{ + uint32_t u32Loop; + if(0u != (u16SyncFlag & (uint16_t)FTU_SYNC_FLAG_FTUEN)) + { + FTU_HWA_ClearModuleUpdateRegBySync(pFtu); + } + if(0u != (u16SyncFlag & (uint16_t)FTU_SYNC_FLAG_LDOK)) + { + FTU_HWA_ClearPwmLoadEnable(pFtu); + } + if(0u != (u16SyncFlag & (uint16_t)FTU_SYNC_FLAG_CNTINC)) + { + FTU_HWA_ClearCntinSync(pFtu); + } + for(u32Loop = 0; u32Loop < 4u; u32Loop++) + { + if(0u != (u16SyncFlag & ((uint16_t)FTU_SYNC_FLAG_SYNCEN01 << u32Loop))) + { + FTU_HWA_ClearChannelSyncEnable(pFtu, u32Loop); + } + } + if(0u != (u16SyncFlag & (uint16_t)FTU_SYNC_FLAG_PWMSYNC)) + { + FTU_HWA_ClearPwmSyncMode(pFtu); + } + if(0u != (u16SyncFlag & (uint16_t)FTU_SYNC_FLAG_REINIT)) + { + FTU_HWA_ClearReinitBySync(pFtu); + } + if(0u != (u16SyncFlag & (uint16_t)FTU_SYNC_FLAG_SYNCHOM)) + { + FTU_HWA_DisableOutputMaskBySync(pFtu); + } +} + +/** + * @brief Disable the reload points of the selected FTU instance + * + * @param pFtu the base address of the FTU instance + * @param u16ReloadPoints The reload points flag + */ +static void disable_reload_points(FTU_Type *pFtu, uint16_t u16ReloadPoints) +{ + uint32_t u32Loop; + if(0u != (u16ReloadPoints & (uint16_t)FTU_RELOAD_POINT_CNTMAX)) + { + /* Enables Maximum Loading Point */ + FTU_HWA_DisableMaxLoadPoint(pFtu); + } + if(0u != (u16ReloadPoints & (uint16_t)FTU_RELOAD_POINT_CNTMIN)) + { + /* Disables Minimum Loading Point */ + FTU_HWA_DisableMinLoadPoint(pFtu); + } + for(u32Loop = 0u; u32Loop < FTU_CHANNEL_CONTROLS_COUNT; u32Loop++) + { + if(0u != (u16ReloadPoints & (uint16_t)((uint16_t)FTU_RELOAD_POINT_CHANNEL_0 << u32Loop))) + { + /* Channel match is not included as a reload opportunity */ + FTU_HWA_DisableChannelMatchReload(pFtu, u32Loop); + } + } +} + +/** + * @brief Enable the reload points of the selected FTU instance + * + * @param pFtu the base address of the FTU instance + * @param u16ReloadPoints The reload points flag + */ +static void enable_reload_points(FTU_Type *pFtu, uint16_t u16ReloadPoints) +{ + uint32_t u32Loop; + if(0u != (u16ReloadPoints & (uint32_t)FTU_RELOAD_POINT_CNTMAX)) + { + /* Enables Maximum Loading Point */ + FTU_HWA_EnableMaxLoadPoint(pFtu); + } + if(0u != (u16ReloadPoints & (uint32_t)FTU_RELOAD_POINT_CNTMIN)) + { + /* Enables Minimum Loading Point */ + FTU_HWA_EnableMinLoadPoint(pFtu); + } + for(u32Loop = 0; u32Loop < FTU_CHANNEL_CONTROLS_COUNT; u32Loop++) + { + if(0u != (u16ReloadPoints & ((uint32_t)FTU_RELOAD_POINT_CHANNEL_0 << u32Loop))) + { + /* Channel match is included as a reload opportunity */ + FTU_HWA_EnableChannelMatchReload(pFtu, u32Loop); + } + } +} + +/********* Global Functions ************/ +/** + * @brief Enable the reload points of the selected FTU instance + * + * @param eInstance the selected FTU instance + * @param u16ReloadPoints The reload points flag + * @return FTU_StatusType whether the operation is successfully + */ +FTU_StatusType FTU_EnableReloadPoints(const FTU_InstanceType eInstance, uint16_t u16ReloadPoints) +{ + FTU_StatusType eStatus = FTU_STATUS_SUCCESS; + if ((uint32_t)eInstance >= FTU_INSTANCE_COUNT) + { + eStatus = FTU_STATUS_PARAM_INVALID; + } + else + { + enable_reload_points(s_pFtuBasePtrs[eInstance], u16ReloadPoints); + } + return eStatus; +} + +/** + * @brief Disable the reload points of the selected FTU instance + * + * @param eInstance the selected FTU instance + * @param u16ReloadPoints The reload points flag + * @return FTU_StatusType whether the operation is successfully + */ +FTU_StatusType FTU_DisableReloadPoints(const FTU_InstanceType eInstance, uint16_t u16ReloadPoints) +{ + FTU_StatusType eStatus = FTU_STATUS_SUCCESS; + if ((uint32_t)eInstance >= FTU_INSTANCE_COUNT) + { + eStatus = FTU_STATUS_PARAM_INVALID; + } + else + { + disable_reload_points(s_pFtuBasePtrs[eInstance], u16ReloadPoints); + } + return eStatus; +} + +/** + * @brief enable the synchronization of the selected FTU + * + * @param eInstance the selected FTU instance + * @param u16ReloadPoints The synchronization flag + * @return FTU_StatusType whether the operation is successfully + */ +FTU_StatusType FTU_EnableSync(const FTU_InstanceType eInstance, uint16_t u16SyncFlag) +{ + FTU_StatusType eStatus = FTU_STATUS_SUCCESS; + if ((uint32_t)eInstance >= FTU_INSTANCE_COUNT) + { + eStatus = FTU_STATUS_PARAM_INVALID; + } + else + { + enable_sync_flag(s_pFtuBasePtrs[eInstance], u16SyncFlag); + } + return eStatus; +} + +/** + * @brief disable the synchronization of the selected FTU + * + * @param eInstance the selected FTU instance + * @param u16ReloadPoints The synchronization flag + * @return FTU_StatusType whether the operation is successfully + */ +FTU_StatusType FTU_DisableSync(const FTU_InstanceType eInstance, uint16_t u16SyncFlag) +{ + FTU_StatusType eStatus = FTU_STATUS_SUCCESS; + if ((uint32_t)eInstance >= FTU_INSTANCE_COUNT) + { + eStatus = FTU_STATUS_PARAM_INVALID; + } + else + { + disable_sync_flag(s_pFtuBasePtrs[eInstance], u16SyncFlag); + } + return eStatus; +} + +/** + * @brief Initialize FTU basic configuration + * + * @param eInstance the selected FTU instance + * @param pCommonStruct the basic configurations of the FTU instance + * @return FTU_StatusType whether the operation is successfully + */ +FTU_StatusType FTU_CommonInit(const FTU_InstanceType eInstance, const FTU_CommonType *const pCommonStruct) +{ + FTU_StatusType eRet = FTU_STATUS_SUCCESS; + if ((uint32_t)eInstance >= FTU_INSTANCE_COUNT) + { + eRet = FTU_STATUS_PARAM_INVALID; + } + else if (pCommonStruct->u32OverflowValue > s_aFtuMaxCounter[(uint32_t)eInstance]) + { + eRet = FTU_STATUS_PARAM_INVALID; + } + else + { + if (true == pCommonStruct->bGtbEnable) + { + FTU_HWA_EnableGlobalTimeBase(s_pFtuBasePtrs[eInstance]); + } + else + { + FTU_HWA_DisableGlobalTimeBase(s_pFtuBasePtrs[eInstance]); + } + FTU_HWA_DisableModuleCpwmMode(s_pFtuBasePtrs[eInstance]); + /* set FTU prescale */ + FTU_HWA_SetModulePrescale(s_pFtuBasePtrs[eInstance], pCommonStruct->ePrescaler); + /* configure fault filter prescaler */ + FTU_HWA_ConfigModuleFilterPrescale(s_pFtuBasePtrs[eInstance], pCommonStruct->eFliterPrescaler); + /*set the compare register as max value*/ + FTU_HWA_SetModuleCompareValue(s_pFtuBasePtrs[eInstance], (uint32_t)pCommonStruct->u32OverflowValue); + /*set initial value as 0*/ + FTU_HWA_SetCounterInitialValue(s_pFtuBasePtrs[eInstance], 0u); + /*set any value to clear the current counter register to initial value*/ + FTU_HWA_ClearModuleCounter(s_pFtuBasePtrs[eInstance], (uint32_t)0x1U); + /* set ftu OUTMASK sync mode, set bit SYNCHOM and OUTMASK register will update when then sync event happened */ + FTU_HWA_EnableOutputMaskBySync(s_pFtuBasePtrs[eInstance]); + /* set ftu debug mode */ + FTU_HWA_ConfigDebugMode(s_pFtuBasePtrs[eInstance], (uint32_t)pCommonStruct->eDbgMode); + /* Disable channel match trigger/interrupt when count-up/down in CPWM/QUAD mode */ + FTU_HWA_ConfigUpDownDisable(s_pFtuBasePtrs[eInstance], pCommonStruct->eUpDownDisable); + /*configure the synchronization*/ + disable_sync_flag(s_pFtuBasePtrs[eInstance], ~pCommonStruct->u16SyncFlag); + enable_sync_flag(s_pFtuBasePtrs[eInstance], pCommonStruct->u16SyncFlag); + + /*configure the reload points*/ + disable_reload_points(s_pFtuBasePtrs[eInstance], ~pCommonStruct->u16ReloadPoints); + enable_reload_points(s_pFtuBasePtrs[eInstance], pCommonStruct->u16ReloadPoints); + + /* configure hardware trigger mode */ + FTU_HWA_ConfigTrigMode(s_pFtuBasePtrs[eInstance], pCommonStruct->eHwTrigMode); + /* configure the frequency of the reload opportunities*/ + FTU_HWA_ConfigFreqOfReloadOp(s_pFtuBasePtrs[eInstance], pCommonStruct->u8ReloadFreq); + + /* select clock source */ + if (FTU_INTERNAL_CLK == pCommonStruct->eClkSrc) + { + s_eFtuClkSrc[eInstance] = FTU_INTERNAL_CLK; + } + else if (FTU_EXTERNAL_CLK0 == pCommonStruct->eClkSrc) + { + s_eFtuClkSrc[eInstance] = FTU_EXTERNAL_CLK0; + FTU_HWA_ConfigExternalClkSrc(s_pFtuBasePtrs[eInstance], FTU_TCLK0_USED); + } + else if (FTU_EXTERNAL_CLK1 == pCommonStruct->eClkSrc) + { + s_eFtuClkSrc[eInstance] = FTU_EXTERNAL_CLK1; + FTU_HWA_ConfigExternalClkSrc(s_pFtuBasePtrs[eInstance], FTU_TCLK1_USED); + } + else if (FTU_EXTERNAL_CLK2 == pCommonStruct->eClkSrc) + { + s_eFtuClkSrc[eInstance] = FTU_EXTERNAL_CLK2; + FTU_HWA_ConfigExternalClkSrc(s_pFtuBasePtrs[eInstance], FTU_TCLK2_USED); + } + else + { + s_eFtuClkSrc[eInstance] = FTU_NO_CLK; + } + } + return eRet; +} + +/** + * @brief De-initialize the FTU instance + * + * @param eInstance the selected FTU instance + * @return FTU_StatusType whether the operation is successfully + */ +FTU_StatusType FTU_DeInit(const FTU_InstanceType eInstance) +{ + FTU_StatusType eStatus = FTU_STATUS_SUCCESS; + if ((uint32_t)eInstance >= FTU_INSTANCE_COUNT) + { + eStatus = FTU_STATUS_PARAM_INVALID; + } + else + { + s_eFtuClkSrc[eInstance] = FTU_NO_CLK; + s_pChannelCallback[eInstance] = NULL; + s_pFaultCallback[eInstance] = NULL; + s_pOverflowCallback[eInstance] = NULL; + s_pReloadPointCallback[eInstance] = NULL; + + FTU_HWA_ClearModuleRegister(s_pFtuBasePtrs[eInstance]); + } + return eStatus; +} + +/** + * @brief Fills in the FTU configuration structure with the default settings. + * + * @param pCommonStruct Pointer to the user configuration structure + */ +void FTU_GetDefaultInitCfg(FTU_CommonType *pCommonStruct) +{ + DEV_ASSERT(NULL_PTR != pCommonStruct); + pCommonStruct->ePrescaler = FTU_DIV_1; + pCommonStruct->eFliterPrescaler = FTU_FLT_DIV_1; + pCommonStruct->u32OverflowValue = 0xFFFF; + pCommonStruct->eClkSrc = FTU_INTERNAL_CLK; + pCommonStruct->u16ReloadPoints = (uint16_t)FTU_RELOAD_POINT_CNTMAX; + pCommonStruct->u8ReloadFreq = 0; + pCommonStruct->u16SyncFlag = 0; + pCommonStruct->eHwTrigMode = FTU_CLEARS_TRIG_WHEN_DETECTED; + pCommonStruct->eDbgMode = FTU_DBG_COUNTER_WORKS_CHN_WORKS; + pCommonStruct->eUpDownDisable = FTU_DISABLE_TRIG_INTR_NONE; + pCommonStruct->bGtbEnable = false; +} + +/** + * @brief Configure FTU to counter mode + * + * @param eInstance the selected FTU instance + * @param pCounterStruct the configurations of the counter mode + * @return FTU_StatusType whether the operation is successfully + * @note This function will stop timer + */ +FTU_StatusType FTU_CounterModeInit(const FTU_InstanceType eInstance, const FTU_CounterModeType *const pCounterStruct) +{ + FTU_StatusType eStatus = FTU_STATUS_SUCCESS; + if ((uint32_t)eInstance >= FTU_INSTANCE_COUNT) + { + eStatus = FTU_STATUS_PARAM_INVALID; + } + else if ( (pCounterStruct->u32CounterValue > s_aFtuMaxCounter[(uint32_t)eInstance]) + || (pCounterStruct->u32InitialValue > s_aFtuMaxCounter[(uint32_t)eInstance])) + { + eStatus = FTU_STATUS_PARAM_INVALID; + } + else + { + /* disable ftu timer */ + FTU_HWA_ConfigModuleClkSrc(s_pFtuBasePtrs[eInstance], FTU_MODULE_NO_CLK); + /* set FTU MOD register value */ + FTU_HWA_SetModuleCompareValue(s_pFtuBasePtrs[eInstance], (uint32_t)pCounterStruct->u32CounterValue); + /*set initial value */ + FTU_HWA_SetCounterInitialValue(s_pFtuBasePtrs[eInstance], (uint32_t)pCounterStruct->u32InitialValue); + } + return eStatus; +} + +/** + * @brief Update the duty cycle of the FTU instance + * + * @param eInstance the selected FTU instance + * @param u8Channel the selected FTU channel + * @param u32Duty duty cycle of the PWM mode + * @return FTU_StatusType whether the operation is successfully + */ +FTU_StatusType FTU_PwmUpdateDuty(const FTU_InstanceType eInstance, uint8_t u8Channel, uint32_t u32Duty) +{ + FTU_StatusType eStatus = FTU_STATUS_SUCCESS; + uint8_t u8CpwmFlag; + if (((uint32_t)eInstance >= FTU_INSTANCE_COUNT) || + (u8Channel >= FTU_CHANNEL_CONTROLS_COUNT) || + (u32Duty > s_aFtuMaxCounter[(uint32_t)eInstance])) + { + eStatus = FTU_STATUS_PARAM_INVALID; + } + else + { + /* get the cpwm flag*/ + u8CpwmFlag = FTU_HWA_GetModuleCpwmMode(s_pFtuBasePtrs[eInstance]); + if(0u != u8CpwmFlag) + { + /* Duty value div 2 if cpwm mode*/ + FTU_HWA_SetChannelValue(s_pFtuBasePtrs[eInstance], u8Channel, (uint32_t)u32Duty >> 1u); + } + else + { + FTU_HWA_SetChannelValue(s_pFtuBasePtrs[eInstance], u8Channel, u32Duty); + } + } + return eStatus; +} + +static void set_deadtime(FTU_Type *pFtu, uint8_t u8Channel, uint32_t u32Deadtime, bool bPair) +{ + /* enable channel deadtime, channel 0/1 2/3 4/5 6/7 are combined*/ + FTU_HWA_EnableChannelDeadtime(pFtu, u8Channel); + if(u32Deadtime < 1024u) + { + if(bPair) + { + /* PAIRDEADTIME has a high priority*/ + FTU_HWA_ConfigPairDeadtimePrescaler(pFtu, u8Channel, FTU_DEADTIME_PRESCALER_DIV_1); + FTU_HWA_ConfigPairDeadtimeValue(pFtu, u8Channel, u32Deadtime); + } + else + { + /* DEADTIME shoud recover PAIRDEADTIME*/ + FTU_HWA_ConfigDeadtimePrescaler(pFtu, FTU_DEADTIME_PRESCALER_DIV_1); + FTU_HWA_ConfigDeadtimeValue(pFtu, u32Deadtime); + } + } + else if(u32Deadtime < 4096u) + { + /*deadtime should multiply 2*/ + if(bPair) + { + /* PAIRDEADTIME has a high priority*/ + FTU_HWA_ConfigPairDeadtimePrescaler(pFtu, u8Channel, + FTU_DEADTIME_PRESCALER_DIV_4); + FTU_HWA_ConfigPairDeadtimeValue(pFtu, (uint32_t)u8Channel, u32Deadtime >> 2u); + } + else + { + /* DEADTIME shoud recover PAIRDEADTIME*/ + FTU_HWA_ConfigDeadtimePrescaler(pFtu, FTU_DEADTIME_PRESCALER_DIV_4); + FTU_HWA_ConfigDeadtimeValue(pFtu, u32Deadtime >> 2u); + } + } + else + { + /*deadtime should multiply 4*/ + if(bPair) + { + /* PAIRDEADTIME has a high priority*/ + FTU_HWA_ConfigPairDeadtimePrescaler(pFtu, u8Channel, FTU_DEADTIME_PRESCALER_DIV_16); + FTU_HWA_ConfigPairDeadtimeValue(pFtu, u8Channel, u32Deadtime >> 4u); + } + else + { + /* DEADTIME shoud recover PAIRDEADTIME*/ + FTU_HWA_ConfigDeadtimePrescaler(pFtu, FTU_DEADTIME_PRESCALER_DIV_16); + FTU_HWA_ConfigDeadtimeValue(pFtu, u32Deadtime >> 4u); + } + } +} + +/** + * @brief Configure FTU to PWM mode + * + * @param eInstance the selected FTU instance + * @param pPwmModeStruct the configurations of the PWM mode + * @return FTU_StatusType whether the operation is successfully + * @note This function will stop timer + */ +FTU_StatusType FTU_PwmModeInit(const FTU_InstanceType eInstance, const FTU_PwmModeType *const pPwmModeStruct) +{ + FTU_StatusType eStatus = FTU_STATUS_SUCCESS; + uint8_t u8Channel; + uint32_t u32Loop; + if ((uint32_t)eInstance >= FTU_INSTANCE_COUNT) + { + eStatus = FTU_STATUS_PARAM_INVALID; + } + else if (pPwmModeStruct->u32PwmPeriod > s_aFtuMaxCounter[(uint32_t)eInstance]) + { + eStatus = FTU_STATUS_PARAM_INVALID; + } + + for (u32Loop = 0u; u32Loop < pPwmModeStruct->u32ChannelCount; u32Loop++) + { + if (pPwmModeStruct->pPwmChannels[u32Loop].u8Channel >= FTU_CHANNEL_CONTROLS_COUNT) + { + eStatus = FTU_STATUS_PARAM_INVALID; + break; + } + + if ( (pPwmModeStruct->pPwmChannels[u32Loop].u32PwmDuty > s_aFtuMaxCounter[(uint32_t)eInstance]) + || (pPwmModeStruct->pPwmChannels[u32Loop].u32PhaseShift > s_aFtuMaxCounter[(uint32_t)eInstance])) + { + eStatus = FTU_STATUS_PARAM_INVALID; + break; + } + + if ( (FTU_CENTER_ALIGNED_PWM == pPwmModeStruct->eAlignedMode) + && (0u < pPwmModeStruct->pPwmChannels[u32Loop].u32PhaseShift)) + { + eStatus = FTU_STATUS_PARAM_INVALID; + break; + } + if ( (true == pPwmModeStruct->pPwmChannels[u32Loop].bLinkMode) + && (0u < pPwmModeStruct->pPwmChannels[u32Loop].u32PhaseShift)) + { + eStatus = FTU_STATUS_PARAM_INVALID; + break; + } + if (( (true == pPwmModeStruct->pPwmChannels[u32Loop].bLinkMode) + || (0u < pPwmModeStruct->pPwmChannels[u32Loop].u32PhaseShift)) + && (pPwmModeStruct->pPwmChannels[u32Loop].u8Channel & 1u)) + { + eStatus = FTU_STATUS_PARAM_INVALID; + break; + } + } + + if (FTU_STATUS_SUCCESS == eStatus) + { + /* disable ftu timer */ + FTU_HWA_ConfigModuleClkSrc(s_pFtuBasePtrs[eInstance], FTU_MODULE_NO_CLK); + if (FTU_EDGE_ALIGNED_PWM == pPwmModeStruct->eAlignedMode) + { + FTU_HWA_DisableModuleCpwmMode(s_pFtuBasePtrs[eInstance]); + FTU_HWA_SetModuleCompareValue(s_pFtuBasePtrs[eInstance], pPwmModeStruct->u32PwmPeriod); + } + else + { + FTU_HWA_EnableModuleCpwmMode(s_pFtuBasePtrs[eInstance]); + FTU_HWA_SetModuleCompareValue(s_pFtuBasePtrs[eInstance], pPwmModeStruct->u32PwmPeriod >> 1u); + } + set_deadtime(s_pFtuBasePtrs[eInstance], 0u, pPwmModeStruct->u32PublicDeadtime, false); + + for (u32Loop = 0u; u32Loop < pPwmModeStruct->u32ChannelCount; u32Loop++) + { + FTU_PwmChannelType *pChannelCfg = &pPwmModeStruct->pPwmChannels[u32Loop]; + u8Channel = pChannelCfg->u8Channel; + if(pChannelCfg->bLinkMode) + { + /* set channel(n+1) complement of channel(n) output */ + FTU_HWA_EnableChannelComplement(s_pFtuBasePtrs[eInstance], u8Channel); + if (!pChannelCfg->bLinkChannelComplement) + { + FTU_HWA_ClearChannelPolarity(s_pFtuBasePtrs[eInstance], (uint8_t)1U << u8Channel); + FTU_HWA_SetChannelPolarity(s_pFtuBasePtrs[eInstance], (uint8_t)1U << (u8Channel + (uint8_t)1U)); + } + else + { + FTU_HWA_ClearChannelPolarity(s_pFtuBasePtrs[eInstance], + (uint8_t)1U << u8Channel| (uint8_t)1U << (u8Channel + 1u)); + } + /*link mode, the u8Channel+1->csc.ELSB bit must be set*/ + FTU_HWA_ConfigChannelPwmLinkMode(s_pFtuBasePtrs[eInstance], u8Channel + (uint8_t)1U); + /* enable u8Channel sync function of the ftu*/ + FTU_HWA_EnableChannelSync(s_pFtuBasePtrs[eInstance], u8Channel); + /* configure pin output as channel mode*/ + FTU_HWA_ConfigTrigOutputMode(s_pFtuBasePtrs[eInstance], u8Channel, FTU_TRIG_OUTPUT_AS_CHANNEL_MODE); + FTU_HWA_ConfigTrigOutputMode(s_pFtuBasePtrs[eInstance], u8Channel + 1u, FTU_TRIG_OUTPUT_AS_CHANNEL_MODE); + /* enable FTU output */ + FTU_HWA_EnableChannelsOutput(s_pFtuBasePtrs[eInstance], (uint8_t)3U << u8Channel); + } + else + { + if (pChannelCfg->u32PhaseShift) + { + FTU_HWA_ClearChannelPolarity(s_pFtuBasePtrs[eInstance], (uint8_t)1U << (u8Channel + 1)); + /* enable u8Channel sync function of the ftu*/ + FTU_HWA_EnableChannelSync(s_pFtuBasePtrs[eInstance], u8Channel); + + /*Enable enhanced phase shift mode*/ + FTU_HWA_EnableChannelPhase(s_pFtuBasePtrs[eInstance], u8Channel); + FTU_HWA_EnableChannelEnhancedPhase(s_pFtuBasePtrs[eInstance], u8Channel); + } + else + { + /* enable u8Channel sync function of the ftu*/ + FTU_HWA_DisableChannelSync(s_pFtuBasePtrs[eInstance], u8Channel); + + /*Enable enhanced phase shift mode*/ + FTU_HWA_DisableChannelPhase(s_pFtuBasePtrs[eInstance], u8Channel); + FTU_HWA_DisableChannelPhase(s_pFtuBasePtrs[eInstance], u8Channel); + } + + /* disable channel(n+1) complement of channel(n) output */ + FTU_HWA_DisableChannelComplement(s_pFtuBasePtrs[eInstance], u8Channel); + FTU_HWA_ClearChannelPolarity(s_pFtuBasePtrs[eInstance], (uint8_t)1U << u8Channel); + /* enable FTU output */ + FTU_HWA_EnableChannelsOutput(s_pFtuBasePtrs[eInstance], (uint8_t)1U << u8Channel); + /* configure pin output as channel mode*/ + FTU_HWA_ConfigTrigOutputMode(s_pFtuBasePtrs[eInstance], u8Channel, FTU_TRIG_OUTPUT_AS_CHANNEL_MODE); + + } + /* set FTU pwm mode */ + if ( (FTU_PWM_HIGH_TRUE_PULSE == pChannelCfg->ePinMode) + && (FTU_EDGE_ALIGNED_PWM == pPwmModeStruct->eAlignedMode)) + { + FTU_HWA_ConfigChannelMode(s_pFtuBasePtrs[eInstance], u8Channel, FTU_CHANNEL_MODE_EDGE_ALIGN_PWM); + FTU_HWA_ConfigChannelEdgeLevel(s_pFtuBasePtrs[eInstance], u8Channel, FTU_CHANNEL_PWM_HIGH_TRUE); + } + else if ( (FTU_PWM_LOW_TRUE_PULSE == pChannelCfg->ePinMode) + && (FTU_EDGE_ALIGNED_PWM == pPwmModeStruct->eAlignedMode)) + { + FTU_HWA_ConfigChannelMode(s_pFtuBasePtrs[eInstance], u8Channel, FTU_CHANNEL_MODE_EDGE_ALIGN_PWM); + FTU_HWA_ConfigChannelEdgeLevel(s_pFtuBasePtrs[eInstance], u8Channel, FTU_CHANNEL_PWM_LOW_TRUE); + } + else if ( (FTU_PWM_HIGH_TRUE_PULSE == pChannelCfg->ePinMode) + && (FTU_CENTER_ALIGNED_PWM == pPwmModeStruct->eAlignedMode)) + { + FTU_HWA_ConfigChannelEdgeLevel(s_pFtuBasePtrs[eInstance], u8Channel, FTU_CHANNEL_PWM_HIGH_TRUE); + } + else if ( (FTU_PWM_LOW_TRUE_PULSE == pChannelCfg->ePinMode) + && (FTU_CENTER_ALIGNED_PWM == pPwmModeStruct->eAlignedMode)) + { + FTU_HWA_ConfigChannelEdgeLevel(s_pFtuBasePtrs[eInstance], u8Channel, FTU_CHANNEL_PWM_LOW_TRUE); + } + + if (pChannelCfg->bDeadtimeEnable) + { + FTU_HWA_EnableChannelDeadtime(s_pFtuBasePtrs[eInstance], u8Channel); + } + else + { + FTU_HWA_DisableChannelDeadtime(s_pFtuBasePtrs[eInstance], u8Channel); + } + + /* set the period time and duty time */ + if(FTU_CENTER_ALIGNED_PWM == pPwmModeStruct->eAlignedMode) + { + FTU_HWA_SetChannelValue(s_pFtuBasePtrs[eInstance], u8Channel, pChannelCfg->u32PwmDuty >> 1u); + } + else + { + if (pChannelCfg->u32PhaseShift) + { + FTU_HWA_SetChannelValue(s_pFtuBasePtrs[eInstance], u8Channel, pChannelCfg->u32PhaseShift); + if ((pChannelCfg->u32PhaseShift + pChannelCfg->u32PwmDuty) > pPwmModeStruct->u32PwmPeriod) + { + FTU_HWA_SetChannelValue(s_pFtuBasePtrs[eInstance], u8Channel + 1, + pChannelCfg->u32PhaseShift + pChannelCfg->u32PwmDuty - pPwmModeStruct->u32PwmPeriod - 1); + } + else + { + FTU_HWA_SetChannelValue(s_pFtuBasePtrs[eInstance], u8Channel + 1, + pChannelCfg->u32PhaseShift + pChannelCfg->u32PwmDuty); + } + + } + else + { + FTU_HWA_SetChannelValue(s_pFtuBasePtrs[eInstance], u8Channel, pChannelCfg->u32PwmDuty); + } + } + set_deadtime(s_pFtuBasePtrs[eInstance], u8Channel, pChannelCfg->u32ChannelDeadtime, true); + } + } + return eStatus; +} + +/** + * @brief Configure FTU to output compare mode + * + * @param eInstance the selected FTU instance + * @param pOutputModeStruct the configurations of the output compare mode + * @return FTU_StatusType whether the operation is successfully + * @note This function will stop timer + */ +FTU_StatusType FTU_OutputCompareModeInit(const FTU_InstanceType eInstance, + const FTU_OutputCompareModeType *const pOCConfig) +{ + FTU_StatusType eStatus = FTU_STATUS_SUCCESS; + if (((uint32_t)eInstance >= FTU_INSTANCE_COUNT) || (pOCConfig->u8Channel >= FTU_CHANNEL_CONTROLS_COUNT)) + { + eStatus = FTU_STATUS_PARAM_INVALID; + } + else if ( pOCConfig->u32CompareValue > s_aFtuMaxCounter[(uint32_t)eInstance]) + { + eStatus = FTU_STATUS_PARAM_INVALID; + } + else + { + /* disable ftu timer */ + FTU_HWA_ConfigModuleClkSrc(s_pFtuBasePtrs[eInstance], FTU_MODULE_NO_CLK); + FTU_HWA_DisableChannelEnhancedPhase(s_pFtuBasePtrs[eInstance], pOCConfig->u8Channel); + FTU_HWA_DisableChannelPhase(s_pFtuBasePtrs[eInstance], pOCConfig->u8Channel); + FTU_HWA_ConfigInputCaptureMeasureMode(s_pFtuBasePtrs[eInstance], pOCConfig->u8Channel, + FTU_MEASURE_MODE_OFF); + FTU_HWA_ConfigChannelMode(s_pFtuBasePtrs[eInstance], pOCConfig->u8Channel, FTU_CHANNEL_MODE_OUTPUT_COMPARE); + if (FTU_OUTPUT_TOGGLE_PIN == pOCConfig->eOutputMode) + { + FTU_HWA_ConfigChannelEdgeLevel(s_pFtuBasePtrs[eInstance], pOCConfig->u8Channel, FTU_CHANNEL_OC_TOGGLE); + } + else if (FTU_OUTPUT_CLEAR_PIN == pOCConfig->eOutputMode) + { + FTU_HWA_ConfigChannelEdgeLevel(s_pFtuBasePtrs[eInstance], pOCConfig->u8Channel, FTU_CHANNEL_OC_CLEAR); + } + else if (FTU_OUTPUT_SET_PIN == pOCConfig->eOutputMode) + { + FTU_HWA_ConfigChannelEdgeLevel(s_pFtuBasePtrs[eInstance], pOCConfig->u8Channel, FTU_CHANNEL_OC_SET); + } + /* Disable Up-Down Mode*/ + FTU_HWA_DisableModuleCpwmMode(s_pFtuBasePtrs[eInstance]); + /* enable FTU output */ + FTU_HWA_EnableChannelsOutput(s_pFtuBasePtrs[eInstance], (uint8_t)1U << pOCConfig->u8Channel); + /* configure initial level */ + if (FTU_OUTPUT_CMP_INIT_LOW == pOCConfig->eInitLevel) + { + FTU_HWA_ClearChannelPolarity(s_pFtuBasePtrs[eInstance], (uint8_t)1U << pOCConfig->u8Channel); + } + else + { + FTU_HWA_SetChannelPolarity(s_pFtuBasePtrs[eInstance], (uint8_t)1U << pOCConfig->u8Channel); + } + /* configure pin output as channel mode*/ + FTU_HWA_ConfigTrigOutputMode(s_pFtuBasePtrs[eInstance], pOCConfig->u8Channel, FTU_TRIG_OUTPUT_AS_CHANNEL_MODE); + /* set FTU CV register value*/ + FTU_HWA_SetChannelValue(s_pFtuBasePtrs[eInstance], pOCConfig->u8Channel, (uint32_t)pOCConfig->u32CompareValue); + + } + return eStatus; +} + +/** + * @brief Enable the output trigger of the selected FTU instance + * + * @param eInstance the selected FTU instance + * @param u32TriggerOutputMask the output trigger mask + * @return FTU_StatusType whether the operation is successfully + */ +FTU_StatusType FTU_EnableTriggerOutput(const FTU_InstanceType eInstance, uint32_t u32TriggerOutputMask) +{ + FTU_StatusType eStatus = FTU_STATUS_SUCCESS; + + if ((uint32_t)eInstance >= FTU_INSTANCE_COUNT) + { + eStatus = FTU_STATUS_PARAM_INVALID; + } + else + { + /* enable the channel match trigger */ + FTU_HWA_EnableChannelTriggerOut(s_pFtuBasePtrs[eInstance], (uint8_t)(u32TriggerOutputMask & (uint32_t)FTU_TRIG_OUTPUT_MASK_ALL_CHANNEL_MATCH)); + if (0u != (u32TriggerOutputMask & (uint32_t)FTU_TRIG_OUTPUT_MASK_RELOAD)) + { + /* enable reload trigger */ + FTU_HWA_EnableReloadTrigger(s_pFtuBasePtrs[eInstance]); + } + } + return eStatus; +} + +/** + * @brief Disable the output trigger of the selected FTU instance + * + * @param eInstance the selected FTU instance + * @param u32TriggerOutputMask the output trigger mask + * @return FTU_StatusType whether the operation is successfully + */ +FTU_StatusType FTU_DisableTriggerOutput(const FTU_InstanceType eInstance, uint32_t u32TriggerOutputMask) +{ + FTU_StatusType eStatus = FTU_STATUS_SUCCESS; + if ((uint32_t)eInstance >= FTU_INSTANCE_COUNT) + { + eStatus = FTU_STATUS_PARAM_INVALID; + } + else + { + /* disenable the channel match trigger */ + FTU_HWA_DisableChannelTriggerOut(s_pFtuBasePtrs[eInstance], (uint8_t)(u32TriggerOutputMask & (uint32_t)FTU_TRIG_OUTPUT_MASK_ALL_CHANNEL_MATCH)); + if (0u != (u32TriggerOutputMask & (uint32_t)FTU_TRIG_OUTPUT_MASK_RELOAD)) + { + /* disable reload trigger */ + FTU_HWA_DisableReloadTrigger(s_pFtuBasePtrs[eInstance]); + } + } + return eStatus; +} + +/** + * @brief Start the FTU instance + * + * @param eInstance the selected FTU instance + * @return FTU_StatusType whether the operation is successfully + */ +FTU_StatusType FTU_StartTimer(const FTU_InstanceType eInstance) +{ + FTU_StatusType eStatus = FTU_STATUS_SUCCESS; + if ((uint32_t)eInstance >= FTU_INSTANCE_COUNT) + { + eStatus = FTU_STATUS_PARAM_INVALID; + } + else + { + /* set FTU module clock source */ + if (s_eFtuClkSrc[eInstance] == FTU_NO_CLK) + { + eStatus = FTU_STATUS_NO_CLOCK_SOURCE; + } + else if(s_eFtuClkSrc[eInstance] == FTU_INTERNAL_CLK) + { + FTU_HWA_ConfigModuleClkSrc(s_pFtuBasePtrs[eInstance], FTU_MODULE_INTERNAL_CLK); + } + else + { + FTU_HWA_ConfigModuleClkSrc(s_pFtuBasePtrs[eInstance], FTU_MODULE_EXTERNAL_CLK); + } + } + return eStatus; +} + +/** + * @brief Stop the FTU global time base + * + * @param u32InstanceMask The selected FTU, each bit represents an instance + */ +void FTU_StopGlobalTimeBase(uint32_t u32InstanceMask) +{ + uint32_t u32GTB = 0u, u32Loop0; + for (u32Loop0 = 0u; u32Loop0 < FTU_INSTANCE_COUNT; u32Loop0++) + { + uint32_t u32InstanceFlag = 1u << u32Loop0; + if (0u != (u32InstanceMask & u32InstanceFlag)) + { + u32GTB |= u32InstanceFlag; + SCM_HWA_ClearFtuGTBMask((uint8_t)u32Loop0); + } + } + SCM_HWA_ClearFtuGTBSelect(u32GTB); +} + +/** + * @brief Start the FTU global time base + * + * @param u32InstanceMask The selected FTU, each bit represents an instance + * @param u32StartMask Start time, refer to FTU_GlobalTimeBaseStartType + */ +void FTU_StartGlobalTimeBase(uint32_t u32InstanceMask, uint32_t u32StartMask) +{ + uint32_t u32GTB = 0u, u32Loop0, u32Loop1; + for (u32Loop0 = 0u; u32Loop0 < FTU_INSTANCE_COUNT; u32Loop0++) + { + uint32_t u32InstanceFlag = 1u << u32Loop0; + if (0u != (u32InstanceMask & u32InstanceFlag)) + { + if (u32StartMask & FTU_GTB_START_AT_ONCE) + { + u32GTB |= u32InstanceFlag; + } + for (u32Loop1 = 0u; u32Loop1 < TSTMP_MODULATE_COUNT; u32Loop1++) + { + if (u32StartMask & (FTU_GTB_START_AT_TSTMP1_MOD0 << u32Loop1)) + { + SCM_HWA_ConfigFtuGTBMask((uint8_t)u32Loop0, (1u << u32Loop1)); + } + } + } + } + SCM_HWA_SetFtuGTBSelect(u32GTB); +} + +/** + * @brief Stop the FTU instance + * + * @param eInstance the selected FTU instance + * @return FTU_StatusType whether the operation is successfully + */ +FTU_StatusType FTU_StopTimer(const FTU_InstanceType eInstance) +{ + FTU_StatusType eStatus = FTU_STATUS_SUCCESS; + if ((uint32_t)eInstance >= FTU_INSTANCE_COUNT) + { + eStatus = FTU_STATUS_PARAM_INVALID; + } + else + { + /* clear FTU module clock source */ + FTU_HWA_ConfigModuleClkSrc(s_pFtuBasePtrs[eInstance], FTU_MODULE_NO_CLK); + //FTU_HWA_ClearModuleCounter(s_pFtuBasePtrs[eInstance], 0); + } + return eStatus; +} + +/** + * @brief Ftu initialize interrupt function + * + * @param eInstance the selected FTU instance + * @param pIntStruct the configurations of the interrupt + * @return FTU_StatusType whether the operation is successfully + */ +FTU_StatusType FTU_InterruptInit(const FTU_InstanceType eInstance, const FTU_InterruptType *const pIntrStruct) +{ + FTU_StatusType eStatus = FTU_STATUS_SUCCESS; + uint32_t u32Loop; + if ((uint32_t)eInstance >= FTU_INSTANCE_COUNT) + { + eStatus = FTU_STATUS_PARAM_INVALID; + } + else + { + for(u32Loop = 0u; u32Loop < FTU_CHANNEL_CONTROLS_COUNT; u32Loop++) + { + if (0u != (pIntrStruct->u32InterruptMask & ((uint32_t)FTU_INTR_MASK_CHANNEL_0 << u32Loop))) + { + /* Enable Channel Interrupt */ + FTU_HWA_EnableChannelInterrupt(s_pFtuBasePtrs[eInstance], (uint8_t)u32Loop); + } + else + { + /* Disable Channel Interrupt */ + FTU_HWA_DisableChannelInterrupt(s_pFtuBasePtrs[eInstance], (uint8_t)u32Loop); + } + } + + if (0u != (pIntrStruct->u32InterruptMask & (uint32_t)FTU_INTR_MASK_OVERFLOW)) + { + /* Enable Overflow Interrupt */ + FTU_HWA_EnableOverflowInterrupt(s_pFtuBasePtrs[eInstance]); + } + else + { + /* Disable Overflow Interrupt */ + FTU_HWA_DisableOverflowInterrupt(s_pFtuBasePtrs[eInstance]); + } + + if (0u != (pIntrStruct->u32InterruptMask & (uint32_t)FTU_INTR_MASK_FAULT)) + { + /* Enable Fault Interrupt */ + FTU_HWA_EnableModuleFaultInterrupt(s_pFtuBasePtrs[eInstance]); + } + else + { + /* Disable Fault Interrupt */ + FTU_HWA_DisableModuleFaultInterrupt(s_pFtuBasePtrs[eInstance]); + } + + if (0u != (pIntrStruct->u32InterruptMask & (uint32_t)FTU_INTR_MASK_RELOAD_POINT)) + { + /* Enable Reload Point Interrupt */ + FTU_HWA_EnableReloadPointInterrupt(s_pFtuBasePtrs[eInstance]); + } + else + { + /* Disable Reload Point Interrupt */ + FTU_HWA_DisableReloadPointInterrupt(s_pFtuBasePtrs[eInstance]); + } + + /*register callback functions*/ + s_pChannelCallback[eInstance] = pIntrStruct->pChannelCallback; + s_pFaultCallback[eInstance] = pIntrStruct->pFaultCallback; + s_pOverflowCallback[eInstance] = pIntrStruct->pOverflowCallback; + s_pReloadPointCallback[eInstance] = pIntrStruct->pReloadPointCallback; + } + return eStatus; +} + +/** + * @brief initialize fault input of the selected Ftu instance + * + * @param eInstance the selected FTU instance + * @param pFaultInit the fault configurations of the FTU instance + * @return FTU_StatusType whether the operation is successfully + */ +FTU_StatusType FTU_FaultInit(const FTU_InstanceType eInstance, const FTU_FaultInitType *const pFaultInit) +{ + FTU_StatusType eStatus = FTU_STATUS_SUCCESS; + uint32_t u32Loop, u32Temp; + if ((uint32_t)eInstance >= FTU_INSTANCE_COUNT) + { + eStatus = FTU_STATUS_PARAM_INVALID; + } + else + { + /* configure fault mode */ + FTU_HWA_ConfigModuleFaultMode(s_pFtuBasePtrs[eInstance], pFaultInit->eFaultMode); + /* Disable all fault inputs*/ + u32Temp = FTU_HWA_GetFaultEnable(s_pFtuBasePtrs[eInstance]); + FTU_HWA_DisableModuleFault(s_pFtuBasePtrs[eInstance], 0xFu); + /* configure fault filter value */ + FTU_HWA_SetModuleFaultFilterValue(s_pFtuBasePtrs[eInstance], pFaultInit->u8FilterValue); + /* recover fault inputs*/ + FTU_HWA_EnableModuleFault(s_pFtuBasePtrs[eInstance], (uint8_t)u32Temp); + /* enables the fault control in channels */ + for(u32Loop = 0u; u32Loop < FTU_FAULT_COUNT; u32Loop++) + { + if (0u != (pFaultInit->u8FaultChannelEnable & ((uint8_t)FTU_FAULT_FOR_CHANNEL01 << u32Loop))) + { + FTU_HWA_EnableChannelFault(s_pFtuBasePtrs[eInstance], (uint8_t)u32Loop << 1u); + } + else + { + FTU_HWA_DisableChannelFault(s_pFtuBasePtrs[eInstance], (uint8_t)u32Loop << 1u); + } + } + + /* set fault disable channel output delay value */ + FTU_HWA_SetFaultDelay0(s_pFtuBasePtrs[eInstance], pFaultInit->u8FaultDisableDelay0); + FTU_HWA_SetFaultDelay1(s_pFtuBasePtrs[eInstance], pFaultInit->u8FaultDisableDelay1); + } + return eStatus; +} + +/** + * @brief Select fault disable channel output delay value + * + * @param eInstance the selected FTU instance + * @param u8Channel FTU channel number, range is 0-7. + * @param eSelection Fault disable channel output delay value selection. + * @return FTU_StatusType whether the operation is successfully + */ +FTU_StatusType FTU_FaultSelectDelayValue(const FTU_InstanceType eInstance, uint8_t u8Channel, FTU_FaultDisableDelayType eDelaySelection) +{ + FTU_StatusType eStatus = FTU_STATUS_SUCCESS; + if ((uint32_t)eInstance >= FTU_INSTANCE_COUNT) + { + eStatus = FTU_STATUS_PARAM_INVALID; + } + else if (u8Channel >= FTU_CHANNEL_CONTROLS_COUNT) + { + eStatus = FTU_STATUS_PARAM_INVALID; + } + else + { + FTU_HWA_SelectFaultDelay(s_pFtuBasePtrs[eInstance], u8Channel, eDelaySelection); + } + return eStatus; +} + +/** + * @brief Enable a fault input + * + * @param eInstance the selected FTU instance + * @param pFaultCtrl configurations of the fault input + * @return FTU_StatusType whether the operation is successfully + */ +FTU_StatusType FTU_FaultEnable(const FTU_InstanceType eInstance, const FTU_FaultControlType *const pFaultCtrl) +{ + FTU_StatusType eStatus = FTU_STATUS_SUCCESS; + + if (((uint32_t)eInstance >= FTU_INSTANCE_COUNT) || + (pFaultCtrl->u8FaultIndex >= FTU_FAULT_COUNT)) + { + eStatus = FTU_STATUS_PARAM_INVALID; + } + else + { + /* configure fault input polarity */ + FTU_HWA_ConfigFaultPolarity(s_pFtuBasePtrs[eInstance], pFaultCtrl->u8FaultIndex, (uint8_t)pFaultCtrl->eFaultPol); + if(true == pFaultCtrl->bFaultFilterEnable) + { + FTU_HWA_EnableModuleFaultGlitchFilter(s_pFtuBasePtrs[eInstance], 1u << pFaultCtrl->u8FaultIndex); + } + else + { + FTU_HWA_DisableModuleFaultGlitchFilter(s_pFtuBasePtrs[eInstance], 1u << pFaultCtrl->u8FaultIndex); + } + /* enable fault input */ + FTU_HWA_EnableModuleFault(s_pFtuBasePtrs[eInstance], 1u << pFaultCtrl->u8FaultIndex); + } + return eStatus; +} + +/** + * @brief Disable a fault input + * + * @param eInstance the selected FTU instance + * @param u32FaultIndex index of the fault input + * @return FTU_StatusType whether the operation is successfully + */ +FTU_StatusType FTU_FaultDisable(const FTU_InstanceType eInstance, uint32_t u32FaultIndex) +{ + FTU_StatusType eStatus = FTU_STATUS_SUCCESS; + if (((uint32_t)eInstance >= FTU_INSTANCE_COUNT) || + (u32FaultIndex >= FTU_FAULT_COUNT)) + { + eStatus = FTU_STATUS_PARAM_INVALID; + } + else + { + FTU_HWA_DisableModuleFault(s_pFtuBasePtrs[eInstance], 0x1u << u32FaultIndex); + } + return eStatus; +} + +/** + * @brief initialize a input capture channel of the selected Ftu instance + * + * @param eInstance the selected FTU instance + * @param pInputChannel configurations of the input capture channel + * @return FTU_StatusType whether the operation is successfully + */ +FTU_StatusType FTU_InputCaptureChannelInit(const FTU_InstanceType eInstance, + const FTU_InputChannelType *const pInputChannel) +{ + FTU_StatusType eStatus = FTU_STATUS_SUCCESS; + + if (((uint32_t)eInstance >= FTU_INSTANCE_COUNT) || + (pInputChannel->u8Channel >= FTU_CHANNEL_CONTROLS_COUNT)) + { + eStatus = FTU_STATUS_PARAM_INVALID; + } + else + { + FTU_HWA_DisableQuadratureMode(s_pFtuBasePtrs[eInstance]); + FTU_HWA_DisableChannelEnhancedPhase(s_pFtuBasePtrs[eInstance], pInputChannel->u8Channel); + FTU_HWA_DisableChannelPhase(s_pFtuBasePtrs[eInstance], pInputChannel->u8Channel); + FTU_HWA_ConfigInputCaptureMeasureMode(s_pFtuBasePtrs[eInstance], pInputChannel->u8Channel, + FTU_MEASURE_MODE_OFF); + FTU_HWA_ConfigChannelMode(s_pFtuBasePtrs[eInstance], pInputChannel->u8Channel, FTU_CHANNEL_MODE_INPUT); + if(pInputChannel->u8Channel < FTU_INPUT_FILTER_COUNT) + { + /* set FTU input capture filter value */ + FTU_HWA_ConfigInputCaptureFilter( + s_pFtuBasePtrs[eInstance], pInputChannel->u8Channel, + pInputChannel->u8FilterValue); + + } + + set_ftu_input_edge(s_pFtuBasePtrs[eInstance], pInputChannel->u8Channel, pInputChannel->eInputMode); + } + return eStatus; +} + +/** + * @brief initialize the quadrature decoder mode + * + * @param eInstance the selected FTU instance + * @param pQuadInit configurations of the quadrature decoder + * @return FTU_StatusType whether the operation is successfully + */ +FTU_StatusType FTU_QuadratureModeInit(const FTU_InstanceType eInstance, + const FTU_QuadratureInitType *const pQuadInit) +{ + FTU_StatusType eStatus = FTU_STATUS_SUCCESS; + + if (((uint32_t)eInstance != FTU_INSTANCE_1) && + ((uint32_t)eInstance != FTU_INSTANCE_2) && + ((uint32_t)eInstance != FTU_INSTANCE_4) && + ((uint32_t)eInstance != FTU_INSTANCE_5)) + { + /* Only FTU1/2/4/5 support quadrature decode*/ + eStatus = FTU_STATUS_PARAM_INVALID; + } + else + { + /* set quadrature mode */ + FTU_HWA_ConfigQuadratureMode(s_pFtuBasePtrs[eInstance], pQuadInit->eQuadMode); + /* set PHA polarity*/ + if(pQuadInit->bPhaInverted) + { + FTU_HWA_EnablePhaInv(s_pFtuBasePtrs[eInstance]); + } + else + { + FTU_HWA_DisablePhaInv(s_pFtuBasePtrs[eInstance]); + } + /* set PHB polarity*/ + if(pQuadInit->bPhbInverted) + { + FTU_HWA_EnablePhbInv(s_pFtuBasePtrs[eInstance]); + } + else + { + FTU_HWA_DisablePhbInv(s_pFtuBasePtrs[eInstance]); + } + + /* Set counter direction */ + FTU_HWA_ConfigQuadDirection(s_pFtuBasePtrs[eInstance], pQuadInit->eQuadDirection); + /* Set overflow direction */ + FTU_HWA_ConfigTimerOverflowDir(s_pFtuBasePtrs[eInstance], pQuadInit->eOveflowDirection); + /* set top value */ + FTU_HWA_SetModuleCompareValue(s_pFtuBasePtrs[eInstance], pQuadInit->u16TopValue); + /* set bottom value */ + FTU_HWA_SetCounterInitialValue(s_pFtuBasePtrs[eInstance], pQuadInit->u16BottomValue); + + /* Set phase A glitch filter value */ + if (0U != pQuadInit->u8PhaFilterVal) + { + FTU_HWA_ConfigChannelFilterValue(s_pFtuBasePtrs[eInstance], 0, pQuadInit->u8PhaFilterVal); + FTU_HWA_EnablePhaGlitchFilter(s_pFtuBasePtrs[eInstance]); + } + else + { + FTU_HWA_DisablePhaGlitchFilter(s_pFtuBasePtrs[eInstance]); + } + /* Set phase B glitch filter value */ + if (0U != pQuadInit->u8PhbFilterVal) + { + FTU_HWA_ConfigChannelFilterValue(s_pFtuBasePtrs[eInstance], 1, pQuadInit->u8PhbFilterVal); + FTU_HWA_EnablePhbGlitchFilter(s_pFtuBasePtrs[eInstance]); + } + else + { + FTU_HWA_DisablePhbGlitchFilter(s_pFtuBasePtrs[eInstance]); + } + /* enable the quadrature*/ + FTU_HWA_EnableQuadratureMode(s_pFtuBasePtrs[eInstance]); + } + return eStatus; +} +/** + * @brief Enable FTU interrupt + * + * @param eInstance the selected FTU instance + * @param u32InterruptMask interrupt enable mask + * @return FTU_StatusType whether the operation is successfully + */ +FTU_StatusType FTU_EnableInterrupt(const FTU_InstanceType eInstance, uint32_t u32InterruptMask) +{ + FTU_StatusType eStatus = FTU_STATUS_SUCCESS; + uint32_t u32Loop; + if ((uint32_t)eInstance >= FTU_INSTANCE_COUNT) + { + eStatus = FTU_STATUS_PARAM_INVALID; + } + else + { + for(u32Loop = 0u; u32Loop < FTU_CHANNEL_CONTROLS_COUNT; u32Loop++) + { + if (0u != (u32InterruptMask & ((uint32_t)FTU_INTR_MASK_CHANNEL_0 << u32Loop))) + { + /* Enable Channel Interrupt */ + FTU_HWA_EnableChannelInterrupt(s_pFtuBasePtrs[eInstance], (uint8_t)u32Loop); + } + } + + if (0u != (u32InterruptMask & (uint32_t)FTU_INTR_MASK_OVERFLOW)) + { + /* Enable Overflow Interrupt */ + FTU_HWA_EnableOverflowInterrupt(s_pFtuBasePtrs[eInstance]); + } + + if (0u != (u32InterruptMask & (uint32_t)FTU_INTR_MASK_FAULT)) + { + /* Enable Fault Interrupt */ + FTU_HWA_EnableModuleFaultInterrupt(s_pFtuBasePtrs[eInstance]); + } + + if (0u != (u32InterruptMask & (uint32_t)FTU_INTR_MASK_RELOAD_POINT)) + { + /* Enable Reload Point Interrupt */ + FTU_HWA_EnableReloadPointInterrupt(s_pFtuBasePtrs[eInstance]); + } + } + return eStatus; +} + +/** + * @brief Disable FTU interrupt + * + * @param eInstance the selected FTU instance + * @param u32InterruptMask interrupt disable mask + * @return FTU_StatusType whether the operation is successfully + */ +FTU_StatusType FTU_DisableInterrupt(const FTU_InstanceType eInstance, uint32_t u32InterruptMask) +{ + FTU_StatusType eStatus = FTU_STATUS_SUCCESS; + uint32_t u32Loop; + if ((uint32_t)eInstance >= FTU_INSTANCE_COUNT) + { + eStatus = FTU_STATUS_PARAM_INVALID; + } + else + { + for(u32Loop = 0; u32Loop < FTU_CHANNEL_CONTROLS_COUNT; u32Loop++) + { + if (0u != (u32InterruptMask & ((uint32_t)FTU_INTR_MASK_CHANNEL_0 << u32Loop))) + { + /* Disable Channel Interrupt */ + FTU_HWA_DisableChannelInterrupt(s_pFtuBasePtrs[eInstance], (uint8_t)u32Loop); + } + } + + if (0u != (u32InterruptMask & (uint32_t)FTU_INTR_MASK_OVERFLOW)) + { + /* Disable Overflow Interrupt */ + FTU_HWA_DisableOverflowInterrupt(s_pFtuBasePtrs[eInstance]); + } + + if (0u != (u32InterruptMask & (uint32_t)FTU_INTR_MASK_FAULT)) + { + /* Disable Fault Interrupt */ + FTU_HWA_DisableModuleFaultInterrupt(s_pFtuBasePtrs[eInstance]); + } + + if (0u != (u32InterruptMask & (uint32_t)FTU_INTR_MASK_RELOAD_POINT)) + { + /* Disable Reload Point Interrupt */ + FTU_HWA_DisableReloadPointInterrupt(s_pFtuBasePtrs[eInstance]); + } + } + return eStatus; +} + +/** + * @brief Clear the fault flag of the FTU instance + * + * @param eInstance the selected FTU instance + * @param u32FaultFlag flag to clear + * @return FTU_StatusType whether the operation is successfully + */ +FTU_StatusType FTU_ClearFault(const FTU_InstanceType eInstance, uint32_t u32FaultFlag) +{ + FTU_StatusType eStatus = FTU_STATUS_SUCCESS; + if ((uint32_t)eInstance >= FTU_INSTANCE_COUNT) + { + eStatus = FTU_STATUS_PARAM_INVALID; + } + else + { + FTU_HWA_ClearModuleFaultFlag(s_pFtuBasePtrs[eInstance], (uint8_t)u32FaultFlag); + } + return eStatus; +} + +/** + * @brief Get the fault flag of the FTU instance + * + * @param eInstance the selected FTU instance + * @return uint32_t the fault flag of the selected Ftu instance + */ +uint32_t FTU_GetFaultFlag(const FTU_InstanceType eInstance) +{ + uint32_t u32FaultFlag = 0; + if ((uint32_t)eInstance < FTU_INSTANCE_COUNT) + { + u32FaultFlag = FTU_HWA_ReadModuleFaultFlag(s_pFtuBasePtrs[eInstance]); + } + return u32FaultFlag; +} + + +/** + * @brief Enable ftu channel DMA + * + * @param eInstance the selected FTU instance + * @param u32DmaMask The dma channel mask. + * @return FTU_StatusType whether the operation is successfully + */ + +FTU_StatusType FTU_EnableChannelDma(const FTU_InstanceType eInstance, uint32_t u32DmaMask) +{ + FTU_StatusType eStatus = FTU_STATUS_SUCCESS; + uint32_t u32Loop; + if ((uint32_t)eInstance >= FTU_INSTANCE_COUNT) + { + eStatus = FTU_STATUS_PARAM_INVALID; + } + else + { + for(u32Loop = 0u; u32Loop < FTU_CHANNEL_CONTROLS_COUNT; u32Loop++) + { + if (0u != (u32DmaMask & ((uint32_t)FTU_INTR_MASK_CHANNEL_0 << u32Loop))) + { + /* Enable Channel Interrupt */ + FTU_HWA_EnableChannelDma(s_pFtuBasePtrs[eInstance], (uint8_t)u32Loop); + } + } + + } + return eStatus; +} + +/** + * @brief Initialize a Expect Edge Number Measurement channel + * + * @param eInstance the selected FTU instance + * @param pExpectEdgeNumMeasure measurement configuration. + * @return FTU_StatusType whether the operation is successfully + */ +FTU_StatusType FTU_ExpectEdgeNumberMeasureChannelInit(const FTU_InstanceType eInstance, FTU_ExpectEdgeNumberMeasureType *pExpectEdgeNumMeasure) +{ + FTU_StatusType eStatus = FTU_STATUS_SUCCESS; + if ( ((uint32_t)eInstance >= FTU_INSTANCE_COUNT) + || (pExpectEdgeNumMeasure->u8Channel >= FTU_CHANNEL_CONTROLS_COUNT) + || (pExpectEdgeNumMeasure->u8Channel & 1u)) + { + eStatus = FTU_STATUS_PARAM_INVALID; + } + else + { + FTU_HWA_ConfigChannelMode(s_pFtuBasePtrs[eInstance], pExpectEdgeNumMeasure->u8Channel, + FTU_CHANNEL_MODE_INPUT); + set_ftu_input_edge(s_pFtuBasePtrs[eInstance], pExpectEdgeNumMeasure->u8Channel, + pExpectEdgeNumMeasure->eEdgeMode); + FTU_HWA_ConfigChannelEdgeLevel(s_pFtuBasePtrs[eInstance], pExpectEdgeNumMeasure->u8Channel + 1u, + FTU_CHANNEL_EDGE_NOT_USED); + FTU_HWA_ConfigEdgeNumber(s_pFtuBasePtrs[eInstance], pExpectEdgeNumMeasure->u8Channel + 1, + pExpectEdgeNumMeasure->u8ExpectEdgeNumber); + if (FTU_MEASURE_CONTINUOUS_MODE == pExpectEdgeNumMeasure->eContinuouslyMode) + { + FTU_HWA_EnableMeasureContinous(s_pFtuBasePtrs[eInstance], pExpectEdgeNumMeasure->u8Channel); + } + else + { + FTU_HWA_DisableMeasureContinous(s_pFtuBasePtrs[eInstance], pExpectEdgeNumMeasure->u8Channel); + } + /* Must put the ICM_MODE setting at the end, otherwise it will not be configured correctly. */ + FTU_HWA_ConfigInputCaptureMeasureMode( s_pFtuBasePtrs[eInstance], pExpectEdgeNumMeasure->u8Channel, + FTU_MEASURE_EXPECT_EDGE_NUMBER); + } + return eStatus; +} + +/** + * @brief Initialize a Edge Number Measurement channel + * + * @param eInstance the selected FTU instance + * @param pEdgeNumMeasure measurement configuration. + * @return FTU_StatusType whether the operation is successfully + */ +FTU_StatusType FTU_EdgeNumberMeasureChannelInit(const FTU_InstanceType eInstance, FTU_EdgeNumberMeasureType *pEdgeNumMeasure) +{ + FTU_StatusType eStatus = FTU_STATUS_SUCCESS; + if ( ((uint32_t)eInstance >= FTU_INSTANCE_COUNT) + || (pEdgeNumMeasure->u8Channel >= FTU_CHANNEL_CONTROLS_COUNT) + || (pEdgeNumMeasure->u8Channel & 1u) + || (pEdgeNumMeasure->u32StartWindow >= pEdgeNumMeasure->u32EndWindow) + || (pEdgeNumMeasure->u32StartWindow > s_aFtuMaxCounter[eInstance])) + { + eStatus = FTU_STATUS_PARAM_INVALID; + } + else + { + FTU_HWA_ConfigChannelMode(s_pFtuBasePtrs[eInstance], pEdgeNumMeasure->u8Channel, + FTU_CHANNEL_MODE_INPUT); + set_ftu_input_edge(s_pFtuBasePtrs[eInstance], pEdgeNumMeasure->u8Channel, pEdgeNumMeasure->eEdgeMode); + + FTU_HWA_ConfigChannelEdgeLevel(s_pFtuBasePtrs[eInstance], pEdgeNumMeasure->u8Channel + 1u, + FTU_CHANNEL_EDGE_NOT_USED); + FTU_HWA_ConfigInputCaptureMeasureMode(s_pFtuBasePtrs[eInstance], pEdgeNumMeasure->u8Channel, + FTU_MEASURE_ICENM_WIND_WRITE); + FTU_HWA_SetChannelValue(s_pFtuBasePtrs[eInstance], pEdgeNumMeasure->u8Channel, + pEdgeNumMeasure->u32StartWindow); + FTU_HWA_SetChannelValue(s_pFtuBasePtrs[eInstance], pEdgeNumMeasure->u8Channel + 1u, + pEdgeNumMeasure->u32EndWindow); + FTU_HWA_ConfigInputCaptureMeasureMode( s_pFtuBasePtrs[eInstance], pEdgeNumMeasure->u8Channel, + FTU_MEASURE_EDGE_NUMBER); + if (FTU_MEASURE_CONTINUOUS_MODE == pEdgeNumMeasure->eContinuouslyMode) + { + FTU_HWA_EnableMeasureContinous(s_pFtuBasePtrs[eInstance], pEdgeNumMeasure->u8Channel); + } + else + { + FTU_HWA_DisableMeasureContinous(s_pFtuBasePtrs[eInstance], pEdgeNumMeasure->u8Channel); + } + + } + return eStatus; +} + +/** + * @brief Get the expect edge number result of the channel + * + * @param eInstance the selected FTU instance + * @param u8Channel FTU channel number, range is 0-7. + * @param pResult point to the result buffer. + * @return FTU_StatusType whether the operation is successfully + */ +FTU_StatusType FTU_GetExpectEdgeNumberResult(const FTU_InstanceType eInstance, uint8_t u8Channel, FTU_ExpectEdgeNumberResultType *pResult) +{ + FTU_StatusType eStatus = FTU_STATUS_SUCCESS; + if ( ((uint32_t)eInstance >= FTU_INSTANCE_COUNT) + || (u8Channel >= FTU_CHANNEL_CONTROLS_COUNT) + || (u8Channel & 1u)) + { + eStatus = FTU_STATUS_PARAM_INVALID; + } + else + { + pResult->u32FirstEdgeTime = FTU_HWA_GetChannelValue(s_pFtuBasePtrs[eInstance], u8Channel); + pResult->u32LastEdgeTime = FTU_HWA_GetChannelValue(s_pFtuBasePtrs[eInstance], u8Channel + 1); + } + return eStatus; +} + +/** + * @brief Get Edge number counter + * + * @param eInstance the selected FTU instance + * @param u8Channel FTU channel number. + * @return uint8_t Edge number counter + */ +uint8_t FTU_GetEdgeNumberCount(const FTU_InstanceType eInstance, uint8_t u8Channel) +{ + uint8_t u8Count = 0; + if ( ((uint32_t)eInstance >= FTU_INSTANCE_COUNT) + || (u8Channel >= FTU_CHANNEL_CONTROLS_COUNT) + || (u8Channel & 1u)) + { + + } + else + { + u8Count = FTU_HWA_GetEdgeNumberCount(s_pFtuBasePtrs[eInstance], u8Channel); + } + return u8Count; +} +/** + * @brief Initialize a signal measure channel + * + * @param eInstance the selected FTU instance + * @param pMeasure measurement configuration. + * @return FTU_StatusType whether the operation is successfully + */ +FTU_StatusType FTU_SignalMeasureChannelInit(const FTU_InstanceType eInstance, FTU_SignalMeasureType *pMeasure) +{ + FTU_StatusType eStatus = FTU_STATUS_SUCCESS; + if ( ((uint32_t)eInstance >= FTU_INSTANCE_COUNT) + || (pMeasure->u8Channel >= FTU_CHANNEL_CONTROLS_COUNT) + || (pMeasure->u8Channel & 1u)) + { + eStatus = FTU_STATUS_PARAM_INVALID; + } + else + { + FTU_HWA_ConfigInputCaptureMeasureMode(s_pFtuBasePtrs[eInstance], pMeasure->u8Channel, FTU_MEASURE_MODE_OFF); + FTU_HWA_ConfigInputCaptureMeasureMode(s_pFtuBasePtrs[eInstance], pMeasure->u8Channel + 1u, FTU_MEASURE_MODE_OFF); + FTU_HWA_DisableChannelEnhancedPhase(s_pFtuBasePtrs[eInstance], pMeasure->u8Channel); + FTU_HWA_DisableChannelPhase(s_pFtuBasePtrs[eInstance], pMeasure->u8Channel); + FTU_HWA_DisableChannelEnhancedPhase(s_pFtuBasePtrs[eInstance], pMeasure->u8Channel + 1u); + FTU_HWA_DisableChannelPhase(s_pFtuBasePtrs[eInstance], pMeasure->u8Channel + 1u); + FTU_HWA_DisableModuleCpwmMode(s_pFtuBasePtrs[eInstance]); + + FTU_HWA_ConfigChannelMode(s_pFtuBasePtrs[eInstance], pMeasure->u8Channel, FTU_CHANNEL_MODE_INPUT); + FTU_HWA_ConfigChannelMode(s_pFtuBasePtrs[eInstance], pMeasure->u8Channel + 1u, FTU_CHANNEL_MODE_INPUT); + if (FTU_SIGNAL_MEASURE_HIGH_TIME == pMeasure->eMeasureMode) + { + FTU_HWA_ConfigChannelEdgeLevel(s_pFtuBasePtrs[eInstance], pMeasure->u8Channel, FTU_CHANNEL_EDGE_RISING); + FTU_HWA_ConfigChannelEdgeLevel(s_pFtuBasePtrs[eInstance], pMeasure->u8Channel + 1u, FTU_CHANNEL_EDGE_FALLING); + FTU_HWA_ConfigInputCaptureMeasureMode(s_pFtuBasePtrs[eInstance], pMeasure->u8Channel, FTU_MEASURE_MODE_DUTY_CYCLE); + FTU_HWA_ConfigInputCaptureMeasureMode(s_pFtuBasePtrs[eInstance], pMeasure->u8Channel + 1, FTU_MEASURE_MODE_DUTY_CYCLE); + FTU_HWA_SetChannelPolarity(s_pFtuBasePtrs[eInstance], 1u << pMeasure->u8Channel); + } + else if (FTU_SIGNAL_MEASURE_LOW_TIME == pMeasure->eMeasureMode) + { + FTU_HWA_ConfigChannelEdgeLevel(s_pFtuBasePtrs[eInstance], pMeasure->u8Channel, FTU_CHANNEL_EDGE_RISING); + FTU_HWA_ConfigChannelEdgeLevel(s_pFtuBasePtrs[eInstance], pMeasure->u8Channel + 1u, FTU_CHANNEL_EDGE_FALLING); + FTU_HWA_ConfigInputCaptureMeasureMode(s_pFtuBasePtrs[eInstance], pMeasure->u8Channel, FTU_MEASURE_MODE_DUTY_CYCLE); + FTU_HWA_ConfigInputCaptureMeasureMode(s_pFtuBasePtrs[eInstance], pMeasure->u8Channel + 1u, FTU_MEASURE_MODE_DUTY_CYCLE); + FTU_HWA_ClearChannelPolarity(s_pFtuBasePtrs[eInstance], 1u << pMeasure->u8Channel); + } + else if (FTU_SIGNAL_MEASURE_PERIOD_RISING_EDGE == pMeasure->eMeasureMode) + { + FTU_HWA_ConfigChannelEdgeLevel(s_pFtuBasePtrs[eInstance], pMeasure->u8Channel, FTU_CHANNEL_EDGE_RISING); + FTU_HWA_ConfigChannelEdgeLevel(s_pFtuBasePtrs[eInstance], pMeasure->u8Channel + 1u, FTU_CHANNEL_EDGE_NOT_USED); + FTU_HWA_ConfigInputCaptureMeasureMode(s_pFtuBasePtrs[eInstance], pMeasure->u8Channel, FTU_MEASURE_MODE_PERIOD); + FTU_HWA_ConfigInputCaptureMeasureMode(s_pFtuBasePtrs[eInstance], pMeasure->u8Channel + 1u, FTU_MEASURE_MODE_PERIOD); + } + else if (FTU_SIGNAL_MEASURE_PERIOD_FALLING_EDGE == pMeasure->eMeasureMode) + { + FTU_HWA_ConfigChannelEdgeLevel(s_pFtuBasePtrs[eInstance], pMeasure->u8Channel, FTU_CHANNEL_EDGE_FALLING); + FTU_HWA_ConfigChannelEdgeLevel(s_pFtuBasePtrs[eInstance], pMeasure->u8Channel + 1u, FTU_CHANNEL_EDGE_NOT_USED); + FTU_HWA_ConfigInputCaptureMeasureMode(s_pFtuBasePtrs[eInstance], pMeasure->u8Channel, FTU_MEASURE_MODE_PERIOD); + FTU_HWA_ConfigInputCaptureMeasureMode(s_pFtuBasePtrs[eInstance], pMeasure->u8Channel + 1u, FTU_MEASURE_MODE_PERIOD); + } + + if (FTU_MEASURE_CONTINUOUS_MODE == pMeasure->eContinuouslyMode) + { + FTU_HWA_EnableMeasureContinous(s_pFtuBasePtrs[eInstance], pMeasure->u8Channel); + } + else + { + FTU_HWA_DisableMeasureContinous(s_pFtuBasePtrs[eInstance], pMeasure->u8Channel); + } + + if (FTU_MEASURE_START_IMMEDIATELY == pMeasure->eStartMode) + { + FTU_HWA_EnableMeasureStartImmd(s_pFtuBasePtrs[eInstance], pMeasure->u8Channel); + } + else + { + FTU_HWA_DisableMeasureStartImmd(s_pFtuBasePtrs[eInstance], pMeasure->u8Channel); + } + } + return eStatus; +} +/** + * @brief Re-start measurement when in single mode + * + * @param eInstance the selected FTU instance + * @param u8Channel FTU channel number, range is 0-7. + * @return FTU_StatusType whether the operation is successfully + */ +FTU_StatusType FTU_SignalMeasureChannelSingle(const FTU_InstanceType eInstance, uint8_t u8Channel) +{ + FTU_StatusType eStatus = FTU_STATUS_SUCCESS; + if ( ((uint32_t)eInstance >= FTU_INSTANCE_COUNT) + || (u8Channel >= FTU_CHANNEL_CONTROLS_COUNT) + || (u8Channel & 1u)) + { + eStatus = FTU_STATUS_PARAM_INVALID; + } + else + { + FTU_HWA_SingleMeasurement(s_pFtuBasePtrs[eInstance], u8Channel); + } + return eStatus; +} + +/** + * @brief Get the measurement result of the channel + * + * @param eInstance the selected FTU instance + * @param u8Channel FTU channel number, range is 0-7. + * @param pResult point to the result buffer. + * @return FTU_StatusType whether the operation is successfully + */ +FTU_StatusType FTU_GetSignalMeasureResult(const FTU_InstanceType eInstance, uint8_t u8Channel, FTU_SignalMeasureValueType *pResult) +{ + FTU_StatusType eStatus = FTU_STATUS_SUCCESS; + if ( ((uint32_t)eInstance >= FTU_INSTANCE_COUNT) + || (u8Channel >= FTU_CHANNEL_CONTROLS_COUNT) + || (u8Channel & 1u)) + { + eStatus = FTU_STATUS_PARAM_INVALID; + } + else + { + FTU_MeasurementModeType eMeasureMode = FTU_HWA_GetMeasureMode(s_pFtuBasePtrs[eInstance], u8Channel); + if (FTU_MEASURE_MODE_DUTY_CYCLE == eMeasureMode) + { + if (FTU_HWA_GetChannelPolarity(s_pFtuBasePtrs[eInstance], 1u << u8Channel)) + { + pResult->u32StartTime = FTU_HWA_GetChannelValue(s_pFtuBasePtrs[eInstance], u8Channel); + pResult->u32EndTime = FTU_HWA_GetChannelValue(s_pFtuBasePtrs[eInstance], u8Channel + 1); + } + else + { + pResult->u32StartTime = FTU_HWA_GetChannelValue(s_pFtuBasePtrs[eInstance], u8Channel + 1); + pResult->u32EndTime = FTU_HWA_GetChannelValue(s_pFtuBasePtrs[eInstance], u8Channel); + } + } + else if(FTU_MEASURE_MODE_PERIOD == eMeasureMode) + { + pResult->u32StartTime = FTU_HWA_GetChannelValue(s_pFtuBasePtrs[eInstance], u8Channel + 1); + pResult->u32EndTime = FTU_HWA_GetChannelValue(s_pFtuBasePtrs[eInstance], u8Channel); + } + else + { + pResult->u32StartTime = 0u; + pResult->u32EndTime = 0u; + } + } + return eStatus; +} + + + +/** + * @brief Interrupt IRQ handle of FTU instance + * + * @param eInstance the selected FTU instance + */ +void FTUn_IRQHandler(const FTU_InstanceType eInstance) +{ + uint32_t u32FaultFlag = 0u; + uint8_t u8FaultEnable = FTU_HWA_ReadFaultIntrEnable(s_pFtuBasePtrs[eInstance]); + uint8_t u8OverflowFlag = FTU_HWA_ReadModuleOverflowFlag(s_pFtuBasePtrs[eInstance]); + uint8_t u8ReloadFlag = FTU_HWA_ReadReloadIntrEnable(s_pFtuBasePtrs[eInstance]); + uint32_t u32Loop, u32ChannelIntrFlag = 0; + uint16_t u16TimeStamp; + + u8OverflowFlag = FTU_HWA_ReadModuleOverflowIntrEnable(s_pFtuBasePtrs[eInstance]) & u8OverflowFlag; + u8ReloadFlag = FTU_HWA_ReadModuleReloadFlag(s_pFtuBasePtrs[eInstance]) & u8ReloadFlag; + if(0u != u8FaultEnable) + { + u32FaultFlag = FTU_HWA_ReadModuleFaultFlag(s_pFtuBasePtrs[eInstance]); + } + + /* Clear interrupt flag*/ + if (0u != u8OverflowFlag) + { + FTU_HWA_ClearOverflowFlag(s_pFtuBasePtrs[eInstance]); + } + if (0u != u8ReloadFlag) + { + FTU_HWA_ClearReloadFlag(s_pFtuBasePtrs[eInstance]); + } + + for (u32Loop = 0U; u32Loop < FTU_CHANNEL_CONTROLS_COUNT; u32Loop++) + { + if ((0u != FTU_HWA_ReadChannelInterruptFlag(s_pFtuBasePtrs[eInstance], (uint8_t)u32Loop)) && + (0u != FTU_HWA_ReadChannelInterruptEnableFlag(s_pFtuBasePtrs[eInstance], (uint8_t)u32Loop))) + { + FTU_HWA_ClearChannelInterruptFlag(s_pFtuBasePtrs[eInstance], (uint8_t)u32Loop); + u32ChannelIntrFlag |= (uint8_t)(1u << u32Loop); + } + } + + /* call callback functions*/ + if ((0u != u8OverflowFlag) && (NULL != s_pOverflowCallback[eInstance])) + { + s_pOverflowCallback[eInstance](); + } + + if ((0u != u8ReloadFlag) && (NULL != s_pReloadPointCallback[eInstance])) + { + s_pReloadPointCallback[eInstance](); + } + + if ((0u != u32FaultFlag) && (NULL != s_pFaultCallback[eInstance])) + { + for (u32Loop = 0U; u32Loop < FTU_FAULT_COUNT; u32Loop++) + { + if (0u != (u32FaultFlag & ((uint32_t)1u << u32Loop))) + { + s_pFaultCallback[eInstance](u32Loop); + } + } + } + + if ((0u != u32ChannelIntrFlag) && (NULL != s_pChannelCallback[eInstance])) + { + for (u32Loop = 0U; u32Loop < FTU_CHANNEL_CONTROLS_COUNT; u32Loop++) + { + if (0u != (u32ChannelIntrFlag & ((uint32_t)1u << u32Loop))) + { + u16TimeStamp = (uint16_t)FTU_HWA_GetChannelValue(s_pFtuBasePtrs[eInstance], (uint8_t)u32Loop); + s_pChannelCallback[eInstance](u32Loop, u16TimeStamp); + } + } + } +} diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_gpio.c b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_gpio.c new file mode 100644 index 0000000..68080a3 --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_gpio.c @@ -0,0 +1,175 @@ +/** + * @file fc7xxx_driver_gpio.h + * @author Flagchip + * @brief FC7xxx GPIO driver type definition and API + * @version 0.1.0 + * @date 2023-2-14 + * + * @copyright Copyright (c) 2023 Flagchip Semiconductors Co., Ltd. + * + * @details + */ +/******************************************************************************** +* Revision History: +* +* Version Date Initials CR# Descriptions +* --------- ---------- ------------ ---------- --------------- +* 0.1.0 31/12/2022 Flagchip0121 N/A First version for FC7240 +********************************************************************************/ + +#include "fc7xxx_driver_gpio.h" + +/** @brief Gpio instance list */ +static GPIO_Type *s_pGpioInstanceTable[GPIO_INSTANCE_COUNT] = GPIO_BASE_PTRS; + +/** + * @brief Initialize GPIO. + * + * @param eGpio GPIO instance + * @param pInitStruct Initialization structure of GPIO. + */ +GPIO_StatusType GPIO_InitPins(const GPIO_InstanceType eGpio, const GPIO_InitType *const pInitStruct) +{ + GPIO_StatusType eRet = GPIO_STATUS_SUCCESS; + GPIO_Type *pGpio; + uint32_t u32TempPins = 0U; + uint8_t u8PinIndex = 0U; + + if ((uint32_t)eGpio >= GPIO_INSTANCE_COUNT) + { + eRet = GPIO_STATUS_PARAM_INVALID; + } + else + { + pGpio = s_pGpioInstanceTable[(uint32_t)(eGpio)]; + u32TempPins = pInitStruct->u32GpioPins; + while (u32TempPins != 0u) + { + if ((u32TempPins & ((uint32_t)1 << u8PinIndex)) != 0u) + { + if (GPIO_OUT == pInitStruct->ePinDirection) + { + if (GPIO_LOW == pInitStruct->ePinLevel) + { + GPIO_HWA_ClearPinOutput(pGpio, u8PinIndex); + } + else + { + GPIO_HWA_SetPinOutput(pGpio, u8PinIndex); + } + GPIO_HWA_SetPinDirection(pGpio, u8PinIndex); + } + else if (GPIO_IN == pInitStruct->ePinDirection) + { + GPIO_HWA_ClearPinDirection(pGpio, u8PinIndex); + } + else + { + GPIO_HWA_SetPinInputDisable(pGpio, u8PinIndex); /* GPIO_ZERO == pInitStruct->ePinDirection */ + } + } + else + { + + } + u32TempPins &= (uint32_t)~((uint32_t)1 << u8PinIndex); + u8PinIndex++; + } + } + return eRet; +} +/** + * @brief De-initialize the GPIO pin + * + * @param eGpio Gpio instance enumeration + * @param u32Pins The bit of u32Pins indicate the Pin number of this Gpio instance. + * @return GPIO status type. + */ +GPIO_StatusType GPIO_Deinit(const GPIO_InstanceType eGpio, const uint32_t u32Pins) +{ + DEV_ASSERT(eGpio < GPIO_INSTANCE_COUNT); + + GPIO_StatusType eRet = GPIO_STATUS_SUCCESS; + GPIO_Type *pGpio = s_pGpioInstanceTable[(uint32_t)(eGpio)]; + uint8_t u8PinIndex = 0U; + uint32_t u32TempPins = u32Pins; + + while (u32TempPins != 0) + { + if (u32TempPins & ((uint32_t)1 << u8PinIndex)) + { + GPIO_HWA_ClearPinDirection(pGpio, u8PinIndex); + GPIO_HWA_ClearPinDataOutput(pGpio, u8PinIndex); + GPIO_HWA_ClearPinInputDisable(pGpio, u8PinIndex); + } + u32TempPins &= (uint32_t)~((uint32_t)1 << u8PinIndex); + u8PinIndex++; + } + return eRet; +} + +/** + * @brief Read level of input port pins. + * + * @param eGpio Port instance for GPIO functionality + * @param u32Pins The bit of u32Pins indicate the pin number of this Port. + * @return Pins level + */ +uint32_t GPIO_ReadPins(const GPIO_InstanceType eGpio, const uint32_t u32Pins) +{ + DEV_ASSERT(eGpio < GPIO_INSTANCE_COUNT); + GPIO_Type *pGpio = s_pGpioInstanceTable[(uint32_t)eGpio]; + return (GPIO_HWA_ReadPortDataInput(pGpio) & u32Pins); +} + +/** + * @brief Write gpio level to u32Pins. + * + * @param eGpio Port instance for GPIO functionality + * @param u32Pins The bit of u32Pins indicate the pin number of this Port. + * @param eOutput Output level enumeration + * @return Port return type. + */ +GPIO_StatusType GPIO_WritePins(const GPIO_InstanceType eGpio, const uint32_t u32Pins, const GPIO_PinLevelType eOutput) +{ + GPIO_StatusType eRet = GPIO_STATUS_SUCCESS; + GPIO_Type *pGpio = s_pGpioInstanceTable[(uint32_t)eGpio]; + if (((uint32_t)eGpio >= GPIO_INSTANCE_COUNT) || (eOutput > GPIO_HIGH)) + { + eRet = GPIO_STATUS_PARAM_INVALID; + } + else + { + if (GPIO_HIGH == eOutput) + { + GPIO_HWA_SetPortOutput(pGpio, u32Pins); + } + else + { + GPIO_HWA_ClearPortOutput(pGpio, u32Pins); + } + } + return eRet; +} + +/** + * @brief Toggle gpio api + * + * @param eGpio eGpio Port instance for GPIO functionality + * @param u32Pins The bit of u32Pins indicate the pin number of this Port. + * @return Port return type. + */ +GPIO_StatusType GPIO_Toggle(const GPIO_InstanceType eGpio, const uint32_t u32Pins) +{ + GPIO_StatusType eRet = GPIO_STATUS_SUCCESS; + GPIO_Type *pGpio = s_pGpioInstanceTable[(uint32_t)eGpio]; + if ((uint32_t)(eGpio >= GPIO_INSTANCE_COUNT)) + { + eRet = GPIO_STATUS_PARAM_INVALID; + } + else + { + GPIO_HWA_TogglePort(pGpio, u32Pins); + } + return eRet; +} diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_hsm.c b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_hsm.c new file mode 100644 index 0000000..094c12d --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_hsm.c @@ -0,0 +1,648 @@ +/** + * @file fc7xxx_driver_hsm.c + * @author Flagchip0103 + * @brief FC7xxx HSM driver source file + * @version 0.1.0 + * @date 2023-12-20 + * + * @copyright Copyright (c) 2023 Flagchip Semiconductors Co., Ltd. + * + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2023-12-20 Flagchip0103 N/A First version for FC7240 + ******************************************************************************** */ + +#include "fc7xxx_driver_hsm.h" + +/* ################################################################################## */ +/* ##################################### Macros ##################################### */ + +typedef enum { + HSM_CMD_ID_TRNG = 0xb55du, + HSM_CMD_ID_SHA = 0xfce2u, + HSM_CMD_ID_ECC_SIGN = 0xde41u, + HSM_CMD_ID_ECC_VERIFY = 0xa522u, + HSM_CMD_ID_SM2_GENKEYPAIR = 0xc9ddu, + HSM_CMD_ID_SM2_ENCRY = 0x30f1u, + HSM_CMD_ID_SM2_DECRY = 0x6351u, + HSM_CMD_ID_SM2_SIGN = 0xe814u, + HSM_CMD_ID_SM2_VERIFY = 0x6e1eu, + HSM_CMD_ID_SM2_GENZA = 0xdbbeu, + HSM_CMD_ID_SM2_GENHASH = 0x5ce5u, + HSM_CMD_ID_SM4_ENCRY = 0xfd5au, + HSM_CMD_ID_SM4_DECRY = 0x4aedu, + HSM_CMD_ID_ECC_ENCRY = 0x4d3fu, + HSM_CMD_ID_ECC_DECRY = 0x97e4u, + HSM_CMD_ID_REQUEST_AUTH = 0x33d9u, + HSM_CMD_ID_LIFECYCLE_CHANGE = 0xbe63u, /* prefa,fa not support in sdk */ + HSM_CMD_ID_DEBUG_AUTH = 0x3928u, // TODO: delete + HSM_CMD_ID_ISP_AUTH = 0xAFBAu, // TODO: delete + HSM_CMD_ID_REVOKE_MRK = 0x19bbu, // TODO: delete + HSM_CMD_ID_REVOKE_UMRK = 0xfdb4u, // TODO: delete + HSM_CMD_ID_USER_KEY_ERASE = 0xac3au, // TODO: delete + HSM_CMD_ID_FLASHTEST_VERIFY = 0xcc29u, // TODO: delete + HSM_CMD_ID_UESR_CODE_VERIFY = 0x72d6u, // TODO: delete + HSM_CMD_ID_CANCEL_JOB = 0x17c3u, + HSM_CMD_ID_SELF_TEST = 0x4e93u, + HSM_CMD_ID_NVR_OTP = 0x2cd8u, + HSM_CMD_ID_LIFECYCLE_CHANGE_TAKE_EFFECT = 0x30fau, + HSM_CMD_ID_USER_KEY_MANAGE = 0xf4cfu, + HSM_CMD_ID_SPACE_MANAGE = 0x4ac0u, + HSM_CMD_ID_AES_ENCRY = 0xa2c6u, + HSM_CMD_ID_AES_DECRY = 0x6576u, + HSM_CMD_ID_CMAC_GEN = 0xf0b9u, + HSM_CMD_ID_XMAC_GEN = 0x32acu, + HSM_CMD_ID_CCM_ENCRY = 0x862fu, + HSM_CMD_ID_CCM_DECRY = 0x79a4u, + HSM_CMD_ID_GCM_ENCRY = 0xd1a6u, + HSM_CMD_ID_GCM_DECRY = 0xc0a3u, + HSM_CMD_ID_MD5 = 0x9371u, + HSM_CMD_ID_SM3 = 0xcfe5u, + HSM_CMD_ID_MONOTONIC_COUNTER = 0xdc97u, + HSM_CMD_ID_RSA = 0x866cu, + HSM_CMD_ID_USRK_GEN = 0xddb7u, // TODO: delete + HSM_CMD_ID_LOAD_FIRMWARE = 0x503du, + HSM_CMD_ID_DH_SM = 0x7F8Au, + HSM_CMD_ID_ECDH = 0x4b06u, + HSM_CMD_ID_DH = 0xb81bu, + HSM_CMD_ID_DH_PBKDF2 = 0xa47du, + HSM_CMD_ID_DH_GMPBKDF = 0xbe1fu, + HSM_CMD_ID_SCATTER_HASH = 0x465du, + HSM_CMD_ID_RAW_AESM = 0x42fdu, + HSM_CMD_ID_SCATTER_MAC = 0xa9e1u, + HSM_CMD_ID_ECC_GENKEYPAIR = 0x16b6u, + HSM_CMD_ID_RSA_SSA_PKCS1V15_SIGN = 0xd047u, + HSM_CMD_ID_RSA_SSA_PSS_SIGN = 0xd873u, + HSM_CMD_ID_RSA_ES_PKCS1V15_ENCRYPT = 0x3090u, + HSM_CMD_ID_RSA_ES_OAEP_ENCRYPT = 0x7F0Bu, + HSM_CMD_ID_RSA_SSA_PKCS1V15_VERIFY = 0x1577u, + HSM_CMD_ID_RSA_SSA_PSS_VERIFY = 0x0076u, + HSM_CMD_ID_RSA_ES_PKCS1V15_DECRYPT = 0x26d5u, + HSM_CMD_ID_RSA_ES_OAEP_DECRYPT = 0xc284u, +} HSM_CmdIdType; + +#define HSMCOM_TRNG_SRC_0 0x40cau +#define HSMCOM_TRNG_SRC_1 0xc51cu +#define HSMCOM_TRNG_SRC_ANY 0x359bu +#define HSMCOM_TRNG_SRC_XOR 0x80a5u +#define HSMCOM_DRNG_SRC 0x648Cu +#define HSMCOM_LIFECYCLE_OEM_DEV 0x4792u +#define HSMCOM_LIFECYCLE_OEM_PDT 0xA4F1u +#define HSMCOM_LIFECYCLE_IN_FIELD 0xaddcu +#define HSMCOM_INCREASE_COUNTER 0xd27fu +#define HSMCOM_READ_COUNTER 0x1875u +#define HSMCOM_SET_COUNTER_VAL 0x439du +#define HSMCOM_INCREASE_COUNTER_WHEN_EQUAL 0x6834u +#define HSMCOM_READ_ALL_FLEX_COUNTERS 0x6a47u +#define HSMCOM_SET_SINGLE_CFG 0x9e4du +#define HSMCOM_GET_SINGLE_CFG 0xaf42u +#define HSMCOM_INCREASE_COUNTER2 0xd280u +#define HSMCOM_READ_COUNTER2 0x1876u +#define HSMCOM_NVR_OTP_READ 0x9C2Fu +#define HSMCOM_NVR_OTP_WRITE 0x358Cu +#define HSMCOM_KEYMANAGER_IMPORT_USER_KEY 0xdcf1u +#define HSMCOM_KEYMANAGER_REVOKE_USER_KEY 0x7278u +#define HSMCOM_KEYMANAGER_EXPORT_USER_KEY 0xd8c9u +#define HSMCOM_KEYMANAGER_GEN_UESR_KEY 0x1853u +#define HSMCOM_KEYMANAGER_ENABLE_KEY_RAM_COPY 0x5ec5u +#define HSMCOM_KEYMANAGER_DISABLE_KEY_RAM_COPY 0x5918u +#define HSMCOM_KEYSPACE_GET_STATUS 0xe39cu +#define HSMCOM_KEYSPACE_NEATEN 0xb12bu +#define HSMCOM_REVOK_UMRK0 0x5edcu +#define HSMCOM_REVOK_UMRK1 0x20d9u +#define HSMCOM_REVOK_UMRK2 0x6ba1u +#define HSMCOM_REVOK_UMRK3 0xac50u + +/* ################################################################################## */ +/* ################################# Local Variables ################################ */ +#define AUTH_CHECK_DATA_BYTE_CNT 32 +static uint32_t s_aHsmDat[8]; +static HSMCom_AuthCheckType s_tHsmDummyCfg = {0, 0, &(s_aHsmDat[0]), &(s_aHsmDat[0]), &(s_aHsmDat[0]), &(s_aHsmDat[0]), &(s_aHsmDat[0]), AUTH_CHECK_DATA_BYTE_CNT}; + +/* ################################################################################## */ +/* ########################### Local Functions Prototype ############################ */ + +/* ################################################################################## */ +/* ################################# Local Functions ############################### */ +static HSM_StatusType hsm_assign_val(HSM_CmdType *pCmd, uint32_t u32Cmd, uint32_t u32Address) +{ + HSM_StatusType eRet = HSM_STATUS_SUCCESS; + + if (NULL != pCmd) + { + pCmd->u32Cmd = u32Cmd; + pCmd->u32Addr = u32Address; + } + else + { + eRet = HSM_STATUS_PARAM_ERR; + } + + return eRet; +} + +/* ################################################################################## */ +/* ################################# Global Functions ############################### */ +HSM_StatusType HSM_TrueRandGetSrc0(HSM_CmdType *pCmd, const HSMCom_TrueRandType*pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_TRNG << 16u) | HSMCOM_TRNG_SRC_0, (uint32_t)pCfg); +} + +HSM_StatusType HSM_TrueRandGetSrc1(HSM_CmdType *pCmd, const HSMCom_TrueRandType*pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_TRNG << 16u) | HSMCOM_TRNG_SRC_1, (uint32_t)pCfg); +} + +HSM_StatusType HSM_TrueRandGetSrcXor(HSM_CmdType *pCmd, const HSMCom_TrueRandType*pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_TRNG << 16) | HSMCOM_TRNG_SRC_XOR, (uint32_t)pCfg); +} + +HSM_StatusType HSM_TrueRandGet(HSM_CmdType *pCmd, const HSMCom_TrueRandType*pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_TRNG << 16) | HSMCOM_TRNG_SRC_ANY, (uint32_t)pCfg); +} + +HSM_StatusType HSM_PseudoRandGet(HSM_CmdType *pCmd, const HSMCom_TrueRandType*pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_TRNG << 16) | HSMCOM_DRNG_SRC, (uint32_t)pCfg); +} + +HSM_StatusType HSM_Sha(HSM_CmdType *pCmd, const HSMCom_ShaType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_SHA << 16), (uint32_t)pCfg); +} + +HSM_StatusType HSM_ShaEx(HSM_CmdType *pCmd, const HSMCom_Sha2Type *pCfg) +{ + uint32_t u32CtrBits = (pCfg->tCfg.eInputFmt & 0x1) | ((pCfg->tCfg.eOutputFmt & 0x1) << 1); + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_SHA << 16) | u32CtrBits, (uint32_t)pCfg); +} + +HSM_StatusType HSM_HashInitEx(HSM_CmdType *pCmd, const HSMCom_ShaType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_SCATTER_HASH << 16), (uint32_t)pCfg); +} + +HSM_StatusType HSM_HashUpdateEx(HSM_CmdType *pCmd, const HSMCom_ShaType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_SCATTER_HASH << 16) | 5u, (uint32_t)pCfg); +} + +HSM_StatusType HSM_HashFinallyEx(HSM_CmdType *pCmd, const HSMCom_ShaType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_SCATTER_HASH << 16) | 6u, (uint32_t)pCfg); +} + +HSM_StatusType HSM_CmacAesm(HSM_CmdType *pCmd, const HSMCom_AesmRawApiType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_RAW_AESM << 16), (uint32_t)pCfg); +} + +HSM_StatusType HSM_CmacScatter(HSM_CmdType *pCmd, const HSMCom_ScatterMacType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_SCATTER_MAC << 16), (uint32_t)pCfg); +} + +HSM_StatusType HSM_EccSign(HSM_CmdType *pCmd, const HSMCom_EccSignType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_ECC_SIGN << 16 | 1u), (uint32_t)pCfg); +} + +HSM_StatusType HSM_EccVerify(HSM_CmdType *pCmd, const HSMCom_EccVerifyType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_ECC_VERIFY << 16), (uint32_t)pCfg); +} + +HSM_StatusType HSM_EccGenKeyPair(HSM_CmdType *pCmd, const HSMCom_EccKeyPairGenType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_ECC_GENKEYPAIR << 16 | 1u), (uint32_t)pCfg); +} + +HSM_StatusType HSM_Sm2GenKeyPair(HSM_CmdType *pCmd, const HSMCom_Sm2GenKeyPairType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_SM2_GENKEYPAIR << 16 | 1u), (uint32_t)pCfg); +} + +HSM_StatusType HSM_Sm2Encry(HSM_CmdType *pCmd, const HSMCom_Sm2EncryptType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_SM2_ENCRY << 16 | 1u), (uint32_t)pCfg); +} + +HSM_StatusType HSM_Sm2Decry(HSM_CmdType *pCmd, const HSMCom_Sm2DecryptType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_SM2_DECRY << 16), (uint32_t)pCfg); +} + +HSM_StatusType HSM_Sm2Sign(HSM_CmdType *pCmd, const HSMCom_Sm2SignType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_SM2_SIGN << 16 | 1u), (uint32_t)pCfg); +} + +HSM_StatusType HSM_Sm2Verify(HSM_CmdType *pCmd, const HSMCom_Sm2VerifyType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_SM2_VERIFY << 16), (uint32_t)pCfg); +} + +HSM_StatusType HSM_Sm2GenZa(HSM_CmdType *pCmd, const HSMCom_Sm2GenZaType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_SM2_GENZA << 16), (uint32_t)pCfg); +} + +HSM_StatusType HSM_Sm2GenHash(HSM_CmdType *pCmd, const HSMCom_Sm2GenHashType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_SM2_GENHASH << 16), (uint32_t)pCfg); +} + +HSM_StatusType HSM_Sm4Encrypt(HSM_CmdType *pCmd, const HSMCom_Sm4EncryptType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_SM4_ENCRY << 16), (uint32_t)pCfg); +} + +HSM_StatusType HSM_Sm4Decrypt(HSM_CmdType *pCmd, const HSMCom_Sm4DecryptType *pCfg) +{ + return hsm_assign_val(pCmd, (HSM_CMD_ID_SM4_DECRY << 16), (uint32_t)pCfg); +} + +HSM_StatusType HSM_EccEasyEncry(HSM_CmdType *pCmd, const HSMCom_EccEasyEncryType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_ECC_ENCRY << 16), (uint32_t)pCfg); +} + +HSM_StatusType HSM_EccEasyDecry(HSM_CmdType *pCmd, const HSMCom_EccEasyDecryType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_ECC_DECRY << 16), (uint32_t)pCfg); +} + +HSM_StatusType HSM_EccPointCalc(HSM_CmdType *pCmd, const HSMCom_EccCalcType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_ECC_DECRY << 16) | 1u, (uint32_t)pCfg); +} + +HSM_StatusType HSM_ScatterHashInit(HSM_CmdType *pCmd, const HSMCom_ScatterHashType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_SCATTER_HASH << 16), (uint32_t)pCfg); +} + +HSM_StatusType HSM_ScatterHashUpdate(HSM_CmdType *pCmd, const HSMCom_ScatterHashType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_SCATTER_HASH << 16) | 5u, (uint32_t)pCfg); +} + +HSM_StatusType HSM_ScatterHashFinally(HSM_CmdType *pCmd, const HSMCom_ScatterHashType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_SCATTER_HASH << 16) | 6u, (uint32_t)pCfg); +} + +HSM_StatusType HSM_RequestAuthorization(HSM_CmdType *pCmd, const HSMCom_RequestAuthType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_REQUEST_AUTH << 16), (uint32_t)pCfg); +} + +HSM_StatusType HSM_OemDevEnter(HSM_CmdType *pCmd) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_LIFECYCLE_CHANGE << 16) | HSMCOM_LIFECYCLE_OEM_DEV, (uint32_t)(&s_tHsmDummyCfg)); +} + +HSM_StatusType HSM_OemPdtEnter(HSM_CmdType *pCmd) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_LIFECYCLE_CHANGE << 16) | HSMCOM_LIFECYCLE_OEM_PDT, (uint32_t)(&s_tHsmDummyCfg)); +} + +HSM_StatusType HSM_InFieldEnter(HSM_CmdType *pCmd) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_LIFECYCLE_CHANGE << 16) | HSMCOM_LIFECYCLE_IN_FIELD, (uint32_t)(&s_tHsmDummyCfg)); +} + +HSM_StatusType HSM_CancelJob(HSM_CmdType *pCmd, const HSMCom_CancelJobType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_CANCEL_JOB << 16), (uint32_t)pCfg); +} + +HSM_StatusType HSM_SelfTest(HSM_CmdType *pCmd, const HSMCom_SelfTestType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_SELF_TEST << 16), (uint32_t)pCfg); +} + +HSM_StatusType HSM_NvrOtpProgram(HSM_CmdType *pCmd, const HSMCom_NvrOtpType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_NVR_OTP << 16) | HSMCOM_NVR_OTP_WRITE, (uint32_t)pCfg); +} + +HSM_StatusType HSM_NvrOtpRead(HSM_CmdType *pCmd, const HSMCom_NvrOtpType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_NVR_OTP << 16) | HSMCOM_NVR_OTP_READ, (uint32_t)pCfg); +} + +HSM_StatusType HSM_TakeEffect(HSM_CmdType *pCmd) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_LIFECYCLE_CHANGE_TAKE_EFFECT << 16), (uint32_t)0); +} + +HSM_StatusType HSM_UserKeyRevoke(HSM_CmdType *pCmd, const HSMCom_UserKeyManageType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_USER_KEY_MANAGE << 16) | HSMCOM_KEYMANAGER_REVOKE_USER_KEY, (uint32_t)pCfg); +} + +HSM_StatusType HSM_UserKeyImport(HSM_CmdType *pCmd, const HSMCom_UserKeyManageType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_USER_KEY_MANAGE << 16) | HSMCOM_KEYMANAGER_IMPORT_USER_KEY, (uint32_t)pCfg); +} + +HSM_StatusType HSM_UserKeyExport(HSM_CmdType *pCmd, const HSMCom_UserKeyManageType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_USER_KEY_MANAGE << 16) | HSMCOM_KEYMANAGER_EXPORT_USER_KEY, (uint32_t)pCfg); +} + +HSM_StatusType HSM_EraseKeyFlash(HSM_CmdType *pCmd, HSMCom_BasicType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_USER_KEY_ERASE << 16) | 0xa80f, (uint32_t)pCfg); +} + +HSM_StatusType HSM_UserKeyGen(HSM_CmdType *pCmd, const HSMCom_UserKeyManageType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_USER_KEY_MANAGE << 16) | HSMCOM_KEYMANAGER_GEN_UESR_KEY, (uint32_t)pCfg); +} + +HSM_StatusType HSM_EnableKeyRamCopy(HSM_CmdType *pCmd, const HSMCom_UserKeyManageType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_USER_KEY_MANAGE << 16) | HSMCOM_KEYMANAGER_ENABLE_KEY_RAM_COPY, (uint32_t)pCfg); +} + +HSM_StatusType HSM_DisableKeyRamCopy(HSM_CmdType *pCmd, const HSMCom_UserKeyManageType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_USER_KEY_MANAGE << 16) | HSMCOM_KEYMANAGER_DISABLE_KEY_RAM_COPY, (uint32_t)pCfg); +} + +HSM_StatusType HSM_GetKeySpaceStatus(HSM_CmdType *pCmd, const HSMCom_KeySpaceStatusType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_SPACE_MANAGE << 16) | HSMCOM_KEYSPACE_GET_STATUS, (uint32_t)pCfg); +} + +HSM_StatusType HSM_TidyUpKeySpace(HSM_CmdType *pCmd, const HSMCom_KeySpaceStatusType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_SPACE_MANAGE << 16) | HSMCOM_KEYSPACE_NEATEN, (uint32_t)pCfg); +} + +HSM_StatusType HSM_AesEncrypt(HSM_CmdType *pCmd, const HSMCom_AesEncryptType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_AES_ENCRY << 16), (uint32_t)pCfg); +} + +HSM_StatusType HSM_Aes_FlexEncrypt(HSM_CmdType *pCmd, const HSMCom_FlexAesEncryptType *pCfg) +{ + uint32_t u32CtrBits =0x1 | + ((pCfg->tCfg.epad & 0x1) << 1) | ((pCfg->tCfg.eInputFmt & 0x1) << 2) | + ((pCfg->tCfg.eOutputFmt & 0x1) << 3) | ((pCfg->tCfg.eBackend & 0x1) << 4) ; + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_AES_ENCRY << 16) | u32CtrBits, (uint32_t)pCfg); +} + +HSM_StatusType HSM_AesDecrypt(HSM_CmdType *pCmd, const HSMCom_AesDecryptType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_AES_DECRY << 16), (uint32_t)pCfg); +} + +HSM_StatusType HSM_Aes_FlexDecrypt(HSM_CmdType *pCmd, const HSMCom_FlexAesDecryptType *pCfg) +{ + uint32_t u32CtrBits = 0x1 | + ((pCfg->tCfg.epad & 0x1) << 1) | ((pCfg->tCfg.eInputFmt & 0x1) << 2) | + ((pCfg->tCfg.eOutputFmt & 0x1) << 3) | ((pCfg->tCfg.eBackend & 0x1) << 4) ; + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_AES_DECRY << 16) | u32CtrBits, (uint32_t)pCfg); +} + +HSM_StatusType HSM_CMac(HSM_CmdType *pCmd, const HSMCom_CMacType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_CMAC_GEN << 16), (uint32_t)pCfg); +} + +HSM_StatusType HSM_CmacEx(HSM_CmdType *pCmd, const HSMCom_CMacExType *pCfg) +{ + uint32_t u32CtrBits = (pCfg->tCfg.eBackend & 0x1) | ((pCfg->tCfg.eInputFmt & 0x1) << 1) | ((pCfg->tCfg.eOutputFmt & 0x1) << 2); + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_CMAC_GEN << 16) | u32CtrBits, (uint32_t)pCfg); +} + +HSM_StatusType HSM_XMac(HSM_CmdType *pCmd, const HSMCom_XMacType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_XMAC_GEN << 16), (uint32_t)pCfg); +} + +HSM_StatusType HSM_XMacEx(HSM_CmdType *pCmd, const HSMCom_XMacExType *pCfg) +{ + uint32_t u32CtrBits = (pCfg->tCfg.eBackend & 0x1) | ((pCfg->tCfg.eInputFmt & 0x1) << 1) | ((pCfg->tCfg.eOutputFmt & 0x1) << 2); + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_XMAC_GEN << 16) | u32CtrBits, (uint32_t)pCfg); +} + +HSM_StatusType HSM_CcmEncry(HSM_CmdType *pCmd, const HSMCom_CcmEncryptType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_CCM_ENCRY << 16), (uint32_t)pCfg); +} + +HSM_StatusType HSM_CcmEncryEx(HSM_CmdType *pCmd, const HSMCom_CcmEncryptExType *pCfg) +{ + uint32_t u32CtrBits = (pCfg->tCfg.eBackend & 0x1); + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_CCM_ENCRY << 16) | u32CtrBits, (uint32_t)pCfg); +} + +HSM_StatusType HSM_CcmDecry(HSM_CmdType *pCmd, const HSMCom_CcmDecryptType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_CCM_DECRY << 16), (uint32_t)pCfg); +} + +HSM_StatusType HSM_CcmDecryEx(HSM_CmdType *pCmd, const HSMCom_CcmDecryptExType *pCfg) +{ + uint32_t u32CtrBits = (pCfg->tCfg.eBackend & 0x1); + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_CCM_DECRY << 16) | u32CtrBits, (uint32_t)pCfg); +} + +HSM_StatusType HSM_GcmEncry(HSM_CmdType *pCmd, const HSMCom_GcmEncryptType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_GCM_ENCRY << 16), (uint32_t)pCfg); +} + +HSM_StatusType HSM_GcmEncryEx(HSM_CmdType *pCmd, const HSMCom_GcmEncryptExType *pCfg) +{ + uint32_t u32CtrBits = (pCfg->tCfg.eBackend & 0x1); + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_GCM_ENCRY << 16) | u32CtrBits, (uint32_t)pCfg); +} + +HSM_StatusType HSM_GcmDecry(HSM_CmdType *pCmd, const HSMCom_GcmDecryptType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_GCM_DECRY << 16), (uint32_t)pCfg); +} + +HSM_StatusType HSM_GcmDecryEx(HSM_CmdType *pCmd, const HSMCom_GcmDecryptExType *pCfg) +{ + uint32_t u32CtrBits = (pCfg->tCfg.eBackend & 0x1); + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_GCM_DECRY << 16) | u32CtrBits, (uint32_t)pCfg); +} + +HSM_StatusType HSM_Md5(HSM_CmdType *pCmd, const HSMCom_Md5Type *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_MD5 << 16), (uint32_t)pCfg); +} + +HSM_StatusType HSM_Md5Ex(HSM_CmdType *pCmd, const HSMCom_Md5Type *pCfg) +{ + uint32_t u32CtrBits = (pCfg->tCfg.eIntputFmt & 0x1) | ((pCfg->tCfg.eOutputFmt & 0x1) << 1); + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_MD5 << 16) | u32CtrBits, (uint32_t)pCfg); +} + +HSM_StatusType HSM_Sm3(HSM_CmdType *pCmd, const HSMCom_Sm3Type *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_SM3 << 16), (uint32_t)pCfg); +} + +HSM_StatusType HSM_Sm3Ex(HSM_CmdType *pCmd, const HSMCom_Sm3Type *pCfg) +{ + uint32_t u32CtrBits = (pCfg->tCfg.eIntputFmt & 0x1) | ((pCfg->tCfg.eOutputFmt & 0x1) << 1); + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_SM3 << 16) | u32CtrBits, (uint32_t)pCfg); +} + +HSM_StatusType HSM_MonotonicCounterIncrease(HSM_CmdType *pCmd, const HSMCom_MonCountType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_MONOTONIC_COUNTER << 16) | HSMCOM_INCREASE_COUNTER, (uint32_t)pCfg); +} + +HSM_StatusType HSM_MonotonicCounterRead(HSM_CmdType *pCmd, const HSMCom_MonCountType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_MONOTONIC_COUNTER << 16) | HSMCOM_READ_COUNTER, (uint32_t)pCfg); +} + +HSM_StatusType HSM_MonotonicCounterSetValue(HSM_CmdType *pCmd, const HSMCom_MonCountType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_MONOTONIC_COUNTER << 16) | HSMCOM_SET_COUNTER_VAL, (uint32_t)pCfg); +} + +HSM_StatusType HSM_MonotonicIncCountWhenEqu(HSM_CmdType *pCmd, const HSMCom_MonCountType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_MONOTONIC_COUNTER << 16) | HSMCOM_INCREASE_COUNTER_WHEN_EQUAL, (uint32_t)pCfg); +} + +HSM_StatusType HSM_MonotonicReadAllFlexCounters(HSM_CmdType *pCmd, const HSMCom_MonCountType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_MONOTONIC_COUNTER << 16) | HSMCOM_READ_ALL_FLEX_COUNTERS, (uint32_t)pCfg); +} + +HSM_StatusType HSM_MonotonicCounterSetSingleCfg(HSM_CmdType *pCmd, const HSMCom_MonCountType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_MONOTONIC_COUNTER << 16) | HSMCOM_SET_SINGLE_CFG, (uint32_t)pCfg); +} + +HSM_StatusType HSM_MonotonicCounterGetSingleCfg(HSM_CmdType *pCmd, const HSMCom_MonCountType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_MONOTONIC_COUNTER << 16) | HSMCOM_GET_SINGLE_CFG, (uint32_t)pCfg); +} + +HSM_StatusType HSM_MonotonicIncreaseCounter2(HSM_CmdType *pCmd, const HSMCom_MonCountType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_MONOTONIC_COUNTER << 16) | HSMCOM_INCREASE_COUNTER2, (uint32_t)pCfg); +} + +HSM_StatusType HSM_MonotonicReadCounter2(HSM_CmdType *pCmd, const HSMCom_MonCountType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_MONOTONIC_COUNTER << 16) | HSMCOM_READ_COUNTER2, (uint32_t)pCfg); +} + +HSM_StatusType HSM_Rsa(HSM_CmdType *pCmd, const HSMCom_RsaType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_RSA << 16), (uint32_t)pCfg); +} + +HSM_StatusType HSM_RSA_SSA_PSS_Sign(HSM_CmdType *pCmd, const HSMCom_RsaSsaPssSignType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_RSA_SSA_PSS_SIGN << 16), (uint32_t)pCfg); +} +HSM_StatusType HSM_RSA_SSA_PSS_Verify(HSM_CmdType *pCmd, const HSMCom_RsaSsaPssVerifyType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_RSA_SSA_PSS_VERIFY << 16), (uint32_t)pCfg); +} + +HSM_StatusType HSM_RSA_SSA_ES_PKCS1V15_Encrypt(HSM_CmdType *pCmd, const HSMCom_RsaEsPkcs1V15EncryptType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_RSA_ES_PKCS1V15_ENCRYPT << 16), (uint32_t)pCfg); +} +HSM_StatusType HSM_RSA_SSA_ES_PKCS1V15_Decrypt(HSM_CmdType *pCmd, const HSMCom_RsaEsPkcs1V15DecryptType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_RSA_ES_PKCS1V15_DECRYPT << 16), (uint32_t)pCfg); +} +HSM_StatusType HSM_RSA_SSA_ES_PKCS1V15_Verify(HSM_CmdType *pCmd, const HSMCom_RsaSsaPkcs1V15VerifyType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_RSA_SSA_PKCS1V15_VERIFY << 16), (uint32_t)pCfg); +} +HSM_StatusType HSM_RSA_SSA_ES_PKCS1V15_Sign(HSM_CmdType *pCmd, const HSMCom_RsaSsaPkcs1V15SignType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_RSA_SSA_PKCS1V15_SIGN << 16), (uint32_t)pCfg); +} + +HSM_StatusType HSM_RSA_SSA_ES_OAEP_Encrypt(HSM_CmdType *pCmd, const HSMCom_RsaEsOaepEncryptType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_RSA_ES_OAEP_ENCRYPT << 16), (uint32_t)pCfg); +} +HSM_StatusType HSM_RSA_SSA_ES_OAEP_Decrypt(HSM_CmdType *pCmd, const HSMCom_RsaEsOaepDecryptType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_RSA_ES_OAEP_DECRYPT << 16), (uint32_t)pCfg); +} + +HSM_StatusType HSM_BigNumberCalc(HSM_CmdType *pCmd, const HSMCom_BigNumberCalcType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_RSA << 16) | 1u, (uint32_t)pCfg); +} + +HSM_StatusType HSM_LoadFirmware(HSM_CmdType *pCmd) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_LOAD_FIRMWARE << 16), (uint32_t)0); +} + +HSM_StatusType HSM_SMDH(HSM_CmdType *pCmd, HSMCom_SmDHType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_DH_SM << 16), (uint32_t)pCfg); +} + +HSM_StatusType HSM_ECDH(HSM_CmdType *pCmd, HSMCom_ECDHType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_ECDH << 16), (uint32_t)pCfg); +} + +HSM_StatusType HSM_DH(HSM_CmdType *pCmd, HSMCom_RsaDHType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_DH << 16), (uint32_t)pCfg); +} + +HSM_StatusType HSM_PBKDF2(HSM_CmdType *pCmd, HSMCom_Pbkdf2Type *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_DH_PBKDF2 << 16), (uint32_t)pCfg); +} + +HSM_StatusType HSM_GMPBKDF(HSM_CmdType *pCmd, HSMCom_GMpbkdfType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_DH_GMPBKDF << 16), (uint32_t)pCfg); +} + +HSM_StatusType HSM_RevokeUmrk0(HSM_CmdType *pCmd) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_REVOKE_UMRK << 16)|HSMCOM_REVOK_UMRK0, (uint32_t)0); +} + +HSM_StatusType HSM_RevokeUmrk1(HSM_CmdType *pCmd) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_REVOKE_UMRK << 16)|HSMCOM_REVOK_UMRK1, (uint32_t)0); +} + +HSM_StatusType HSM_RevokeUmrk2(HSM_CmdType *pCmd) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_REVOKE_UMRK << 16)|HSMCOM_REVOK_UMRK2, (uint32_t)0); +} + +HSM_StatusType HSM_RevokeUmrk3(HSM_CmdType *pCmd) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_REVOKE_UMRK << 16)|HSMCOM_REVOK_UMRK3, (uint32_t)0); +} + +HSM_StatusType HSM_GenUsrk(HSM_CmdType *pCmd,const HSMCom_RsaType *pCfg) +{ + return hsm_assign_val(pCmd,(uint32_t)(HSM_CMD_ID_USRK_GEN << 16), (uint32_t)pCfg); +} diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_intm.c b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_intm.c new file mode 100644 index 0000000..5e12985 --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_intm.c @@ -0,0 +1,190 @@ +/** + * @file fc7xxx_driver_intm.c + * @author Flagchip + * @brief FC7240 INTM driver type definition and API + * @version 0.1.0 + * @date 2024-01-10 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-01-10 Flagchip084 N/A FC7240 release version + ******************************************************************************** */ + +#include "fc7xxx_driver_intm.h" +#include "interrupt_manager.h" + +/* ################################################################################## */ +/* ##################################### Macros ##################################### */ + +/* ################################################################################## */ +/* ################################# Local Variables ################################ */ + +static INTM_Type *const s_aIntm_Base[INTM_INSTANCE_MAX] = INTM_BASE_PTRS; +static INTM_ISRCallbackType s_aIntmISRCallback[INTM_INSTANCE_MAX][INTM_IRQ_MONITOR_MAX] = {NULL}; +/* ################################################################################## */ +/* ########################### Local Functions Prototype ############################ */ +void INTM0_IRQHandler(void); +void INTMn_IRQHandler(INTM_InstanceType eInstance); + +/* ################################################################################## */ +/* ################################# Local Functions ############################### */ + +/* ################################################################################## */ +/* ################################# Global Functions ############################### */ + +INTM_ReturnType INTM_Init(INTM_InstanceType eInstance, INTM_IrqMonitorType eIrqMonitorIndex, INTM_InitType *pInitCfg) +{ + INTM_MonitorType *pMonitor; + + if ((NULL == pInitCfg) || (eInstance >= INTM_INSTANCE_MAX) || (eIrqMonitorIndex >= INTM_IRQ_MONITOR_MAX)) + { + return INTM_RETURN_E_PARAM; + } + + if (pInitCfg->u32SrcDelayCnt >= 0xFFFFFFU) + { + return INTM_RETURN_E_PARAM; + } + + if (pInitCfg->u16IrqNumber >= IRQn_MAX) + { + return INTM_RETURN_E_PARAM; + } + + pMonitor = INTM_HWA_GetIrqMonitor(s_aIntm_Base[eInstance], (uint8_t)eIrqMonitorIndex); + INTM_HWA_SetIRQReqNum(pMonitor, pInitCfg->u16IrqNumber); + INTM_HWA_EnableReset(pMonitor, pInitCfg->bEnReset); + INTM_HWA_EnableInterrupt(pMonitor, pInitCfg->bEnInterrupt); + INTM_HWA_SetLatency(pMonitor, pInitCfg->u32SrcDelayCnt); + if (pInitCfg->eMode == INTM_INTERRUPT_MODE_INACTIVE) + { + INTM_HWA_EnableInactiveMode(pMonitor, true); + } + else + { + INTM_HWA_EnableInactiveMode(pMonitor, false); + } + s_aIntmISRCallback[eInstance][eIrqMonitorIndex] = pInitCfg->pIntmIsrCallback; + return INTM_RETURN_OK; +} + +INTM_ReturnType INTM_enable(INTM_InstanceType eInstance, bool bEnable) +{ + if (eInstance >= INTM_INSTANCE_MAX) + { + return INTM_RETURN_E_PARAM; + } + + INTM_HWA_Enable(s_aIntm_Base[eInstance], bEnable); + + return INTM_RETURN_OK; +} + +INTM_ReturnType INTM_StartInactiveMode(INTM_InstanceType eInstance, INTM_IrqMonitorType eIrqMonitorIndex) +{ + INTM_MonitorType *pMonitor; + + if ((eInstance >= INTM_INSTANCE_MAX) || (eIrqMonitorIndex >= INTM_IRQ_MONITOR_MAX)) + { + return INTM_RETURN_E_PARAM; + } + + pMonitor = INTM_HWA_GetIrqMonitor(s_aIntm_Base[eInstance], (uint8_t)eIrqMonitorIndex); + INTM_HWA_StartInactiveMode(pMonitor); + return INTM_RETURN_OK; +} + +INTM_ReturnType INTM_StopInactiveMode(INTM_InstanceType eInstance, INTM_IrqMonitorType eIrqMonitorIndex) +{ + INTM_MonitorType *pMonitor; + + if ((eInstance >= INTM_INSTANCE_MAX) || (eIrqMonitorIndex >= INTM_IRQ_MONITOR_MAX)) + { + return INTM_RETURN_E_PARAM; + } + + pMonitor = INTM_HWA_GetIrqMonitor(s_aIntm_Base[eInstance], (uint8_t)eIrqMonitorIndex); + INTM_HWA_StopInactiveMode(pMonitor); + return INTM_RETURN_OK; +} + +INTM_ReturnType INTM_SetAcknowledge(INTM_InstanceType eInstance, uint16_t u16IrqNumber) +{ + if (eInstance >= INTM_INSTANCE_MAX) + { + return INTM_RETURN_E_PARAM; + } + + INTM_HWA_SetIACKR(s_aIntm_Base[eInstance], u16IrqNumber); + + return INTM_RETURN_OK; +} + +uint32_t INTM_GetCounterValue(INTM_InstanceType eInstance, INTM_IrqMonitorType eIrqMonitorIndex) +{ + INTM_MonitorType *pMonitor; + + if ((eInstance >= INTM_INSTANCE_MAX) || (eIrqMonitorIndex >= INTM_IRQ_MONITOR_MAX)) + { + return 0; + } + + pMonitor = INTM_HWA_GetIrqMonitor(s_aIntm_Base[eInstance], (uint8_t)eIrqMonitorIndex); + return INTM_HWA_GetTimerCounter(pMonitor); +} + +INTM_ReturnType INTM_ClearIntFlag(INTM_InstanceType eInstance, INTM_IrqMonitorType eIrqMonitorIndex) +{ + INTM_MonitorType *pMonitor; + + if ((eInstance >= INTM_INSTANCE_MAX) || (eIrqMonitorIndex >= INTM_IRQ_MONITOR_MAX)) + { + return INTM_RETURN_E_PARAM; + } + + pMonitor = INTM_HWA_GetIrqMonitor(s_aIntm_Base[eInstance], (uint8_t)eIrqMonitorIndex); + INTM_HWA_SetTimerCounter(pMonitor, 0U); + return INTM_RETURN_OK; +} + +bool INTM_GetTimeoutStatus(INTM_InstanceType eInstance, INTM_IrqMonitorType eIrqMonitorIndex) +{ + INTM_MonitorType *pMonitor; + + if ((eInstance >= INTM_INSTANCE_MAX) || (eIrqMonitorIndex >= INTM_IRQ_MONITOR_MAX)) + { + return false; + } + + pMonitor = INTM_HWA_GetIrqMonitor(s_aIntm_Base[eInstance], (uint8_t)eIrqMonitorIndex); + return INTM_HWA_ReadStatus(pMonitor); +} + +void INTMn_IRQHandler(INTM_InstanceType eInstance) +{ + uint8_t u8i; + INTM_MonitorType *pMonitor; + + for (u8i = 0; u8i < (uint8_t)INTM_IRQ_MONITOR_MAX; u8i++) + { + pMonitor = INTM_HWA_GetIrqMonitor(s_aIntm_Base[eInstance], u8i); + if (INTM_HWA_ReadStatus(pMonitor)) + { + if (s_aIntmISRCallback[eInstance][u8i] != NULL) + { + s_aIntmISRCallback[eInstance][u8i](); + } + } + } +} + +void INTM0_IRQHandler(void) +{ + INTMn_IRQHandler(INTM_INSTANCE_0); +} diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_ism.c b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_ism.c new file mode 100644 index 0000000..08df27d --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_ism.c @@ -0,0 +1,347 @@ +/** + * @file fc7xxx_driver_ism.c + * @author Flagchip + * @brief FC7xxx ISM driver type definition and API + * @version 0.1.0 + * @date 2023-02-13 + * + * @copyright Copyright (c) 2023 Flagchip Semiconductors Co., Ltd. + * + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-1-10 Flagchip095 N/A First version for FC7240 + ******************************************************************************** */ +#include "fc7xxx_driver_ism.h" + +/* ################################################################################## */ +/* ####################################### Macro #################################### */ +#define FPC_INSTANCE_COUNT (16U) +#define LAM_INSTANCE_COUNT (16U) +#define ECM_INSTANCE_COUNT (4U) +/* ################################################################################## */ +/* ################################### Type define ################################## */ + +/* ################################################################################## */ +/* ################################ Local Variables ################################# */ +static ISM_Type *const s_apIsmBase[ISM_INSTANCE_COUNT] = ISM_BASE_PTRS; +static ISM_EventISRCallbackType s_apEventISRCallback = NULL; +static FPC_ISRCallbackType s_apFpcISRCallback[FPC_INSTANCE_COUNT] = {NULL}; +static LAM_ISRCallbackType s_apLamOverFlowIsrCallback[LAM_INSTANCE_COUNT] = {NULL}; +/* ################################################################################## */ +/* ########################### Local Prototype Functions ############################ */ + +/* ################################################################################## */ +/* ######################### Global prototype Functions ############################ */ +void ISM0_IRQHandler(void); +/* ################################################################################## */ +/* ################################ Local Functions ################################ */ + +/* ################################################################################## */ +/* ################################ Global Functions ################################ */ + +void ISM_Init(const ISM_InitCfgType *pInitConfig) +{ + ISM_Type *pIsm = ISM; + + DEV_ASSERT(ISM_HWA_PARAM_ECMC(pIsm) == ECM_INSTANCE_COUNT); + DEV_ASSERT(ISM_HWA_PARAM_FPC(pIsm) == FPC_INSTANCE_COUNT); + DEV_ASSERT(ISM_HWA_PARAM_LAM(pIsm) == LAM_INSTANCE_COUNT); + DEV_ASSERT(pInitConfig != NULL); + + s_apEventISRCallback = pInitConfig->pEventIsrCallback; + ISM_HWA_InterruptEnable(pIsm, pInitConfig->bIntEnable); +} + +uint8_t ISM_GetEcmEventHappenedChannels(void) +{ + ISM_Type *pIsm = ISM; + + return (uint8_t)ISM_HWA_GetEcs(pIsm); +} + +uint16_t ISM_GetLamEventHappenedChannels(void) +{ + ISM_Type *pIsm = ISM; + + return ISM_HWA_GetEs(pIsm); +} + +void ISM_ClearEcmEventHappenedChannels(uint8_t u8Channels) +{ + ISM_Type *pIsm = ISM; + + ISM_HWA_ClearEcs(pIsm, (uint32_t)u8Channels); +} + +void ISM_ClearLamEventHappenedChannels(uint16_t u16Channels) +{ + ISM_Type *pIsm = ISM; + + ISM_HWA_ClearEs(pIsm, (uint32_t)u16Channels); +} + +void ISM_EnableEcmSystemEvent(uint32_t u32Channels, bool bEnable) +{ + ISM_Type *pIsm = ISM; + + ISM_HWA_EnableEcmSystemEvent(pIsm, u32Channels, bEnable); +} + +void ISM_EnableLamSystemEvent(uint32_t u32Channels, bool bEnable) +{ + ISM_Type *pIsm = ISM; + + ISM_HWA_EnableLamSystemEvent(pIsm, u32Channels, bEnable); +} + +void ISM_EcmEventConfig(uint8_t u8LamIndex, uint8_t u8EcmIndex, uint8_t u8EventCount) +{ + ISM_Type *pIsm = ISM; + + DEV_ASSERT(u8LamIndex < LAM_INSTANCE_COUNT); + DEV_ASSERT(u8EcmIndex < ECM_INSTANCE_COUNT); + if (u8EcmIndex == 0U) + { + ISM_HWA_SetEcm0EcCtrl(pIsm, u8EventCount, u8LamIndex); + } + else if (u8EcmIndex == 1U) + { + ISM_HWA_SetEcm1EcCtrl(pIsm, u8EventCount, u8LamIndex); + } + else if (u8EcmIndex == 2U) + { + ISM_HWA_SetEcm2EcCtrl(pIsm, u8EventCount, u8LamIndex); + } + else if (u8EcmIndex == 3U) + { + ISM_HWA_SetEcm3EcCtrl(pIsm, u8EventCount, u8LamIndex); + } + else + { + + } +} + +void ISM_ClearLamStatusCounter(uint8_t u8LamIndex) +{ + LAM_Type *pLam; + + DEV_ASSERT(u8LamIndex < LAM_INSTANCE_COUNT); + + pLam = ISM_HWA_GetLam(ISM, u8LamIndex); + + ISM_HWA_ClearLamStatusCounter(pLam); +} + +uint32_t ISM_GetLamStatusCounter(uint8_t u8LamIndex) +{ + LAM_Type *pLam; + + DEV_ASSERT(u8LamIndex < LAM_INSTANCE_COUNT); + + pLam = ISM_HWA_GetLam(ISM, u8LamIndex); + + return ISM_HWA_GetLamStatusCounter(pLam); +} + +void ISM_ClearLamStatusOvfl(uint8_t u8LamIndex) +{ + LAM_Type *pLam; + + DEV_ASSERT(u8LamIndex < LAM_INSTANCE_COUNT); + + pLam = ISM_HWA_GetLam(ISM, u8LamIndex); + + ISM_HWA_ClearLamStatusOvfl(pLam); +} + +bool ISM_GetLamStatusOvfl(uint8_t u8LamIndex) +{ + LAM_Type *pLam; + + DEV_ASSERT(u8LamIndex < LAM_INSTANCE_COUNT); + + pLam = ISM_HWA_GetLam(ISM, u8LamIndex); + + return ISM_HWA_GetLamStatusOvfl(pLam); +} + +void ISM_Enable(bool bEnable) +{ + ISM_Type *pIsm = ISM; + + ISM_HWA_Enable(pIsm, bEnable); +} + +void ISM_InterruptEnable(bool bEnable) +{ + ISM_Type *pIsm = ISM; + + ISM_HWA_InterruptEnable(pIsm, bEnable); +} + +void ISM_LamOverflowInterruptEnable(uint8_t u8LamIndex, bool bEnable) +{ + LAM_Type *pLam; + + DEV_ASSERT(u8LamIndex < LAM_INSTANCE_COUNT); + + pLam = ISM_HWA_GetLam(ISM, u8LamIndex); + + ISM_HWA_SetLamCtrIen(pLam, bEnable); +} + +void ISM_LamEnable(uint8_t u8LamIndex, bool bEnable) +{ + LAM_Type *pLam; + + DEV_ASSERT(u8LamIndex < LAM_INSTANCE_COUNT); + + pLam = ISM_HWA_GetLam(ISM, u8LamIndex); + + ISM_HWA_SetLamCtrEn(pLam, bEnable); +} + +void ISM_LamConfig(uint8_t u8LamIndex, const ISM_LamCfgType *pConfig) +{ + uint32_t u32TempValue = 0; + LAM_Type *pLam; + + DEV_ASSERT(u8LamIndex < LAM_INSTANCE_COUNT); + DEV_ASSERT(pConfig != NULL); + + pLam = ISM_HWA_GetLam(ISM, u8LamIndex); + + ISM_HWA_SetLamCtrIen(pLam, pConfig->bOvflIntEnable); + ISM_HWA_SetLamCounter(pLam, pConfig->u32EvtCntThreshold); + + u32TempValue |= ISM_LAM_CONFIG_RCS(pConfig->u8SrcSel); + u32TempValue |= ISM_LAM_CONFIG_MCS(pConfig->u8MonSel); + u32TempValue |= ISM_LAM_CONFIG_IVW(pConfig->eInvWin); + u32TempValue |= ISM_LAM_CONFIG_EDS(pConfig->eWinEdgSel); + u32TempValue |= ISM_LAM_CONFIG_EWS(pConfig->eEvtWinSel); + u32TempValue |= ISM_LAM_CONFIG_RMS(pConfig->eRunMode); + u32TempValue |= ISM_LAM_CONFIG_MOS(pConfig->eMonSrcSel); + u32TempValue |= ISM_LAM_CONFIG_IVM(pConfig->eInvMon); + u32TempValue |= ISM_LAM_CONFIG_IVR(pConfig->eInvRef); + + s_apLamOverFlowIsrCallback[u8LamIndex] = pConfig->pLamOverFlowIsrCallback; + + ISM_HWA_SetLamConfig(pLam, u32TempValue); +} + +void ISM_FpcGlitchInterruptEnable(uint8_t u8FpcIndex, bool bEnable) +{ + FPC_Type *pFpc; + + DEV_ASSERT(u8FpcIndex < FPC_INSTANCE_COUNT); + + pFpc = ISM_HWA_GetFpc(ISM, u8FpcIndex); + + ISM_HWA_SetFpcCtrlIen(pFpc, bEnable); +} + +void ISM_FpcEnable(uint8_t u8FpcIndex, bool bEnable) +{ + FPC_Type *pFpc; + + DEV_ASSERT(u8FpcIndex < FPC_INSTANCE_COUNT); + + pFpc = ISM_HWA_GetFpc(ISM, u8FpcIndex); + + ISM_HWA_SetFpcCtrlEn(pFpc, bEnable); +} + +void ISM_FpcConfig(uint8_t u8FpcIndex, const ISM_FpcCfgType *pConfig) +{ + uint32_t u32TempValue = 0; + FPC_Type *pFpc; + + DEV_ASSERT(u8FpcIndex < FPC_INSTANCE_COUNT); + DEV_ASSERT(pConfig != NULL); + + pFpc = ISM_HWA_GetFpc(ISM, u8FpcIndex); + + ISM_HWA_SetFpcCtrlIen(pFpc, pConfig->bGlitchIntEnable); + + u32TempValue |= ISM_FPC_CONFIG_FED(pConfig->eFallingDelayNode); + u32TempValue |= ISM_FPC_CONFIG_FEG(pConfig->eFallingDetectMode); + u32TempValue |= ISM_FPC_CONFIG_RED(pConfig->eRisingDelayNode); + u32TempValue |= ISM_FPC_CONFIG_REG(pConfig->eRisingDetectMode); + u32TempValue |= ISM_FPC_CONFIG_CMP(pConfig->u32ThresholdValue); + + s_apFpcISRCallback[u8FpcIndex] = pConfig->pFpcIsrCallback; + + ISM_HWA_SetFpcConfig(pFpc, u32TempValue); +} + +void ISM0_IRQHandler(void) +{ + uint8_t u8i; + FPC_Type *pFpc; + LAM_Type *pLam; + uint8_t u8EcmFlags; + uint16_t u16LamFlags; + ISM_Type *pIsm = s_apIsmBase[ISM_INSTANCE_0]; + + u8EcmFlags = ISM_HWA_GetEcs(pIsm)&ISM_HWA_GetEnabledEcmSystemEvent(pIsm); + u16LamFlags = ISM_HWA_GetEs(pIsm)&ISM_HWA_GetEnabledLamSystemEvent(pIsm); + + if (s_apEventISRCallback != NULL) + { + s_apEventISRCallback(u16LamFlags, u8EcmFlags); + } + + ISM_HWA_ClearEcs(pIsm, u8EcmFlags); + ISM_HWA_ClearEs(pIsm, u16LamFlags); + + for (u8i = 0; u8i < FPC_INSTANCE_COUNT; u8i++) + { + pFpc = ISM_HWA_GetFpc(s_apIsmBase[ISM_INSTANCE_0], u8i); + if (ISM_HWA_GetFpcCtrlIen(pFpc)) + { + uint32_t u32Status = 0U; + if (ISM_HWA_GetFpcRgd(pFpc)) + { + u32Status |= (uint32_t)FPC_RISING_GLITCH_DETECTED; + } + if (ISM_HWA_GetFpcFgd(pFpc)) + { + u32Status |= (uint32_t)FPC_FALLING_GLITCH_DETECTED; + } + if (s_apFpcISRCallback[u8i] != NULL) + { + s_apFpcISRCallback[u8i](u32Status); + } + if ((u32Status & (uint32_t)FPC_RISING_GLITCH_DETECTED) == (uint32_t)FPC_RISING_GLITCH_DETECTED) + { + ISM_HWA_ClearFpcRgd(pFpc); + } + if ((u32Status & (uint32_t)FPC_FALLING_GLITCH_DETECTED) == (uint32_t)FPC_FALLING_GLITCH_DETECTED) + { + ISM_HWA_ClearFpcFgd(pFpc); + } + } + } + + for (u8i = 0; u8i < LAM_INSTANCE_COUNT; u8i++) + { + pLam = ISM_HWA_GetLam(s_apIsmBase[ISM_INSTANCE_0], u8i); + if (ISM_HWA_GetLamCtrIen(pLam)) + { + if (ISM_HWA_GetLamStatusOvfl(pLam)) + { + if (s_apLamOverFlowIsrCallback[u8i] != NULL) + { + s_apLamOverFlowIsrCallback[u8i](); + } + } + ISM_HWA_ClearLamStatusOvfl(pLam); + } + } + +} diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_lin.c b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_lin.c new file mode 100644 index 0000000..aa9fe8c --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_lin.c @@ -0,0 +1,1505 @@ +/** + * @file fc7xxx_driver_lin.c + * @author Flagchip + * @brief FC7xxx LIN driver type definition and API + * @version 0.1.0 + * @date 2024-01-14 + * + * @copyright Copyright (c) 2023 Flagchip Semiconductors Co., Ltd. + * + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-01-14 Flagchip0122 N/A FC7xxx internal release version + ******************************************************************************** */ + +#include "fc7xxx_driver_lin.h" +#include "device_header.h" +#include "fc7xxx_driver_fcuart.h" + +/* ################################################################################## */ +/* ####################################### Macro #################################### */ + +/** UART Instance Number */ +#define LIN_INSTANCE_NUM FCUART_INSTANCE_COUNT + +/* ################################################################################## */ +/* ################################### type define ################################## */ + +/* ################################################################################## */ +/* ################################ Local Variables ################################# */ + +static uint8_t s_aInstanceUsed[LIN_INSTANCE_NUM] = {0}; +static lin_config_t *s_aLinConfig[LIN_INSTANCE_NUM] = {0}; +static lin_xfer_state_t *s_aLinXfer[LIN_INSTANCE_NUM] = {0}; + +/* UART instance array */ +static FCUART_Type *const s_aFCUART_InstanceTable[FCUART_INSTANCE_COUNT] = FCUART_BASE_PTRS; + +/* ################################################################################## */ +/* ########################### Local Prototype Functions ############################ */ +static LIN_StatusType LIN_DrvCalBaudrate(uint8_t u8LinIndex, uint32_t *u32OverSamp, + uint32_t *u32Sbr); +static LIN_NodeType LIN_DrvCheckMode(uint8_t u8LinIndex); +LOCAL_INLINE uint8_t BIT(uint8_t A, uint8_t B); +static uint8_t LIN_DrvParityMake(uint8_t PID); +static uint8_t LIN_DrvParityCheck(uint8_t PID); +static void LIN_DrvHeaderHandle(uint8_t u8LinIndex, uint8_t u8ReceiveByte); +static uint8_t LIN_DrvMakeCheckSum(uint8_t u8LinIndex, uint8_t *pBuf, uint8_t u8Size, + uint8_t u8Pid); +static void LIN_DrvReceiveFrameData(uint8_t u8LinIndex, uint8_t u8ReceiveByte); +static void LIN_DrvSendFrameData(uint8_t u8LinIndex, uint8_t u8ReceiveByte); +static void LIN_DrvFrameHandle(uint8_t u8LinIndex); +static void LIN_DrvWakeupHandle(uint8_t u8LinIndex); + +/* ################################################################################## */ +/* ########################### Global Prototype Functions ########################### */ + +/* ################################################################################## */ +/* ################################ Local Functions ################################# */ + +/** + * @brief LIN instance generate baudrate value, include oversample value and sbr value. + */ +static LIN_StatusType LIN_DrvCalBaudrate(uint8_t u8LinIndex, uint32_t *u32OverSamp, + uint32_t *u32Sbr) +{ + LIN_StatusType tRetVal = LIN_STATUS_ERROR; + uint32_t u32SbrTemp; + uint32_t u32OverSampTemp; + uint32_t u32TempSmbDiff; + uint32_t u32SmbDiff; + uint32_t u32CalcSmb; + uint32_t u32OverSamp1; + uint32_t u32Sbr1; + uint32_t u32Smb; + + u32OverSamp1 = 4U; /* 4..32 */ + u32Smb = s_aLinConfig[u8LinIndex]->clockSrcFreq / s_aLinConfig[u8LinIndex]->baudRate; + + /* sbr = srcFreq/baudrate/oversamp */ + u32Sbr1 = (uint16_t)(u32Smb / (u32OverSamp1)); + u32CalcSmb = (u32OverSamp1) * (u32Sbr1); + + if (u32CalcSmb > u32Smb) + { + u32SmbDiff = u32CalcSmb - u32Smb; + } + else + { + u32SmbDiff = u32Smb - u32CalcSmb; + } + + if (u32SmbDiff != 0U) + { + + /* loop to find the best u32OverSamp1 value possible, one that generates minimum u32SmbDiff + * iterate through the rest of the supported values of u32OverSamp */ + for (u32OverSampTemp = 5U; u32OverSampTemp <= 32U; u32OverSampTemp++) + { + /* calculate the temporary u32Sbr value */ + u32SbrTemp = (uint32_t)(u32Smb / u32OverSampTemp); + /* calculate the baud rate based on the temporary u32OverSamp and u32Sbr values */ + u32CalcSmb = (uint32_t)(u32OverSampTemp * u32SbrTemp); + + if (u32CalcSmb > u32Smb) + { + u32TempSmbDiff = u32CalcSmb - u32Smb; + } + else + { + u32TempSmbDiff = u32Smb - u32CalcSmb; + } + + if (u32TempSmbDiff < u32SmbDiff) + { + u32SmbDiff = u32TempSmbDiff; + u32OverSamp1 = u32OverSampTemp; /* update and store the best u32OverSamp value calculated */ + u32Sbr1 = u32SbrTemp; /* update store the best u32Sbr value calculated */ + } + + /* when differ is 0U, break */ + if (u32SmbDiff == 0U) + { + break; + } + } + } + + /* check differ */ + if (u32SmbDiff == 0U) + { + tRetVal = LIN_STATUS_SUCCESS; + + /* out the calculated value */ + *u32Sbr = u32Sbr1; + *u32OverSamp = u32OverSamp1; + } + else + { + tRetVal = LIN_STATUS_ERROR; + } + + return tRetVal; +} + +/** + * @brief Check the node mode, slave or master. + */ +static LIN_NodeType LIN_DrvCheckMode(uint8_t u8LinIndex) { return s_aLinConfig[u8LinIndex]->nodeMode; } + +/** + * @brief Bit function. + */ +LOCAL_INLINE uint8_t BIT(uint8_t A, uint8_t B) { return (uint8_t)((A >> B) & 0x01U); } + +/** + * @brief Make parity value. + */ +static uint8_t LIN_DrvParityMake(uint8_t PID) +{ + uint8_t parity; + uint8_t retVal; + + parity = (uint8_t)((((0xFFU & BIT(PID, 0U)) ^ (0xFFU & BIT(PID, 1U)) ^ (0xFFU & BIT(PID, 2U)) ^ (0xFFU & BIT(PID, 4U))) << 6U) | + ((0xFFU ^ (BIT(PID, 1U)) ^ (0xFFU & BIT(PID, 3U)) ^ (0xFFU & BIT(PID, 4U)) ^ (0xFFU & BIT(PID, 5U))) << 7U)); + + /* Making parity bits */ + retVal = (uint8_t)(PID | parity); + + return retVal; +} + +/** + * @brief Check parity value. + */ +static uint8_t LIN_DrvParityCheck(uint8_t PID) +{ + uint8_t parity; + uint8_t retVal; + + parity = (uint8_t)((((0xFFU & BIT(PID, 0U)) ^ (0xFFU & BIT(PID, 1U)) ^ (0xFFU & BIT(PID, 2U)) ^ (0xFFU & BIT(PID, 4U))) << 6U) | + ((0xFFU ^ (BIT(PID, 1U)) ^ (0xFFU & BIT(PID, 3U)) ^ (0xFFU & BIT(PID, 4U)) ^ (0xFFU & BIT(PID, 5U))) << 7U)); + + /* If parity bits are incorrect */ + if ((PID & 0xC0U) != parity) + { + retVal = 0xFFU; + } + else + { + retVal = (uint8_t)(PID & 0x3FU); + } + + return retVal; +} + +/** + * @brief Handle the frame header step by step, break field, sync field and PID field. + */ +static void LIN_DrvHeaderHandle(uint8_t u8LinIndex, uint8_t u8ReceiveByte) +{ + FCUART_Type *base = s_aFCUART_InstanceTable[u8LinIndex]; + lin_xfer_state_t *xferState = s_aLinXfer[u8LinIndex]; + + /* Step 1: Handle the break field state. */ + if (FCUART_HWA_GetStatus(base, FCUART_STAT_LBKDIF)) + { + FCUART_HWA_ClearStatus(base, (uint32_t)FCUART_STAT_LBKDIF); + /* Disable the lin break detect interrupt and clean the status flag. */ + FCUART_HWA_SetLinBreakDetectInterrupt(base, false); + /* Disable lin detect feature, so the data can be stored to RX FIFO. */ + FCUART_HWA_SetLinBreakDetectEnable(base, false); + + /* In this state, maste need send sync field character 0x55U, slave need call callback fucntion.*/ + if (LIN_NODE_MASTER == LIN_DrvCheckMode(u8LinIndex)) + { + if (xferState->currentNodeState == LIN_NODE_STATE_SEND_BREAK_FIELD) + { + xferState->currentNodeState = LIN_NODE_STATE_SEND_PID; + xferState->isBusBusy = true; + + FCUART_HWA_SetData(base, 0x55U); + xferState->currentNodeState = LIN_NODE_STATE_RECV_SYNC; + } + } + else + { + xferState->isBusBusy = true; + xferState->currentEventId = LIN_RECV_BREAK_FIELD_OK; + /* call user's application. */ + if (NULL != xferState->Callback) + { + xferState->Callback(u8LinIndex, xferState); + } + /* Enter next state. */ + xferState->currentNodeState = LIN_NODE_STATE_RECV_SYNC; + } + } + /* Step 2: receive sync filed 0x55U. */ + else if (xferState->currentNodeState == LIN_NODE_STATE_RECV_SYNC) + { + /* If sync byte is 0x55U,transfer success, other failed, maybe baudrate error or protocol error. */ + if (0x55U == u8ReceiveByte) + { + xferState->currentEventId = LIN_SYNC_OK; + xferState->currentNodeState = LIN_NODE_STATE_RECV_PID; + + if (LIN_NODE_MASTER == LIN_DrvCheckMode(u8LinIndex)) + { + FCUART_HWA_SetData(base, (uint32_t)xferState->currentPid); + } + } + else + { + xferState->isBusBusy = false; + xferState->currentEventId = LIN_SYNC_ERROR; + + /* Inform user the transfer status. */ + if (NULL != xferState->Callback) + { + xferState->Callback(u8LinIndex, xferState); + } + + /* Go to IDLE state, start a new transfer. */ + LIN_DrvGoToIdleMode(u8LinIndex); + } + } + /* Step 3: receive and Check PID. */ + else if (xferState->currentNodeState == LIN_NODE_STATE_RECV_PID) + { + /* master node only check if the receive data is match current pid, then enter next state. */ + if (LIN_NODE_MASTER == LIN_DrvCheckMode(u8LinIndex)) + { + /* Update the xfer state */ + if (u8ReceiveByte == xferState->currentPid) + { + xferState->currentNodeState = LIN_NODE_STATE_RECV_DATA; + xferState->isBusBusy = false; + xferState->currentEventId = LIN_PID_OK; + } + else + { + xferState->currentNodeState = LIN_NODE_STATE_IDLE; + xferState->isBusBusy = false; + xferState->currentEventId = LIN_PID_ERROR; + } + + /* Inform user the transfer status. */ + if (NULL != xferState->Callback) + { + xferState->Callback(u8LinIndex, xferState); + } + } + else + { + xferState->currentId = LIN_DrvParityCheck(u8ReceiveByte); + xferState->currentPid = u8ReceiveByte; + + /* Update xfer state. */ + if (0xFFU == xferState->currentId) + { + xferState->currentNodeState = LIN_NODE_STATE_IDLE; + xferState->isBusBusy = false; + xferState->currentEventId = LIN_PID_ERROR; + } + else + { + xferState->currentNodeState = LIN_NODE_STATE_RECV_DATA; + xferState->isBusBusy = false; + xferState->currentEventId = LIN_PID_OK; + } + + /* Inform user the transfer status. */ + if (NULL != xferState->Callback) + { + xferState->Callback(u8LinIndex, xferState); + } + } + } + else + { + /* Misra check */ + } +} + + +/** + * @brief Make checksum byte + */ +static uint8_t LIN_DrvMakeCheckSum(uint8_t u8LinIndex, uint8_t *pBuf, uint8_t u8Size, uint8_t u8Pid) +{ + lin_config_t *pConfig = s_aLinConfig[u8LinIndex]; + uint16_t u16Checksum = 0U; + uint8_t u8Length = 0U; + +// if ((pConfig->numOfClassicPID == 0U) || (pConfig->numOfClassicPID == 255U)) +// { + if (pConfig->classicPID != NULL) + { +// for (uint8_t i = 0U; i < pConfig->numOfClassicPID; i++) +// { +// if (u8Pid == pConfig->classicPID[i]) +// { + u8Pid = 0U; +// break; +// } +// } + } +// } + + /* For PID is 0x3C (ID 0x3C) or 0x7D (ID 0x3D) or 0xFE (ID 0x3E) or 0xBF (ID 0x3F)*/ + if ((0x3CU == u8Pid) || (0x7DU == u8Pid) || (0xFEU == u8Pid) || (0xBFU == u8Pid)) + { + u8Pid = 0U; + } + + u16Checksum += u8Pid; + + for (u8Length = 0U; u8Length < u8Size; u8Length++) + { + u16Checksum += *pBuf; + pBuf++; + if (u16Checksum > 0xFFU) + { + u16Checksum -= 0xFFU; + } + } + + return ~(uint8_t)(u16Checksum); +} + +/** + * @brief receive frame data in IRQ handler. + */ +static void LIN_DrvReceiveFrameData(uint8_t u8LinIndex, uint8_t u8ReceiveByte) +{ + lin_xfer_state_t *xferState = s_aLinXfer[u8LinIndex]; + + xferState->cntByte++; + + if (xferState->cntByte < xferState->rxSize) + { + *(xferState->rxBuff) = u8ReceiveByte; + xferState->rxBuff++; + } + /* Checksum data. */ + else if (xferState->cntByte == xferState->rxSize) + { + xferState->checkSum = u8ReceiveByte; + xferState->rxBuff -= (xferState->rxSize - 1U); + + // Checksun compared. + if (xferState->checkSum == LIN_DrvMakeCheckSum(u8LinIndex, xferState->rxBuff, + xferState->rxSize - 1U, xferState->currentPid)) + { + xferState->currentNodeState = LIN_NODE_STATE_RECV_DATA_COMPLETED; + xferState->currentEventId = LIN_RX_COMPLETED; + } + else + { + xferState->currentEventId = LIN_CHECKSUM_ERROR; + } + + /* call user's application. */ + if (NULL != xferState->Callback) + { + xferState->Callback(u8LinIndex, xferState); + } + + /* Go to IDLE state, start a new transfer. */ + LIN_DrvGoToIdleMode(u8LinIndex); + } + /* Maybe error occurred. */ + else + { + /* MISRA-2012 check. */ + } +} + +/** + * @brief This API will send frame data, due to the LIN node will receive the byte sent by itself, + * we will also check the receive data while sending bytes. + */ +static void LIN_DrvSendFrameData(uint8_t u8LinIndex, uint8_t u8ReceiveByte) +{ + lin_xfer_state_t *xferState = s_aLinXfer[u8LinIndex]; + FCUART_Type *base = s_aFCUART_InstanceTable[u8LinIndex]; + + if (xferState->cntByte < xferState->txSize) + { + /* The received byte should be the byte just send. */ + if (u8ReceiveByte != *(xferState->txBuff - 1)) + { + xferState->currentEventId = LIN_READBACK_ERROR; + + /* call user's application. */ + if (NULL != xferState->Callback) + { + xferState->Callback(u8LinIndex, xferState); + } + } + else + { + if (xferState->cntByte == (xferState->txSize - 1U)) + { + FCUART_HWA_SetData(base, (uint32_t)xferState->checkSum); + } + else + { + FCUART_HWA_SetData(base, (uint32_t) * (xferState->txBuff)); + } + + xferState->txBuff++; + xferState->cntByte++; + } + } + /* Last byte received, no need to send anything. */ + else if (xferState->cntByte == xferState->txSize) + { + if (u8ReceiveByte != xferState->checkSum) + { + xferState->currentEventId = LIN_READBACK_ERROR; + } + else + { + xferState->currentEventId = LIN_TX_COMPLETED; + } + + /* call user's application. */ + if (NULL != xferState->Callback) + { + xferState->Callback(u8LinIndex, xferState); + } + + /* Go to IDLE state, start a new transfer. */ + LIN_DrvGoToIdleMode(u8LinIndex); + } + else + { + /* MISRA Check. */ + } +} + +/** + * @brief Handle the frame data, sending or receiving frame data. + */ + +static void LIN_DrvFrameHandle(uint8_t u8LinIndex) +{ + lin_xfer_state_t *xferState = s_aLinXfer[u8LinIndex]; + FCUART_Type *base = s_aFCUART_InstanceTable[u8LinIndex]; + uint8_t u8ReceiveByte = 0U; + + if (FCUART_HWA_GetStatus(base, FCUART_STAT_RDRFF)) + { + u8ReceiveByte = FCUART_HWA_GetData(base); + } + + /* Handle node to recive frame data. */ + if (LIN_NODE_STATE_RECV_DATA == xferState->currentNodeState) + { + LIN_DrvReceiveFrameData(u8LinIndex, u8ReceiveByte); + } + /* Handle node to send frame data. */ + else if (LIN_NODE_STATE_SEND_DATA == xferState->currentNodeState) + { + LIN_DrvSendFrameData(u8LinIndex, u8ReceiveByte); + } + /* Handle header. */ + else + { + LIN_DrvHeaderHandle(u8LinIndex, u8ReceiveByte); + } +} + +/** + * @brief This API will handle wakeup signal, and calculate the value wakeup signal send. + * Actually, step 1, FCUART will wait a low level in RX pin, and than inverse the RX data + * while the rise edge is coming, another interrupt will be triggered, the time between this + * two interrupt is the wakeup time value. + */ +static void LIN_DrvWakeupHandle(uint8_t u8LinIndex) +{ + lin_xfer_state_t *xferState = s_aLinXfer[u8LinIndex]; + FCUART_Type *base = s_aFCUART_InstanceTable[u8LinIndex]; + uint32_t s_wakeupTime = 0U; + + /* Clear status.*/ + FCUART_HWA_ClearStatus(base, FCUART_STAT_RPAEIF); + + /* Step 1, record the first receive active time. */ + if (false == FCUART_HWA_GetReceiveDataInverse(base)) + { + /* Call the uer time value call function. */ + if (NULL != s_aLinConfig[u8LinIndex]->getIntervalTimeValueCallback) + { + s_aLinConfig[u8LinIndex]->getIntervalTimeValueCallback(&s_wakeupTime); + } + + /* Chang the receive data inverse, and receive the next interrupt. */ + FCUART_HWA_SetReceiveDataInverse(base, true); + } + /* Step 2. calculate the wakeup time. */ + else + { + FCUART_HWA_SetReceiveDataInverse(base, false); + + /* Call the uer time value call function. */ + if (NULL != s_aLinConfig[u8LinIndex]->getIntervalTimeValueCallback) + { + s_aLinConfig[u8LinIndex]->getIntervalTimeValueCallback(&s_wakeupTime); + } + + if (150U < s_wakeupTime) + { + xferState->currentEventId = LIN_WAKEUP_SIGNAL; + + /* call user's application. */ + if (NULL != xferState->Callback) + { + xferState->Callback(u8LinIndex, xferState); + } + + /* Enter IDLE state to prepare next transfer. */ + LIN_DrvGoToIdleMode(u8LinIndex); + } + } +} + +/* ################################################################################## */ +/* ################################ Global Functions ################################ */ + +/** + * @brief Init the LIN instance for LIN network. This API will help initialize the FCUART to expect state, + * but will nots start the TX&RX function, if users want to start the LIN protocol transfer, please + * call the function LIN_DrvStart() after this API is called. + * + * @param u8LinIndex LIN hardware instance, 0U... + * @param pConfig Configuration for LIN hardware, must not be null. + * @return operation status: + * - LIN_STATUS_SUCCESS : operation is successfully. + * - LIN_STATUS_USEED : The instance has been used, user should use another instance or de-initialize this instance + * firstly. + * - LIN_STATUS_ERROR : the baudrate has not been set successfully. + */ +LIN_StatusType LIN_DrvInit(uint8_t u8LinIndex, lin_config_t *pConfig) +{ + LIN_StatusType tRetVal = LIN_STATUS_SUCCESS; + FCUART_Type *base = s_aFCUART_InstanceTable[u8LinIndex]; + uint32_t u32BaudRegValue = 0U; + uint32_t u32CtrlRegValue = 0U; + uint32_t u32StatRegValue = 0U; + uint32_t u32Sbr = 0U; + uint32_t u32OverSamp = 0U; + + DEV_ASSERT(u8LinIndex < LIN_INSTANCE_NUM); + DEV_ASSERT(pConfig != NULL); + + /* Check the LIN instance used or not. */ + if (s_aInstanceUsed[u8LinIndex] == 1U) + { + tRetVal = LIN_STATUS_USEED; + } + else + { + s_aLinConfig[u8LinIndex] = pConfig; + + /* Reset the hardware LIN instance to expect state. */ + FCUART_HWA_SoftwareReset(base); + + /* Set BAUD register configuration: + * - calculate the baudrate generated value. + * - LIN break detect interrupt enable; + * - RX pin active edge disabled, for checking the wakeup signal; + * - Stop bit set to 1; + */ + tRetVal = LIN_DrvCalBaudrate(u8LinIndex, &u32OverSamp, &u32Sbr); + u32BaudRegValue |= FCUART_BAUD_OVR_SAMP(u32OverSamp - 1U) | FCUART_BAUD_BEDGE_SAMP( + 1U) | FCUART_BAUD_SBR(u32Sbr); + FCUART_HWA_SetBaud(base, u32BaudRegValue); + FCUART_HWA_SetLinBreakDetectInterrupt(base, true); + + /* Set LIN break send and detect to 13 bits minimum. If in slave node, only enable detect feature. */ + u32StatRegValue |= FCUART_STAT_BCGL(1U) | FCUART_STAT_LBKDE(0U); + FCUART_HWA_WriteClearSTAT(base, u32StatRegValue); + + /* Set CTRL register configuration: + * - Enable frame error interrupt; + * - Enable receive interrupt; + * - 8 bits transfer mode enabled; + * - Parity check mode disable; + */ + //FCUART_CTRL_IDLECFG(FCUART_IDLE_CHARCTER_128) + + u32CtrlRegValue |= FCUART_CTRL_FEIE(1U) | FCUART_CTRL_RIE(1U) | FCUART_CTRL_BMSEL(0U) | FCUART_CTRL_PE(0U); + FCUART_HWA_SetCtrl(base, u32CtrlRegValue); + + /* Do not use the FIFO feature. the baudrate of LIN protocol is not too high, so do not use fifo feature. */ + FCUART_HWA_SetFifo(base, 0U); + + /* FIFO watermark set to 0. */ + FCUART_HWA_SetWaterMark(base, 0U); + + /* Update the instance used state. */ + s_aInstanceUsed[u8LinIndex] = 1U; + } + + return tRetVal; +} + +/** + * @brief De-Init the LIN instance used by LIN network. + * This API will help disable the fcuart interrupts and stop the TX/RX transfer. + * + * @return operation status: + * - LIN_STATUS_SUCCESS : operation is successfully. + * - LIN_STATUS_NOT_INIT : The instance has not been initialized. + */ +LIN_StatusType LIN_DrvDeInit(uint8_t u8LinIndex) +{ + LIN_StatusType tRetVal = LIN_STATUS_SUCCESS; + FCUART_Type *base = s_aFCUART_InstanceTable[u8LinIndex]; + lin_xfer_state_t *xferState = s_aLinXfer[u8LinIndex]; + + DEV_ASSERT(u8LinIndex < LIN_INSTANCE_NUM); + + /* Instance has not been initialized, no need to do anything */ + if (s_aInstanceUsed[u8LinIndex] == 0U) + { + tRetVal = LIN_STATUS_NOT_INIT; + } + else + { + /* Check if still bytes need to be send or receive. wait the protocol is not busy. */ + while (xferState->isBusBusy) + { + } + + /* Update LIN instance to initialize state. */ + s_aLinConfig[u8LinIndex] = NULL; + s_aLinXfer[u8LinIndex] = NULL; + s_aInstanceUsed[u8LinIndex] = 0U; + + /* Stop TX/TX function and FCUART instance. */ + FCUART_HWA_SetTxTransfer(base, false); + FCUART_HWA_SetRxTransfer(base, false); + + /* Reset the FCUART instance. */ + FCUART_HWA_SoftwareReset(base); + } + + return tRetVal; +} + +/** + * @brief Help users get the default configuration of LIN node. users should provide the configuration structure + * in app code, and transfer the ptr address to driver code. uses can also set this parameters in the application code + * as designed. + * + * @param u8NodeMode LIN node mode select, 0 for slave mode and 1 for master mode. + * @param pConfig default configuration for LIN node, must not be null. + */ +void LIN_DrvGetDefaultConfig(LIN_NodeType eNodeMode, lin_config_t *pConfig) +{ + /* Check NUll ptr for bus error. */ + DEV_ASSERT(pConfig != NULL); + + pConfig->nodeMode = eNodeMode; /*!< Node mode as Master node or Slave node. 0: slave 1: master */ + pConfig->baudRate = 19200U; /*!< baudrate configurations for LIN protocol. */ + pConfig->getIntervalTimeValueCallback = NULL; /*!< Callback function to get time interval in nanoseconds */ + pConfig->classicPID = NULL; /*!< List of PIDs use classic checksum */ + pConfig->numOfClassicPID = 0U; /*!< Number of PIDs use classic checksum */ +} + +/** + * @brief Start LIN node transfer, this API should be called after LIN hardware has been initialized, and must + * be called before starting a LIN node transfer. Users should provide a tansfer structure for storing the + * transfer state, ant LIN node state changed will be stored to this xfer state. + * + * @param u8LinIndex LIN hardware instance, 0U... + * @param pXferState Transfer state structure which will help store the trasnfer state. + * @return operation status: + * - LIN_STATUS_SUCCESS : operation is successfully. + * - LIN_STATUS_PARAM_ERROR: the parameter setting maybe not correct, maybe instance has bot been initialized. + */ +LIN_StatusType LIN_DrvStart(uint8_t u8LinIndex, lin_xfer_state_t *pXferState) +{ + LIN_StatusType tRetVal = LIN_STATUS_ERROR; + FCUART_Type *base = s_aFCUART_InstanceTable[u8LinIndex]; + + DEV_ASSERT(pXferState != NULL); + DEV_ASSERT(u8LinIndex < LIN_INSTANCE_NUM); + + /* If instance has not been intialized, inform users with the error state. */ + if (0U == s_aInstanceUsed[u8LinIndex]) + { + tRetVal = LIN_STATUS_PARAM_ERROR; + } + else + { + /* Register transfer ptr. */ + s_aLinXfer[u8LinIndex] = pXferState; + + /* Initialize the xfer state of LIN transfer. */ + pXferState->isTxBusy = false; + pXferState->isRxBusy = false; + pXferState->isBusBusy = false; + pXferState->isRxBlocking = false; + pXferState->isTxBlocking = false; + pXferState->timeoutCounterFlag = false; + pXferState->timeoutCounter = 0U; + pXferState->currentNodeState = LIN_NODE_STATE_IDLE; + pXferState->currentEventId = LIN_NO_EVENT; + + FCUART_HWA_SetTxTransfer(base, true); + FCUART_HWA_SetRxTransfer(base, true); + { + /*TOBE CHECKED*/ + uint32_t u32Temp; + u32Temp = FCUART_HWA_GetSTAT(base); + u32Temp |= FCUART_STAT_M1F | FCUART_STAT_M0F | FCUART_STAT_FEF; + FCUART_HWA_ClearStatus(base, u32Temp); + FCUART_HWA_GetData(base); + } + + /* Slave will enter the IDEL state, and listening the protocol all time, waiting for a break files. */ + if (LIN_NODE_SLAVE == s_aLinConfig[u8LinIndex]->nodeMode) + { + /* Start hardware. */ + FCUART_HWA_SetLinBreakDetectEnable(base, true); + FCUART_HWA_SetLinBreakDetectInterrupt(base, true); + } + + tRetVal = LIN_STATUS_SUCCESS; + } + + return tRetVal; +} + +/** + * @brief This function will help install callback function that used by application code. + * users can handle some needed operations in driver code or get some important states. + * or uses can also setting this in transfer state structure. + * + * @param u8LinIndex LIN hardware instance, 0U... + * @param callback user's callbak function that need be called in driver code. + * @return operation status: + * - LIN_STATUS_SUCCESS : operation is successfully. + * - LIN_STATUS_NOT_INIT : The instance required has bot been initialized. + */ +LIN_StatusType LIN_DrvInstallUserCallback(uint8_t u8LinIndex, lin_callback_t callback) +{ + DEV_ASSERT(u8LinIndex < LIN_INSTANCE_NUM); + LIN_StatusType tRetVal = LIN_STATUS_ERROR; + lin_xfer_state_t *xferState = s_aLinXfer[u8LinIndex]; + + if (NULL == xferState) + { + tRetVal = LIN_STATUS_NOT_INIT; + } + else + { + xferState->Callback = callback; + tRetVal = LIN_STATUS_SUCCESS; + } + + return tRetVal; +} + +/** + * @brief This function will help users send a header in master node which will help start a new + * frame transfer. please do not used this API will LIN instance is configured as slave node. + * This API will make a parity ID, and only send a break field to the protocol, all the other + * filed like sync filed and pid byte will be handled in FCUART IRQHandler. more details can + * refer to IRQ routine. + * + * @param u8LinIndex LIN hardware instance, 0U... + * @param u8Id The ID data that useds need to send in header. + * @return operation status: + * - LIN_STATUS_SUCCESS : operation is successfully. + * - LIN_STATUS_NOT_INIT : Instance required has not been intialized. + * - LIN_STATUS_UNSUPPORTED : Current node is slave not, could not send header to protocol. + * - LIN_STATUS_BUSY : Bus busy which means node is sending or receiving another frame. + */ +LIN_StatusType LIN_DrvSendHeader(uint8_t u8LinIndex, uint8_t u8Id) +{ + DEV_ASSERT(u8LinIndex < LIN_INSTANCE_NUM); + FCUART_Type *base = s_aFCUART_InstanceTable[u8LinIndex]; + lin_xfer_state_t *xferState = s_aLinXfer[u8LinIndex]; + LIN_StatusType tRetVal = LIN_STATUS_SUCCESS; + + DEV_ASSERT(u8LinIndex < LIN_INSTANCE_NUM); + DEV_ASSERT(xferState != NULL); + + /* Check node state. */ + if (xferState->currentNodeState == LIN_NODE_STATE_UNINIT) + { + tRetVal = LIN_STATUS_NOT_INIT; + } + /* Slave node can not send header. */ + else if (s_aLinConfig[u8LinIndex]->nodeMode == LIN_NODE_SLAVE) + { + tRetVal = LIN_STATUS_UNSUPPORTED; + } + else + { + if (xferState->isBusBusy == true) + { + tRetVal = LIN_STATUS_BUSY; + } + else + { + /* Update node state. */ + xferState->currentId = u8Id; + xferState->currentPid = LIN_DrvParityMake(u8Id); + xferState->currentEventId = LIN_NO_EVENT; + xferState->currentNodeState = LIN_NODE_STATE_SEND_BREAK_FIELD; + xferState->isBusBusy = false; + + /* Start hardware. */ + FCUART_HWA_SetLinBreakDetectEnable(base, true); + FCUART_HWA_SetLinBreakDetectInterrupt(base, true); + + /* Send a break filed to protocol. */ + FCUART_HWA_SendBreakField(base); + } + } + + return tRetVal; +} + +/** + * @brief This API will help users send a frame data through LIN protocol, and will return only when + * all frame data has been sent to the protocol, or while timeout occurred, so please configure + * the u32TimeOut parameter as needed. And currentlyt this API has not implement the OS feature, + * so do not call this API in interrupt routine, otherwise, routine maybe halted by this API. + * + * @param u8LinIndex LIN hardware instance, 0U... + * @param pTxBuf TX buffer whihc will be sent to protocol, MUST NOT BE NULL. + * @param u8Length bytes lengths in TX buffer. + * @param u32TimeOut Timeout value, 0 indicates timeout feature is not used, in unit of millieconds. + * @return operation status: + * - LIN_STATUS_SUCCESS : operation is successfully. + * - LIN_STATUS_NOT_INIT : Instance required has not been initialized. + * - LIN_STATUS_BUSY : Bus busy, node is transfer state. + */ +LIN_StatusType LIN_DrvSendFrameBlocking(uint8_t u8LinIndex, uint8_t *pTxBuf, uint8_t u8Length, + uint32_t u32TimeOut) +{ + FCUART_Type *base = s_aFCUART_InstanceTable[u8LinIndex]; + lin_xfer_state_t *xferState = s_aLinXfer[u8LinIndex]; + LIN_StatusType tRetVal = LIN_STATUS_SUCCESS; + + DEV_ASSERT(u8LinIndex < LIN_INSTANCE_NUM); + DEV_ASSERT((NULL != pTxBuf) && (0U != u8Length)); + DEV_ASSERT(xferState != NULL); + + /* Check node state. */ + if (xferState->currentNodeState == LIN_NODE_STATE_UNINIT) + { + tRetVal = LIN_STATUS_NOT_INIT; + } + else + { + if (xferState->isBusBusy) + { + tRetVal = LIN_STATUS_BUSY; + } + else + { + xferState->currentNodeState = LIN_NODE_STATE_SEND_DATA; + xferState->currentEventId = LIN_NO_EVENT; + + xferState->txBuff = pTxBuf; + xferState->txSize = u8Length + 1U; + xferState->cntByte = 0U; + xferState->checkSum = LIN_DrvMakeCheckSum(u8LinIndex, pTxBuf, u8Length, + xferState->currentPid); + xferState->isTxBusy = true; + xferState->isBusBusy = true; + xferState->isTxBlocking = true; + xferState->timeoutCounter = u32TimeOut; + xferState->timeoutCounterFlag = false; + + FCUART_HWA_SetLinBreakDetectEnable(base, false); + FCUART_HWA_SetData(base, (uint32_t) * (xferState->txBuff)); + + xferState->txBuff++; + xferState->cntByte++; + + /* Waiting for teansfer complete. */ + while (xferState->isTxBusy == true) + { + if (xferState->timeoutCounterFlag == true) + { + tRetVal = LIN_STATUS_TIMEOUT; + break; + } + } + + LIN_DrvGoToIdleMode(u8LinIndex); + } + } + + return tRetVal; +} + +/** + * @brief This API will help users send a frame data through LIN protocol, this API will return immediately. + * data will be stored in txbuffer, users can check the transmit status while data is sending. + * + * @param u8LinIndex LIN hardware instance, 0U... + * @param pTxBuf TX buffer whihc will be sent to protocol, MUST NOT BE NULL. + * @param u8Length bytes lengths in TX buffer. + * @param u32TimeOut Timeout value, 0 indicates timeout feature is not used, in unit of millieconds. + * @return operation status: + * - LIN_STATUS_SUCCESS : operation is successfully. + * - LIN_STATUS_NOT_INIT : Instance required has not been initialized. + * - LIN_STATUS_BUSY : Bus busy, node is transfer state. + */ +LIN_StatusType LIN_DrvSendFrameNonBlocking(uint8_t u8LinIndex, uint8_t *pTxBuf, uint8_t u8Length) +{ + FCUART_Type *base = s_aFCUART_InstanceTable[u8LinIndex]; + lin_xfer_state_t *xferState = s_aLinXfer[u8LinIndex]; + LIN_StatusType tRetVal = LIN_STATUS_SUCCESS; + + DEV_ASSERT(u8LinIndex < LIN_INSTANCE_NUM); + DEV_ASSERT((NULL != pTxBuf) && (0U != u8Length)); + DEV_ASSERT(xferState != NULL); + + /* Check node state. */ + if (xferState->currentNodeState == LIN_NODE_STATE_UNINIT) + { + tRetVal = LIN_STATUS_NOT_INIT; + } + else + { + if (xferState->isBusBusy) + { + tRetVal = LIN_STATUS_BUSY; + } + else + { + xferState->currentNodeState = LIN_NODE_STATE_SEND_DATA; + xferState->currentEventId = LIN_NO_EVENT; + + xferState->txBuff = pTxBuf; + xferState->txSize = u8Length + 1U; + xferState->cntByte = 0U; + xferState->checkSum = LIN_DrvMakeCheckSum(u8LinIndex, pTxBuf, u8Length, xferState->currentPid); + xferState->isTxBusy = true; + xferState->isBusBusy = true; + + FCUART_HWA_SetLinBreakDetectEnable(base, false); + FCUART_HWA_SetData(base, (uint32_t) * (xferState->txBuff)); + + xferState->txBuff++; + xferState->cntByte++; + } + } + + return tRetVal; +} + +/** + * @brief This API will help users get the LIN transfer status while data is sending. and will also + * help user get remainning byte in transfer still need sending in buffer. + * + * @param u8LinIndex LIN hardware instance, 0U... + * @param pRemainBytes Address to be stored the remain byte value, should not be NULL. + * @return operation status: + * - LIN_STATUS_TIMEOUT : node transfer timeout occurred. + * - LIN_STATUS_SUCCESS : transfer complete. + * - LIN_STATUS_BUSY : transfer is going + */ +LIN_StatusType LIN_DrvGetTransmitStatus(uint8_t u8LinIndex, uint8_t *pRemainBytes) +{ + LIN_StatusType tRetVal = LIN_STATUS_SUCCESS; + lin_xfer_state_t *xferState = s_aLinXfer[u8LinIndex]; + + /* Return the remaining byte inlcude checksun byte. */ + *pRemainBytes = xferState->txSize - xferState->cntByte; + + /* Check LIN node status. */ + if (xferState->timeoutCounterFlag == true) + { + tRetVal = LIN_STATUS_TIMEOUT; + } + else if (xferState->isTxBusy == true) + { + tRetVal = LIN_STATUS_BUSY; + } + else + { + } + + return tRetVal; +} + +/** + * @brief This API will help users receive frame data through LIN protocol, this API will return only when + * all frame data has been received from the protocol, or while timeout occurred, so please configure + * the u32TimeOut parameter as needed. And currently, this API has not implement the OS feature, + * so do not call this API in interrupt routine, otherwise, routine maybe halted by this API. + * + * @param u8LinIndex LIN hardware instance, 0U... + * @param pRxBuf RX buffer which will be received from protocol, MUST not be NULL. + * @param u8Length bytes lengths should be received. + * @param u32TimeOut Timeout value, 0 indicates timeout feature is not used, in millieconds. + * @return operation status: + * - LIN_STATUS_SUCCESS : operation is successfully. + * - LIN_STATUS_NOT_INIT : Instance has not been initialized + * - LIN_STATUS_BUSY : Bus in busy state, need wait bus idle. + * - LIN_STATUS_TIMEOUT : Timeout occurred, data received may not successful. + */ +LIN_StatusType LIN_DrvReceiveFrameBlocking(uint8_t u8LinIndex, uint8_t *pRxBuf, uint8_t u8Length, + uint32_t u32TimeOut) +{ + FCUART_Type *base = s_aFCUART_InstanceTable[u8LinIndex]; + lin_xfer_state_t *xferState = s_aLinXfer[u8LinIndex]; + LIN_StatusType tRetVal = LIN_STATUS_SUCCESS; + + DEV_ASSERT(u8LinIndex < LIN_INSTANCE_NUM); + DEV_ASSERT((NULL != pRxBuf) && (0U != u8Length)); + DEV_ASSERT(xferState != NULL); + + /* Check node state. */ + if (xferState->currentNodeState == LIN_NODE_STATE_UNINIT) + { + tRetVal = LIN_STATUS_NOT_INIT; + } + else + { + if (xferState->isBusBusy) + { + tRetVal = LIN_STATUS_BUSY; + } + else + { + xferState->currentNodeState = LIN_NODE_STATE_RECV_DATA; + xferState->currentEventId = LIN_NO_EVENT; + + xferState->rxBuff = pRxBuf; + xferState->rxSize = u8Length + 1U; + xferState->cntByte = 0U; + xferState->isRxBusy = true; + xferState->isBusBusy = true; + xferState->isRxBlocking = true; + xferState->timeoutCounter = u32TimeOut; + xferState->timeoutCounterFlag = false; + + /* Waiting for complete. */ + while (xferState->isRxBusy == true) + { + if (true == xferState->timeoutCounterFlag) + { + tRetVal = LIN_STATUS_TIMEOUT; + break; + } + } + + FCUART_HWA_SetLinBreakDetectEnable(base, false); + } + } + + return tRetVal; +} + +/** + * @brief This API will help users receive frame data through LIN protocol, this API will return immediately. + * data will be stored in rxbuffer, users can check the receive status while using this API. + * + * @param u8LinIndex LIN hardware instance, 0U... + * @param pRxBuf RX buffer which will be received from protocol, MUST not be NULL. + * @param u8Length bytes lengths should be received. + * @param u32TimeOut Timeout value, 0 indicates timeout feature is not used, in millieconds. + * @return operation status: + * - LIN_STATUS_SUCCESS : operation is successfully. + * - LIN_STATUS_NOT_INIT : Instance has not been initialized + * - LIN_STATUS_BUSY : Bus in busy state, need wait bus idle. + * - LIN_STATUS_TIMEOUT : Timeout occurred, data received may not successful. + */ +LIN_StatusType LIN_DrvReceiveFrameNonBlocking(uint8_t u8LinIndex, uint8_t *pRxBuf, uint8_t u8Length) +{ + FCUART_Type *base = s_aFCUART_InstanceTable[u8LinIndex]; + lin_xfer_state_t *xferState = s_aLinXfer[u8LinIndex]; + LIN_StatusType tRetVal = LIN_STATUS_SUCCESS; + + DEV_ASSERT(u8LinIndex < LIN_INSTANCE_NUM); + DEV_ASSERT((NULL != pRxBuf) && (0U != u8Length)); + DEV_ASSERT(xferState != NULL); + + /* Check node state. */ + if (xferState->currentNodeState == LIN_NODE_STATE_UNINIT) + { + tRetVal = LIN_STATUS_NOT_INIT; + } + else + { + if (xferState->isBusBusy) + { + tRetVal = LIN_STATUS_BUSY; + } + else + { + xferState->currentNodeState = LIN_NODE_STATE_RECV_DATA; + xferState->currentEventId = LIN_NO_EVENT; + + xferState->rxBuff = pRxBuf; + xferState->rxSize = u8Length + 1U; + xferState->cntByte = 0U; + xferState->isRxBusy = true; + xferState->isBusBusy = true; + + FCUART_HWA_SetLinBreakDetectEnable(base, false); + } + } + + return tRetVal; +} + +/** + * @brief This API will help users get the LIN transfer status while data is receiving. and will also + * help user get remainning byte in transfer still need receiving in buffer. + * + * @param u8LinIndex LIN hardware instance, 0U... + * @param pRemainBytes Address to be stored the remain byte value, should not be NULL. + * @return operation status: + * - LIN_STATUS_TIMEOUT : node transfer timeout occurred. + * - LIN_STATUS_SUCCESS : transfer complete. + * - LIN_STATUS_BUSY : transfer is going, could read the remain byte in pRemainBytes. + */ +LIN_StatusType LIN_DrvGetReceiveStatus(uint8_t u8LinIndex, uint8_t *pRemainBytes) +{ + LIN_StatusType tRetVal = LIN_STATUS_SUCCESS; + lin_xfer_state_t *xferState = s_aLinXfer[u8LinIndex]; + + DEV_ASSERT(u8LinIndex < LIN_INSTANCE_NUM); + + /* Return the remaining byte inlcude checksun byte. */ + *pRemainBytes = xferState->rxSize - xferState->cntByte; + + if (xferState->timeoutCounterFlag == true) + { + tRetVal = LIN_STATUS_TIMEOUT; + } + else if (xferState->isRxBusy == true) + { + tRetVal = LIN_STATUS_BUSY; + } + else + { + } + return tRetVal; +} + +/** + * @brief Abort transfer both sending or receiving data, actually, call this APU will enter IDLE state. + * will stop end and receive even data transfer is on going. + * + * @param u8LinIndex LIN hardware instance, 0U... + * @return operation status: + * - LIN_STATUS_SUCCESS : operation is successfully. + */ +LIN_StatusType LIN_DrvAbortTransfer(uint8_t u8LinIndex) +{ + LIN_StatusType tRetVal = LIN_STATUS_SUCCESS; + DEV_ASSERT(u8LinIndex < LIN_INSTANCE_NUM); + + /* Update the LIN state to IDLE state directly. */ + tRetVal = LIN_DrvGoToIdleMode(u8LinIndex); + + return tRetVal; +} + +/** + * @brief This API should be called while no data is transferring, once this API is called, node will + * enter sleep mode, TX/RX and interrupts will also be disabled, and node will wait a wakeup signal + * on the protocol. This API will enable receive active interrupt, once a wakeup signal triggered, + * routine will entern uart IRQHandler to handle this case, and then wakeup the LIN node. + * + * @param u8LinIndex LIN hardware instance, 0U... + * @return operation status: + * - LIN_STATUS_SUCCESS : operation is successfully. + */ +LIN_StatusType LIN_DrvGoToSleepMode(uint8_t u8LinIndex) +{ + FCUART_Type *base = s_aFCUART_InstanceTable[u8LinIndex]; + lin_xfer_state_t *xferState = s_aLinXfer[u8LinIndex]; + DEV_ASSERT(u8LinIndex < LIN_INSTANCE_NUM); + + /* Update software status. */ + xferState->currentEventId = LIN_NO_EVENT; + xferState->currentNodeState = LIN_NODE_STATE_SLEEP_MODE; + xferState->isBusBusy = false; + xferState->isRxBusy = false; + xferState->isTxBusy = false; + + /* Disable all enabled interrupt except receive active interrupt. */ + FCUART_HWA_SetLinBreakDetectEnable(base, true); + FCUART_HWA_SetLinBreakDetectInterrupt(base, false); + FCUART_HWA_DisableErrorInterrupt(base); + FCUART_HWA_DisableReceiveInterrupt(base); + FCUART_HWA_SetReceiveActiveInterrupt(base, true); + + return LIN_STATUS_SUCCESS; +} + +/** + * @brief THis API will help confgure the mode into IDLE state. In IDLE state, node will enable receive interrupt and break + * field detect interrupt, slave node will wait the break field from master node, master node will prepare to send a + * new break filed to start a new frame. + * + * @param u8LinIndex LIN hardware instance, 0U... + * @return operation status: + * - LIN_STATUS_SUCCESS : operation is successfully. + */ +LIN_StatusType LIN_DrvGoToIdleMode(uint8_t u8LinIndex) +{ + FCUART_Type *base = s_aFCUART_InstanceTable[u8LinIndex]; + lin_xfer_state_t *xferState = s_aLinXfer[u8LinIndex]; + + DEV_ASSERT(u8LinIndex < LIN_INSTANCE_NUM); + + /* Update software status. */ + xferState->cntByte = 0U; + xferState->txSize = 0U; + xferState->rxSize = 0U; + xferState->isBusBusy = false; + xferState->isRxBusy = false; + xferState->isTxBusy = false; + xferState->isTxBlocking = false; + xferState->isRxBlocking = false; + xferState->currentId = 0U; + xferState->currentPid = 0U; + xferState->currentEventId = LIN_NO_EVENT; + xferState->currentNodeState = LIN_NODE_STATE_IDLE; + xferState->timeoutCounter = 0U; + xferState->timeoutCounterFlag = false; + + /* Update hardware configration. + * 1. Enable LIN break detect interrupr; + * 2. Enable frame error interrupt. + * 3. Enable receive interrupt; + */ + FCUART_HWA_WriteClearSTAT(base, FCUART_STAT_LBKDIF | FCUART_STAT_RPAEIF | FCUART_STAT_RORF_MASK | FCUART_STAT_NF_MASK | FCUART_STAT_FEF_MASK | FCUART_STAT_PEF_MASK); + FCUART_HWA_SetLinBreakDetectEnable(base, true); + FCUART_HWA_SetLinBreakDetectInterrupt(base, true); + FCUART_HWA_EnableErrorInterrupt(base); + FCUART_HWA_EnableReceiveInterrupt(base); + FCUART_HWA_SetReceiveActiveInterrupt(base, false); + FCUART_HWA_SetReceiveDataInverse(base, false); + + return LIN_STATUS_SUCCESS; +} + +/** + * @brief Sending a wakeup signal to the protocol, all LIN network nodes receive this signal will + * wakeup from sleep mode. Actually, the master will send a character which will cause a 150us + * larger active level to the protocol. while receiving this signal, LIN node will wake up + * from sleep mode. + * + * @param u8LinIndex LIN hardware instance, 0U... + * @return operation status: + * - LIN_STATUS_SUCCESS : operation is successfully. + * - LIN_STATUS_NOT_INIT : Instance required is not initialized. + * - LIN_STATUS_BUSY :LIN node state is not correct, need update state firstly. + */ +LIN_StatusType LIN_DrvSendWakeupSignal(uint8_t u8LinIndex) +{ + FCUART_Type *base = s_aFCUART_InstanceTable[u8LinIndex]; + lin_xfer_state_t *xferState = s_aLinXfer[u8LinIndex]; + LIN_StatusType tRetVal = LIN_STATUS_SUCCESS; + + DEV_ASSERT(u8LinIndex < LIN_INSTANCE_NUM); + DEV_ASSERT(xferState != NULL); + + /* Check node state. */ + if (xferState->currentNodeState == LIN_NODE_STATE_UNINIT) + { + tRetVal = LIN_STATUS_NOT_INIT; + } + else + { + if (xferState->isBusBusy == true) + { + tRetVal = LIN_STATUS_BUSY; + } + else + { + if (s_aLinConfig[u8LinIndex]->baudRate > 10000U) + { + /* Wakeup signal will be range from 400us to 800us depend on baudrate, 0x80U */ + FCUART_HWA_SetData(base, 0x00U); + } + else + { + /* Wakeup signal will be range from 400us to 4ms depend on baudrate, 0xF8U */ + FCUART_HWA_SetData(base, 0xF8U); + } + + tRetVal = LIN_STATUS_SUCCESS; + } + } + + return tRetVal; +} + +/** + * @brief Get the LIN node state. + * + * @param u8LinIndex LIN hardware instance, 0U... + * @return the node current state, refer to @lin_node_state_t + */ +lin_node_state_t LIN_DrvGetNodeState(uint8_t u8LinIndex) +{ + DEV_ASSERT(u8LinIndex < LIN_INSTANCE_NUM); + DEV_ASSERT(s_aLinXfer[u8LinIndex] != NULL); + + lin_xfer_state_t *xferState = s_aLinXfer[u8LinIndex]; + + return xferState->currentNodeState; +} + +/** + * @brief This API should be called by user's application code, and the timeout periods should be 1ms once. + * Better to provide a timer IRQhandler to call this APIs 1ms onces. internal timeout feature will + * use this API t o handle the time counter. + * + * @param u8LinIndex LIN hardware instance, 0U... + * @return operation status: + * - LIN_STATUS_SUCCESS : operation is successfully. + */ +LIN_StatusType LIN_DrvTimeOutService(uint8_t u8LinIndex) +{ + DEV_ASSERT(u8LinIndex < LIN_INSTANCE_NUM); + + lin_xfer_state_t *xferState = s_aLinXfer[u8LinIndex]; + LIN_StatusType tRetVal = LIN_STATUS_SUCCESS; + + if ((LIN_NODE_STATE_SEND_DATA == (xferState->currentNodeState)) || (LIN_NODE_STATE_RECV_DATA == (xferState->currentNodeState))) + { + /* time counter down to 0, timeout occurred. */ + if (0U == xferState->timeoutCounter) + { + xferState->timeoutCounterFlag = true; + + /* If send data blocking feature is enabled. anc callback is not NULL. */ + xferState->currentEventId = LIN_TIMEOUT; + + if (NULL != xferState->Callback) + { + xferState->Callback(u8LinIndex, xferState); + } + + tRetVal = LIN_DrvGoToIdleMode(u8LinIndex); + } + else + { + xferState->timeoutCounter--; + } + } + + return tRetVal; +} + +/** + * @brief This API will help users set the timeout counter with one API, users should use this feature with + * LIN_DrvTimeOutService() called every fixed time. + * + * @param u8LinIndex LIN hardware instance, 0U... + * @param u32TimeOutValue Timeout value. + * @return operation status: + * - LIN_STATUS_SUCCESS : operation is successfully. + * - LIN_STATUS_NOT_INIT : Instance required is not initialized. + */ +LIN_StatusType LIN_DrvSetTimeOutCounter(uint8_t u8LinIndex, uint32_t u32TimeOutValue) +{ + LIN_StatusType tRetVal = LIN_STATUS_SUCCESS; + + DEV_ASSERT(u8LinIndex < LIN_INSTANCE_NUM); + + lin_xfer_state_t *xferState = s_aLinXfer[u8LinIndex]; + + if (NULL == xferState) + { + tRetVal = LIN_STATUS_NOT_INIT; + } + else + { + xferState->timeoutCounterFlag = false; + xferState->timeoutCounter = u32TimeOutValue; + } + + return tRetVal; +} + +/** + * @brief This API will help users get the Node timeout flag status. + * + * @param u8LinIndex LIN hardware instance, 0U... + * @return true for timeout occurred, false indicate no timeout. + */ +bool LIN_DrvGetTimeOutFlag(uint8_t u8LinIndex) +{ + DEV_ASSERT(u8LinIndex < LIN_INSTANCE_NUM); + DEV_ASSERT(NULL != s_aLinXfer[u8LinIndex]); + + lin_xfer_state_t *xferState = s_aLinXfer[u8LinIndex]; + + return xferState->timeoutCounterFlag; +} + +/** + * @brief This is LIN IRQ routine code, uses should call this in the FCUART IRQhandler code. please must implement + * the feature in application code. + * + * @param u8LinIndex LIN hardware instance, 0U... + */ +void LIN_DrvIRQHandler(uint8_t u8LinIndex) +{ + DEV_ASSERT(u8LinIndex < LIN_INSTANCE_NUM); + + FCUART_Type *base = s_aFCUART_InstanceTable[u8LinIndex]; + lin_xfer_state_t *xferState = s_aLinXfer[u8LinIndex]; + + /* Handle the wakeup feature by protocol. */ + if (true == FCUART_HWA_GetReceiveActiveInterrupt(base)) + { + if (FCUART_HWA_GetStatus(base, FCUART_STAT_RPAEIF)) + { + LIN_DrvWakeupHandle(u8LinIndex); + } + } + /* Data or lin break detect has been received from protocol. */ + else if (FCUART_HWA_GetStatus(base, (FCUART_StatType)(FCUART_STAT_LBKDIF | FCUART_STAT_RDRFF))) + { + LIN_DrvFrameHandle(u8LinIndex); + } + /* Handle error status. */ + else + { + if (FCUART_HWA_GetStatus(base, FCUART_STAT_RORF)) + { + xferState->currentEventId = LIN_RX_OVERRUN; + } + else + { + xferState->currentEventId = LIN_FRAME_ERROR; + } + + FCUART_HWA_WriteClearSTAT(base, FCUART_STAT_RORF_MASK | FCUART_STAT_NF_MASK | FCUART_STAT_FEF_MASK | FCUART_STAT_PEF_MASK); + + if (NULL != xferState->Callback) + { + xferState->Callback(u8LinIndex, xferState); + } + + /* Error occurred, enater IDLE state. */ + LIN_DrvGoToIdleMode(u8LinIndex); + } +} diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_lu.c b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_lu.c new file mode 100644 index 0000000..616ec93 --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_lu.c @@ -0,0 +1,184 @@ +/** + * @file fc7xxx_driver_lu.c + * @author Flagchip0103 + * @brief FC7xxx LU driver type definition and API + * @version 0.1.0 + * @date 2023-12-19 + * + * @copyright Copyright (c) 2023 Flagchip Semiconductors Co., Ltd. + * + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2023-12-19 Flagchip0103 N/A First version for FC7240 + ******************************************************************************** */ + +#include "fc7xxx_driver_lu.h" + +/** + * @brief Initialize Lu instance + * + * @param pInitStruct Lu initialization structure + * @return LU return type + */ +LU_StatusType LU_Init(const LU_InitType *const pInitStruct) +{ + uint32_t u32TempReg, u32TempCfg; + LU_StatusType eRet = LU_STATUS_SUCCESS; + LU_Type* pLu = LU; + + DEV_ASSERT(NULL_PTR != pInitStruct); + + /* set AOI0 value */ + LU_HWA_ConfigAOI0(pLu, pInitStruct->eLgNum, 0U); + /* set AOI1 value */ + LU_HWA_ConfigAOI1(pLu, pInitStruct->eLgNum, 0U); + /* set CTRL value */ + LU_HWA_ConfigCtrl(pLu, pInitStruct->eLgNum, 0U); + /* set FILT value */ + LU_HWA_ConfigFilter(pLu, pInitStruct->eLgNum, 0U); + + u32TempCfg = (uint32_t)0U | + LU_AOI_IN_CFG(LU_AOI_IN_N_A, pInitStruct->tAoi0Config.tIn0Config.eInNACfg) | + LU_AOI_IN_CFG(LU_AOI_IN_N_B, pInitStruct->tAoi0Config.tIn0Config.eInNBCfg) | + LU_AOI_IN_CFG(LU_AOI_IN_N_C, pInitStruct->tAoi0Config.tIn0Config.eInNCCfg) | + LU_AOI_IN_CFG(LU_AOI_IN_N_D, pInitStruct->tAoi0Config.tIn0Config.eInNDCfg); + u32TempReg = (uint32_t)0U | LU_AOI_IN_N_CFG(LU_AOI_IN_0, u32TempCfg); + + u32TempCfg = (uint32_t)0U | + LU_AOI_IN_CFG(LU_AOI_IN_N_A, pInitStruct->tAoi0Config.tIn1Config.eInNACfg) | + LU_AOI_IN_CFG(LU_AOI_IN_N_B, pInitStruct->tAoi0Config.tIn1Config.eInNBCfg) | + LU_AOI_IN_CFG(LU_AOI_IN_N_C, pInitStruct->tAoi0Config.tIn1Config.eInNCCfg) | + LU_AOI_IN_CFG(LU_AOI_IN_N_D, pInitStruct->tAoi0Config.tIn1Config.eInNDCfg); + u32TempReg |= LU_AOI_IN_N_CFG(LU_AOI_IN_1, u32TempCfg); + + u32TempCfg = (uint32_t)0U | + LU_AOI_IN_CFG(LU_AOI_IN_N_A, pInitStruct->tAoi0Config.tIn2Config.eInNACfg) | + LU_AOI_IN_CFG(LU_AOI_IN_N_B, pInitStruct->tAoi0Config.tIn2Config.eInNBCfg) | + LU_AOI_IN_CFG(LU_AOI_IN_N_C, pInitStruct->tAoi0Config.tIn2Config.eInNCCfg) | + LU_AOI_IN_CFG(LU_AOI_IN_N_D, pInitStruct->tAoi0Config.tIn2Config.eInNDCfg); + u32TempReg |= LU_AOI_IN_N_CFG(LU_AOI_IN_2, u32TempCfg); + + u32TempCfg = (uint32_t)0U | + LU_AOI_IN_CFG(LU_AOI_IN_N_A, pInitStruct->tAoi0Config.tIn3Config.eInNACfg) | + LU_AOI_IN_CFG(LU_AOI_IN_N_B, pInitStruct->tAoi0Config.tIn3Config.eInNBCfg) | + LU_AOI_IN_CFG(LU_AOI_IN_N_C, pInitStruct->tAoi0Config.tIn3Config.eInNCCfg) | + LU_AOI_IN_CFG(LU_AOI_IN_N_D, pInitStruct->tAoi0Config.tIn3Config.eInNDCfg); + u32TempReg |= LU_AOI_IN_N_CFG(LU_AOI_IN_3, u32TempCfg); + /* set AOI0 value */ + LU_HWA_ConfigAOI0(pLu, pInitStruct->eLgNum, u32TempReg); + + u32TempCfg = (uint32_t)0U | + LU_AOI_IN_CFG(LU_AOI_IN_N_A, pInitStruct->tAoi1Config.tIn0Config.eInNACfg) | + LU_AOI_IN_CFG(LU_AOI_IN_N_B, pInitStruct->tAoi1Config.tIn0Config.eInNBCfg) | + LU_AOI_IN_CFG(LU_AOI_IN_N_C, pInitStruct->tAoi1Config.tIn0Config.eInNCCfg) | + LU_AOI_IN_CFG(LU_AOI_IN_N_D, pInitStruct->tAoi1Config.tIn0Config.eInNDCfg); + u32TempReg = (uint32_t)0U | LU_AOI_IN_N_CFG(LU_AOI_IN_0, u32TempCfg); + + u32TempCfg = (uint32_t)0U | + LU_AOI_IN_CFG(LU_AOI_IN_N_A, pInitStruct->tAoi1Config.tIn1Config.eInNACfg) | + LU_AOI_IN_CFG(LU_AOI_IN_N_B, pInitStruct->tAoi1Config.tIn1Config.eInNBCfg) | + LU_AOI_IN_CFG(LU_AOI_IN_N_C, pInitStruct->tAoi1Config.tIn1Config.eInNCCfg) | + LU_AOI_IN_CFG(LU_AOI_IN_N_D, pInitStruct->tAoi1Config.tIn1Config.eInNDCfg); + u32TempReg |= LU_AOI_IN_N_CFG(LU_AOI_IN_1, u32TempCfg); + + u32TempCfg = (uint32_t)0U | + LU_AOI_IN_CFG(LU_AOI_IN_N_A, pInitStruct->tAoi1Config.tIn2Config.eInNACfg) | + LU_AOI_IN_CFG(LU_AOI_IN_N_B, pInitStruct->tAoi1Config.tIn2Config.eInNBCfg) | + LU_AOI_IN_CFG(LU_AOI_IN_N_C, pInitStruct->tAoi1Config.tIn2Config.eInNCCfg) | + LU_AOI_IN_CFG(LU_AOI_IN_N_D, pInitStruct->tAoi1Config.tIn2Config.eInNDCfg); + u32TempReg |= LU_AOI_IN_N_CFG(LU_AOI_IN_2, u32TempCfg); + + u32TempCfg = (uint32_t)0U | + LU_AOI_IN_CFG(LU_AOI_IN_N_A, pInitStruct->tAoi1Config.tIn3Config.eInNACfg) | + LU_AOI_IN_CFG(LU_AOI_IN_N_B, pInitStruct->tAoi1Config.tIn3Config.eInNBCfg) | + LU_AOI_IN_CFG(LU_AOI_IN_N_C, pInitStruct->tAoi1Config.tIn3Config.eInNCCfg) | + LU_AOI_IN_CFG(LU_AOI_IN_N_D, pInitStruct->tAoi1Config.tIn3Config.eInNDCfg); + u32TempReg |= LU_AOI_IN_N_CFG(LU_AOI_IN_3, u32TempCfg); + /* set AOI1 value */ + LU_HWA_ConfigAOI1(pLu, pInitStruct->eLgNum, u32TempReg); + + /* force bypass mode */ + LU_HWA_SetLgBypassControl(pLu, pInitStruct->eLgNum, pInitStruct->eAoiMode); + /* set Flip-Flop mode configure */ + LU_HWA_SetLgFlipFlopMode(pLu, pInitStruct->eLgNum, pInitStruct->eFFMode); + u32TempCfg = 0U; + if (pInitStruct->tSyncCtrl.bInputNA) + { + u32TempCfg |= LU_SYNC_CONTROL_INPUT_N(1U, LU_INPUT_N_A); + } + if (pInitStruct->tSyncCtrl.bInputNB) + { + u32TempCfg |= LU_SYNC_CONTROL_INPUT_N(1U, LU_INPUT_N_B); + } + if (pInitStruct->tSyncCtrl.bInputNC) + { + u32TempCfg |= LU_SYNC_CONTROL_INPUT_N(1U, LU_INPUT_N_C); + } + if (pInitStruct->tSyncCtrl.bInputND) + { + u32TempCfg |= LU_SYNC_CONTROL_INPUT_N(1U, LU_INPUT_N_D); + } + /* set LG inputs synchronous control */ + LU_HWA_SetLgInputsSyncCtrl(pLu, pInitStruct->eLgNum, u32TempCfg); + + if (LU_JKFF_MODE == pInitStruct->eFFMode) + { + /* set LG output feedback override control */ + LU_HWA_SetLgFeedbackOverrideCtrl(pLu, pInitStruct->eLgNum, pInitStruct->eFbMode); + } + + if (LU_OUTPUT_INIT_DISABLE > pInitStruct->eFFInitValue) + { + if (LU_OUTPUT_INIT_ONE == pInitStruct->eFFInitValue) + { + /* Configure the output of flip-flop as "1" */ + LU_HWA_ConfigFlipFlopTo1(pLu, pInitStruct->eLgNum); + } + else + { + /* Configure the output of flip-flop as "0" */ + LU_HWA_ConfigFlipFlopTo0(pLu, pInitStruct->eLgNum); + } + /* Flip-Flop initial output enable control */ + LU_HWA_EnableControlFlipFlopInitOutput(pLu, pInitStruct->eLgNum); + } + + /* set input filter sample count for AOI0 */ + LU_HWA_SetAOI0InputFilterSampleCount(pLu, pInitStruct->eLgNum, (uint32_t)pInitStruct->u8Aoi0FiltCnt); + /* set input filter sample period for AOI0 */ + LU_HWA_SetAOI0InputFilterSamplePeriod(pLu, pInitStruct->eLgNum, (uint32_t)pInitStruct->u8Aoi0Period); + /* set input filter sample count for AOI1 */ + LU_HWA_SetAOI1InputFilterSampleCount(pLu, pInitStruct->eLgNum, (uint32_t)pInitStruct->u8Aoi1FiltCnt); + /* set input filter sample period for AOI0 */ + LU_HWA_SetAOI1InputFilterSamplePeriod(pLu, pInitStruct->eLgNum, (uint32_t)pInitStruct->u8Aoi1Period); + + return eRet; +} + +/** + * @brief De-initialize Lu instance + * @param eLu LU instance + */ +void LU_Deinit() +{ + uint8_t u8Index; + LU_Type* pLu = NULL_PTR; + + for (u8Index = 0U; u8Index < (uint8_t)LG_CNT; u8Index++) + { + /* set AOI0 value */ + LU_HWA_ConfigAOI0(pLu, (LU_LgType)u8Index, 0U); + /* set AOI1 value */ + LU_HWA_ConfigAOI1(pLu, (LU_LgType)u8Index, 0U); + /* set CTRL value */ + LU_HWA_ConfigCtrl(pLu, (LU_LgType)u8Index, 0U); + /* set FILT value */ + LU_HWA_ConfigFilter(pLu, (LU_LgType)u8Index, 0U); + } +} + + diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_mam.c b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_mam.c new file mode 100644 index 0000000..3ed3e5d --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_mam.c @@ -0,0 +1,259 @@ +/** + * @file fc7xxx_driver_mam.c + * @author Flagchip + * @brief FC7xxx MAM driver source code + * @version 0.1.0 + * @date 2023-02-08 + * + * @copyright Copyright (c) 2023 Flagchip Semiconductors Co., Ltd. + * + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-01-10 Flagchip095 N/A First version for FC7240 + ******************************************************************************** */ + +#include "fc7xxx_driver_mam.h" +#include "interrupt_manager.h" + + +#define MAM0_MIN_ADDR 0x01000000U +#define MAM0_MAX_ADDR 0x4049FFFFU + +#define ROM_START_ADDR 0x04800000U +#define ROM_END_ADDR 0x0481FFFFU +#define ROM_BLOCK_SIZE 0x20000U + +#define FLASH0_START_ADDR 0x01000000U +#define FLASH0_END_ADDR 0x011FFFFFU +#define FLASH0_BLOCK_SIZE 0x20000U + +#define NVR_START_ADDR 0x04400000U +#define NVR_END_ADDR 0x04411FFFU +#define NVR_BLOCK_SIZE 0x20000U + +#define NVR_CFG_START_ADDR 0x04420000U +#define NVR_CFG_END_ADDR 0x04431FFFU +#define NVR_CFG_BLOCK_SIZE 0x20000U + +#define FLASH1_START_ADDR 0x04000000U +#define FLASH1_END_ADDR 0x0401FFFFU +#define FLASH1_BLOCK_SIZE 0x2000U + +#define SRAM_START_ADDR 0x21000000U +#define SRAM_END_ADDR 0x21017FFFU +#define SRAM_BLOCK_SIZE 0x4000U + +#define CPU0_DTCM_START_ADDR 0x20000000U +#define CPU0_DTCM_END_ADDR 0x2001FFFFU +#define CPU0_DTCM_BLOCK_SIZE 0x4000U + +#define CPU0_ITCM_START_ADDR 0x00000000U +#define CPU0_ITCM_END_ADDR 0x00007FFFU +#define CPU0_ITCM_BLOCK_SIZE 0x4000U + +#define AFCB0_START_ADDR 0x40000000U +#define AFCB0_END_ADDR 0x4009FFFFU +#define AFCB0_BLOCK_SIZE 0x1000U + +#define AFCB1_START_ADDR 0x40400000U +#define AFCB1_END_ADDR 0x4049FFFFU +#define AFCB1_BLOCK_SIZE 0x1000U + +/** + * @brief Get mam information according to the address + * + * @param u32Addr Input address + */ +static MAM_Inf_Type MAM_Get_MAM_Inf(uint32_t u32Addr); + + +/*************** Local Functions ***************/ +static MAM_Inf_Type MAM_Get_MAM_Inf(uint32_t u32Addr) +{ + MAM_Inf_Type inf = {.error = 0}; + if(MAM0_MIN_ADDR <= u32Addr && u32Addr < MAM0_MAX_ADDR) + { + if(ROM_START_ADDR == u32Addr) + { + inf.block_num = 0; + } + else if(FLASH0_START_ADDR <= u32Addr && u32Addr < FLASH0_END_ADDR) + { + if((u32Addr - FLASH0_START_ADDR)%FLASH0_BLOCK_SIZE == 0U) + { + inf.block_num = (u32Addr - FLASH0_START_ADDR) / FLASH0_BLOCK_SIZE + 1U; + } + else + { + inf.error = 1; + } + } + else if(NVR_START_ADDR <= u32Addr && u32Addr < NVR_END_ADDR) + { + if((u32Addr - NVR_START_ADDR)%NVR_BLOCK_SIZE == 0U) + { + inf.block_num = (u32Addr - NVR_START_ADDR) / NVR_BLOCK_SIZE + 17U; + } + else + { + inf.error = 1; + } + } + else if(NVR_CFG_START_ADDR <= u32Addr && u32Addr < NVR_CFG_END_ADDR) + { + if((u32Addr - NVR_CFG_START_ADDR)%NVR_CFG_BLOCK_SIZE == 0U) + { + inf.block_num = (u32Addr - NVR_CFG_START_ADDR) / NVR_CFG_BLOCK_SIZE + 18U; + } + else + { + inf.error = 1; + } + } + else if(FLASH1_START_ADDR <= u32Addr && u32Addr < FLASH1_END_ADDR) + { + if((u32Addr - FLASH1_START_ADDR)%FLASH1_BLOCK_SIZE == 0U) + { + inf.block_num = (u32Addr - FLASH1_START_ADDR) / FLASH1_BLOCK_SIZE + 19U; + } + else + { + inf.error = 1; + } + } + else if(SRAM_START_ADDR <= u32Addr && u32Addr < SRAM_END_ADDR) + { + if((u32Addr - SRAM_START_ADDR)%SRAM_BLOCK_SIZE == 0U) + { + inf.block_num = (u32Addr - SRAM_START_ADDR) / SRAM_BLOCK_SIZE + 35U; + } + else + { + inf.error = 1; + } + } + else if(CPU0_DTCM_START_ADDR <= u32Addr && u32Addr < CPU0_DTCM_END_ADDR) + { + if((u32Addr - CPU0_DTCM_START_ADDR)%SRAM_BLOCK_SIZE == 0U) + { + inf.block_num = (u32Addr - CPU0_DTCM_START_ADDR) / CPU0_DTCM_BLOCK_SIZE + 43U; + } + else + { + inf.error = 1; + } + } + else if(u32Addr < CPU0_ITCM_END_ADDR) + { + if((u32Addr - CPU0_ITCM_START_ADDR)%CPU0_ITCM_BLOCK_SIZE == 0U) + { + inf.block_num = (u32Addr - CPU0_ITCM_START_ADDR) / CPU0_ITCM_BLOCK_SIZE + 41U; + } + else + { + inf.error = 1; + } + } + else if(AFCB0_START_ADDR <= u32Addr && u32Addr < AFCB0_END_ADDR) + { + if((u32Addr - AFCB0_START_ADDR)%AFCB0_BLOCK_SIZE == 0U) + { + inf.block_num = (u32Addr - AFCB0_START_ADDR) / AFCB0_BLOCK_SIZE + 51U; + } + else + { + inf.error = 1; + } + } + else if(AFCB1_START_ADDR <= u32Addr && u32Addr < AFCB1_END_ADDR) + { + if((u32Addr - AFCB1_START_ADDR)%AFCB1_BLOCK_SIZE == 0U) + { + inf.block_num = (u32Addr - AFCB1_START_ADDR) / AFCB1_BLOCK_SIZE + 211U; + } + else + { + inf.error = 1; + } + } + else + { + inf.error = 1; + } + } + else + { + inf.error = 1; + } + return inf; +} + + +/***************** Global Functions *******************/ +uint8_t MAM_Config(MAM_Master_Type Master, uint32_t u32Addr, uint32_t u32Val) +{ + MAM_Inf_Type inf = MAM_Get_MAM_Inf(u32Addr); + uint32_t reg_idx = 0U; + uint32_t bit_idx = 0U; + uint8_t status = 0U; + if(inf.error == 1U) + { + status = 1; + } + else + { + reg_idx = inf.block_num / 8U + 47U*(uint32_t)Master; /* 371 block , 371/8 + 1*/ + bit_idx = inf.block_num % 8U; + Mam_HWA_Set_ACR(MAM, reg_idx, u32Val << (bit_idx * 4U)); + reg_idx = inf.block_num / 32U + 12U*(uint32_t)Master; /* 371 block , 371/32 + 1*/ + bit_idx = inf.block_num % 32U; + Mam_HWA_Set_ACLR(MAM, reg_idx, 1UL << bit_idx); + } + return status; +} + +uint8_t MAM_Enable_Wdg(MAM_Master_Type Master,uint32_t u32Addr) +{ + uint8_t status = 0U; + uint32_t bit_idx = 0U; + uint32_t regval = 0U; + MAM_Inf_Type inf = MAM_Get_MAM_Inf(u32Addr); + + if(Master >= MAM_MASTER_NUM || inf.error == 1U) + { + status = 1; + } + else + { + bit_idx = (uint32_t)Master; + regval = Mam_HWA_Get_Wdgctr(MAM); + regval |= 1UL << bit_idx; + Mam_HWA_Set_Wdgctr(MAM, regval); + } + return status; +} + +uint8_t MAM_Disable_Wdg(MAM_Master_Type Master,uint32_t u32Addr) +{ + uint8_t status = 0U; + uint32_t regval = 0U; + uint32_t bit_idx = 0U; + MAM_Inf_Type inf = MAM_Get_MAM_Inf(u32Addr); + + if(Master >= MAM_MASTER_NUM || inf.error == 1U) + { + status = 1; + } + else + { + bit_idx = (uint32_t)Master; + regval = Mam_HWA_Get_Wdgctr(MAM); + regval &= ~(1U << bit_idx); + Mam_HWA_Set_Wdgctr(MAM, regval); + } + return status; +} diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_mb.c b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_mb.c new file mode 100644 index 0000000..d93fce1 --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_mb.c @@ -0,0 +1,456 @@ +/** + * @file fc7xxx_driver_mb.c + * @author Flagchip070 + * @brief FC7xxx Mailbox driver type definition and API + * @version 0.1.0 + * @date 2022-11-15 + * + * @copyright Copyright (c) 2022 Flagchip Semiconductors Co., Ltd. + * + * @details + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2022-11-15 Flagchip070 N/A First version for FC7300 + ******************************************************************************** */ + +#include "fc7xxx_driver_mb.h" + + +/********* Local variable ************/ +static uint32_t s_u32CoreIndex = MB_NOT_INIT; +static const uint8_t s_aMasterIdTab[MB_INT_CONFIG_COUNT] = { + 0u, 8u +}; + +static void (*s_pRequestCallback)(MB_ReceiveType *pReceive) = NULL; +static void (*s_pDoneCallback)(uint32_t u32ChannelMask) = NULL; + +/******* Local Function Prototype *********/ +static uint32_t core_id_2_index(uint32_t u32MasterId); +static uint8_t get_channel_status(uint32_t u32Channel); + +/** + * @brief Convert core master id to index + * + * @param u32MasterId Core master ID + * + */ +static uint32_t core_id_2_index(uint32_t u32MasterId) +{ + uint32_t u32Index = 0; + uint32_t u32Loop; + for(u32Loop = 0; u32Loop < MB_INT_CONFIG_COUNT; u32Loop++) + { + if(s_aMasterIdTab[u32Loop] == u32MasterId) + { + u32Index = u32Loop; + break; + } + } + return u32Index; +} + +/** + * @brief Get the master security information and processing mode of the channel + * + * @param u32Channel the selected MB channel + * + */ +static uint8_t get_channel_status(uint32_t u32Channel) +{ + uint8_t u8Status = 0; + if(0u == MB_HWA_GetSecure(u32Channel)) + { + u8Status |= MB_CHANNEL_STATUS_SECURE; + } + if(0u != MB_HWA_GetSupervisor(u32Channel)) + { + u8Status |= MB_CHANNEL_STATUS_PRIVILEGED; + } + return u8Status; +} + +/********* Global Functions ************/ + +/** + * @brief Get the index of the core + * + * @return uint32_t index of the core + */ +uint32_t MB_GetCoreIndex(void) +{ + return s_u32CoreIndex; +} + +/** + * @brief Initialize the Mailbox + * + * @param pInitConfig the configurations of the Mailbox + * @return MB_StatusType whether the operation is successfully + */ +MB_StatusType MB_Init(const MB_InitType *pInitConfig) +{ + MB_StatusType eStatus = MB_STATUS_SUCCESS; + if(MB_NOT_INIT != s_u32CoreIndex) + { + eStatus = MB_STATUS_ALREADY_INITED; + } + else + { + /* Get Core Index */ +#if defined(DEVICE_TYPE) && (DEVICE_TYPE == FC7XXXHSM) + s_u32CoreIndex = HSM_MAILBOX_CORE_INDEX; +#else + uint32_t u32CoreId; + uint32_t u32Index; + u32CoreId = (MCM->MICR & MCM_MICR_COREID_Msk) >> MCM_MICR_COREID_Pos; + for(u32Index = 0; u32Index < MB_INT_CONFIG_COUNT; u32Index++) + { + if(u32CoreId == s_aMasterIdTab[u32Index]) + { + s_u32CoreIndex = u32Index; + break; + } + } +#endif + if(MB_NOT_INIT != s_u32CoreIndex) + { + /*Registering callback functions*/ + s_pRequestCallback = pInitConfig->pRequestCallback; + s_pDoneCallback = pInitConfig->pDoneCallback; + /*Configure the event mask*/ + MB_HWA_ConfigFlagMask(s_u32CoreIndex, pInitConfig->u32EventMask); + /*Enable event interrupts */ + MB_HWA_ConfigIntrEnable(s_u32CoreIndex, pInitConfig->u32IntrMask); + } + else + { + eStatus = MB_STATUS_FAILED; + } + } + + return eStatus; +} + +/** + * @brief De-initialize the Mailbox + * + * @return MB_StatusType whether the operation is successfully + */ +MB_StatusType MB_DeInit(void) +{ + MB_StatusType eStatus = MB_STATUS_UNINIT; + if(MB_NOT_INIT != s_u32CoreIndex) + { + /*Disable all event interrupts and flag*/ + MB_HWA_ConfigFlagMask(s_u32CoreIndex, 0); + MB_HWA_ConfigIntrEnable(s_u32CoreIndex, 0); + s_u32CoreIndex = MB_NOT_INIT; + } + return eStatus; +} + +/** + * @brief Attempt to acquire a Mailbox channel + * + * @param u32Channel the selected Mailbox channel + * @return MB_StatusType whether the operation is successfully + */ +MB_StatusType MB_LockChannel(uint32_t u32Channel) +{ + MB_StatusType eStatus = MB_STATUS_SUCCESS; + uint32_t u32Lock; + + if(MB_NOT_INIT == s_u32CoreIndex) + { + eStatus = MB_STATUS_UNINIT; + } + else + { + if(u32Channel < MB_CHANNEL_CONFIG_COUNT) + { + /*Read SEMA to lock the selected channel*/ + u32Lock = MB_HWA_LockChannel(u32Channel); + if(0u == u32Lock) + { + eStatus = MB_STATUS_LOCKED; + } + } + else + { + eStatus = MB_STATUS_PARAM_ERROR; + } + } + return eStatus; +} + +/** + * @brief Release a Mailbox channel + * + * @param u32Channel the selected Mailbox channel + * @return MB_StatusType whether the operation is successfully + */ +MB_StatusType MB_ReleaseChannel(uint32_t u32Channel) +{ + MB_StatusType eStatus = MB_STATUS_SUCCESS; + uint32_t u32MasterId; + if(MB_NOT_INIT == s_u32CoreIndex) + { + eStatus = MB_STATUS_UNINIT; + } + else + { + if(u32Channel < MB_CHANNEL_CONFIG_COUNT) + { + /*Check the master core of the channel*/ + u32MasterId = MB_HWA_GetMasterID(u32Channel); + if(u32MasterId == s_aMasterIdTab[s_u32CoreIndex]) + { + /*Release the selected channel*/ + MB_HWA_ReleaseChannel(u32Channel); + } + else + { + eStatus = MB_STATUS_FAILED; + } + } + else + { + eStatus = MB_STATUS_PARAM_ERROR; + } + } + return eStatus; +} + +/** + * @brief Software clears channel lock + * + * @param u32Channel the selected Mailbox channel + * @return MB_StatusType whether the operation is successfully + */ +MB_StatusType MB_UnlockChannel(uint32_t u32Channel) +{ + MB_StatusType eStatus = MB_STATUS_SUCCESS; + if(MB_NOT_INIT == s_u32CoreIndex) + { + eStatus = MB_STATUS_UNINIT; + } + else + { + if(u32Channel < MB_CHANNEL_CONFIG_COUNT) + { + MB_HWA_UnlockChanne(u32Channel); + } + else + { + eStatus = MB_STATUS_PARAM_ERROR; + } + } + return eStatus; +} + +/** + * @brief Launching a Mailbox request + * + * @param pRequest Configuration of the request + * @return MB_StatusType whether the operation is successfully + */ +MB_StatusType MB_SendRequest(MB_RequestType *pRequest) +{ + MB_StatusType eStatus = MB_LockChannel(pRequest->u8Channel); + if(MB_STATUS_SUCCESS == eStatus) + { + if(pRequest->u8DoneMasterIndex < MB_INT_CONFIG_COUNT) + { + MB_HWA_ConfigDoneMasterId(pRequest->u8Channel, s_aMasterIdTab[pRequest->u8DoneMasterIndex]); + MB_HWA_ConfigDoneMask(pRequest->u8Channel, pRequest->u8DoneMask); + MB_HWA_ConfigAutoUnlock(pRequest->u8Channel, pRequest->u8AutoReleaseFlag); + MB_HWA_WriteData(pRequest->u8Channel, pRequest->aData); + MB_HWA_ConfigRequest(pRequest->u8Channel, pRequest->u8RequestMask); + } + else + { + eStatus = MB_STATUS_PARAM_ERROR; + } + } + return eStatus; +} + +/** + * @brief Attempt to receive a request from the selected channel + * + * @param pReceive Configuration of the receiving request + * @return MB_StatusType whether the operation is successfully + */ +MB_StatusType MB_ReceiveChannel(MB_ReceiveType *pReceive) +{ + MB_StatusType eStatus = MB_STATUS_SUCCESS; + uint32_t u32Flag; + if(MB_NOT_INIT == s_u32CoreIndex) + { + eStatus = MB_STATUS_UNINIT; + } + else if(pReceive->u8Channel < MB_CHANNEL_CONFIG_COUNT) + { + u32Flag = MB_HWA_GetFlag(s_u32CoreIndex, MB_EVENT_REQ(pReceive->u8Channel)); + if(0u != u32Flag) + { + /* Clear events flag */ + MB_HWA_ClearFlag(s_u32CoreIndex, u32Flag); + /* receiving data */ + MB_HWA_GetData(pReceive->u8Channel, pReceive->aData); + /* get the security information and processing mode */ + pReceive->u8ChannelStatus = get_channel_status(pReceive->u8Channel); + /*get the master core index of the request*/ + pReceive->u8MasterCoreIndex = (uint8_t)MB_HWA_GetMasterID(pReceive->u8Channel); + pReceive->u8MasterCoreIndex = (uint8_t)core_id_2_index((uint32_t)pReceive->u8MasterCoreIndex); + } + else + { + eStatus = MB_STATUS_NO_REQUEST; + } + } + else + { + eStatus = MB_STATUS_PARAM_ERROR; + } + return eStatus; +} + +/** + * @brief Issue a done event to the selected channel + * + * @param u32Channel the selected Mailbox channel + * @param u32DoneMask The mask for issuing done + * @return MB_StatusType whether the operation is successfully + */ +MB_StatusType MB_DoneChannel(uint32_t u32Channel, uint32_t u32DoneMask) +{ + MB_StatusType eStatus = MB_STATUS_SUCCESS; + uint32_t u32DoneMasterId, u32DoneMaskAllow; + if(MB_NOT_INIT == s_u32CoreIndex) + { + eStatus = MB_STATUS_UNINIT; + } + else if(u32Channel < MB_CHANNEL_CONFIG_COUNT) + { + /* Check the done master of the channel*/ + u32DoneMasterId = MB_HWA_GetDoneMasterId(u32Channel); + if(u32DoneMasterId == s_aMasterIdTab[s_u32CoreIndex]) + { + /* Check if the done mask is allowed */ + u32DoneMaskAllow = MB_HWA_GetDoneMask(u32Channel); + if((u32DoneMaskAllow & u32DoneMask) == u32DoneMask) + { + /* issue a done event */ + MB_HWA_SetDone(u32Channel, u32DoneMask); + } + else + { + eStatus = MB_STATUS_FAILED; + } + } + else + { + eStatus = MB_STATUS_FAILED; + } + } + else + { + eStatus = MB_STATUS_PARAM_ERROR; + } + return eStatus; +} + +/** + * @brief Polling the done event of all channels + * + * @param u32PollMask mask of the done event + * @param pDoneMask buffer to store the done events + * @return MB_StatusType whether the operation is successfully + */ +MB_StatusType MB_PollDone(uint32_t u32PollMask, uint32_t *pDoneMask) +{ + MB_StatusType eStatus = MB_STATUS_SUCCESS; + uint32_t u32Flag, u32Index; + *pDoneMask = 0; + + if(MB_NOT_INIT == s_u32CoreIndex) + { + eStatus = MB_STATUS_UNINIT; + } + else if(0u != u32PollMask) + { + for(u32Index = 0; u32Index < MB_CHANNEL_CONFIG_COUNT; u32Index++) + { + if(0u != (u32PollMask & ((uint32_t)1u << u32Index))) + { + u32Flag = MB_HWA_GetFlag(s_u32CoreIndex, MB_EVENT_DONE(u32Index)); + if(0u != u32Flag) + { + /* Clear done flag */ + MB_HWA_ClearFlag(s_u32CoreIndex, u32Flag); + /* store the done event */ + *pDoneMask |= (uint32_t)1u << u32Index; + } + } + } + } + else + { + eStatus = MB_STATUS_PARAM_ERROR; + } + return eStatus; +} + +/** + * @brief Interrupt IRQ handle of Mailbox + * + */ +void MB_IRQProcess(void) +{ + uint32_t u32FlagStat = MB_HWA_GetFlagStat(s_u32CoreIndex, MB_INTn_FLG_STAT_MASK); + uint32_t u32Index, u32MasterCore, u32ChannelMask = 0; + MB_ReceiveType tReceive; + + MB_HWA_ClearFlag(s_u32CoreIndex, u32FlagStat); + for(u32Index = 0; u32Index < MB_CHANNEL_CONFIG_COUNT; u32Index++) + { + /* get the master core index of the channel*/ + u32MasterCore = MB_HWA_GetMasterID(u32Index); + u32MasterCore = core_id_2_index(u32MasterCore); + if(0u != (u32FlagStat & ((uint32_t)1u << u32Index))) + { + /* request event */ + if(NULL != s_pRequestCallback) + { + tReceive.u8Channel = (uint8_t)u32Index; + tReceive.u8ChannelStatus = get_channel_status(u32Index); + tReceive.u8MasterCoreIndex = (uint8_t)u32MasterCore; + MB_HWA_GetData(u32Index, tReceive.aData); + /* call the request callback*/ + s_pRequestCallback(&tReceive); + } + } + if(0u != (u32FlagStat & ((uint32_t)1u << (u32Index + MB_INTn_FLG_STAT_FLG_DONE_INT_STAT_SHIFT)))) + { + u32ChannelMask |= (uint32_t)1u << u32Index; + /*done event*/ + if((0u == MB_HWA_GetAutoClear(u32Index, s_u32CoreIndex)) && (u32MasterCore == s_u32CoreIndex)) + { + /* if channel is not automatically clear, + * and master core is self, release the channel */ + MB_HWA_ReleaseChannel(u32Index); + } + } + } + + if((NULL != s_pDoneCallback) && (0u != u32ChannelMask)) + { + s_pDoneCallback(u32ChannelMask); + } +} diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_mpu.c b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_mpu.c new file mode 100644 index 0000000..a5e0cca --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_mpu.c @@ -0,0 +1,128 @@ +/** + * @file fc7xxx_driver_mpu.c + * @author Flagchip085 + * @brief FC7xxx MPU driver type definition and API + * @version 0.1.0 + * @date 2024-01-12 + * + * @copyright Copyright (c) 2023 Flagchip Semiconductors Co., Ltd. + * + * @details The MPU only checks the CPU master access to CTCM and DTCM memory. When access denied, it will cause MemManage Interrupt. + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-01-12 Flagchip085 N/A First version for FC7240 + ******************************************************************************** */ + +#include "fc7xxx_driver_mpu.h" + +void MPU_Disable(void) +{ + __DMB(); /* make sure outstanding transfers are done */ + MPU_HWA_Fault_Disable(); + MPU_HWA_Set_CR(0U); /* disable mpu and clear its control register*/ +} + +void MPU_Enable(MPU_EnableOptionType eOption) +{ + uint32_t u32Option; + + switch (eOption) + { + case MPU_EN_HARDFAULT_NMI: + u32Option = CORTEX_MPU_CTRL_HFNMIENA_MASK; + break; + + case MPU_EN_PRIVILEGED_DEFAULT: + u32Option = CORTEX_MPU_CTRL_RPRIVDEFENA_MASK; + break; + + case MPU_EN_HFNMI_PRIVDEF: + u32Option = (CORTEX_MPU_CTRL_HFNMIENA_MASK | CORTEX_MPU_CTRL_RPRIVDEFENA_MASK); + break; + + case MPU_EN_HFNMI_PRIVDEF_NONE: + u32Option = 0U; + break; + + default: + u32Option = 0U; + break; + } + MPU_HWA_Set_CR(CORTEX_MPU_CTRL_ENABLE_MASK | (((uint32_t)u32Option) & MPU_EN_MASK_U32)); + MPU_HWA_Fault_Enable(); /* mpu fault MemManage INT enable */ + __DSB(); + __ISB(); +} + +MPU_StatusType MPU_RegionDisable(MPU_RegionNumberType eRegion) +{ + MPU_HWA_Set_NR((uint8_t)eRegion); + MPU_HWA_Set_BAR(0x00U); + MPU_HWA_Set_ASR(0x00U); + + return MPU_STATUS_SUCCESS; +} + +MPU_StatusType MPU_RegionEnable(MPU_RegionNumberType eRegion, const MPU_RegionConfigurationType *pConfig) +{ + MPU_StatusType eRet = MPU_STATUS_SUCCESS; + uint32_t u32Srd; + uint32_t u32Asr; + + if ((NULL == pConfig) || + ((uint32_t)eRegion > (uint32_t)MPU_REGION_NUMBER_15) || + (0U != (pConfig->u32BaseAddr & MPU_RBAR_VALID_REGION_MASK_U32)) || + ((uint32_t)pConfig->eRegionSize < (uint32_t)MPU_REGION_SIZE_32B) || + ((uint32_t)pConfig->eRegionSize > (uint32_t)MPU_REGION_SIZE_4GB)) + { + eRet = MPU_STATUS_ERROR; + } + else + { + /* use bit shift is surely safe */ + u32Srd = (((((uint32_t)pConfig->eSubRegionDis_0) << 0) | + (((uint32_t)pConfig->eSubRegionDis_1) << 1) | + (((uint32_t)pConfig->eSubRegionDis_2) << 2) | + (((uint32_t)pConfig->eSubRegionDis_3) << 3) | + (((uint32_t)pConfig->eSubRegionDis_4) << 4) | + (((uint32_t)pConfig->eSubRegionDis_5) << 5) | + (((uint32_t)pConfig->eSubRegionDis_6) << 6) | + (((uint32_t)pConfig->eSubRegionDis_7) << 7)) & 0xFFU); + + u32Asr = CORTEX_MPU_RASR_XN(pConfig->eExecuteNever) | + CORTEX_MPU_RASR_AP(pConfig->eAccessPermission) | + CORTEX_MPU_RASR_TEX(pConfig->eTypeExtLevel) | + CORTEX_MPU_RASR_S(pConfig->eShareable) | + CORTEX_MPU_RASR_C(pConfig->eCacheable) | + CORTEX_MPU_RASR_B(pConfig->eBufferable) | + CORTEX_MPU_RASR_SRD(u32Srd) | + CORTEX_MPU_RASR_SIZE(pConfig->eRegionSize) | + CORTEX_MPU_RASR_ENABLE_MASK; + + MPU_HWA_Set_NR((uint8_t)eRegion); + MPU_HWA_Set_BAR(pConfig->u32BaseAddr & MPU_RBAR_BASEADDR_MASK_U32); /* ignore VALID and REGION bits */ + MPU_HWA_Set_ASR(u32Asr); + } + + return eRet; +} + + + + +MPU_StatusType MPU_CheckExist(void) +{ + uint32_t u32RegVal = MPU_HWA_Get_Type(); + MPU_StatusType eRet = MPU_STATUS_SUCCESS; + + if (0U == u32RegVal) + { + eRet = MPU_STATUS_ERROR; + } + + return eRet; +} diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_msc.c b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_msc.c new file mode 100644 index 0000000..51d411d --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_msc.c @@ -0,0 +1,569 @@ +/** + * @file fc7xxx_driver_msc.c + * @author Flagchip + * @brief FC7240 MSC driver type definition and API + * @version 0.1.0 + * @date 2024-01-10 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-01-10 Flagchip084 N/A FC7240 release version + ******************************************************************************** */ + +#include "fc7xxx_driver_msc.h" + +/* ################################################################################## */ +/* ####################################### Macro #################################### */ + +/* ################################################################################## */ +/* ################################### Type define ################################## */ + +/* ################################################################################## */ +/* ################################ Local Variables ################################# */ +static MSC_Type *const s_apMscBase[MSC_INSTANCE_COUNT] = MSC_BASE_PTRS; +static MSC_ISRCallbackType s_apMscRFISRCallback[MSC_INSTANCE_COUNT] = {NULL}; +static MSC_ISRCallbackType s_apMscTFISRCallback[MSC_INSTANCE_COUNT] = {NULL}; +static MSC_ISRCallbackType s_apMscCFISRCallback[MSC_INSTANCE_COUNT] = {NULL}; +static MSC_ISRCallbackType s_apMscDFISRCallback[MSC_INSTANCE_COUNT] = {NULL}; +static MSC_ISRCallbackType s_apMscTOISRCallback[MSC_INSTANCE_COUNT] = {NULL}; + +/* ################################################################################## */ +/* ########################### Local Prototype Functions ############################ */ +static void MSCn_IRQHandler(const MSC_InstanceType eInstance); +static void MSC_ClearReceiveInterruptFlag(const MSC_InstanceType eInstance); +static void MSC_ClearTimeFrameInterruptFlag(const MSC_InstanceType eInstance); +static void MSC_ClearCommandFrameInterruptFlag(const MSC_InstanceType eInstance); +static void MSC_ClearDataFrameInterruptFlag(const MSC_InstanceType eInstance); +/* ################################################################################## */ +/* ######################### Global prototype Functions ############################ */ +void MSC0_IRQHandler(void); +/* ################################################################################## */ +/* ################################ Local Functions ################################ */ +static void MSCn_IRQHandler(const MSC_InstanceType eInstance) +{ + uint32_t u32IntFlag = MSC_GetInterruptStatus(eInstance); + MSC_Type *const pMsc = s_apMscBase[eInstance]; + + if (u32IntFlag & MSC_INSR_RFI_MASK) + { + MSC_ClearReceiveInterruptFlag(eInstance); + if (MSC_HWA_GetRfieEnable(pMsc) && s_apMscRFISRCallback[eInstance] != NULL) + { + s_apMscRFISRCallback[eInstance](eInstance); + } + } + if (u32IntFlag & MSC_INSR_TFI_MASK) + { + MSC_ClearTimeFrameInterruptFlag(eInstance); + if (MSC_HWA_GetTfieEnable(pMsc) && s_apMscTFISRCallback[eInstance] != NULL) + { + s_apMscTFISRCallback[eInstance](eInstance); + } + } + if (u32IntFlag & MSC_INSR_CFI_MASK) + { + MSC_ClearCommandFrameInterruptFlag(eInstance); + if (MSC_HWA_GetCfieEnable(pMsc) && s_apMscCFISRCallback[eInstance] != NULL) + { + s_apMscCFISRCallback[eInstance](eInstance); + } + } + if (u32IntFlag & MSC_INSR_DFI_MASK) + { + MSC_ClearDataFrameInterruptFlag(eInstance); + if (MSC_HWA_GetDfieEnable(pMsc) && s_apMscDFISRCallback[eInstance] != NULL) + { + s_apMscDFISRCallback[eInstance](eInstance); + } + } + if (MSC_HWA_GetTofEnable(pMsc)) + { + MSC_HWA_ClearTofEnable(pMsc); + if (MSC_HWA_GetToieEnable(pMsc) && s_apMscTOISRCallback[eInstance] != NULL) + { + s_apMscTOISRCallback[eInstance](eInstance); + } + } +} +/* ################################################################################## */ +/* ################################ Global Functions ################################ */ + +void MSC0_IRQHandler(void) +{ + MSCn_IRQHandler(MSC_INSTANCE_0); +} + +MSC_ReturnType MSC_init(const MSC_InstanceType eInstance, const MSC_InitCfgType *pInitConfig) +{ + DEV_ASSERT((uint8_t)eInstance < MSC_INSTANCE_COUNT); + DEV_ASSERT(pInitConfig != NULL); + + MSC_Type *const pMsc = s_apMscBase[eInstance]; + uint32_t u32TempValue; + uint32_t u32TimeoutCount = 0xFFFFFFU; + + if (pInitConfig->u8CommandBitLength > 32U || pInitConfig->u8SRLDataBitLength > 16U || pInitConfig->u8SRHDataBitLength > 16U) + { + return MSC_RETURN_E_PARAM; + } + + MSC_HWA_SetMsrRst(pMsc); + + while (MSC_HWA_GetMsrRdone(pMsc) == false) + { + u32TimeoutCount--; + if (u32TimeoutCount == 0U) + { + break; + } + } + + if (u32TimeoutCount == 0U) + { + return MSC_RETURN_E_NOT_OK; + } + + MSC_HWA_ClearMsrDone(pMsc); + + u32TempValue = MSC_TCCTR_PL(pInitConfig->u8PassiveLength) | MSC_TCCTR_WM(pInitConfig->eWorkMode) | MSC_TCCTR_SELH(pInitConfig->bSelSRH) | MSC_TCCTR_SELL(pInitConfig->bSelSRL) | + MSC_TCCTR_NBS(pInitConfig->u8CommandBitLength) | MSC_TCCTR_NHBS(pInitConfig->u8SRHDataBitLength) | MSC_TCCTR_NLBS(pInitConfig->u8SRLDataBitLength); + MSC_HWA_SetTcctr(pMsc, u32TempValue); + + MSC_HWA_SetNp(pMsc, pInitConfig->u8PTFNumber); + + u32TempValue = + MSC_RCCSR_RFT(pInitConfig->eRsvFrameType) | MSC_RCCSR_RBR(pInitConfig->eBaudRate) | MSC_RCCSR_PCTL(pInitConfig->eParity) | MSC_RCCSR_HIDC(pInitConfig->bDelayControl); + MSC_HWA_SetRccsr(pMsc, u32TempValue); + + return MSC_RETURN_OK; +} + +void MSC_initInterrupt(const MSC_InstanceType eInstance, const MSC_InterruptCfgType *pInteruptConfig) +{ + DEV_ASSERT((uint8_t)eInstance < MSC_INSTANCE_COUNT); + DEV_ASSERT(pInteruptConfig != NULL); + uint32_t u32TempValue; + MSC_Type *const pMsc = s_apMscBase[eInstance]; + + u32TempValue = MSC_INCR_RFIE(pInteruptConfig->eRFIEMode) | MSC_INCR_TFIE(pInteruptConfig->bTFIntEnable) | MSC_INCR_CFIE(pInteruptConfig->bCFIntEnable) | + MSC_INCR_DFIE(pInteruptConfig->eDFIEMode); + MSC_HWA_SetIncr(pMsc, u32TempValue); + + u32TempValue = MSC_RTOR_TOIE(pInteruptConfig->bTOIntEnable) | MSC_RTOR_TOV(pInteruptConfig->u16TimeoutValue); + MSC_HWA_SetRtor(pMsc, u32TempValue); + + s_apMscRFISRCallback[eInstance] = pInteruptConfig->pReceiveFrameISRCallback; + s_apMscTFISRCallback[eInstance] = pInteruptConfig->pTimeFrameISRCallback; + s_apMscCFISRCallback[eInstance] = pInteruptConfig->pCommandFrameISRCallback; + s_apMscDFISRCallback[eInstance] = pInteruptConfig->pDataFrameISRCallback; + s_apMscTOISRCallback[eInstance] = pInteruptConfig->pReceiveTimeOutISRCallback; +} + +void MSC_SelTranmittingSource(const MSC_InstanceType eInstance, uint32_t u32SourceMask, MSC_TransSourceType eSourceType) +{ + DEV_ASSERT((uint8_t)eInstance < MSC_INSTANCE_COUNT); + + MSC_Type *const pMsc = s_apMscBase[eInstance]; + uint32_t u32TempValue1 = 0; + uint16_t u32TempValue2; + uint8_t u8i; + + u32TempValue2 = (uint16_t)(u32SourceMask & 0xFFFFU); + + for (u8i = 0U; u8i < 16U; u8i++) + { + if ((u32TempValue2 & 0x01U) != 0U) + { + u32TempValue1 |= (uint32_t)eSourceType << (u8i << 1U); + } + u32TempValue2 = u32TempValue2 >> 1; + } + MSC_HWA_SetTcslr(pMsc, u32TempValue1); + + u32TempValue2 = (uint16_t)((u32SourceMask >> 16) & 0xFFFFU); + for (u8i = 0U; u8i < 16U; u8i++) + { + if ((u32TempValue2 & 0x01U) != 0U) + { + u32TempValue1 |= (uint32_t)eSourceType << (u8i << 1U); + } + u32TempValue2 = u32TempValue2 >> 1; + } + MSC_HWA_SetTcshr(pMsc, u32TempValue1); +} + +void MSC_SetEmergencyLoad(const MSC_InstanceType eInstance, uint32_t u32Value) +{ + DEV_ASSERT((uint8_t)eInstance < MSC_INSTANCE_COUNT); + + MSC_Type *const pMsc = s_apMscBase[eInstance]; + + MSC_HWA_SetTcelr(pMsc, u32Value); +} + +void MSC_SetIOControl(const MSC_InstanceType eInstance, const MSC_IOControlInitType *pIOConfig) +{ + DEV_ASSERT((uint8_t)eInstance < MSC_INSTANCE_COUNT); + + uint32_t u32TempValue = 0; + MSC_Type *const pMsc = s_apMscBase[eInstance]; + + u32TempValue |= MSC_IOCR_IDS(pIOConfig->eSDIsel); + u32TempValue |= MSC_IOCR_ESC(pIOConfig->eENCSel); + u32TempValue |= MSC_IOCR_ESH(pIOConfig->eENHSel); + u32TempValue |= MSC_IOCR_ESL(pIOConfig->eENLSel); + u32TempValue |= MSC_IOCR_FCLCTRL(pIOConfig->eFclCtrl); + u32TempValue |= MSC_IOCR_IPS(pIOConfig->eSDIPol); + u32TempValue |= MSC_IOCR_ENP(pIOConfig->eENXPol); + u32TempValue |= MSC_IOCR_SOP(pIOConfig->eSOPPol); + u32TempValue |= MSC_IOCR_FCLP(pIOConfig->eFCLPPol); + + MSC_HWA_SetIocr(pMsc, u32TempValue); +} + +void MSC_Enable(const MSC_InstanceType eInstance) +{ + DEV_ASSERT((uint8_t)eInstance < MSC_INSTANCE_COUNT); + MSC_Type *const pMsc = s_apMscBase[eInstance]; + + MSC_HWA_SetMscEnable(pMsc, true); +} + +void MSC_Disable(const MSC_InstanceType eInstance) +{ + DEV_ASSERT((uint8_t)eInstance < MSC_INSTANCE_COUNT); + MSC_Type *const pMsc = s_apMscBase[eInstance]; + + MSC_HWA_SetMscEnable(pMsc, false); +} + +void MSC_SetDataFrame(const MSC_InstanceType eInstance, uint32_t u32Data) +{ + DEV_ASSERT((uint8_t)eInstance < MSC_INSTANCE_COUNT); + MSC_Type *const pMsc = s_apMscBase[eInstance]; + + MSC_HWA_SetTcdar(pMsc, u32Data); +} + +void MSC_SendDataFrame(const MSC_InstanceType eInstance) +{ + DEV_ASSERT((uint8_t)eInstance < MSC_INSTANCE_COUNT); + MSC_Type *const pMsc = s_apMscBase[eInstance]; + MSC_HWA_SetDataNeedSend(pMsc); +} + +void MSC_SendCommandFrame(const MSC_InstanceType eInstance, uint32_t u32Command) +{ + DEV_ASSERT((uint8_t)eInstance < MSC_INSTANCE_COUNT); + MSC_Type *const pMsc = s_apMscBase[eInstance]; + + MSC_HWA_SetTccor(pMsc, u32Command); +} + +uint8_t MSC_GetReceivedFrameAddr(const MSC_InstanceType eInstance, MSC_RDRxIndexType eIndex) +{ + DEV_ASSERT((uint8_t)eInstance < MSC_INSTANCE_COUNT); + DEV_ASSERT(eIndex < MSC_RDRx_COUNT); + + MSC_Type *const pMsc = s_apMscBase[eInstance]; + uint8_t u8Addr = 0U; + + if (eIndex == MSC_RDR0) + { + u8Addr = MSC_HWA_GetRdr0Addr(pMsc); + } + else if (eIndex == MSC_RDR1) + { + u8Addr = MSC_HWA_GetRdr1Addr(pMsc); + } + else if (eIndex == MSC_RDR2) + { + u8Addr = MSC_HWA_GetRdr2Addr(pMsc); + } + else if (eIndex == MSC_RDR3) + { + u8Addr = MSC_HWA_GetRdr3Addr(pMsc); + } + else {} + + return u8Addr; +} + +MSC_ReceiveStatusType MSC_GetReceivedFrame(const MSC_InstanceType eInstance, MSC_RDRxIndexType eIndex, uint8_t *pData) +{ + DEV_ASSERT((uint8_t)eInstance < MSC_INSTANCE_COUNT); + DEV_ASSERT(eIndex < MSC_RDRx_COUNT); + + MSC_Type *const pMsc = s_apMscBase[eInstance]; + MSC_ReceiveStatusType eRsvStatus = MSC_RSV_SUCCESS; + + if (eIndex == MSC_RDR0) + { + eRsvStatus = MSC_HWA_GetRdr0Rerr(pMsc); + if (MSC_RSV_SUCCESS == eRsvStatus) + { + *pData = MSC_HWA_GetRdr0Data(pMsc); + } + } + else if (eIndex == MSC_RDR1) + { + eRsvStatus = MSC_HWA_GetRdr1Rerr(pMsc); + if (MSC_RSV_SUCCESS == eRsvStatus) + { + *pData = MSC_HWA_GetRdr1Data(pMsc); + } + } + else if (eIndex == MSC_RDR2) + { + eRsvStatus = MSC_HWA_GetRdr2Rerr(pMsc); + if (MSC_RSV_SUCCESS == eRsvStatus) + { + *pData = MSC_HWA_GetRdr2Data(pMsc); + } + } + else if (eIndex == MSC_RDR3) + { + eRsvStatus = MSC_HWA_GetRdr3Rerr(pMsc); + if (MSC_RSV_SUCCESS == eRsvStatus) + { + *pData = MSC_HWA_GetRdr3Data(pMsc); + } + } + else {} + + return eRsvStatus; +} + +uint32_t MSC_GetInterruptStatus(const MSC_InstanceType eInstance) +{ + DEV_ASSERT((uint8_t)eInstance < MSC_INSTANCE_COUNT); + + MSC_Type *const pMsc = s_apMscBase[eInstance]; + return MSC_HWA_GetInsr(pMsc); +} + +void MSC_EnableTrasmit(const MSC_InstanceType eInstance, bool bEnable) +{ + DEV_ASSERT((uint8_t)eInstance < MSC_INSTANCE_COUNT); + + MSC_Type *const pMsc = s_apMscBase[eInstance]; + + if (bEnable) + { + MSC_HWA_ClearTcdis(pMsc); + } + else + { + MSC_HWA_SetTcdis(pMsc); + } +} + +void MSC_ClearReceiveInterruptFlag(const MSC_InstanceType eInstance) +{ + DEV_ASSERT((uint8_t)eInstance < MSC_INSTANCE_COUNT); + + MSC_Type *const pMsc = s_apMscBase[eInstance]; + + MSC_HWA_ClearCrfi(pMsc); +} + +void MSC_ClearTimeFrameInterruptFlag(const MSC_InstanceType eInstance) +{ + DEV_ASSERT((uint8_t)eInstance < MSC_INSTANCE_COUNT); + + MSC_Type *const pMsc = s_apMscBase[eInstance]; + + MSC_HWA_ClearCtfi(pMsc); +} + +void MSC_ClearCommandFrameInterruptFlag(const MSC_InstanceType eInstance) +{ + DEV_ASSERT((uint8_t)eInstance < MSC_INSTANCE_COUNT); + + MSC_Type *const pMsc = s_apMscBase[eInstance]; + + MSC_HWA_ClearCcfi(pMsc); +} + +void MSC_ClearDataFrameInterruptFlag(const MSC_InstanceType eInstance) +{ + DEV_ASSERT((uint8_t)eInstance < MSC_INSTANCE_COUNT); + + MSC_Type *const pMsc = s_apMscBase[eInstance]; + + MSC_HWA_ClearCdfi(pMsc); +} + +void MSC_EnableDataFrameInterrupt(const MSC_InstanceType eInstance, bool bEnable) +{ + DEV_ASSERT((uint8_t)eInstance < MSC_INSTANCE_COUNT); + + MSC_Type *const pMsc = s_apMscBase[eInstance]; + + MSC_HWA_SetDfieEnable(pMsc, bEnable); +} + +void MSC_EnableCommandFrameInterrupt(const MSC_InstanceType eInstance, bool bEnable) +{ + DEV_ASSERT((uint8_t)eInstance < MSC_INSTANCE_COUNT); + + MSC_Type *const pMsc = s_apMscBase[eInstance]; + + MSC_HWA_SetCfieEnable(pMsc, bEnable); +} + +void MSC_EnableTimeFrameInterrupt(const MSC_InstanceType eInstance, bool bEnable) +{ + DEV_ASSERT((uint8_t)eInstance < MSC_INSTANCE_COUNT); + + MSC_Type *const pMsc = s_apMscBase[eInstance]; + + MSC_HWA_SetTfieEnable(pMsc, bEnable); +} + +void MSC_EnableReceiveInterrupt(const MSC_InstanceType eInstance, bool bEnable) +{ + DEV_ASSERT((uint8_t)eInstance < MSC_INSTANCE_COUNT); + + MSC_Type *const pMsc = s_apMscBase[eInstance]; + + MSC_HWA_SetRfieEnable(pMsc, bEnable); +} + +void MSC_EnableTimeoutInterrupt(const MSC_InstanceType eInstance, bool bEnable) +{ + DEV_ASSERT((uint8_t)eInstance < MSC_INSTANCE_COUNT); + + MSC_Type *const pMsc = s_apMscBase[eInstance]; + + MSC_HWA_SetToieEnable(pMsc, bEnable); +} + +MSC_ReturnType Msc_SwitchENXChannel(const MSC_InstanceType eInstance, Msc_ENxType eEnx, Msc_ENxActiveType eENn, uint32_t u32TimeoutLoops) +{ + MSC_ReturnType eTempReturn = MSC_RETURN_E_NOT_OK; + uint32 u32TempValue; + uint32 u32TempTryCount = 0u; + uint8 u8CmdNeedSend; + uint8 u8CmdFrameBusy; + uint8 u8DataNeedSend; + uint8 u8DataFrameBusy; + MSC_Type *const pMsc = s_apMscBase[eInstance]; + + if (eEnx == MSC_ENC) + { + do + { + u8CmdFrameBusy = MSC_HWA_GetCfb(pMsc); + u8CmdNeedSend = MSC_HWA_GetCmdNeedSend(pMsc); + + if ((u8CmdNeedSend == TRUE) || (u8CmdFrameBusy == TRUE)) + { + u32TempValue = TRUE; + } + else + { + u32TempValue = FALSE; + } + + /* check receive rc flag */ + if (u32TempValue == FALSE) + { + break; + } + else + { + u32TempTryCount++; + } + } while (u32TempTryCount < u32TimeoutLoops); + + if (u32TempTryCount != u32TimeoutLoops) + { + u32TempValue = (MSC_HWA_GetIocr(pMsc) & ~MSC_IOCR_ESC_MASK) | MSC_IOCR_ESC(eENn); + MSC_HWA_SetIocr(pMsc, u32TempValue); + eTempReturn = MSC_RETURN_OK; + } + } + else + { + do + { + u8DataFrameBusy = MSC_HWA_GetDfb(pMsc); + u8DataNeedSend = MSC_HWA_GetDataNeedSend(pMsc); + + if ((u8DataFrameBusy == TRUE) || (u8DataNeedSend == TRUE)) + { + u32TempValue = TRUE; + } + else + { + u32TempValue = FALSE; + } + + /* check receive rc flag */ + if (u32TempValue == FALSE) + { + break; + } + else + { + u32TempTryCount++; + } + } while (u32TempTryCount < u32TimeoutLoops); + + if (u32TempTryCount != u32TimeoutLoops) + { + if (eEnx == MSC_ENH) + { + u32TempValue = (MSC_HWA_GetIocr(pMsc) & ~MSC_IOCR_ESH_MASK) | MSC_IOCR_ESH(eENn); + MSC_HWA_SetIocr(pMsc, u32TempValue); + } + else + { + u32TempValue = (MSC_HWA_GetIocr(pMsc) & ~MSC_IOCR_ESL_MASK) | MSC_IOCR_ESL(eENn); + MSC_HWA_SetIocr(pMsc, u32TempValue); + } + eTempReturn = MSC_RETURN_OK; + } + } + + return eTempReturn; +} + +MSC_ReturnType Msc_SwitchSDIChannel(const MSC_InstanceType eInstance, MSC_SDISelectionType eSDIChannel, uint32_t u32TimeoutLoops) +{ + MSC_ReturnType eTempReturn = MSC_RETURN_E_NOT_OK; + uint32_t u32TempValue; + uint32_t u32TempTryCount = 0u; + MSC_Type *const pMsc = s_apMscBase[eInstance]; + + do + { + u32TempValue = MSC_HWA_GetRxBusy(pMsc); + + /* check receive rc flag */ + if (u32TempValue == 0U) + { + break; + } + else + { + u32TempTryCount++; + } + } while (u32TempTryCount < u32TimeoutLoops); + + if (u32TempTryCount != u32TimeoutLoops) + { + u32TempValue = (MSC_HWA_GetIocr(pMsc) & ~MSC_IOCR_IDS_MASK) | MSC_IOCR_IDS(eSDIChannel); + MSC_HWA_SetIocr(pMsc, u32TempValue); + + eTempReturn = MSC_RETURN_OK; + } + return eTempReturn; +} diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_overlay.c b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_overlay.c new file mode 100644 index 0000000..744dfbb --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_overlay.c @@ -0,0 +1,498 @@ +/** + * @file fc7xxx_driver_overlay.c + * @author Flagchip + * @brief FC7xxx overlay driver type definition and API + * @version 0.1.0 + * @date 2023-12-25 + * + * @copyright Copyright (c) 2022 Flagchip Semiconductors Co., Ltd. + * + */ + +/******************************************************************************** +* Revision History: +* +* Version Date Initials CR# Descriptions +* --------- ---------- ------------ ---------- --------------- +* 0.1.0 2023-12-25 Flagchip0038 N/A First version for FC7240 +********************************************************************************/ + +#include "fc7xxx_driver_overlay.h" + +typedef void (*Void_Type)(void); +typedef void (*U32_Type)(uint32_t u32Data); +typedef void (*SizeEnum_Type)(OVERLAY_OverlaySizeType eSize); + +static Void_Type const s_aRegionEnDisable[OVERLYA_REGION_CNT] = +{ + OVERLAY_HWA_OverlayRegion0Disable, + OVERLAY_HWA_OverlayRegion1Disable, + OVERLAY_HWA_OverlayRegion2Disable +}; + + +static Void_Type const s_aRegionEnEnable[OVERLYA_REGION_CNT] = +{ + OVERLAY_HWA_OverlayRegion0Enable, + OVERLAY_HWA_OverlayRegion1Enable, + OVERLAY_HWA_OverlayRegion2Enable +}; + +static U32_Type const s_aRegionSrc[OVERLYA_REGION_CNT] = +{ + OVERLAY_HWA_SetOverlayRegion0Src, + OVERLAY_HWA_SetOverlayRegion1Src, + OVERLAY_HWA_SetOverlayRegion2Src +}; + +static U32_Type const s_aRegionDst[OVERLYA_REGION_CNT] = +{ + OVERLAY_HWA_SetOverlayRegion0Dst, + OVERLAY_HWA_SetOverlayRegion1Dst, + OVERLAY_HWA_SetOverlayRegion2Dst +}; + +static SizeEnum_Type const s_aRegionSize[OVERLYA_REGION_CNT] = +{ + OVERLAY_HWA_SetOverlayRegion0Size, + OVERLAY_HWA_SetOverlayRegion1Size, + OVERLAY_HWA_SetOverlayRegion2Size +}; + +static OVERLAY_ErrorCallback_Type s_tErrorCallbackFunc; + +/** + * @brief Overlay region initial function + * + * @param pOverlayInitCfg initial parameters + * @return ERROR_OK is ok, others are not ok + */ +OVERLAY_ErrorType OVERLAY_RegionInit(OVERLAY_OverlayRegionInitType *pOverlayInitCfg) +{ + OVERLAY_ErrorType eRetval; + uint32_t u32Index; + uint32_t u32ErrorInfo; + + eRetval = OVERLAY_ERROR_OK; + + /* global overlay Disable */ + OVERLAY_HWA_OverlayDisable(); + + /* loop all region */ + for (u32Index = 0U; (u32Index < OVERLYA_REGION_CNT) && (eRetval == OVERLAY_ERROR_OK); u32Index++) + { + /* check overlay region enable */ + if (pOverlayInitCfg->aOverlayRegionEn[u32Index]) + { + if ((pOverlayInitCfg->aOverlayRegionSrc[u32Index] >= PFLASH_START) && + (pOverlayInitCfg->aOverlayRegionSrc[u32Index] <= PFLASH_END) && + (pOverlayInitCfg->aOverlayRegionDst[u32Index] >= SRAM_START) && + (pOverlayInitCfg->aOverlayRegionDst[u32Index] <= SRAM_END) + ) + { + + /* disable region n */ + s_aRegionEnDisable[u32Index](); + + /* source */ + s_aRegionSrc[u32Index](pOverlayInitCfg->aOverlayRegionSrc[u32Index]); + + /* dest */ + s_aRegionDst[u32Index](pOverlayInitCfg->aOverlayRegionDst[u32Index]); + + /* size */ + s_aRegionSize[u32Index](pOverlayInitCfg->aOverlayRegionSize[u32Index]); + + /* enable region n */ + s_aRegionEnEnable[u32Index](); + } + else + { + eRetval = OVERLAY_ERROR_ADDR; + } + } + else + { + /* disable region n */ + s_aRegionEnDisable[u32Index](); + } + + } + + if (eRetval == OVERLAY_ERROR_OK) + { + /* global overlay enable */ + OVERLAY_HWA_OverlayEnable(); + } + + /* check error flag */ + u32ErrorInfo = OVERLAY_HWA_GetErrorFlag(); + if (u32ErrorInfo) + { + eRetval = OVERLAY_ERROR_FLAG; + } + + return eRetval; +} + +/** + * @brief De-Init Overlay Region + * + * @return ERROR_OK is ok, others are not ok + */ +OVERLAY_ErrorType OVERLAY_RegionDeInit(void) +{ + OVERLAY_ErrorType eRetval; + uint32_t u32Index; + + eRetval = OVERLAY_ERROR_OK; + + /* disable global overlay */ + OVERLAY_HWA_OverlayDisable(); + + for (u32Index = 0U; u32Index < OVERLYA_REGION_CNT; u32Index++) + { + /* disable region n */ + s_aRegionEnDisable[u32Index](); + + /* source */ + s_aRegionSrc[u32Index](0U); + + /* dest */ + s_aRegionDst[u32Index](0U); + + /* size */ + s_aRegionSize[u32Index](OVERLAY_OVERLAYSIZE_1KB); + } + + return eRetval; +} + + +/** + * @brief Far initial function + * + * @param pFarInitCfg initial parameters + * @return ERROR_OK is ok, others are not ok + */ +OVERLAY_ErrorType OVERLAY_FARInit(OVERLAY_FARInitType *pFarInitCfg) +{ + OVERLAY_ErrorType eRetval; + uint32_t u32ErrorInfo; + + eRetval = OVERLAY_ERROR_OK; + + if (pFarInitCfg->u32FAREn == 0U) + { + + /* disable far */ + OVERLAY_HWA_FARDisable(); + } + else + { + /* must align to 64KB, */ + if ((pFarInitCfg->u32FARSize <= OVERLAY_FAR_SIZE_MAX) && + ((pFarInitCfg->u32FARSize & OVERLAY_FAR_SIZE_MASK) == 0U) + ) + { + if ((pFarInitCfg->u32FARDst >= PFLASH_START) && + (pFarInitCfg->u32FARDst <= PFLASH_END) + ) + { + /* disable far */ + OVERLAY_HWA_FARDisable(); + + /* set far dest */ + OVERLAY_HWA_SetFarDst(pFarInitCfg->u32FARDst); + /* set far size */ + OVERLAY_HWA_SetFarSize(pFarInitCfg->u32FARSize / OVERLAY_FAR_SIZE_ALIGN - 1); + /* disable enable */ + OVERLAY_HWA_FAREnable(); + } + else + { + eRetval = OVERLAY_ERROR_ADDR; + } + } + else + { + eRetval = OVERLAY_ERROR_SIZE; + } + } + + if (eRetval == OVERLAY_ERROR_OK) + { + /* enable far */ + OVERLAY_HWA_FAREnable(); + } + + + /* check error flag */ + u32ErrorInfo = OVERLAY_HWA_GetErrorFlag(); + if (u32ErrorInfo) + { + eRetval = OVERLAY_ERROR_FLAG; + } + + + return eRetval; +} + +/** + * @brief De-Init FAR Region + * + * @return ERROR_OK is ok, others are not ok + */ +OVERLAY_ErrorType OVERLAY_FARDeInit(void) +{ + OVERLAY_ErrorType eRetval; + + eRetval = OVERLAY_ERROR_OK; + + /* disable global far */ + OVERLAY_HWA_FARDisable(); + + /* set far dest */ + OVERLAY_HWA_SetFarDst(0x01000000U); + /* set far size */ + OVERLAY_HWA_SetFarSize(0U); + + return eRetval; +} + +/** + * @brief Enable or Disable Interrupt + * + * @param pInterruptCfg interrupt config parameter + */ +void OVERLAY_SetInterrupt(OVERLAY_InterruptType *pInterruptCfg) +{ + if (pInterruptCfg->bEnableInterrupt) + { + OVERLAY_HWA_ErrorInterruptEnable(); + s_tErrorCallbackFunc = pInterruptCfg->pCallBack; + } + else + { + OVERLAY_HWA_ErrorInterruptDisable(); + s_tErrorCallbackFunc = NULL; + } + +} + +/** + * @brief Get Error Info + * + * @param pErrorInfo error info point + */ +void OVERLAY_GetErrorInfo(OVERLAY_ErrorInfoType *pErrorInfo) +{ + uint32_t u32ErrorInfo; + u32ErrorInfo = OVERLAY_HWA_GetErrorFlag(); + + if (u32ErrorInfo & AHB_OVERLAY_INTR_FLAG_FAR_SIZE_INTR_MASK) + { + pErrorInfo->bError_FAR_SIZE_INTR = 1U; + } + else + { + pErrorInfo->bError_FAR_SIZE_INTR = 0U; + } + + if (u32ErrorInfo & AHB_OVERLAY_INTR_FLAG_FAR_DST_OVERFLOW_INTR_MASK) + { + pErrorInfo->bError_FAR_DST_OVERFLOW_INTR = 1U; + } + else + { + pErrorInfo->bError_FAR_DST_OVERFLOW_INTR = 0U; + } + + if (u32ErrorInfo & AHB_OVERLAY_INTR_FLAG_FAR_DST_NO_FLASH_INTR_MASK) + { + pErrorInfo->bError_FAR_DST_NO_FLASH_INTR = 1U; + } + else + { + pErrorInfo->bError_FAR_DST_NO_FLASH_INTR = 0U; + } + + if (u32ErrorInfo & AHB_OVERLAY_INTR_FLAG_REGION2_D_CROS_INTR_MASK) + { + pErrorInfo->bError_REGION2_D_CROS_INTR = 1U; + } + else + { + pErrorInfo->bError_REGION2_D_CROS_INTR = 0U; + } + + if (u32ErrorInfo & AHB_OVERLAY_INTR_FLAG_REGION2_S_CROS_INTR_MASK) + { + pErrorInfo->bError_REGION2_S_CROS_INTR = 1U; + } + else + { + pErrorInfo->bError_REGION2_S_CROS_INTR = 0U; + } + + if (u32ErrorInfo & AHB_OVERLAY_INTR_FLAG_REGION2_SIZE_INTR_MASK) + { + pErrorInfo->bError_REGION2_SIZE_INTR = 1U; + } + else + { + pErrorInfo->bError_REGION2_SIZE_INTR = 0U; + } + + if (u32ErrorInfo & AHB_OVERLAY_INTR_FLAG_REGION2_DST_INTR_MASK) + { + pErrorInfo->bError_REGION2_DST_INTR = 1U; + } + else + { + pErrorInfo->bError_REGION2_DST_INTR = 0U; + } + + if (u32ErrorInfo & AHB_OVERLAY_INTR_FLAG_REGION2_SRC_INTR_MASK) + { + pErrorInfo->bError_REGION2_SRC_INTR = 1U; + } + else + { + pErrorInfo->bError_REGION2_SRC_INTR = 0U; + } + + if (u32ErrorInfo & AHB_OVERLAY_INTR_FLAG_REGION1_D_CROS_INTR_MASK) + { + pErrorInfo->bError_REGION1_D_CROS_INTR = 1U; + } + else + { + pErrorInfo->bError_REGION1_D_CROS_INTR = 0U; + } + + if (u32ErrorInfo & AHB_OVERLAY_INTR_FLAG_REGION1_S_CROS_INTR_MASK) + { + pErrorInfo->bError_REGION1_S_CROS_INTR = 1U; + } + else + { + pErrorInfo->bError_REGION1_S_CROS_INTR = 0U; + } + + if (u32ErrorInfo & AHB_OVERLAY_INTR_FLAG_REGION1_SIZE_INTR_MASK) + { + pErrorInfo->bError_REGION1_SIZE_INTR = 1U; + } + else + { + pErrorInfo->bError_REGION1_SIZE_INTR = 0U; + } + + if (u32ErrorInfo & AHB_OVERLAY_INTR_FLAG_REGION1_DST_INTR_MASK) + { + pErrorInfo->bError_REGION1_DST_INTR = 1U; + } + else + { + pErrorInfo->bError_REGION1_DST_INTR = 0U; + } + + if (u32ErrorInfo & AHB_OVERLAY_INTR_FLAG_REGION1_SRC_INTR_MASK) + { + pErrorInfo->bError_REGION1_SRC_INTR = 1U; + } + else + { + pErrorInfo->bError_REGION1_SRC_INTR = 0U; + } + + if (u32ErrorInfo & AHB_OVERLAY_INTR_FLAG_REGION0_D_CROS_INTR_MASK) + { + pErrorInfo->bError_REGION0_D_CROS_INTR = 1U; + } + else + { + pErrorInfo->bError_REGION0_D_CROS_INTR = 0U; + } + + if (u32ErrorInfo & AHB_OVERLAY_INTR_FLAG_REGION0_S_CROS_INTR_MASK) + { + pErrorInfo->bError_REGION0_S_CROS_INTR = 1U; + } + else + { + pErrorInfo->bError_REGION0_S_CROS_INTR = 0U; + } + + if (u32ErrorInfo & AHB_OVERLAY_INTR_FLAG_REGION0_SIZE_INTR_MASK) + { + pErrorInfo->bError_REGION0_SIZE_INTR = 1U; + } + else + { + pErrorInfo->bError_REGION0_SIZE_INTR = 0U; + } + + if (u32ErrorInfo & AHB_OVERLAY_INTR_FLAG_REGION0_DST_INTR_MASK) + { + pErrorInfo->bError_REGION0_DST_INTR = 1U; + } + else + { + pErrorInfo->bError_REGION0_DST_INTR = 0U; + } + + if (u32ErrorInfo & AHB_OVERLAY_INTR_FLAG_REGION0_SRC_INTR_MASK) + { + pErrorInfo->bError_REGION0_SRC_INTR = 1U; + } + else + { + pErrorInfo->bError_REGION0_SRC_INTR = 0U; + } +} + +/** + * @brief Clear Error Info + * + * @param pErrorInfo error info point + */ +void OVERLAY_ClrErrorInfo(OVERLAY_ErrorInfoType *pErrorInfo) +{ + uint32_t u32ErrorInfo; + + u32ErrorInfo = AHB_OVERLAY_INTR_FLAG_FAR_SIZE_INTR(pErrorInfo->bError_FAR_SIZE_INTR); + u32ErrorInfo |= AHB_OVERLAY_INTR_FLAG_FAR_DST_OVERFLOW_INTR(pErrorInfo->bError_FAR_DST_OVERFLOW_INTR); + u32ErrorInfo |= AHB_OVERLAY_INTR_FLAG_FAR_DST_NO_FLASH_INTR(pErrorInfo->bError_FAR_DST_NO_FLASH_INTR); + u32ErrorInfo |= AHB_OVERLAY_INTR_FLAG_REGION2_D_CROS_INTR(pErrorInfo->bError_REGION2_D_CROS_INTR); + u32ErrorInfo |= AHB_OVERLAY_INTR_FLAG_REGION2_S_CROS_INTR(pErrorInfo->bError_REGION2_S_CROS_INTR); + u32ErrorInfo |= AHB_OVERLAY_INTR_FLAG_REGION2_SIZE_INTR(pErrorInfo->bError_REGION2_SIZE_INTR); + u32ErrorInfo |= AHB_OVERLAY_INTR_FLAG_REGION2_DST_INTR(pErrorInfo->bError_REGION2_DST_INTR); + u32ErrorInfo |= AHB_OVERLAY_INTR_FLAG_REGION2_SRC_INTR(pErrorInfo->bError_REGION2_SRC_INTR); + u32ErrorInfo |= AHB_OVERLAY_INTR_FLAG_REGION1_D_CROS_INTR(pErrorInfo->bError_REGION1_D_CROS_INTR); + u32ErrorInfo |= AHB_OVERLAY_INTR_FLAG_REGION1_S_CROS_INTR(pErrorInfo->bError_REGION1_S_CROS_INTR); + u32ErrorInfo |= AHB_OVERLAY_INTR_FLAG_REGION1_SIZE_INTR(pErrorInfo->bError_REGION1_SIZE_INTR); + u32ErrorInfo |= AHB_OVERLAY_INTR_FLAG_REGION1_DST_INTR(pErrorInfo->bError_REGION1_DST_INTR); + u32ErrorInfo |= AHB_OVERLAY_INTR_FLAG_REGION1_SRC_INTR(pErrorInfo->bError_REGION1_SRC_INTR); + u32ErrorInfo |= AHB_OVERLAY_INTR_FLAG_REGION0_D_CROS_INTR(pErrorInfo->bError_REGION0_D_CROS_INTR); + u32ErrorInfo |= AHB_OVERLAY_INTR_FLAG_REGION0_S_CROS_INTR(pErrorInfo->bError_REGION0_S_CROS_INTR); + u32ErrorInfo |= AHB_OVERLAY_INTR_FLAG_REGION0_SIZE_INTR(pErrorInfo->bError_REGION0_SIZE_INTR); + u32ErrorInfo |= AHB_OVERLAY_INTR_FLAG_REGION0_DST_INTR(pErrorInfo->bError_REGION0_DST_INTR); + u32ErrorInfo |= AHB_OVERLAY_INTR_FLAG_REGION0_SRC_INTR(pErrorInfo->bError_REGION0_SRC_INTR); + + OVERLAY_HWA_ClrErrorFlag(u32ErrorInfo); +} +/** + * @brief Call Me in Overlay Error interrupt handler + * + */ +void OVERLAY_ErrorInterruptRoutine(void) +{ + OVERLAY_ErrorInfoType tErrorInfo; + if (s_tErrorCallbackFunc != NULL) + { + OVERLAY_GetErrorInfo(&tErrorInfo); + s_tErrorCallbackFunc(tErrorInfo); + } +} diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_pcc.c b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_pcc.c new file mode 100644 index 0000000..61c9638 --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_pcc.c @@ -0,0 +1,421 @@ +/** + * @file fc7xxx_driver_pcc.c + * @author Flagchip + * @brief FC7xxx PCC driver type definition and API + * @version 0.1.0 + * @date 2024-01-12 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + */ + +/******************************************************************************** +* Revision History: +* +* Version Date Initials CR# Descriptions +* --------- ---------- ------------ ---------- --------------- +* 0.1.0 2024-01-12 Flagchip085 N/A First version for FC7240 +********************************************************************************/ + +#include "fc7xxx_driver_pcc.h" +#include "fc7xxx_driver_scg.h" +#include "fc7xxx_board_conf.h" + +/***************** mcaro *********************/ +/* PCC property MACRO, defines every peripheral clock system architecture */ +#define PCC_CLK_NOT_APPLY (0U) +#define PCC_CGC_AVAILABLE (1U << 0U) +#define PCC_FUNCCLK_MUXDIVH_USED (1U << 1U) +#define PCC_FUNCCLK_MUXDIVM_USED (1U << 2U) +#define PCC_FUNCCLK_MUXDIVL_USED (1U << 3U) +#define PCC_FUNCCLK_MUXDIVHPIN_USED (1U << 4U) +#define PCC_MOUDULE_DIV_USED (1U << 5U) +#define PCC_CLK_DOMAIN_CORE (1U << 6U) +#define PCC_CLK_DOMAIN_BUS (1U << 7U) +#define PCC_CLK_DOMAIN_SLOW (1U << 8U) +#define PCC_DWP_SWR_AVAILABLE (0U << 9U) + +#define PCC_PROPERTY_MUXDIV_MASK (PCC_FUNCCLK_MUXDIVH_USED | PCC_FUNCCLK_MUXDIVM_USED | PCC_FUNCCLK_MUXDIVL_USED) +#define PCC_PROPERTY_MUXDIV_ALL_MASK (PCC_FUNCCLK_MUXDIVH_USED | PCC_FUNCCLK_MUXDIVM_USED | PCC_FUNCCLK_MUXDIVL_USED | PCC_FUNCCLK_MUXDIVHPIN_USED) + +/***************** Type define *********************/ +/** + * @brief PCC clock attribution. + * @param u32RegOffset: the register offset base on PCC module base address 0x4002_4000h + * @param u8ClockProperty include clock domain and clock MUX information by bit filed setting. + */ +typedef struct +{ + uint32_t u32RegOffset; + uint32_t u32ClockProperty; +} PCC_ClockMapType; + +/** + * @brief PCC peripheral clock index map to SCG clock source + * @param ePccClkIndex: PCC peripheral clock index + * @param eScgClkIndex SCG clock source + */ +typedef struct +{ + PCC_ClkGateSrcType ePccClkIndex; + SCG_ClkSrcType eScgClkIndex; +} PCC_ClockIndexMap; + +/***************** Local Variables *********************/ +/** + * @brief PCC clock index to SCG clock source map. +*/ +static const PCC_ClockIndexMap s_tPccClocIndexkMap[PCC_MUX_MAX_NUMBER] = { + {PCC_CLKGATE_SRC_OFF_OR_TCLK, SCG_END_OF_CLOCKS}, + {PCC_CLKGATE_SRC_FOSCDIV, SCG_FOSCDIVH_CLK}, + {PCC_CLKGATE_SRC_SIRCDIV, SCG_SIRCDIVH_CLK}, + {PCC_CLKGATE_SRC_FIRCDIV, SCG_FIRCDIVH_CLK}, + {PCC_CLKGATE_SRC_RESERVE0, SCG_END_OF_CLOCKS}, + {PCC_CLKGATE_SRC_PLL1DIV, SCG_PLL1DIVH_CLK}, + {PCC_CLKGATE_SRC_PLL0DIV, SCG_PLL0DIVH_CLK}, + {PCC_CLKGATE_SRC_RESERVE1, SCG_END_OF_CLOCKS} +}; + +/** + * @brief clock attribution map. + */ +static const PCC_ClockMapType s_tPccClockMap[PCC_END_OF_CLOCKS] = +{ + {0x20, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_DWP_SWR_AVAILABLE}, /* DMA0 */ + {0x28, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_DWP_SWR_AVAILABLE}, /* DMAMUX0 */ + {0x4C, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_DWP_SWR_AVAILABLE}, /* ROMC */ + {0x60, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_DWP_SWR_AVAILABLE}, /* ERM0 */ + {0x64, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_SLOW | PCC_DWP_SWR_AVAILABLE}, /* EIM0 */ + {0x68, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_SLOW | PCC_DWP_SWR_AVAILABLE}, /* INTM0 */ + {0x6C, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_DWP_SWR_AVAILABLE}, /* ISM0 */ + {0x88, PCC_CLK_DOMAIN_SLOW | PCC_DWP_SWR_AVAILABLE}, /* WDOG0 */ + {0x98, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_SLOW | PCC_DWP_SWR_AVAILABLE}, /* TRGSEL0 */ + {0x9C, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_SLOW | PCC_DWP_SWR_AVAILABLE}, /* TRGSEL1 */ + {0xA0, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_SLOW | PCC_DWP_SWR_AVAILABLE}, /* TRGSEL2 */ + {0xA4, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_SLOW | PCC_DWP_SWR_AVAILABLE}, /* TRGSEL3 */ + {0xA8, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_DWP_SWR_AVAILABLE}, /* CRC0 */ + {0xAC, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_DWP_SWR_AVAILABLE}, /* CORDIC */ + {0xB0, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_DWP_SWR_AVAILABLE}, /* TSTMP0 */ + {0xB4, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_DWP_SWR_AVAILABLE}, /* TSTMP1 */ + {0xB8, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVH_USED | PCC_DWP_SWR_AVAILABLE}, /* FCPIT0 */ + {0xBC, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_SLOW | PCC_FUNCCLK_MUXDIVL_USED | PCC_MOUDULE_DIV_USED | PCC_DWP_SWR_AVAILABLE}, /* AONTIMER0 */ + {0xC0, PCC_CLK_DOMAIN_SLOW | PCC_DWP_SWR_AVAILABLE}, /* RTC */ + {0xC4, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_SLOW | PCC_DWP_SWR_AVAILABLE}, /* CMU0 */ + {0xC8, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_SLOW | PCC_DWP_SWR_AVAILABLE}, /* CMU1 */ + {0xCC, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_SLOW | PCC_DWP_SWR_AVAILABLE}, /* CMU2 */ + {0xD0, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_SLOW | PCC_DWP_SWR_AVAILABLE}, /* CMU3 */ + {0xD4, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_SLOW | PCC_DWP_SWR_AVAILABLE}, /* CMU4 */ + {0xDC, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_DWP_SWR_AVAILABLE}, /* PTIMER0 */ + {0xE0, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_DWP_SWR_AVAILABLE}, /* PTIMER1 */ + {0xEC, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVH_USED | PCC_MOUDULE_DIV_USED | PCC_DWP_SWR_AVAILABLE}, /* ADC0 */ + {0xF0, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVH_USED | PCC_MOUDULE_DIV_USED | PCC_DWP_SWR_AVAILABLE}, /* ADC1 */ + {0xFC, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_SLOW | PCC_DWP_SWR_AVAILABLE}, /* WKU0 */ + {0x100, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_SLOW | PCC_DWP_SWR_AVAILABLE}, /* CMP0 */ + {0x104, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_SLOW | PCC_DWP_SWR_AVAILABLE}, /* CMP1 */ + {0x10C, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_SLOW | PCC_FUNCCLK_MUXDIVL_USED | PCC_DWP_SWR_AVAILABLE}, /* TMU0 */ + {0x150, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVL_USED | PCC_MOUDULE_DIV_USED | PCC_DWP_SWR_AVAILABLE}, /* SENT0 */ + {0x160, PCC_CLK_DOMAIN_BUS | PCC_DWP_SWR_AVAILABLE}, /* MB0 */ + {0x170, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVH_USED | PCC_FUNCCLK_MUXDIVHPIN_USED | PCC_DWP_SWR_AVAILABLE}, /* FTU0 */ + {0x174, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVH_USED | PCC_FUNCCLK_MUXDIVHPIN_USED | PCC_DWP_SWR_AVAILABLE}, /* FTU1 */ + {0x178, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVH_USED | PCC_FUNCCLK_MUXDIVHPIN_USED | PCC_DWP_SWR_AVAILABLE}, /* FTU2 */ + {0x17C, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVH_USED | PCC_FUNCCLK_MUXDIVHPIN_USED | PCC_DWP_SWR_AVAILABLE}, /* FTU3 */ + {0x188, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVM_USED | PCC_DWP_SWR_AVAILABLE}, /* FCSPI0 */ + {0x18C, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVM_USED | PCC_DWP_SWR_AVAILABLE}, /* FCSPI1 */ + {0x190, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVM_USED | PCC_DWP_SWR_AVAILABLE}, /* FCSPI2 */ + {0x198, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVM_USED | PCC_DWP_SWR_AVAILABLE}, /* FCIIC0 */ + {0x1A0, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVM_USED | PCC_DWP_SWR_AVAILABLE}, /* FCUART0 */ + {0x1A4, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVM_USED | PCC_DWP_SWR_AVAILABLE}, /* FCUART1 */ + {0x1A8, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVM_USED | PCC_DWP_SWR_AVAILABLE}, /* FCUART2 */ + {0x1AC, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVM_USED | PCC_DWP_SWR_AVAILABLE}, /* FCUART3 */ + {0x1C0, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_SLOW | PCC_DWP_SWR_AVAILABLE}, /* LU0 */ + {0x1E0, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_DWP_SWR_AVAILABLE}, /* FREQM */ + {0x1FC, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_SLOW | PCC_DWP_SWR_AVAILABLE}, /* STCU */ + {0x200, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVH_USED | PCC_MOUDULE_DIV_USED | PCC_DWP_SWR_AVAILABLE}, /* FLEXCAN0 */ + {0x210, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVH_USED | PCC_MOUDULE_DIV_USED | PCC_DWP_SWR_AVAILABLE}, /* FLEXCAN1 */ + {0x34C, PCC_CLK_DOMAIN_SLOW | PCC_DWP_SWR_AVAILABLE}, /* WDOG1 */ + {0x36C, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_SLOW | PCC_DWP_SWR_AVAILABLE}, /* TRGSEL4 */ + {0x370, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_SLOW | PCC_DWP_SWR_AVAILABLE}, /* TRGSEL5 */ + {0x37C, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVM_USED | PCC_DWP_SWR_AVAILABLE}, /* FCSPI3 */ + {0x380, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVM_USED | PCC_DWP_SWR_AVAILABLE}, /* FCSPI4 */ + {0x384, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVM_USED | PCC_DWP_SWR_AVAILABLE}, /* FCSPI5 */ + {0x3FC, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVH_USED | PCC_FUNCCLK_MUXDIVHPIN_USED | PCC_DWP_SWR_AVAILABLE}, /* FTU4 */ + {0x400, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVH_USED | PCC_FUNCCLK_MUXDIVHPIN_USED | PCC_DWP_SWR_AVAILABLE}, /* FTU5 */ + {0x404, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVH_USED | PCC_FUNCCLK_MUXDIVHPIN_USED | PCC_DWP_SWR_AVAILABLE}, /* FTU6 */ + {0x408, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVH_USED | PCC_FUNCCLK_MUXDIVHPIN_USED | PCC_DWP_SWR_AVAILABLE}, /* FTU7 */ + {0x41C, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVM_USED | PCC_DWP_SWR_AVAILABLE}, /* FCIIC1 */ + {0x420, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVM_USED | PCC_DWP_SWR_AVAILABLE}, /* FCUART4 */ + {0x424, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVM_USED | PCC_DWP_SWR_AVAILABLE}, /* FCUART5 */ + {0x428, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVM_USED | PCC_DWP_SWR_AVAILABLE}, /* FCUART6 */ + {0x42C, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVM_USED | PCC_DWP_SWR_AVAILABLE}, /* FCUART7 */ + {0x450, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVM_USED | PCC_MOUDULE_DIV_USED | PCC_DWP_SWR_AVAILABLE}, /* MSC0 */ + {0x480, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVH_USED | PCC_MOUDULE_DIV_USED | PCC_DWP_SWR_AVAILABLE}, /* FLEXCAN2 */ + {0x490, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVH_USED | PCC_MOUDULE_DIV_USED | PCC_DWP_SWR_AVAILABLE}, /* FLEXCAN3 */ +}; + +/***************** Local Prototype Functions *********************/ + +/***************** Local Functions *********************/ + +/***************** Global Functions *********************/ + +/** + * @brief get PCC function clock status and value. + * + * @param pcc_ClkSrcType eClockName: used for choose PCC clock source to query. + */ +uint32_t PCC_GetPccFunctionClock(const PCC_ClkSrcType eClockName) +{ + uint32_t u32DivVal; + PCC_ClkGateSrcType eSelVal; + uint32_t u32ScgClkIndex = 0U; + uint32_t u32FunctionFreqVal = 0U; + uint32_t u32RegVal, u32ScgClkDivIndex; + const PCC_ClockMapType *pAttributeVal; + + DEV_ASSERT((uint32_t)eClockName < (uint32_t)PCC_END_OF_CLOCKS); + + /* Get peripheral PCC register value */ + u32RegVal = PCC_HWA_GetRegister(s_tPccClockMap[(uint32_t)eClockName].u32RegOffset); + pAttributeVal = &s_tPccClockMap[(uint32_t)eClockName]; + + /* Check peripheral PCC is valid or not and peripheral have function clock or not */ + if ((PCC_CGC_MASK == (u32RegVal & PCC_CGC_MASK)) && (0U != (pAttributeVal->u32ClockProperty & PCC_PROPERTY_MUXDIV_ALL_MASK))) + { + eSelVal = (PCC_ClkGateSrcType)((uint8_t)PCC_GetSEL(u32RegVal)); + /* Get PCC divide value */ + if (PCC_MOUDULE_DIV_USED == (pAttributeVal->u32ClockProperty & PCC_MOUDULE_DIV_USED)) + { + u32DivVal = PCC_GetDIV(u32RegVal) + (uint32_t)1U; + } + else + { + u32DivVal = 1U; + } + + /* Get peripheral function clock source which is from SCG or TCLK */ + if (PCC_CLKGATE_SRC_OFF_OR_TCLK == eSelVal) + { + if (PCC_FUNCCLK_MUXDIVHPIN_USED == (pAttributeVal->u32ClockProperty & PCC_FUNCCLK_MUXDIVHPIN_USED)) + { + u32FunctionFreqVal = PCC_FTU_TCLK_FREQ; + } + else + { + u32FunctionFreqVal = 0U; + } + } + else + { + if (PCC_FUNCCLK_MUXDIVH_USED == (pAttributeVal->u32ClockProperty & PCC_FUNCCLK_MUXDIVH_USED)) + { + u32ScgClkDivIndex = 0U; + } + else if (PCC_FUNCCLK_MUXDIVM_USED == (pAttributeVal->u32ClockProperty & PCC_FUNCCLK_MUXDIVM_USED)) + { + u32ScgClkDivIndex = 1U; + } + else if (PCC_FUNCCLK_MUXDIVL_USED == (pAttributeVal->u32ClockProperty & PCC_FUNCCLK_MUXDIVL_USED)) + { + u32ScgClkDivIndex = 2U; + } + else + { + u32ScgClkDivIndex = 0U; + } + u32ScgClkIndex = (uint32_t)s_tPccClocIndexkMap[eSelVal].eScgClkIndex + u32ScgClkDivIndex; + } + + /* If clock source is valid, calculate peripheral function clock */ + if (u32ScgClkIndex < (uint32_t)SCG_END_OF_CLOCKS) + { + u32FunctionFreqVal = SCG_GetScgClockFreq((SCG_ClkSrcType)u32ScgClkIndex) / u32DivVal; + } + } + + return u32FunctionFreqVal; +} + +/** + * @brief get PCC interface clock status and value. + * + * @param pcc_ClkSrcType eClockName: used for choose PCC clock source to query. + */ +uint32_t PCC_GetPccInterfaceClock(const PCC_ClkSrcType eClockName) +{ + uint32_t u32InterfaceFreqVal, u32AttributeVal; + + DEV_ASSERT((uint32_t)eClockName < (uint32_t)PCC_END_OF_CLOCKS); + + u32AttributeVal = s_tPccClockMap[(uint32_t)eClockName].u32ClockProperty; + if (PCC_CLK_DOMAIN_BUS == (u32AttributeVal & PCC_CLK_DOMAIN_BUS)) + { + u32InterfaceFreqVal = SCG_GetScgClockFreq(SCG_BUS_CLK); + } + else if (PCC_CLK_DOMAIN_SLOW == (u32AttributeVal & PCC_CLK_DOMAIN_SLOW)) + { + u32InterfaceFreqVal = SCG_GetScgClockFreq(SCG_SLOW_CLK); + } + else + { + u32InterfaceFreqVal = 0U; + } + + return u32InterfaceFreqVal; +} + + +/** + * @brief set PCC one peripheral clock configuration. + * + * @param PCC_CtrlType* pConfig: the PCC initialize value point set by user. + * @return PCC_StatusType pcc function status + */ +PCC_StatusType PCC_SetPcc(const PCC_CtrlType *const pConfig) +{ + PCC_StatusType eStatus = PCC_STATUS_SUCCESS; + uint32_t u32DivVal; + uint32_t u32ScgClkIndex = 0U, u32ScgClkDivIndex; + uint32_t u32FreqVal = 0U; + uint32_t u32FunctionFreqVal = 0U; + uint32_t u32RegVal = 0U; + uint32_t u32ExpectedRegVal; + const PCC_ClockMapType *pAttributeVal; + + DEV_ASSERT(NULL_PTR != pConfig); + DEV_ASSERT((uint32_t)pConfig->eClockName < (uint32_t)PCC_END_OF_CLOCKS); + + pAttributeVal = &s_tPccClockMap[(uint32_t)pConfig->eClockName]; + /* check peripheral clock domain to calculate module clock */ + if (PCC_CLK_DOMAIN_BUS == (pAttributeVal->u32ClockProperty & PCC_CLK_DOMAIN_BUS)) + { + u32FreqVal = SCG_GetScgClockFreq(SCG_BUS_CLK); + } + else if (PCC_CLK_DOMAIN_SLOW == (pAttributeVal->u32ClockProperty & PCC_CLK_DOMAIN_SLOW)) + { + u32FreqVal = SCG_GetScgClockFreq(SCG_SLOW_CLK); + } + else + { + /* Do nothing */ + } + + if (0U == u32FreqVal) + { + /* Please call SCG function first */ + eStatus = PCC_STATUS_CLOCK_INVALID; + } + + if (PCC_STATUS_SUCCESS == eStatus) + { + /* Disable PCC gate */ + PCC_HWA_SetClockGateControl(pAttributeVal->u32RegOffset,false); + if (pConfig->bEn) + { + if (PCC_MOUDULE_DIV_USED == (pAttributeVal->u32ClockProperty & PCC_MOUDULE_DIV_USED)) + { + u32DivVal = (uint32_t)pConfig->eDivider + (uint32_t)1U; + u32RegVal |= PCC_DIV(pConfig->eDivider); + } + else + { + u32DivVal = 1U; + } + + if (0U != (pAttributeVal->u32ClockProperty & PCC_PROPERTY_MUXDIV_ALL_MASK)) + { + u32RegVal |= PCC_SEL(pConfig->eClkSrc); + } + + if (PCC_CGC_AVAILABLE == (pAttributeVal->u32ClockProperty & PCC_CGC_AVAILABLE)) + { + /* Enable peripheral clock */ + u32RegVal |= PCC_CGC_MASK; + } + + /* Configure PCC register */ + PCC_HWA_SetRegister(pAttributeVal->u32RegOffset,u32RegVal); + + /* Get peripheral function clock source which is from SCG or TCLK */ + if (PCC_CLKGATE_SRC_OFF_OR_TCLK == pConfig->eClkSrc) + { + if (PCC_FUNCCLK_MUXDIVHPIN_USED == (pAttributeVal->u32ClockProperty & PCC_FUNCCLK_MUXDIVHPIN_USED)) + { + u32FunctionFreqVal = PCC_FTU_TCLK_FREQ; + } + else + { + u32FunctionFreqVal = 0U; + } + } + else if (PCC_CLKGATE_UNINVOLVED == pConfig->eClkSrc) + { + /* do nothing */ + } + else + { + if (PCC_FUNCCLK_MUXDIVH_USED == (pAttributeVal->u32ClockProperty & PCC_FUNCCLK_MUXDIVH_USED)) + { + u32ScgClkDivIndex = 0U; + } + else if (PCC_FUNCCLK_MUXDIVM_USED == (pAttributeVal->u32ClockProperty & PCC_FUNCCLK_MUXDIVM_USED)) + { + u32ScgClkDivIndex = 1U; + } + else if (PCC_FUNCCLK_MUXDIVL_USED == (pAttributeVal->u32ClockProperty & PCC_FUNCCLK_MUXDIVL_USED)) + { + u32ScgClkDivIndex = 2U; + } + else + { + u32ScgClkDivIndex = 0U; + } + u32ScgClkIndex = (uint32_t)s_tPccClocIndexkMap[(uint32_t)pConfig->eClkSrc].eScgClkIndex + u32ScgClkDivIndex; + } + + /* Calculate peripheral function clock */ + if (u32ScgClkIndex < (uint32_t)SCG_END_OF_CLOCKS) + { + u32FunctionFreqVal = SCG_GetScgClockFreq((SCG_ClkSrcType)u32ScgClkIndex) / u32DivVal; + } + u32ExpectedRegVal = u32RegVal; + } + else + { + /* Clear PCC register */ + PCC_HWA_SetRegister(pAttributeVal->u32RegOffset,0U); + u32ExpectedRegVal = 0U; + u32FunctionFreqVal = 0U; + } + + /* Check PCC register has been configured, If current CPU do not have permission to configure the PCC register, the except value + * will not match the actual value */ + if (u32ExpectedRegVal != PCC_HWA_GetRegister(pAttributeVal->u32RegOffset)) + { + /* In this case, current core does not have permission to control the register */ + eStatus = PCC_STATUS_CONFIGURED_NOT_SUPPORT; + } + else if (u32FunctionFreqVal > 160000000U) + { + /* In this case, current function clock too high, must configured below 150M */ + eStatus = PCC_STATUS_CONFIGURED_NOT_SUPPORT; + } + else + { + /* do nothing */ + } + } + + return eStatus; +} + +/** + * @brief Generate peripheral reset + * + */ +void PCC_GenPeripheralReset(const PCC_ClkSrcType eClockName) +{ + DEV_ASSERT((uint32_t)eClockName < (uint32_t)PCC_END_OF_CLOCKS); + PCC_HWA_SoftwareReset(s_tPccClockMap[(uint32_t)eClockName].u32RegOffset); +} + + diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_pmc.c b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_pmc.c new file mode 100644 index 0000000..1d8a4cd --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_pmc.c @@ -0,0 +1,175 @@ +/* @file fc7xxx_driver_pmc.c +* @author Flagchip032 +* @brief FC7xxx PMC driver type definition and API +* @version 0.1.0 +* @date 2022-11-21 +* +* @copyright Copyright (c) 2022 Flagchip Semiconductors Co., Ltd. +* +*/ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials Descriptions + * --------- ---------- ------------ --------------- + * 0.1.0 2022-11-21 Flagchip032 First version for FC7xxx + ******************************************************************************** */ +#include "fc7xxx_driver_pmc.h" + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/***************** Local variable *********************/ +static PMC_VolIntCallbackType pIsrNotify = NULL_PTR; + + +/***************** prototype *********************/ +/** + * @brief PMC interrupt function entry + * + */ +void PMC_IRQHandler(void); + +/***************** Global Functions *********************/ +/** + * @brief Get LVCSRRegister Value + * + * @return uint32_t LVCSRRegister Value + */ +uint32_t PMC_GetLVCSRRegister(void) +{ + return PMC_HWA_GetLVCSRRegister(); +} + +/** + * @brief Get All voltage flag + * + * @return uint32_t All voltage flag + */ +uint32_t PMC_GetAllVolFlag(void) +{ + uint32_t u32AllVolFlag = 0U; + u32AllVolFlag = (PMC_HWA_GetLVCSRRegister() & PMC_LVCSR_ALLFLAG_MASK); + return u32AllVolFlag; +} + +/** + * @brief Get specific voltage flag + * + * @param eFlag Voltage flag + * @return boolean If return true, the specific voltage flag is 0, otherwise, the flag is 1. + */ +boolean PMC_GetSpecificVolFlag(const PMC_FlagType eFlag) +{ + return ((PMC_HWA_GetLVCSRRegister() & eFlag) != 0U) ? true : false; +} + +/** + * @brief Clear all voltage flag + * + */ +void PMC_ClearAllVolFlag(void) +{ + PMC_HWA_SetLVCSRRegister(PMC_LVCSR_ALLFLAG_MASK); +} + +/** + * @brief Clear specific voltage flag + * + * @param eFlag Voltage flag + */ +void PMC_ClearSpecificVolFlag(const PMC_FlagType eFlag) +{ + PMC_HWA_SetLVCSRRegister(eFlag); +} + +/** + * @brief Get All voltage status + * + * @return uint32_t All voltage status + */ +uint32_t PMC_GetAllVolStatus(void) +{ + uint32_t u32AllVolStatus = 0U; + u32AllVolStatus = (PMC_HWA_GetLVCSRRegister() & PMC_LVCSR_ALLSTATUS_MASK); + return u32AllVolStatus; +} + +/** + * @brief Get specific voltage status + * + * @param eStatus Specific voltage status + * @return boolean If return true, the specific voltage status is 0, otherwise, the status is 1. + */ +boolean PMC_GetSpecificVolStatus(const PMC_StatusType eStatus) +{ + return ((PMC_HWA_GetLVCSRRegister() & eStatus) != 0U) ? true : false; +} + +/** + * @brief Configure Voltage + * + * @param pCtrl Configuration of voltage + */ +void PMC_ConfigVoltage(const PMC_CtrlType *const pCtrl) +{ + uint32_t u32ConfigVal = 0U; + PMC_HWA_UnlockConfigRegister(); + + if ((pCtrl->bLvdIntEn) || (pCtrl->bHvdIntEn) || (pCtrl->b5VBMonEn) \ + || (pCtrl->bRpmV25En) || (pCtrl->bV15AutoswEn) || (pCtrl->bV15CtrlEn)) + { + pIsrNotify = pCtrl->pIsrNotify; + } + + u32ConfigVal = PMC_CONFIG_LVD_IE(pCtrl->bLvdIntEn) | PMC_CONFIG_HVD_IE(pCtrl->bHvdIntEn) | PMC_CONFIG_V15_CTRL_EN(pCtrl->bV15CtrlEn) | PMC_CONFIG_V15_AUTOSW( + pCtrl->bV15AutoswEn) | PMC_CONFIG_RPM_VDD2P5_EN(pCtrl->bRpmV25En); + PMC_HWA_SetConfigRegister(u32ConfigVal); +} + +/** + * @brief Clear all PMC register + * + */ +void PMC_Deinit(void) +{ + PMC_HWA_SetLVCSRRegister(0x93ff0030U); + PMC_HWA_SetConfigRegister(0x8000U); +} + +/** + * @brief PMC interrupt function entry + * + */ +void PMC_IRQHandler(void) +{ + if (NULL_PTR != pIsrNotify) + { + pIsrNotify(); + } + if(PMC_GetSpecificVolFlag(PMC_HVD5V_FLAG)) + { + PMC_ClearSpecificVolFlag(PMC_HVD5V_FLAG); + } + if (PMC_GetSpecificVolFlag(PMC_HVD2P5V_FLAG)) + { + PMC_ClearSpecificVolFlag(PMC_HVD2P5V_FLAG); + } + if (PMC_GetSpecificVolFlag(PMC_HVD1P1V_FLAG)) + { + PMC_ClearSpecificVolFlag(PMC_HVD1P1V_FLAG); + } + if (PMC_GetSpecificVolFlag(PMC_LVD5V_FLAG)) + { + PMC_ClearSpecificVolFlag(PMC_LVD5V_FLAG); + } + if (PMC_GetSpecificVolFlag(PMC_LVD1P5V_FLAG)) + { + PMC_ClearSpecificVolFlag(PMC_LVD1P5V_FLAG); + } + if (PMC_GetSpecificVolFlag(PMC_HVD1P5V_FLAG)) + { + PMC_ClearSpecificVolFlag(PMC_HVD1P5V_FLAG); + } +} diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_port.c b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_port.c new file mode 100644 index 0000000..d83178d --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_port.c @@ -0,0 +1,486 @@ +/** + * @file fc7xxx_driver_port.c + * @author Flagchip + * @brief FC7xxx PORT driver type definition and API + * @version 0.1.0 + * @date 2023-2-4 + * + * @copyright Copyright (c) 2023 Flagchip Semiconductors Co., Ltd. + * + * @details + */ +/******************************************************************************** +* Revision History: +* +* Version Date Initials CR# Descriptions +* --------- ---------- ------------ ---------- --------------- +* 0.1.0 31/12/2022 Flagchip0121 N/A First version for FC7240 +********************************************************************************/ +#include "fc7xxx_driver_port.h" +#include "interrupt_manager.h" + +/** @brief PORTA interrupt entry */ +void PORTA_IRQHandler(void); +/** @brief PORTB interrupt entry */ +void PORTB_IRQHandler(void); +/** @brief PORTC interrupt entry */ +void PORTC_IRQHandler(void); +/** @brief PORTD interrupt entry */ +void PORTD_IRQHandler(void); +/** @brief PORTE interrupt entry */ +void PORTE_IRQHandler(void); + + + +/********* Local Variables ************/ +/** @brief PORT instance list */ +static PORT_Type *const s_pPortInstanceTable[PORT_INSTANCE_COUNT] = PORT_BASE_PTRS; +/** @brief PORT user defined interrupt function */ +static PORT_PinInterruptCallBackType s_pPortPinNotifyTable[PORT_PIN_NUM_MAX] = {NULL}; +/** @brief PORT interrupt mode table */ +static PORT_IntConfigType s_aPortPinIrqTable[PORT_PIN_NUM_MAX] = {PORT_IRQ_DISABLE}; +/** @brief port common interrupt handle function */ +static void Port_CommonProcessInterrupt(const PORT_InstanceType ePort, const uint8_t u8Pin); + + +/***************PORT Global Functions*****************/ +/** + * @brief Initialize port + * + * @param ePort Port instance + * @param pInitStruct Initialization structure of port + * @return Port return type. + */ +PORT_StatusType PORT_InitPins(const PORT_InstanceType ePort, const PORT_InitType *const pInitStruct) +{ + PORT_StatusType eRet = PORT_STATUS_SUCCESS; + PORT_Type *pPort; + uint32_t u32PcrRegValue = 0U; + uint32_t u32LowPcrRegValue = 0U; + uint32_t u32HighPcrRegValue = 0U; + + if (((uint32_t)ePort >= PORT_INSTANCE_COUNT) || (NULL == pInitStruct)) + { + eRet = PORT_STATUS_PARAM_INVALID; + } + else + { + pPort = s_pPortInstanceTable[(uint32_t)ePort]; + + u32PcrRegValue |= PORT_PCR_MUX(pInitStruct->uPortPinMux.u32PortPinMode); + + u32PcrRegValue |= PORT_PCR_IRQC(pInitStruct->eTriggrtMode); + + u32PcrRegValue |= PORT_PCR_PE(pInitStruct->bPullEn); + u32PcrRegValue |= PORT_PCR_PS(pInitStruct->ePullSel); + + u32PcrRegValue |= PORT_PCR_DSE0(pInitStruct->bDrvStrength0En); + u32PcrRegValue |= PORT_PCR_DSE1(pInitStruct->bDrvStrength1En); + + u32PcrRegValue |= PORT_PCR_PFE(pInitStruct->u8PassiveFilterEn); + + u32PcrRegValue |= PORT_PCR_ISF_MASK; + + u32LowPcrRegValue = u32PcrRegValue & PORT_PCR_LOW_16BITS_MASK; + u32HighPcrRegValue = u32PcrRegValue & PORT_PCR_HIGH_16BITS_MASK; + + PORT_HWA_WriteGPCLR(pPort,pInitStruct->u32PortPins,u32LowPcrRegValue); + PORT_HWA_WriteGPCHR(pPort,pInitStruct->u32PortPins,u32LowPcrRegValue); + PORT_HWA_WriteGICLR(pPort,pInitStruct->u32PortPins,u32HighPcrRegValue); + PORT_HWA_WriteGICHR(pPort,pInitStruct->u32PortPins,u32HighPcrRegValue); + } + return eRet; +} + +/** + * @brief De-initialize the Port instance + * + * @param ePort Port instance enumeration + * @param u32Pins The bit of u32Pins indicate the Pin number of this Port. + * @return Port return type. + */ +PORT_StatusType PORT_Deinit(const PORT_InstanceType ePort, const uint32_t u32Pins) +{ + PORT_StatusType eRet = PORT_STATUS_SUCCESS; + PORT_Type *pPort = s_pPortInstanceTable[ePort]; + uint8_t u8PinIndex = 0U; + uint32_t u32TempPins = u32Pins; + if ((uint32_t)ePort >= PORT_INSTANCE_COUNT) + { + eRet = PORT_STATUS_PARAM_INVALID; + } + else + { + while (u32TempPins != 0u) + { + if ((u32TempPins & ((uint32_t)1 << u8PinIndex)) != 0u) + { + PORT_HWA_ConfigPin(pPort, u8PinIndex, (uint32_t)0U); + s_aPortPinIrqTable[PORT_PIN_NUM(ePort, u8PinIndex)] = PORT_IRQ_DISABLE; + s_pPortPinNotifyTable[PORT_PIN_NUM(ePort, u8PinIndex)] = NULL; + } + u32TempPins &= (uint32_t)~((uint32_t)1 << u8PinIndex); + u8PinIndex++; + } + } + return eRet; +} + +/** + * @brief Enable interrupt function of port + * + * @param ePort Port instance enumeration + * @param pIntStruct Interrupt structure of port. + * @return Port return type. + */ +PORT_StatusType PORT_InitInterrupt(const PORT_InstanceType ePort, const PORT_InterruptType *const pIntStruct) +{ + PORT_StatusType eRet = PORT_STATUS_SUCCESS; + uint8_t u8PinIndex = 0U; + uint32_t u32TempPins = 0U; + PORT_Type *pPort = s_pPortInstanceTable[ePort]; + if (((uint32_t)ePort >= PORT_INSTANCE_COUNT) || (NULL == pIntStruct)) + { + eRet = PORT_STATUS_PARAM_INVALID; + } + else + { + u32TempPins = pIntStruct->u32PortPins; + while (u32TempPins != 0u) + { + if ((u32TempPins & ((uint32_t)1 << u8PinIndex)) != 0u) + { + PORT_HWA_ClearPinInterruptFlag(pPort, u8PinIndex); + PORT_HWA_SetPinInterruptMode(pPort, u8PinIndex, (PORT_IntConfigType)pIntStruct->ePortIsrMode); + + s_aPortPinIrqTable[PORT_PIN_NUM(ePort, u8PinIndex)] = pIntStruct->ePortIsrMode; + if (NULL != pIntStruct->pIsrNotify) + { + s_pPortPinNotifyTable[PORT_PIN_NUM(ePort, u8PinIndex)] = pIntStruct->pIsrNotify; + } + } + + u32TempPins &= (uint32_t)~((uint32_t)1 << u8PinIndex); + u8PinIndex++; + } + /* IntMgr_EnableInterrupt((IRQn_Type)((uint32_t)PORTA_IRQn + (uint32_t)ePort)); */ + } + return eRet; +} + +/** + * @brief Enable interrupt function of port + * + * @param ePort Port instance enumeration + * @param u32Pins The bit of u32Pins indicate the Pin number of this Port. + * @return Port return type. + */ +PORT_StatusType PORT_EnableInterrupt(const PORT_InstanceType ePort, const uint32_t u32Pins) +{ + PORT_StatusType eRet = PORT_STATUS_SUCCESS; + uint8_t u8PinIndex = 0U; + uint32_t u32TempPins = u32Pins; + PORT_Type *pPort = s_pPortInstanceTable[ePort]; + if ((uint32_t)ePort >= PORT_INSTANCE_COUNT) + { + eRet = PORT_STATUS_PARAM_INVALID; + } + else + { + while (u32TempPins != 0u) + { + if ((u32TempPins & ((uint32_t)1 << u8PinIndex)) != 0u) + { + PORT_HWA_ClearPinInterruptFlag(pPort, u8PinIndex); + PORT_HWA_SetPinInterruptMode(pPort, u8PinIndex, (PORT_IntConfigType)s_aPortPinIrqTable[PORT_PIN_NUM(ePort, + u8PinIndex)]); + } + u32TempPins &= (uint32_t)~((uint32_t)1 << u8PinIndex); + u8PinIndex++; + } + } + return eRet; +} + +/** + * @brief Disable interrupt function of port + * + * @param ePort Port instance enumeration + * @param u32Pins The bit of u32Pins indicate the Pin number of this Port. + * @return Port return type. + */ +PORT_StatusType PORT_DisableInterrupt(const PORT_InstanceType ePort, const uint32_t u32Pins) +{ + PORT_StatusType eRet = PORT_STATUS_SUCCESS; + uint8_t u8PinIndex = 0U; + uint32_t u32TempPins = u32Pins; + PORT_Type *pPort = s_pPortInstanceTable[ePort]; + if ((uint32_t)ePort >= PORT_INSTANCE_COUNT) + { + eRet = PORT_STATUS_PARAM_INVALID; + } + else + { + while (u32TempPins != 0u) + { + if ((u32TempPins & ((uint32_t)1 << u8PinIndex)) != 0u) + { + PORT_HWA_ClearPinInterruptFlag(pPort, u8PinIndex); + PORT_HWA_ClearPinInterruptMode(pPort, u8PinIndex); + } + u32TempPins &= (uint32_t)~((uint32_t)1 << u8PinIndex); + u8PinIndex++; + } + } + return eRet; +} + +PORT_StatusType PORT_SetPinsDmaReqMode(const PORT_InstanceType ePort, const uint32_t u32Pins, const PORT_DMAReqType eDMAReqMode) +{ + PORT_StatusType eRet = PORT_STATUS_SUCCESS; + uint8_t u8PinIndex = 0U; + uint32_t u32TempPins = u32Pins; + PORT_Type *pPort = s_pPortInstanceTable[ePort]; + if ((uint32_t)ePort >= PORT_INSTANCE_COUNT) + { + eRet = PORT_STATUS_PARAM_INVALID; + } + else + { + while (u32TempPins != 0u) + { + if ((u32TempPins & ((uint32_t)1 << u8PinIndex)) != 0u) + { + PORT_HWA_SetPinDMAReqMode(pPort, u8PinIndex, eDMAReqMode); + } + u32TempPins &= (uint32_t)~((uint32_t)1 << u8PinIndex); + u8PinIndex++; + } + } + return eRet; +} + +/** + * @brief Initialize digital filter for Port instance + * + * @param ePort Port instance enumeration + * @param pDFStruct Digital filter initialization structure of port + * @return Port return type. + */ +PORT_StatusType PORT_InitDigitalFilterPort(const PORT_InstanceType ePort, const PORT_DigitalFilterType *pDFStruct) +{ + PORT_StatusType eRet = PORT_STATUS_SUCCESS; + PORT_Type *pPort = s_pPortInstanceTable[ePort]; + if ((NULL == pDFStruct) || ((uint32_t)ePort >= PORT_INSTANCE_COUNT)) + { + eRet = PORT_STATUS_PARAM_INVALID; + } + else + { + if (pDFStruct->u32PortPinsEn != 0u) + { + if (PORT_FILTER_AON32K_CLK == pDFStruct->eClkSrc) + { + PORT_HWA_SetDigitalFilterClkSrc(pPort, pDFStruct->eClkSrc); + } + else + { + PORT_HWA_ClearDigitalFilterClkSrc(pPort); + } + PORT_HWA_ConfigDigitalFilterWidth(pPort, (uint32_t)pDFStruct->u8FilterLength); + PORT_HWA_ConfigDigitalFilter(pPort, pDFStruct->u32PortPinsEn); + } + } + return eRet; +} + +/** + * @brief De-initialize digital filter for Port instance + * + * @param ePort Port instance enumeration + * @return Port return type. + */ +PORT_StatusType PORT_DeinitDigitalFilterPort(const PORT_InstanceType ePort) +{ + PORT_StatusType eRet = PORT_STATUS_SUCCESS; + PORT_Type *pPort = s_pPortInstanceTable[ePort]; + if ((uint32_t)ePort >= PORT_INSTANCE_COUNT) + { + eRet = PORT_STATUS_PARAM_INVALID; + } + else + { + PORT_HWA_ClearDigitalFilterClkSrc(pPort); + PORT_HWA_ClearDigitalFilterWidth(pPort); + PORT_HWA_ClearDigitalFilterEnable(pPort); + } + return eRet; +} + +/** + * @brief Enable the digital filter function for the specific pin. + * + * @param ePort Port instance enumeration + * @param u32Pins The bit of u32Pins indicate the Pin number of this Port. + * @return Port return type. + */ +PORT_StatusType PORT_EnableDigitalFilterPin(const PORT_InstanceType ePort, const uint32_t u32Pins) +{ + PORT_StatusType eRet = PORT_STATUS_SUCCESS; + uint8_t u8PinIndex = 0U; + uint32_t u32TempPins = u32Pins; + PORT_Type *pPort; + if ((uint32_t)ePort >= PORT_INSTANCE_COUNT) + { + eRet = PORT_STATUS_PARAM_INVALID; + } + else + { + pPort = s_pPortInstanceTable[ePort]; + while (u32TempPins != 0u) + { + if ((u32TempPins & ((uint32_t)1 << u8PinIndex)) != 0u) + { + PORT_HWA_SetDigitalFilterEnable(pPort, u8PinIndex); + } + u32TempPins &= (uint32_t)~((uint32_t)1 << u8PinIndex); + u8PinIndex++; + } + } + return eRet; +} + +/** + * @brief Disable the digital filter function for the specific pin. + * + * @param ePort Port instance enumeration + * @param u32Pins The bit of u32Pins indicate the Pin number of this Port. + */ +PORT_StatusType PORT_DisableDigitalFilterPin(const PORT_InstanceType ePort, const uint32_t u32Pins) +{ + PORT_StatusType eRet = PORT_STATUS_SUCCESS; + uint8_t u8PinIndex = 0U; + uint32_t u32TempPins = u32Pins; + PORT_Type *pPort; + if ((uint32_t)ePort >= PORT_INSTANCE_COUNT) + { + eRet = PORT_STATUS_PARAM_INVALID; + } + else + { + pPort = s_pPortInstanceTable[ePort]; + while (u32TempPins != 0u) + { + if ((u32TempPins & ((uint32_t)1 << u8PinIndex)) != 0u) + { + PORT_HWA_ClearDigitalFilterPin(pPort, u8PinIndex); + } + u32TempPins &= (uint32_t)~((uint32_t)1 << u8PinIndex); + u8PinIndex++; + } + } + return eRet; +} + + +/** + * \brief port common interrupt handle function + * + * \param ePort port instance + * \param u8Pin bit of u8Pin indicate pin number + */ +static void Port_CommonProcessInterrupt(const PORT_InstanceType ePort, const uint8_t u8Pin) +{ + if (NULL != s_pPortPinNotifyTable[PORT_PIN_NUM(ePort, u8Pin)]) + { + s_pPortPinNotifyTable[PORT_PIN_NUM(ePort, u8Pin)](); + } +} + + +/***************PORT IRQ Functions*****************/ +/** + * \brief PORTA interrupt entry + * + */ +void PORTA_IRQHandler(void) +{ + uint8_t u8PinIndex; + for (u8PinIndex = 0U; u8PinIndex < (uint32_t)32; u8PinIndex++) + { + if (PORT_HWA_ReadPinInterruptFlag(PORTA, u8PinIndex)) + { + PORT_HWA_ClearPinInterruptFlag(PORTA, u8PinIndex); + Port_CommonProcessInterrupt(PORT_A, u8PinIndex); + } + } +} + +/** + * \brief PORTB interrupt entry + * + */ +void PORTB_IRQHandler(void) +{ + uint8_t u8PinIndex; + for (u8PinIndex = 0U; u8PinIndex < (uint8_t)32; u8PinIndex++) + { + if (PORT_HWA_ReadPinInterruptFlag(PORTB, u8PinIndex)) + { + PORT_HWA_ClearPinInterruptFlag(PORTB, u8PinIndex); + Port_CommonProcessInterrupt(PORT_B, u8PinIndex); + } + } +} + +/** + * \brief PORTC interrupt entry + * + */ +void PORTC_IRQHandler(void) +{ + uint8_t u8PinIndex; + for (u8PinIndex = 0U; u8PinIndex < (uint8_t)32; u8PinIndex++) + { + if (PORT_HWA_ReadPinInterruptFlag(PORTC, u8PinIndex)) + { + PORT_HWA_ClearPinInterruptFlag(PORTC, u8PinIndex); + Port_CommonProcessInterrupt(PORT_C, u8PinIndex); + } + } +} + +/** + * \brief PORTD interrupt entry + * + */ +void PORTD_IRQHandler(void) +{ + uint8_t u8PinIndex; + for (u8PinIndex = 0U; u8PinIndex < (uint8_t)32; u8PinIndex++) + { + if (PORT_HWA_ReadPinInterruptFlag(PORTD, u8PinIndex)) + { + PORT_HWA_ClearPinInterruptFlag(PORTD, u8PinIndex); + Port_CommonProcessInterrupt(PORT_D, u8PinIndex); + } + } +} + +/** + * \brief PORTE interrupt entry + * + */ +void PORTE_IRQHandler(void) +{ + uint8_t u8PinIndex; + for (u8PinIndex = 0U; u8PinIndex < (uint8_t)32; u8PinIndex++) + { + if (PORT_HWA_ReadPinInterruptFlag(PORTE, u8PinIndex)) + { + PORT_HWA_ClearPinInterruptFlag(PORTE, u8PinIndex); + Port_CommonProcessInterrupt(PORT_E, u8PinIndex); + } + } +} + diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_ptimer.c b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_ptimer.c new file mode 100644 index 0000000..cc5d945 --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_ptimer.c @@ -0,0 +1,326 @@ +/** + * @file fc7xxx_driver_ptimer.c + * @author Flagchip0126 + * @brief FC7xxx PTIMER driver source code + * @version 0.1.0 + * @date 2024-01-15 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Author CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-01-15 Flagchip0126 N/A First version for FC7240 + ******************************************************************************** */ + +#include + +#include "fc7xxx_driver_ptimer.h" +#include "fc7xxx_driver_scg.h" +#include "HwA_scm.h" + +static PTIMER_Type *const s_apPtimerBase[PTIMER_INSTANCE_COUNT] = PTIMER_BASE_PTRS; + +static uint8_t s_u8ChnNum[PTIMER_INSTANCE_COUNT] = {0U}; + +static PTIMER_InterruptCallbackType s_apPtimerIntNotify[PTIMER_INSTANCE_COUNT] = {NULL}; +static PTIMER_SeqErrorCallbackType s_apPtimerSeqErrorNotify[ADC_INSTANCE_COUNT] = {NULL}; + +/** + * @brief Calculate the delay value base on the delay micro seconds + * + * @param eInstance the Ptimer instance to use + * @param u32DelayUs the delay time in micro seconds + * @return uint16_t the delay time in ptimer clock count + */ +static uint16_t PTIMER_CalcDelayValue(const PTIMER_InstanceType eInstance, const uint32_t u32DelayUs); + +/** + * @brief the internal Ptimer interrupt handler + * + * @param eInstance the Ptimer instance to use + */ +static void PTIMERn_IRQHandler(const PTIMER_InstanceType eInstance); + +void PTIMER0_IRQHandler(void); + +void PTIMER1_IRQHandler(void); + +static uint16_t PTIMER_CalcDelayValue(const PTIMER_InstanceType eInstance, const uint32_t u32DelayUs) +{ + DEV_ASSERT((uint8_t)eInstance < PTIMER_INSTANCE_COUNT); + + const PTIMER_Type *const pPtimer = s_apPtimerBase[eInstance]; + + uint32_t u32DelayVal; + uint32_t u32SysFreq; + uint32_t u32PtimerFreqUs = 0U; + PTIMER_ClockPreDividerType ePreDivider = PTIMER_HWA_GetDivPrescaler(pPtimer); + PTIMER_ClockPreDivMultiplyFactorType ePreDivMultFactor = PTIMER_HWA_GetDivMultiply(pPtimer); + uint8_t u8Prescaler = (1U << ePreDivider); + uint8_t u8PrescalerMult = 1U; + + switch (ePreDivMultFactor) + { + case PTIMER_PRE_DIVIDER_MULTIPLY_BY_1: + u8PrescalerMult = 1U; + break; + + case PTIMER_PRE_DIVIDER_MULTIPLY_BY_10: + u8PrescalerMult = 10U; + break; + + case PTIMER_PRE_DIVIDER_MULTIPLY_BY_20: + u8PrescalerMult = 20U; + break; + + case PTIMER_PRE_DIVIDER_MULTIPLY_BY_40: + u8PrescalerMult = 40U; + break; + + default: + u8PrescalerMult = 1U; + break; + } + + u32SysFreq = SCG_GetScgClockFreq(SCG_CORE_CLK); + u32PtimerFreqUs = u32SysFreq / 1000000U; + + u32DelayVal = (u32DelayUs * u32PtimerFreqUs) / ((uint32_t)u8Prescaler * u8PrescalerMult); + DEV_ASSERT(u32DelayVal < (1U << 16U)); + + return (uint16_t)u32DelayVal; +} + +void PTIMER0_IRQHandler(void) +{ + PTIMERn_IRQHandler(PTIMER_INSTANCE_0); +} + +void PTIMER1_IRQHandler(void) +{ + PTIMERn_IRQHandler(PTIMER_INSTANCE_1); +} + +static void PTIMERn_IRQHandler(const PTIMER_InstanceType eInstance) +{ + PTIMER_Type *const pPtimer = s_apPtimerBase[eInstance]; + uint8_t u8Channel; + if (PTIMER_HWA_GetInterruptFlag(pPtimer) == true) + { + PTIMER_HWA_ClearInterruptFlag(pPtimer); + if (s_apPtimerIntNotify[eInstance] != NULL) + { + s_apPtimerIntNotify[eInstance](); + } + } + + for (u8Channel = 0U; u8Channel < s_u8ChnNum[eInstance]; u8Channel++) + { + if (PTIMER_HWA_GetChannelSequenceErrorFlag(pPtimer, u8Channel) == true) + { + PTIMER_HWA_ClearChannelSequenceErrorFlag(pPtimer, u8Channel); + if (s_apPtimerSeqErrorNotify[eInstance] != NULL) + { + s_apPtimerSeqErrorNotify[eInstance](u8Channel); + } + } + } +} + +void PTIMER_DeInit(const PTIMER_InstanceType eInstance) +{ + DEV_ASSERT((uint8_t)eInstance < PTIMER_INSTANCE_COUNT); + + PTIMER_Type *const pPtimer = s_apPtimerBase[eInstance]; + uint8_t u8Chn; + + /* Reset PTIMER Status Ctrl Register */ + PTIMER_HWA_SetStatusCtrl(pPtimer, 0U); + /* Enable PTIMER */ + PTIMER_HWA_Enable(pPtimer); + /* Reset PTIMER Max Cnt Register */ + PTIMER_HWA_SetMaxCount(pPtimer, 0xFFFFU); + /* Reset PTIMER Int Dly Register */ + PTIMER_HWA_SetInterruptDelay(pPtimer, 0xFFFFU); + + for (u8Chn = 0U; u8Chn < PTIMER_DLY_CNT; u8Chn++) + { + PTIMER_HWA_SetChannelControl(pPtimer, u8Chn, false, false, false); + PTIMER_HWA_ClearChannelCounterFlag(pPtimer, u8Chn); + PTIMER_HWA_ClearChannelSequenceErrorFlag(pPtimer, u8Chn); + PTIMER_HWA_SetChannelDelay(pPtimer, u8Chn, 0U); + } + + /* For Pulse out trigger. */ + PTIMER_HWA_DisablePulseOut(pPtimer); + PTIMER_HWA_SetPulseOutDelay(pPtimer, 0U, 0U); + + PTIMER_HWA_LoadValue(pPtimer); + PTIMER_HWA_Disable(pPtimer); +} + +void PTIMER_Init(const PTIMER_InstanceType eInstance, const PTIMER_InitType *const pInitCfg) +{ + DEV_ASSERT(pInitCfg != NULL_PTR); + DEV_ASSERT((uint8_t)eInstance < PTIMER_INSTANCE_COUNT); + + PTIMER_Type *const pPtimer = s_apPtimerBase[(uint8_t)eInstance]; + + PTIMER_DeInit(eInstance); + + PTIMER_HWA_SetLoadMode(pPtimer, pInitCfg->eLoadValueMode); + PTIMER_HWA_SetDivPrescaler(pPtimer, pInitCfg->eClkPreDiv); + PTIMER_HWA_SetTriggerSource(pPtimer, pInitCfg->eTriggerInput); + PTIMER_HWA_SetDivMultiply(pPtimer, pInitCfg->eClkPreMultFactor); + PTIMER_HWA_SetContinuoiusModeFlag(pPtimer, pInitCfg->bContinuousModeEnable); + PTIMER_HWA_SetDMAEnableFlag(pPtimer, pInitCfg->bDmaEnable); +} + +void PTIMER_InitChannel(const PTIMER_InstanceType eInstance, + const PTIMER_ChannelCfgType aChannelCfg[], const uint8_t u8ChnNum) +{ + DEV_ASSERT(aChannelCfg != NULL_PTR); + DEV_ASSERT((uint8_t)eInstance < PTIMER_INSTANCE_COUNT); + DEV_ASSERT(u8ChnNum <= PTIMER_DLY_CNT); + + PTIMER_Type *const pPtimer = s_apPtimerBase[eInstance]; + + uint8_t u8ChnIdx; + uint16_t u16PtimerChannelDelay ; + + for (u8ChnIdx = 0U; u8ChnIdx < u8ChnNum; u8ChnIdx++) + { + PTIMER_HWA_SetChannelControl(pPtimer, u8ChnIdx, aChannelCfg[u8ChnIdx].bPreTriggerEnable, + aChannelCfg[u8ChnIdx].bPreTriggerOutputEnable, aChannelCfg[u8ChnIdx].bPreTriggerBackToBackEnable); + u16PtimerChannelDelay = PTIMER_CalcDelayValue(eInstance, aChannelCfg[u8ChnIdx].u32DelayUs); + PTIMER_HWA_SetChannelDelay(pPtimer, u8ChnIdx, u16PtimerChannelDelay); + } + s_u8ChnNum[eInstance] = u8ChnNum; +} + +void PTIMER_InitInterrupt(const PTIMER_InstanceType eInstance, + const PTIMER_InterruptType *const pInterruptCfg) +{ + DEV_ASSERT(pInterruptCfg != NULL_PTR); + DEV_ASSERT((uint8_t)eInstance < PTIMER_INSTANCE_COUNT); + PTIMER_Type *const pPtimer = s_apPtimerBase[eInstance]; + + PTIMER_HWA_SetSeqErrIntEnableFlag(pPtimer, pInterruptCfg->bSeqErrIntEnable); + uint16_t u16IntDelay = PTIMER_CalcDelayValue(eInstance, pInterruptCfg->u32IntDelayPeriodUs); + PTIMER_HWA_SetInterruptDelay(pPtimer, u16IntDelay); + PTIMER_HWA_SetInterruptEnableFlag(pPtimer, pInterruptCfg->bDelayIntEnable); + + if (pInterruptCfg->bDelayIntEnable) + { + s_apPtimerIntNotify[eInstance] = pInterruptCfg->pIntNotify; + } + else + { + s_apPtimerIntNotify[eInstance] = NULL; + } + + if (pInterruptCfg->bSeqErrIntEnable) + { + s_apPtimerSeqErrorNotify[eInstance] = pInterruptCfg->pSeqErrorNotify; + } + else + { + s_apPtimerSeqErrorNotify[eInstance] = NULL; + } + + if ((pInterruptCfg->bSeqErrIntEnable == true) || (pInterruptCfg->bDelayIntEnable == true)) + { + switch ((uint8_t)eInstance) + { + case (uint8_t)PTIMER_INSTANCE_0: + IntMgr_EnableInterrupt(PTIMER0_IRQn); + break; + + case (uint8_t)PTIMER_INSTANCE_1: + IntMgr_EnableInterrupt(PTIMER1_IRQn); + break; + + default: + break; + } + } +} + +void PTIMER_SetPeriod(const PTIMER_InstanceType eInstance, uint32_t u32PeriodUs) +{ + DEV_ASSERT((uint8_t)eInstance < PTIMER_INSTANCE_COUNT); + + PTIMER_Type *const pPtimer = s_apPtimerBase[eInstance]; + + uint16_t u16MaxCnt = PTIMER_CalcDelayValue(eInstance, u32PeriodUs); + PTIMER_HWA_SetMaxCount(pPtimer, u16MaxCnt); +} + +void PTIMER_SetPulseOut(const PTIMER_InstanceType eInstance, const PTIMER_PulseOutType *pPulseOutCfg) +{ + DEV_ASSERT((uint8_t)eInstance < PTIMER_INSTANCE_COUNT); + DEV_ASSERT(pPulseOutCfg != NULL_PTR); + PTIMER_Type *const pPtimer = s_apPtimerBase[eInstance]; + + uint16_t u16PulseOutCfgDlyHigh = PTIMER_CalcDelayValue(eInstance, pPulseOutCfg->u32PulseOutDlyHighUs); + uint16_t u16PulseOutCfgDlyLow = PTIMER_CalcDelayValue(eInstance, pPulseOutCfg->u32PulseOutDlyLowUs); + + PTIMER_HWA_SetPulseOutDelay(pPtimer, u16PulseOutCfgDlyHigh, u16PulseOutCfgDlyLow); +} + +void PTIMER_LoadValue(const PTIMER_InstanceType eInstance) +{ + DEV_ASSERT((uint8_t)eInstance < PTIMER_INSTANCE_COUNT); + + PTIMER_Type *const pPtimer = s_apPtimerBase[eInstance]; + PTIMER_HWA_LoadValue(pPtimer); +} + +void PTIMER_Enable(const PTIMER_InstanceType eInstance) +{ + DEV_ASSERT((uint8_t)eInstance < PTIMER_INSTANCE_COUNT); + + PTIMER_Type *const pPtimer = s_apPtimerBase[eInstance]; + PTIMER_HWA_Enable(pPtimer); +} + +void PTIMER_Disable(const PTIMER_InstanceType eInstance) +{ + DEV_ASSERT((uint8_t)eInstance < PTIMER_INSTANCE_COUNT); + + PTIMER_Type *const pPtimer = s_apPtimerBase[eInstance]; + PTIMER_HWA_Disable(pPtimer); +} + +void PTIMER_EnablePulseOut(const PTIMER_InstanceType eInstance) +{ + DEV_ASSERT((uint8_t)eInstance < PTIMER_INSTANCE_COUNT); + + PTIMER_Type *const pPtimer = s_apPtimerBase[eInstance]; + PTIMER_HWA_EnablePulseOut(pPtimer); +} + +void PTIMER_DisablePulseOut(const PTIMER_InstanceType eInstance) +{ + DEV_ASSERT((uint8_t)eInstance < PTIMER_INSTANCE_COUNT); + + PTIMER_Type *const pPtimer = s_apPtimerBase[eInstance]; + PTIMER_HWA_DisablePulseOut(pPtimer); +} + +void PTIMER_SelectInstance01BackToBackMode(SCM_PTimerLMSelType ePTimerLoopMode) +{ + SCM_HWA_PTimerLoopModeSel(ePTimerLoopMode); +} + +void PTIMER_GenerateSWTrigger(const PTIMER_InstanceType eInstance) +{ + DEV_ASSERT((uint8_t)eInstance < PTIMER_INSTANCE_COUNT); + + PTIMER_Type *const pPtimer = s_apPtimerBase[eInstance]; + PTIMER_HWA_GenerateSwTrigger(pPtimer); +} diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_rgm.c b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_rgm.c new file mode 100644 index 0000000..7a5b4ae --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_rgm.c @@ -0,0 +1,312 @@ +/** + * @file fc7xxx_driver_rgm.c + * @author Flagchip + * @brief FC7xxx RGM driver source code + * @version 0.1.0 + * @date 2024-01-12 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + * @details + */ +/******************************************************************************** +* Revision History: +* +* Version Date Initials CR# Descriptions +* --------- ---------- ------------ ---------- --------------- +* 0.1.0 2024-01-12 Flagchip119 N/A First version for FC7240 +********************************************************************************/ +#include "fc7xxx_driver_rgm.h" +#include "interrupt_manager.h" + +/** @brief Rgm user defined CPU0 core related system interrupt function */ +static RGM_InterruptCallBackType s_pRgmCPU0PreIntPtr = NULL; + +/** @brief Rgm pre-reset interrupt entry */ +void RGM_Pre_IRQHandler(void); + +/** + * @brief This api can get RGM_SRS register that indicate the source of the most recent reset. + * + * @return RGM->RGM_SRS register, bit 0-15,29-31 corresponding to RGM_ResetEventType, refer to reference manual for details. + * @note Multiple flags can be set if multiple reset events occur at the same time + */ +uint32_t RGM_GetLastResetFLag(void) +{ + return RGM_HWA_ReadLastResetFlag(); +} + +/** + * @brief This api can get RGM_SSRS register that indicate all reset sources since the last POR or LVD that have not been cleared by software. + * + * @return RGM->RGM_SSRS register, bit 0-15,29-31 corresponding to RGM_ResetEventType, refer to reference manual for details. + */ +uint32_t RGM_GetAllResetFlag(void) +{ + return RGM_HWA_ReadAllResetFlagBeforePOR(); +} + +/** + * @brief This api can clear reset flag of RGM_SSRS register which indicate all reset sources since the last POR or LVD that have not been cleared by software. + * + * @param eReset Enumeration of reset event flag + */ +void RGM_ClearResetFlagAfterPOR(const RGM_ResetEventType eReset) +{ + RGM_HWA_ClearResetFlagAfterPOR(eReset); +} + +/** + * @brief This api can clear all reset flag of RGM_SSRS register which indicate all reset sources since the last POR or LVD that have not been cleared by software. + * + */ +void RGM_ClearAllResetFlagAfterPOR(void) +{ + RGM_HWA_ClearAllResetFlagAfterPOR(); +} + +/** + * @brief Enable reset pin filter + * + * @param eClk Reset pin filter clock source + * @param u8BusClockFilterWidth Bus clock filter width + * @param bLpClkEn select whether enable reset pin filter using AON32clock in low power mode + * @return RGM return type + * @note If use AON32K clock, A reset signal whose length is less than 2 AON32K clock periods will be filtered + */ +RGM_StatusType RGM_EnableResetFilter(RGM_FilterClkSrc eClk, uint8_t u8BusClockFilterWidth, bool bLpClkEn) +{ + RGM_StatusType eRet = RGM_STATUS_SUCCESS; + if(eClk > RGM_RESET_FILTER_AON32K_CLOCK) + { + eRet = RGM_STATUS_PARAM_INVALID; + } + if (RGM_STATUS_SUCCESS == eRet) + { + if (RGM_RESET_FILTER_AON32K_CLOCK == eClk) + { + if ((RGM_HWA_ReadResetPinFilterEnable() & RGM_RSTFLT_RSTFLT_BUS_MASK) >> RGM_RSTFLT_RSTFLT_BUS_SHIFT == 1U) + { + RGM_HWA_DisableBusClockFilter(); + } + RGM_HWA_EnableAon32kClockFilter(); + } + if (RGM_RESET_FILTER_BUS_CLOCK == eClk) + { + if ((RGM_HWA_ReadResetPinFilterEnable() & RGM_RSTFLT_RSTFLT_AON_MASK) >> RGM_RSTFLT_RSTFLT_AON_SHIFT == 1U) + { + RGM_HWA_DisableAon32kClockFilter(); + } + RGM_HWA_SetBusClockFilterWidth(u8BusClockFilterWidth); + RGM_HWA_EnableBusClockFilter(); + } + if (bLpClkEn) + { + RGM_HWA_EnableAon32kLPClockFilter(); + } + } + return eRet; +} + +/** + * @brief Disable reset pin filter + * + * @param eClk Reset pin filter clock source + * @param bLpClkEn select whether disable reset pin filter using AON32clock in low power mode + * @return RGM return type + */ +RGM_StatusType RGM_DisableResetFilter(RGM_FilterClkSrc eClk, bool bLpClkEn) +{ + RGM_StatusType eRet = RGM_STATUS_SUCCESS; + if (eClk > RGM_RESET_FILTER_AON32K_CLOCK) + { + eRet = RGM_STATUS_PARAM_INVALID; + } + if (RGM_STATUS_SUCCESS == eRet) + { + if (RGM_RESET_FILTER_AON32K_CLOCK == eClk) + { + RGM_HWA_DisableAon32kClockFilter(); + } + if (bLpClkEn) + { + RGM_HWA_DisableAon32kLPClockFilter(); + } + if (RGM_RESET_FILTER_BUS_CLOCK == eClk) + { + RGM_HWA_ClearBusClockFilterWidth(); + RGM_HWA_DisableBusClockFilter(); + } + } + return eRet; +} + +/** + * @brief This api can enable interrupt before an system reset appear. + * + * @param eDelay Enumeration of delay cycles + * @param eResetInterrupt Reset event flag, like: RGM_INT_CLKERR0 | RGM_INT_FCSMU + * @return RGM return type + * + * @note Here is the interrupted master switch control + */ +RGM_StatusType RGM_EnableSystemResetInt(RGM_ResetDelayType eDelay, RGM_ResetIntMangerType eResetInterrupt) +{ + RGM_StatusType eRet = RGM_STATUS_SUCCESS; + if (eDelay > RGM_512_CLOCK_CYCLES) + { + eRet = RGM_STATUS_PARAM_INVALID; + } + if (RGM_STATUS_SUCCESS == eRet) + { + RGM_HWA_EnableGlobalResetInterrupt(); + RGM_HWA_SetResetDelay(eDelay); + RGM_HWA_EnableResetInterrupt(eResetInterrupt); + } + return eRet; +} + +/** + * @brief This api can disable interrupt before an system reset appear. + * + * @param eResetInterrupt Reset event flag, like: RGM_INT_CLKERR0 | RGM_INT_FCSMU + * @param bClearDelay Whether to clear delay configuration + * @return RGM return type + */ +RGM_StatusType RGM_DisableSystemResetInt(RGM_ResetIntMangerType eResetInterrupt, bool bClearDelay) +{ + RGM_StatusType eRet = RGM_STATUS_SUCCESS; + if (bClearDelay) + { + RGM_HWA_ClearResetDelay(); + } + RGM_HWA_DisableResetInterrupt(eResetInterrupt); + return eRet; +} + +/** + * @brief Generate software reset through cotex-m register + * + */ +void RGM_GenerateSwReset(void) +{ + CM7_HWA_SystemReset(); +} + +/** + * @brief This api can enable interrupt before an CPU0 core related reset appear. + * + * @param eCPU0Interrupt Reset event flag, like: RGM_CPU_INT_SWRST | RGM_CPU_INT_SYSRST + * @param pIsrNotify Interrupt function + * @return RGM return type + */ +RGM_StatusType RGM_EnableCPU0CoreResetInt(RGM_CPUIntMangerType eCPU0Interrupt,RGM_InterruptCallBackType pIsrNotify) +{ + RGM_StatusType eRet = RGM_STATUS_SUCCESS; + if((uint8_t)eCPU0Interrupt > 0x1FU) + { + eRet = RGM_STATUS_PARAM_INVALID; + } + if (RGM_STATUS_SUCCESS == eRet) + { + RGM_HWA_EnableCPU0InterruptFlag(eCPU0Interrupt); + s_pRgmCPU0PreIntPtr = pIsrNotify; + } + return eRet; +} + +/** + * @brief This api can disable interrupt before an CPU0 core related reset appear. + * + * @param eCPU0Interrupt Reset event flag, like: RGM_CPU_INT_SWRST | RGM_CPU_INT_SYSRST + * @return RGM return type + */ +RGM_StatusType RGM_DisableCPU0CoreResetInt(RGM_CPUIntMangerType eCPU0Interrupt) +{ + RGM_StatusType eRet = RGM_STATUS_SUCCESS; + if((uint8_t)eCPU0Interrupt > 0x1FU) + { + eRet = RGM_STATUS_PARAM_INVALID; + } + if (RGM_STATUS_SUCCESS == eRet) + { + RGM_HWA_DisableCPU0InterruptFlag(eCPU0Interrupt); + } + return eRet; +} + +/** + * @brief Get the CPU0 exit reset flag + * + * @return RGM_CPU_OUT_RST_UNDER CPU0 is under reset + * @return RGM_CPU_OUT_RST_OUT CPU0 is out of reset + */ +RGM_CPUOutResetType RGM_GetCPU0OutResetFlag(void) +{ + return RGM_HWA_GetCPU0OutResetFlag(); +} + +/** + * @brief Generate a CPU0 software reset. + * + */ +void RGM_GenerateCPU0SwReset(void) +{ + RGM_HWA_CPU0SWReset(); +} + +/** + * @brief This api can get RGM_C0_SRS register that indicate the source of the most recent CPU0 reset. + * + * @return RGM->RGM_C0_SRS register, bit 0-20 corresponding to RGM_ResetEventType, refer to reference manual for details. + * @note Multiple flags can be set if multiple reset events occur at the same time + */ +uint32_t RGM_GetCPU0LastResetFLag(void) +{ + return RGM_HWA_ReadCPU0LastResetFlag(); +} + +/** + * @brief This api can get RGM_C0_SSRS register that indicate all CPU0 reset sources since the last POR or LVD that have not been cleared by software. + * + * @returnRGM->RGM_C0_SSRS register, bit 0-20,29-31 corresponding to RGM_CPUResetEventType, refer to reference manual for details. + */ +uint32_t RGM_GetCPU0AllResetFlag(void) +{ + return RGM_HWA_ReadCPU0AllResetFlagBeforePOR(); +} + +/** + * @brief This api can clear reset flag of RGM_C0_SSRS register which indicate CPU0 all reset sources since the last POR or LVD that have not been cleared by software. + * + * @param eReset Enumeration of reset event flag + */ +void RGM_ClearCPU0ResetFlagAfterPOR(const RGM_CPUResetEventType eReset) +{ + RGM_HWA_ClearC0ResetFlagAfterPOR(eReset); +} + +/** + * @brief This api can clear all reset flag of RGM_C0_SSRS register which indicate CPU0 all reset sources since the last POR or LVD that have not been cleared by software. + * + */ +void RGM_ClearCPU0AllResetFlagAfterPOR(void) +{ + RGM_HWA_ClearC0AllResetFlagAfterPOR(); +} + +/** + * @brief RGM Pre-interrupt entry + * + */ +void RGM_Pre_IRQHandler(void) +{ + IntMgr_DisableGlobalInterrupt(); + + if (NULL != s_pRgmCPU0PreIntPtr) + { + s_pRgmCPU0PreIntPtr(RGM_GetCPU0LastResetFLag()); + } + IntMgr_EnableGlobalInterrupt(); +} + diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_rtc.c b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_rtc.c new file mode 100644 index 0000000..bcc371f --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_rtc.c @@ -0,0 +1,365 @@ +/** + * @file fc7xxx_driver_rtc.c + * @author Flagchip + * @brief FC7xxx rtc driver type definition and API + * @version 0.1.0 + * @date 2024-01-10 + * + * @copyright Copyright (c) 2023 Flagchip Semiconductors Co., Ltd. + * + * @details + */ +/******************************************************************************** +* Revision History: +* +* Version Date Initials CR# Descriptions +* --------- ---------- ------------ ---------- --------------- +* 0.1.0 2024-01-10 Flagchip0076 N/A First version for FC7240 +********************************************************************************/ +#include "fc7xxx_driver_rtc.h" + +#include "fc7xxx_driver_csc.h" + + + +/** + * @brief Rtc user defined alarm interrupt function + * */ +static RTC_InterruptCallBackType s_pRTCAlarmNotifyPtr = NULL; + +/** + * @brief Rtc user defined seconds interrupt function + * */ +static RTC_InterruptCallBackType s_pRTCSecondNotifyPtr = NULL; + +/** + * @brief Rtc user defined overflow interrupt function + * */ +static RTC_InterruptCallBackType s_pRTCOverFlowNotifyPtr = NULL; + +/** + * @brief RTC common interrupt function + * */ +static void Rtc_CommonProcessInterrupt(const RTC_IntEventType eIntEvent); + +/** + * @brief RTC interrupt entry + * */ +void RTC_IRQHandler(void); + + +/** + * @brief Initialize Rtc instance + * + * @param pInitStruct Rtc initialization structure + * @return Rtc return type + * @note This function could only write once after POR. + */ +void RTC_Init(const RTC_InitType *const pInitStruct) +{ + DEV_ASSERT(pInitStruct != NULL); + /* Disable interrupt */ + RTC_HWA_DisableOverflowInterrupt(); + /*Disable Second interrupt*/ + RTC_HWA_DisableSecondInterrupt(); + /*Disable Alarm interrupt*/ + RTC_HWA_DisableAlarmInterrupt(); + /* disable the rtc clock*/ + RTC_HWA_DisableRtcCounter(); + /* clear PR register */ + RTC_HWA_SetPrescalerCounterValue(0U); + /* clear SR register */ + RTC_HWA_SetSecondCounterValue(0U); + /* clear CR register */ + RTC_HWA_ConfigControl(0U); + if (pInitStruct->bStableClkoutFreq) + { + RTC_HWA_SetClkoutFreqStable(); + } + else + { + RTC_HWA_SetClkoutFromSelectFreq(); + } + /* TSIC should only be altered when TSIE is clear */ + RTC_HWA_SetSecondAndClkoutFreq(pInitStruct->eSecIntAndClkoutFreq); + /* Set alarm value */ + RTC_HWA_SetAlarmCounterValue(pInitStruct->u32AlarmValue); +} + +/** + * @brief Rtc set interrupt + * + * @param pIntStruct interrupt structure pointer + * @return Rtc return type + * @note this function will stop Rtc timer + */ +RTC_StatusType RTC_InitInterrupt(const RTC_InterruptType *const pIntStruct) +{ + RTC_StatusType eRet = RTC_STATUS_SUCCESS; + if (NULL == pIntStruct) + { + eRet = RTC_STATUS_PARAM_INVALID; + } + else + { + /* disable the rtc timer */ + RTC_HWA_DisableRtcCounter(); + if (pIntStruct->bAlarmIntEn) + { + /* enable alarm interrupt */ + RTC_HWA_EnableAlarmInterrupt(); + s_pRTCAlarmNotifyPtr = pIntStruct->pIsrAlarmNotify; + } + else + { + /* disable alarm interrupt */ + RTC_HWA_DisableAlarmInterrupt(); + s_pRTCAlarmNotifyPtr = NULL; + } + + if (pIntStruct->bOverflowIntEn) + { + /* enable overflow interrupt */ + RTC_HWA_EnableOverflowInterrupt(); + s_pRTCOverFlowNotifyPtr = pIntStruct->pIsrOverflowNotify; + } + else + { + /* disable overflow interrupt */ + RTC_HWA_DisableOverflowInterrupt(); + s_pRTCOverFlowNotifyPtr = NULL; + } + + if (pIntStruct->bSecondIntEn) + { + /* enable second interrupt */ + RTC_HWA_EnableSecondInterrupt(); + s_pRTCSecondNotifyPtr = pIntStruct->pIsrSecondNotify; + } + else + { + /* disable second interrupt */ + RTC_HWA_DisableSecondInterrupt(); + s_pRTCSecondNotifyPtr = NULL; + } + } + return eRet; +} + +/** + * @brief De-initialize Rtc instance + * + */ +void RTC_Deinit(void) +{ + /* disable the rtc timer */ + RTC_HWA_DisableRtcCounter(); + /* clear PR register */ + RTC_HWA_SetPrescalerCounterValue(0U); + /* clear SR register */ + RTC_HWA_SetSecondCounterValue(0U); + /* clear TAR register */ + RTC_HWA_SetAlarmCounterValue(0U); + /* clear IER register */ + RTC_HWA_SetInterruptValue(0U); + /* clear CR register */ + RTC_HWA_ConfigControl(0U); + s_pRTCAlarmNotifyPtr = NULL; + s_pRTCSecondNotifyPtr = NULL; + s_pRTCOverFlowNotifyPtr = NULL; +} + +/** + * @brief Rtc enable interrupt + * + * @param bAlarmIntEn whether enable alarm interrupt + * @param bSecondIntEn whether enable second interrupt + * @param bOverflowIntEn whether enable overflow interrupt + */ +void RTC_EnableInterrupt(const bool bAlarmIntEn, const bool bSecondIntEn, const bool bOverflowIntEn) +{ + /* disable the rtc timer */ + RTC_HWA_DisableRtcCounter(); + if (bAlarmIntEn) + { + /* enable alarm interrupt */ + RTC_HWA_EnableAlarmInterrupt(); + } + if (bSecondIntEn) + { + /* enable second interrupt */ + RTC_HWA_EnableSecondInterrupt(); + } + if (bOverflowIntEn) + { + /* enable overflow interrupt */ + RTC_HWA_EnableOverflowInterrupt(); + } + /*enable the rtc clock*/ + RTC_HWA_EnableRtcCounter(); +} + +/** + * @brief Rtc disable interrupt + * + * @param bAlarmIntEn whether disable alarm interrupt + * @param bSecondIntEn whether disable second interrupt + * @param boverflowIntEn whether disable overflow interrupt + */ +void RTC_DisableInterrupt(const bool bAlarmIntEn, const bool bSecondIntEn, const bool boverflowIntEn) +{ + /* disable the rtc timer */ + RTC_HWA_DisableRtcCounter(); + if (bAlarmIntEn) + { + /* disable alarm interrupt */ + RTC_HWA_DisableAlarmInterrupt(); + } + if (bSecondIntEn) + { + /* disable second interrupt */ + RTC_HWA_DisableSecondInterrupt(); + } + if (boverflowIntEn) + { + /* disable overflow interrupt */ + RTC_HWA_DisableOverflowInterrupt(); + } + /*enable the rtc clock*/ + RTC_HWA_EnableRtcCounter(); +} + +/** + * @brief rtc start + * + */ +void RTC_Start(void) +{ + /*enable the rtc clock*/ + RTC_HWA_EnableRtcCounter(); +} + +/** + * @brief Rtc stop + * + */ +void RTC_Stop(void) +{ + /*disable the rtc clock*/ + RTC_HWA_DisableRtcCounter(); +} + +/** + * @brief Rtc alarm value + * + * @param u32AlarmValue Input value + */ +void RTC_UpdateAlarmValue(const uint32_t u32AlarmValue) +{ + /*disable the rtc clock*/ + RTC_HWA_DisableRtcCounter(); + /* clear PR register */ + RTC_HWA_SetPrescalerCounterValue(0U); + /* Set alarm value */ + RTC_HWA_SetAlarmCounterValue(RTC_HWA_ReadSecondValue() + u32AlarmValue - (uint32_t)1U); + /*enable the rtc clock*/ + RTC_HWA_EnableRtcCounter(); +} + +/** + * @brief Get Rtc counter value + * + * @return Rtc counter value + */ +uint32_t RTC_GetTime(void) +{ + return RTC_HWA_ReadSecondValue(); +} + +/** + * @brief Check RTC overflow flag + * + * @return Overflow flag + */ +bool RTC_CheckOverflowFlag(void) +{ + return RTC_HWA_GetOverflowFlag(); +} + +/** + * @brief Set second counter value + * @param u32Value the second value. + * */ +void RTC_SetSecondCounterValue(uint32_t u32Value) +{ + RTC_HWA_DisableRtcCounter(); + RTC_HWA_SetSecondCounterValue(u32Value); + RTC_HWA_EnableRtcCounter(); +} + +/** + * @brief RTC common interrupt function + * + * @param eIntEvent RTC interrupt event + */ +static void Rtc_CommonProcessInterrupt(const RTC_IntEventType eIntEvent) +{ + switch (eIntEvent) + { + case RTC_ALARM_INT: + if (NULL != s_pRTCAlarmNotifyPtr) + { + s_pRTCAlarmNotifyPtr(); + } + break; + case RTC_SECOND_INT: + if (NULL != s_pRTCSecondNotifyPtr) + { + s_pRTCSecondNotifyPtr(); + } + break; + case RTC_OVERFLOW_INT: + if (NULL != s_pRTCOverFlowNotifyPtr) + { + s_pRTCOverFlowNotifyPtr(); + } + break; + default: + /* do nothing*/ + break; + } +} + +/** + * @brief RTC alarm interrupt handler entry + * + */ +void RTC_IRQHandler(void) +{ + bool overflow_flag = RTC_HWA_GetOverflowFlag(); + bool overflow_enablebit = RTC_HWA_GetOverflowEnable(); + bool alarm_flag = RTC_HWA_GetAlarmFlag(); + bool alarm_enablebit = RTC_HWA_GetAlarmEnable(); + if ((overflow_flag) && (overflow_enablebit)) + { + /*oveflow Int*/ + /*disable the rtc clock*/ + RTC_HWA_DisableRtcCounter(); + RTC_HWA_SetSecondCounterValue(0u); + Rtc_CommonProcessInterrupt(RTC_OVERFLOW_INT); + + + } + else if ((alarm_flag) && (alarm_enablebit)) + { + /*alarm Int*/ + RTC_HWA_SetAlarmCounterValue(0u); + Rtc_CommonProcessInterrupt(RTC_ALARM_INT); + + } + else + { + /*second Int*/ + Rtc_CommonProcessInterrupt(RTC_SECOND_INT); + } +} diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_scg.c b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_scg.c new file mode 100644 index 0000000..ef8545e --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_scg.c @@ -0,0 +1,1941 @@ +/** + * @file fc7xxx_driver_scg.c + * @author Flagchip + * @brief FC7xxx SCG driver type definition and API + * @version 0.1.0 + * @date 2024-01-12 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + */ + +/******************************************************************************** +* Revision History: +* +* Version Date Initials CR# Descriptions +* --------- ---------- ------------ ---------- --------------- +* 0.1.0 2024-01-12 Flagchip085 N/A First version for FC7240 +********************************************************************************/ +#include "fc7xxx_driver_scg.h" +#include "fc7xxx_board_conf.h" + +#if ((FOSC_FREQUENCY < 16000000U) || (FOSC_FREQUENCY > 48000000U)) +#error "FOSC is not in range 16M ~ 48 M" +#endif + +/***************** Macros *********************/ +#define SIRC_CLOCK 12000000U +#define SIRC32K_CLOCK 32000U +#define FIRC_CLOCK 96000000U +#define NVM_CLOCK 12000000U +#define FOSC_STABILIZATION_TIMEOUT 96000U +#define FIRC_STABILIZATION_TIMEOUT 20U +#define SIRC_STABILIZATION_TIMEOUT 100U +#define SOSC_STABILIZATION_TIMEOUT 320500U +#define PLL_STABILIZATION_TIMEOUT 320500U +#define SCG_CLKSRC_STABILIZATION_TIMEOUT 1000U +#define CLOCK_OFF_STABILIZATION_TIMEOUT 1000U /* clock out time is about 1us */ +#define CLOCK_DIV_STABILIZATION_TIMEOUT 1000U + +#define PLL0_CLK_MAX 240000000U +#define PLL1_CLK_MAX 320000000U +#define PLL_VCO_CLK_MAX 800000000U +#define PLL_VCO_CLK_MIN 300000000U +#define PLL_FEEDBACK_CLK_MAX 4000000U +#define PLL_FEEDBACK_CLK_MIN 2000000U +#define SYS_CORE_CLK_MAX 240000000U +#define SYS_BUS_CLK_MAX 120000000U +#define SYS_SLOW_CLK_MAX 60000000U + +#define FOSC_DIVH_MAX_CLOCK 48000000U +#define FOSC_DIVM_MAX_CLOCK 48000000U +#define FOSC_DIVL_MAX_CLOCK 48000000U +#define FIRC_DIVH_MAX_CLOCK 96000000U +#define FIRC_DIVM_MAX_CLOCK 96000000U +#define FIRC_DIVL_MAX_CLOCK 48000000U +#define PLL0_DIVH_MAX_CLOCK 240000000U +#define PLL0_DIVM_MAX_CLOCK 120000000U +#define PLL0_DIVL_MAX_CLOCK 60000000U +#define PLL1_DIVH_MAX_CLOCK 320000000U +#define PLL1_DIVM_MAX_CLOCK 160000000U +#define PLL1_DIVL_MAX_CLOCK 80000000U + +/***************** mcaro function *********************/ +#define SCG_CheckClockAckStatus(x, timeout, returnVal) \ + while ((x) && (timeout > 0U)) \ + { \ + timeout--; \ + } \ + if (timeout != 0U) \ + { \ + returnVal = SCG_STATUS_SUCCESS; \ + } \ + else \ + { \ + returnVal = SCG_STATUS_TIMEOUT; \ + } + + +#define SCG_GetDivHClock(_clock_, input_freq, ouput_freq) \ + { \ + uint32_t u32DivRegVal; \ + \ + u32DivRegVal = SCG_HWA_GetClockDiv(_clock_); \ + ouput_freq = SCG_CALCULATE_DIVH_FREQ(input_freq, u32DivRegVal); \ + } + +#define SCG_GetDivMClock(_clock_, input_freq, ouput_freq) \ + { \ + uint32_t u32DivRegVal; \ + u32DivRegVal = SCG_HWA_GetClockDiv(_clock_); \ + ouput_freq = SCG_CALCULATE_DIVM_FREQ(input_freq, u32DivRegVal); \ + } + +#define SCG_GetDivLClock(_clock_, input_freq, ouput_freq) \ + { \ + uint32_t u32DivRegVal; \ + u32DivRegVal = SCG_HWA_GetClockDiv(_clock_); \ + ouput_freq = SCG_CALCULATE_DIVL_FREQ(input_freq, u32DivRegVal); \ + } + +/***************** Local Functions *********************/ + +static uint32_t SCG_CalculateSircFreq(const SCG_ClkSrcType eScgClockName) +{ + uint32_t u32Freq; + + if (SCG_SIRC_CLK == eScgClockName) + { + u32Freq = SIRC_CLOCK; + } + else if (SCG_SIRCDIVH_CLK == eScgClockName) + { + SCG_GetDivHClock(SCG_SIRC_CLOCK_SYMBOL, SIRC_CLOCK, u32Freq); + } + else if (SCG_SIRCDIVM_CLK == eScgClockName) + { + SCG_GetDivMClock(SCG_SIRC_CLOCK_SYMBOL, SIRC_CLOCK, u32Freq); + } + else if (SCG_SIRCDIVL_CLK == eScgClockName) + { + SCG_GetDivLClock(SCG_SIRC_CLOCK_SYMBOL, SIRC_CLOCK, u32Freq); + } + else + { + u32Freq = UNKNOWN_CLOCK; + } + + return u32Freq; +} + +static uint32_t SCG_CalculateFircFreq(const SCG_ClkSrcType eScgClockName) +{ + uint32_t u32Freq; + + if (true == SCG_HWA_GetClockVliad(SCG_FIRC_CLOCK_SYMBOL)) + { + if (SCG_FIRC_CLK == eScgClockName) + { + u32Freq = FIRC_CLOCK; + } + else if (SCG_FIRCDIVH_CLK == eScgClockName) + { + SCG_GetDivHClock(SCG_FIRC_CLOCK_SYMBOL, FIRC_CLOCK, u32Freq); + } + else if (SCG_FIRCDIVM_CLK == eScgClockName) + { + SCG_GetDivMClock(SCG_FIRC_CLOCK_SYMBOL, FIRC_CLOCK, u32Freq); + } + else if (SCG_FIRCDIVL_CLK == eScgClockName) + { + SCG_GetDivLClock(SCG_FIRC_CLOCK_SYMBOL, FIRC_CLOCK, u32Freq); + } + else + { + u32Freq = UNKNOWN_CLOCK; + } + } + else + { + u32Freq = UNKNOWN_CLOCK; + } + + return u32Freq; +} + +static uint32_t SCG_CalculateFoscFreq(const SCG_ClkSrcType eScgClockName) +{ + uint32_t u32Freq; + + if (true == SCG_HWA_GetClockVliad(SCG_FOSC_CLOCK_SYMBOL)) + { + if (SCG_FOSC_CLK == eScgClockName) + { + u32Freq = FOSC_FREQUENCY; + } + else if (SCG_FOSCDIVH_CLK == eScgClockName) + { + SCG_GetDivHClock(SCG_FOSC_CLOCK_SYMBOL, FOSC_FREQUENCY, u32Freq); + } + else if (SCG_FOSCDIVM_CLK == eScgClockName) + { + SCG_GetDivMClock(SCG_FOSC_CLOCK_SYMBOL, FOSC_FREQUENCY, u32Freq); + } + else if (SCG_FOSCDIVL_CLK == eScgClockName) + { + SCG_GetDivLClock(SCG_FOSC_CLOCK_SYMBOL, FOSC_FREQUENCY, u32Freq); + } + else + { + u32Freq = UNKNOWN_CLOCK; + } + } + else + { + u32Freq = UNKNOWN_CLOCK; + } + + return u32Freq; +} + +static uint32_t SCG_CalculatePll0Freq(const SCG_ClkSrcType eScgClockName) +{ + uint32_t u32Freq, u32ClkFreq; + uint32_t u32Temp, u32PreDiv, u32PstDiv; + uint32_t u32Mult; + + if (true == SCG_HWA_GetClockVliad(SCG_PLL0_CLOCK_SYMBOL)) + { + u32Temp = SCG_HWA_GetPllSrc(SCG_PLL0_CLOCK_SYMBOL); + if (u32Temp == (uint32_t)SCG_PLLSOURCE_FIRC) + { + + u32ClkFreq = FIRC_CLOCK / 2U; + } + else + { + /* (u32Temp == (uint32_t)SCG_PLLSOURCE_FOSC) */ + u32ClkFreq = FOSC_FREQUENCY; + } + u32PreDiv = SCG_HWA_GetPllPrediv(SCG_PLL0_CLOCK_SYMBOL) + 1U; + u32Mult = SCG_HWA_GetPllMult(SCG_PLL0_CLOCK_SYMBOL) + 1U; + u32PstDiv = SCG_HWA_GetPllPstdiv(SCG_PLL0_CLOCK_SYMBOL); + if(u32PstDiv == 0U) + { + u32PstDiv = 1U; + } + u32ClkFreq = (u32ClkFreq / (u32PreDiv) * (u32Mult)) >> (u32PstDiv); + + if (SCG_PLL0_CLK == eScgClockName) + { + u32Freq = u32ClkFreq; + } + else if (SCG_PLL0DIVH_CLK == eScgClockName) + { + SCG_GetDivHClock(SCG_PLL0_CLOCK_SYMBOL, u32ClkFreq, u32Freq); + } + else if (SCG_PLL0DIVM_CLK == eScgClockName) + { + SCG_GetDivMClock(SCG_PLL0_CLOCK_SYMBOL, u32ClkFreq, u32Freq); + } + else if (SCG_PLL0DIVL_CLK == eScgClockName) + { + SCG_GetDivLClock(SCG_PLL0_CLOCK_SYMBOL, u32ClkFreq, u32Freq); + } + else + { + u32Freq = UNKNOWN_CLOCK; + } + } + else + { + u32Freq = UNKNOWN_CLOCK; + } + + return u32Freq; +} + +static uint32_t SCG_CalculatePll1Freq(const SCG_ClkSrcType eScgClockName) +{ + uint32_t u32Freq, u32ClkFreq; + uint32_t u32Temp, u32PreDiv, u32PstDiv; + uint32_t u32Mult; + + if (true == SCG_HWA_GetClockVliad(SCG_PLL1_CLOCK_SYMBOL)) + { + u32Temp = SCG_HWA_GetPllSrc(SCG_PLL1_CLOCK_SYMBOL); + if (u32Temp == (uint32_t)SCG_PLLSOURCE_FIRC) + { + u32ClkFreq = FIRC_CLOCK / 2U; + } + else + { + /* (u32Temp == (uint32_t)SCG_PLLSOURCE_FOSC) */ + u32ClkFreq = FOSC_FREQUENCY; + } + u32PreDiv = SCG_HWA_GetPllPrediv(SCG_PLL1_CLOCK_SYMBOL) + 1U; + u32Mult = SCG_HWA_GetPllMult(SCG_PLL1_CLOCK_SYMBOL) + 1U; + u32PstDiv = SCG_HWA_GetPllPstdiv(SCG_PLL1_CLOCK_SYMBOL); + if(u32PstDiv == 0U) + { + u32PstDiv = 1U; + } + u32ClkFreq = (u32ClkFreq / (u32PreDiv) * (u32Mult)) >> (u32PstDiv); + + if (SCG_PLL1_CLK == eScgClockName) + { + u32Freq = u32ClkFreq; + } + else if (SCG_PLL1DIVH_CLK == eScgClockName) + { + SCG_GetDivHClock(SCG_PLL1_CLOCK_SYMBOL, u32ClkFreq, u32Freq); + } + else if (SCG_PLL1DIVM_CLK == eScgClockName) + { + SCG_GetDivMClock(SCG_PLL1_CLOCK_SYMBOL, u32ClkFreq, u32Freq); + } + else if (SCG_PLL1DIVL_CLK == eScgClockName) + { + SCG_GetDivLClock(SCG_PLL1_CLOCK_SYMBOL, u32ClkFreq, u32Freq); + } + else + { + u32Freq = UNKNOWN_CLOCK; + } + } + else + { + u32Freq = UNKNOWN_CLOCK; + } + + return u32Freq; +} + +static uint32_t SCG_CalculateSystemFreq(const SCG_ClkSrcType eScgClockName) +{ + uint32_t u32Freq, u32ClkFreq; + uint32_t u32Temp, u32DivCore, u32DivBus, u32DivSlow; + + u32Temp = (uint32_t)SCG_HWA_GetSysClkSrc(); + + if ((uint32_t)SCG_CLOCK_SRC_FOSC == u32Temp) + { + u32ClkFreq = FOSC_FREQUENCY; + } + else if ((uint32_t)SCG_CLOCK_SRC_FIRC == u32Temp) + { + u32ClkFreq = FIRC_CLOCK; + } + else if ((uint32_t)SCG_CLOCK_SRC_PLL0 == u32Temp) + { + u32ClkFreq = SCG_CalculatePll0Freq(SCG_PLL0_CLK); + } + else if ((uint32_t)SCG_CLOCK_SRC_SIRC == u32Temp) + { + u32ClkFreq = SCG_CalculateSircFreq(SCG_SIRC_CLK); + } + else + { + u32ClkFreq = UNKNOWN_CLOCK; + } + + u32DivCore = (uint32_t)(SCG_HWA_GetSysClkDivCore() + 1U); + u32DivBus = (uint32_t)(SCG_HWA_GetSysClkDivBus() + 1U); + u32DivSlow = (uint32_t)(SCG_HWA_GetSysClkDivSlow() + 1U); + + u32ClkFreq = (uint32_t)(u32ClkFreq / u32DivCore); + + if (SCG_CORE_CLK == eScgClockName) + { + u32Freq = u32ClkFreq; + } + else if (SCG_BUS_CLK == eScgClockName) + { + u32Freq = (uint32_t)(u32ClkFreq / u32DivBus); + } + else + { + /* (SCG_SLOW_CLK == eScgClockName) */ + u32Freq = (uint32_t)((u32ClkFreq / u32DivBus) / u32DivSlow); + } + + return u32Freq; +} + +static uint32_t SCG_CalculateClkOutFreq(void) +{ + uint8_t u8ClockoutSrc; + uint32_t u32Freq; + /* check clock out configuration */ + u8ClockoutSrc = SCG_HWA_GetClkOutSel(); + + if ((uint8_t)SCG_CLOCKOUT_SRC_OFF == u8ClockoutSrc) + { + u32Freq = 0U; + } + else if ((uint8_t)SCG_CLOCKOUT_SRC_FOSC == u8ClockoutSrc) + { + u32Freq = FOSC_FREQUENCY; + } + else if ((uint8_t)SCG_CLOCKOUT_SRC_SIRC == u8ClockoutSrc) + { + u32Freq = SCG_CalculateSircFreq(SCG_SIRC_CLK); + } + else if ((uint8_t)SCG_CLOCKOUT_SRC_FIRC == u8ClockoutSrc) + { + u32Freq = SCG_CalculateFircFreq(SCG_FIRC_CLK); + } + else if ((uint8_t)SCG_CLOCKOUT_SRC_SOSC == u8ClockoutSrc) + { + u32Freq = SOSC_FREQUENCY; + } + else if ((uint8_t)SCG_CLOCKOUT_SRC_PLL1 == u8ClockoutSrc) + { + u32Freq = SCG_CalculatePll1Freq(SCG_PLL1_CLK); + } + else if ((uint8_t)SCG_CLOCKOUT_SRC_PLL0 == u8ClockoutSrc) + { + u32Freq = SCG_CalculatePll0Freq(SCG_PLL0_CLK); + } + else if ((uint8_t)SCG_CLOCKOUT_SRC_SIRC32K == u8ClockoutSrc) + { + u32Freq = SIRC32K_CLOCK; + } + else + { + u32Freq = UNKNOWN_CLOCK; + } + + return u32Freq; +} + +static uint32_t SCG_CalculateCMU4RefFreq(void) +{ + uint32_t u32Freq,u32Temp; + + u32Temp = SCG_HWA_GetClkOutCfg(); + + if((u32Temp & SCG_CLKOUTCFG_CMU4CLK_FOSC_MASK) != 0U) + { + u32Freq = FOSC_FREQUENCY; + } + else if((u32Temp & SCG_CLKOUTCFG_CMU4CLK_SIRC_MASK) != 0U) + { + u32Freq = SIRC_CLOCK; + } + else + { + u32Freq = UNKNOWN_CLOCK; + } + + return u32Freq; +} + +static SCG_StatusType SCG_EnablePLL0(const SCG_PllType *const pPllConfig) +{ + SCG_StatusType eStatusVal = SCG_STATUS_SUCCESS; + uint32_t u32TempVal; + uint32_t u32Freq; + uint32_t u32FeedBackFreq,u32VcoFreq; + uint32_t u32DivHClockFreq = 0u; + uint32_t u32DivMClockFreq = 0u; + uint32_t u32DivLClockFreq = 0u; + uint32_t u32Pll0DivEn = 0u; + + /* check pll is valid, if valid, do not configure PLL */ + if (true == SCG_HWA_GetClockVliad(SCG_PLL0_CLOCK_SYMBOL)) + { + eStatusVal = SCG_STATUS_SEQUENCE_ERROR; + } + else + { + /* PLL input is FOSC or FIRC clock/2 */ + u32Freq = (SCG_PLLSOURCE_FOSC == pPllConfig->eSrc) ? (FOSC_FREQUENCY) : (FIRC_CLOCK / 2U); + + /* Check the PLL feedback clock range */ + u32FeedBackFreq = u32Freq / (pPllConfig->u8Prediv + 1U); + if(u32FeedBackFreq < PLL_FEEDBACK_CLK_MIN || u32FeedBackFreq > PLL_FEEDBACK_CLK_MAX) + { + eStatusVal = SCG_STATUS_PARAM_ERROR; + } + else + { + /* Check the PLL VCO clock range */ + u32VcoFreq = u32FeedBackFreq * (pPllConfig->u16Mult + 1U); + if((u32VcoFreq < PLL_VCO_CLK_MIN) || (u32VcoFreq > PLL_VCO_CLK_MAX)) + { + eStatusVal = SCG_STATUS_PARAM_ERROR; + } + else + { + /* Check the PLL out clock range */ + u32Freq = u32VcoFreq >> (uint32_t)pPllConfig->ePstDiv; + if (u32Freq > PLL0_CLK_MAX) + { + eStatusVal = SCG_STATUS_PARAM_ERROR; + } + } + } + + /* Check DIV clock frequency is valid or not */ + if (eStatusVal == SCG_STATUS_SUCCESS) + { + if(pPllConfig->eDivH != SCG_ASYNC_CLOCK_DISABLE) + { + u32DivHClockFreq = (uint32_t)(u32Freq >> ((uint32_t)pPllConfig->eDivH - 1u)); + u32Pll0DivEn |= (uint32_t)SCG_CLOCK_DIV_H; + } + if(pPllConfig->eDivM != SCG_ASYNC_CLOCK_DISABLE) + { + u32DivMClockFreq = (uint32_t)(u32Freq >> ((uint32_t)pPllConfig->eDivM - 1u)); + u32Pll0DivEn |= (uint32_t)SCG_CLOCK_DIV_M; + } + if(pPllConfig->eDivL != SCG_ASYNC_CLOCK_DISABLE) + { + u32DivLClockFreq = (uint32_t)(u32Freq >> ((uint32_t)pPllConfig->eDivL - 1u)); + u32Pll0DivEn |= (uint32_t)SCG_CLOCK_DIV_L; + } + if ((u32DivHClockFreq > PLL0_DIVH_MAX_CLOCK) || (u32DivMClockFreq > PLL0_DIVM_MAX_CLOCK) || (u32DivLClockFreq > PLL0_DIVL_MAX_CLOCK)) + { + eStatusVal = SCG_STATUS_PARAM_ERROR; + } + } + } + + if (eStatusVal == SCG_STATUS_SUCCESS) + { + /* unlock PLL CSR register */ + SCG_HWA_UnlockPllCsr(SCG_PLL0_CLOCK_SYMBOL); + + /* Configure PLLCFG register */ + u32TempVal = SCG_PLLCFG_PREDIV(pPllConfig->u8Prediv) | SCG_PLLCFG_MULT(pPllConfig->u16Mult) | SCG_PLLCFG_PSTDIV( + pPllConfig->ePstDiv) | SCG_PLLCFG_SOURCE(pPllConfig->eSrc) ; + SCG_HWA_SetPllCfg(SCG_PLL0_CLOCK_SYMBOL, u32TempVal); + + /* Configure PLLCSR register */ + u32TempVal = SCG_PLLCSR_STEN(pPllConfig->bSten); + SCG_HWA_SetPllCsr(SCG_PLL0_CLOCK_SYMBOL, u32TempVal); + + /* Configure PLLDIV */ + SCG_HWA_DiablePll0Div(SCG_CLOCK_DIV_ALL); + u32TempVal = SCG_HWA_GetClockDiv(SCG_PLL0_CLOCK_SYMBOL); + u32TempVal &= ~(uint32_t)(SCG_PLLDIV_DIVL_MASK | SCG_PLLDIV_DIVM_MASK | SCG_PLLDIV_DIVH_MASK); + u32TempVal |= (SCG_PLLDIV_DIVH(pPllConfig->eDivH) | SCG_PLLDIV_DIVM(pPllConfig->eDivM) | SCG_PLLDIV_DIVL( + pPllConfig->eDivL)); + SCG_HWA_SetPllDiv(SCG_PLL0_CLOCK_SYMBOL, u32TempVal) ; + + /* Set CSR[EN] bit to 1 */ + SCG_HWA_EnablePll(SCG_PLL0_CLOCK_SYMBOL); + + /* Wait PLL valid */ + u32TempVal = PLL_STABILIZATION_TIMEOUT; + SCG_CheckClockAckStatus((false == SCG_HWA_GetClockVliad(SCG_PLL0_CLOCK_SYMBOL)), u32TempVal, eStatusVal) + + if (eStatusVal == SCG_STATUS_SUCCESS) + { + /* Enable PLLDIV */ + SCG_HWA_EnablePll0Div((SCG_DivEnableType)u32Pll0DivEn); + + if (pPllConfig->bCm) + { + SCG_HWA_EnablePllClockMonitor(SCG_PLL0_CLOCK_SYMBOL); + } + + if (pPllConfig->bCmre) + { + SCG_HWA_EnablePllClockMonitorReset(SCG_PLL0_CLOCK_SYMBOL); + } + + if (pPllConfig->bLock) + { + /* lock CSR register */ + SCG_HWA_LockPllCsr(SCG_PLL0_CLOCK_SYMBOL); + } + + /* Wait DIV[ACK] change to 1 */ + u32TempVal = CLOCK_DIV_STABILIZATION_TIMEOUT; + SCG_CheckClockAckStatus((SCG_HWA_GetPll0DivAck((SCG_DivEnableType)u32Pll0DivEn) != true), u32TempVal, eStatusVal) + } + else + { + /* Clear CFG configuration */ + SCG_HWA_SetPllCfg(SCG_PLL0_CLOCK_SYMBOL, 0U); + + /* Clear CSR configuration */ + SCG_HWA_SetPllCsr(SCG_PLL0_CLOCK_SYMBOL, 0U); + + /* Clear DIV configuration*/ + SCG_HWA_SetPllDiv(SCG_PLL0_CLOCK_SYMBOL, 0U); + } + + } + + return eStatusVal; +} + +static SCG_StatusType SCG_EnablePLL1(const SCG_PllType *const pPllConfig) +{ + SCG_StatusType eStatusVal = SCG_STATUS_SUCCESS; + uint32_t u32TempVal; + uint32_t u32Freq; + uint32_t u32FeedBackFreq,u32VcoFreq; + uint32_t u32DivHClockFreq = 0u; + uint32_t u32DivMClockFreq = 0u; + uint32_t u32DivLClockFreq = 0u; + uint32_t u32Pll1DivEn = 0u; + + /* check pll is valid, if valid, do not configure PLL */ + if (true == SCG_HWA_GetClockVliad(SCG_PLL1_CLOCK_SYMBOL)) + { + eStatusVal = SCG_STATUS_SEQUENCE_ERROR; + } + else + { + /* PLL input is FOSC or FIRC clock/2 */ + u32Freq = (SCG_PLLSOURCE_FOSC == pPllConfig->eSrc) ? (FOSC_FREQUENCY) : (FIRC_CLOCK / 2U); + + /* Check the PLL feedback clock range */ + u32FeedBackFreq = u32Freq / (pPllConfig->u8Prediv + 1U); + if(u32FeedBackFreq < PLL_FEEDBACK_CLK_MIN || u32FeedBackFreq > PLL_FEEDBACK_CLK_MAX) + { + eStatusVal = SCG_STATUS_PARAM_ERROR; + } + else + { + /* Check the PLL VCO clock range */ + u32VcoFreq = u32FeedBackFreq * (pPllConfig->u16Mult + 1U); + if((u32VcoFreq < PLL_VCO_CLK_MIN) || (u32VcoFreq > PLL_VCO_CLK_MAX)) + { + eStatusVal = SCG_STATUS_PARAM_ERROR; + } + else + { + /* Check the PLL out clock range */ + u32Freq = u32VcoFreq >> (uint32_t)pPllConfig->ePstDiv; + if (u32Freq > PLL1_CLK_MAX) + { + eStatusVal = SCG_STATUS_PARAM_ERROR; + } + } + } + + /* Check DIV clock frequency is valid or not */ + if (eStatusVal == SCG_STATUS_SUCCESS) + { + if(pPllConfig->eDivH != SCG_ASYNC_CLOCK_DISABLE) + { + u32DivHClockFreq = (uint32_t)(u32Freq >> ((uint32_t)pPllConfig->eDivH - 1u)); + u32Pll1DivEn |= (uint32_t)SCG_CLOCK_DIV_H; + } + if(pPllConfig->eDivM != SCG_ASYNC_CLOCK_DISABLE) + { + u32DivMClockFreq = (uint32_t)(u32Freq >> ((uint32_t)pPllConfig->eDivM - 1u)); + u32Pll1DivEn |= (uint32_t)SCG_CLOCK_DIV_M; + } + if(pPllConfig->eDivL != SCG_ASYNC_CLOCK_DISABLE) + { + u32DivLClockFreq = (uint32_t)(u32Freq >> ((uint32_t)pPllConfig->eDivL - 1u)); + u32Pll1DivEn |= (uint32_t)SCG_CLOCK_DIV_L; + } + if ((u32DivHClockFreq > PLL1_DIVH_MAX_CLOCK) || (u32DivMClockFreq > PLL1_DIVM_MAX_CLOCK) || (u32DivLClockFreq > PLL1_DIVL_MAX_CLOCK)) + { + eStatusVal = SCG_STATUS_PARAM_ERROR; + } + } + } + + if (eStatusVal == SCG_STATUS_SUCCESS) + { + /* unlock PLL CSR register */ + SCG_HWA_UnlockPllCsr(SCG_PLL1_CLOCK_SYMBOL); + + /* Configure PLLCFG register */ + u32TempVal = SCG_PLLCFG_PREDIV(pPllConfig->u8Prediv) | SCG_PLLCFG_MULT(pPllConfig->u16Mult) | SCG_PLLCFG_PSTDIV( + pPllConfig->ePstDiv) | SCG_PLLCFG_SOURCE(pPllConfig->eSrc) ; + SCG_HWA_SetPllCfg(SCG_PLL1_CLOCK_SYMBOL, u32TempVal); + + /* Configure PLLCSR register */ + u32TempVal = SCG_PLLCSR_STEN(pPllConfig->bSten); + SCG_HWA_SetPllCsr(SCG_PLL1_CLOCK_SYMBOL, u32TempVal); + + /* Configure PLLDIV */ + SCG_HWA_DiablePll1Div(SCG_CLOCK_DIV_ALL); + u32TempVal = SCG_HWA_GetClockDiv(SCG_PLL1_CLOCK_SYMBOL); + u32TempVal &= ~(uint32_t)(SCG_PLLDIV_DIVL_MASK | SCG_PLLDIV_DIVM_MASK | SCG_PLLDIV_DIVH_MASK); + u32TempVal |= (SCG_PLLDIV_DIVH(pPllConfig->eDivH) | SCG_PLLDIV_DIVM(pPllConfig->eDivM) | SCG_PLLDIV_DIVL( + pPllConfig->eDivL)); + SCG_HWA_SetPllDiv(SCG_PLL1_CLOCK_SYMBOL, u32TempVal) ; + + /* Set CSR[EN] bit to 1 */ + SCG_HWA_EnablePll(SCG_PLL1_CLOCK_SYMBOL); + + /* Wait PLL valid */ + u32TempVal = PLL_STABILIZATION_TIMEOUT; + SCG_CheckClockAckStatus((false == SCG_HWA_GetClockVliad(SCG_PLL1_CLOCK_SYMBOL)), u32TempVal, eStatusVal) + + if (eStatusVal == SCG_STATUS_SUCCESS) + { + /* Enable PLLDIV */ + SCG_HWA_EnablePll1Div((SCG_DivEnableType)u32Pll1DivEn); + + if (pPllConfig->bCm) + { + SCG_HWA_EnablePllClockMonitor(SCG_PLL1_CLOCK_SYMBOL); + } + + if (pPllConfig->bCmre) + { + SCG_HWA_EnablePllClockMonitorReset(SCG_PLL1_CLOCK_SYMBOL); + } + + if (pPllConfig->bLock) + { + /* lock CSR register */ + SCG_HWA_LockPllCsr(SCG_PLL1_CLOCK_SYMBOL); + } + + /* Wait DIV[ACK] change to 1 */ + u32TempVal = CLOCK_DIV_STABILIZATION_TIMEOUT; + SCG_CheckClockAckStatus((SCG_HWA_GetPll1DivAck((SCG_DivEnableType)u32Pll1DivEn) != true), u32TempVal, eStatusVal) + } + else + { + /* Clear CFG configuration */ + SCG_HWA_SetPllCfg(SCG_PLL1_CLOCK_SYMBOL, 0U); + + /* Clear CSR configuration */ + SCG_HWA_SetPllCsr(SCG_PLL1_CLOCK_SYMBOL, 0U); + + /* Clear DIV configuration*/ + SCG_HWA_SetPllDiv(SCG_PLL1_CLOCK_SYMBOL, 0U); + } + + } + + return eStatusVal; +} + +static SCG_StatusType SCG_DisablePLL0(void) +{ + SCG_StatusType eStatusVal = SCG_STATUS_SUCCESS; + uint32_t u32TempVal; + + /* unlock PLL CSR register */ + SCG_HWA_UnlockPllCsr(SCG_PLL0_CLOCK_SYMBOL); + + /* Clear CFG configuration */ + SCG_HWA_SetPllCfg(SCG_PLL0_CLOCK_SYMBOL, 0U); + + /* Clear CSR configuration */ + SCG_HWA_SetPllCsr(SCG_PLL0_CLOCK_SYMBOL, 0U); + + u32TempVal = CLOCK_OFF_STABILIZATION_TIMEOUT; + SCG_CheckClockAckStatus((true == SCG_HWA_GetClockVliad(SCG_PLL0_CLOCK_SYMBOL)), u32TempVal, eStatusVal) + + if (eStatusVal == SCG_STATUS_SUCCESS) + { + /* Clear CSR register */ + SCG_HWA_SetPllCsr(SCG_PLL0_CLOCK_SYMBOL, 0U); + + /* In order to avoid the DIV register value not cleared, Clear PLL DIV register twice */ + SCG_HWA_SetPllDiv(SCG_PLL0_CLOCK_SYMBOL, 0U); + SCG_HWA_SetPllDiv(SCG_PLL0_CLOCK_SYMBOL, 0U); + } + + + return eStatusVal; +} + +static SCG_StatusType SCG_DisablePLL1(void) +{ + SCG_StatusType eStatusVal = SCG_STATUS_SUCCESS; + uint32_t u32TempVal; + + /* unlock PLL CSR register */ + SCG_HWA_UnlockPllCsr(SCG_PLL1_CLOCK_SYMBOL); + + /* Clear CFG configuration */ + SCG_HWA_SetPllCfg(SCG_PLL1_CLOCK_SYMBOL, 0U); + + /* Clear CSR configuration */ + SCG_HWA_SetPllCsr(SCG_PLL1_CLOCK_SYMBOL, 0U); + + u32TempVal = CLOCK_OFF_STABILIZATION_TIMEOUT; + SCG_CheckClockAckStatus((true == SCG_HWA_GetClockVliad(SCG_PLL1_CLOCK_SYMBOL)), u32TempVal, eStatusVal) + + if (eStatusVal == SCG_STATUS_SUCCESS) + { + /* Clear CSR register */ + SCG_HWA_SetPllCsr(SCG_PLL1_CLOCK_SYMBOL, 0U); + + /* In order to avoid the DIV register value not cleared, Clear PLL DIV register twice */ + SCG_HWA_SetPllDiv(SCG_PLL1_CLOCK_SYMBOL, 0U); + SCG_HWA_SetPllDiv(SCG_PLL1_CLOCK_SYMBOL, 0U); + } + + return eStatusVal; +} + +/** + * @brief Check the system clock frequency + * @details This function check the system clock source valid and the system clock dividers valid, and get the frequency of eClock + * + * @param eClock selected clock source + * @param pSysClkConfig system clock configuration + * @param pClockFreq pointer to the memory to save clock source frequency + * @return SCG_StatusType function status + * + */ +static SCG_StatusType SCG_CheckSystemClockSourceFreq(const SCG_ClockSrcType eClock,const SCG_ClockCtrlType *const pSysClkConfig,uint32_t *pClockFreq) +{ + SCG_StatusType eStatusVal = SCG_STATUS_SUCCESS; + uint32_t u32Freq; + uint32_t u32FreqCore, u32FreqBus, u32FreqSlow; + bool eClockValid; + + if (SCG_CLOCK_SRC_FOSC == eClock) + { + eClockValid = SCG_HWA_GetClockVliad(SCG_FOSC_CLOCK_SYMBOL); + u32Freq = FOSC_FREQUENCY; + } + else if (SCG_CLOCK_SRC_FIRC == eClock) + { + eClockValid = SCG_HWA_GetClockVliad(SCG_FIRC_CLOCK_SYMBOL); + u32Freq = FIRC_CLOCK; + } + else if (SCG_CLOCK_SRC_PLL0 == eClock) + { + eClockValid = SCG_HWA_GetClockVliad(SCG_PLL0_CLOCK_SYMBOL); + u32Freq = SCG_CalculatePll0Freq(SCG_PLL0_CLK); + + } + else if (SCG_CLOCK_SRC_SIRC == eClock) + { + eClockValid = SCG_HWA_GetClockVliad(SCG_SIRC_CLOCK_SYMBOL); + u32Freq = SIRC_CLOCK; + } + else + { + eClockValid = false; + } + + if(eClockValid == false) + { + eStatusVal = SCG_STATUS_SEQUENCE_ERROR; + } + else + { + *pClockFreq = u32Freq; + + if(pSysClkConfig != NULL_PTR) + { + u32FreqCore = u32Freq / ((uint8_t)pSysClkConfig->eDivCore + 1U); + u32FreqBus = u32FreqCore / ((uint8_t)pSysClkConfig->eDivBus + 1U); + u32FreqSlow = u32FreqBus / ((uint8_t)pSysClkConfig->eDivSlow + 1U); + if ((u32FreqCore > SYS_CORE_CLK_MAX) || (u32FreqBus > SYS_BUS_CLK_MAX) || (u32FreqSlow > SYS_SLOW_CLK_MAX)) + { + eStatusVal = SCG_STATUS_PARAM_ERROR; + } + } + } + return eStatusVal; +} + +/** + * @brief Switch system clock source , and configure system clock divider if pSysClkConfig is not null. + * @details If pSysClkConfig is null , and clock switch form slow to fast(eg. FIRC to PLL0), + * the bus and slow clock may exceed the max value. So the new divider must be configured + * if the system clock is switched to a faster source. + * + * @param eClock selected clock source + * @return SCG_StatusType function status + * SCG_STATUS_SUCCESS : clock source and dividers are valid,and switch system clock successfully + * SCG_STATUS_SEQUENCE_ERROR: new clock source is not enabled + * SCG_STATUS_PARAM_ERROR: the core bus slow divider are invalid + * SCG_STATUS_TIMEOUT: switch system clock procedure time out + */ +static SCG_StatusType SCG_SwitchSystemClockWithConfig(const SCG_ClockSrcType eClock,const SCG_ClockCtrlType *const pSysClkConfig) +{ + SCG_StatusType eStatusVal = SCG_STATUS_SUCCESS; + uint32_t u32Timeout; + uint32_t u32CurClkFreq = 0U,u32NewClkFreq; + uint32_t u32RegValue; + uint8_t u8CurClkSrc,u8ClkSrc; + + u8CurClkSrc = SCG_HWA_GetSysClkSrc(); + if(u8CurClkSrc != eClock) + { + eStatusVal = SCG_CheckSystemClockSourceFreq(eClock,pSysClkConfig,&u32NewClkFreq); + + if(eStatusVal == SCG_STATUS_SUCCESS) + { + /* Get current system clock source frequency */ + if (SCG_CLOCK_SRC_FOSC == u8CurClkSrc) + { + u32CurClkFreq = FOSC_FREQUENCY; + } + else if (SCG_CLOCK_SRC_FIRC == u8CurClkSrc) + { + u32CurClkFreq = FIRC_CLOCK; + } + else if (SCG_CLOCK_SRC_PLL0 == u8CurClkSrc) + { + u32CurClkFreq = SCG_CalculatePll0Freq(SCG_PLL0_CLK); + } + else if (SCG_CLOCK_SRC_SIRC == u8CurClkSrc) + { + u32CurClkFreq = SIRC_CLOCK; + } + else + { + /* Never come here */ + } + + /* To switch the system clock source from slow to fast, configure the divider first to ensure that + the core bus slow clocks do not exceed the max value */ + if((pSysClkConfig != NULL_PTR) && (u32NewClkFreq > u32CurClkFreq)) + { + u32RegValue = SCG_HWA_GetCCR(); + u32RegValue &= ~(SCG_CCR_SYSCLK_CME_MASK | SCG_CCR_DIVCORE_MASK | SCG_CCR_DIVBUS_MASK | SCG_CCR_DIVSLOW_MASK); + u32RegValue |= (uint32_t)((uint32_t)SCG_CCR_SYSCLK_CME(pSysClkConfig->bSysClkMonitor) | + (uint32_t)SCG_CCR_DIVCORE(pSysClkConfig->eDivCore) | + (uint32_t)SCG_CCR_DIVBUS(pSysClkConfig->eDivBus) | + (uint32_t)SCG_CCR_DIVSLOW(pSysClkConfig->eDivSlow)); + SCG_HWA_SetCCR(u32RegValue); + } + + SCG_HWA_SetSystemClock((uint8_t)eClock); + + u32Timeout = SCG_CLKSRC_STABILIZATION_TIMEOUT; + do { + u8ClkSrc = SCG_HWA_GetSysClkSrc(); + --u32Timeout; + if(u32Timeout == 0U) + { + eStatusVal = SCG_STATUS_TIMEOUT; + break; + } + } while((SCG_HWA_GetSysClkUPRD() == false) && (u8ClkSrc != (uint8_t)eClock)); + + if (eStatusVal == SCG_STATUS_SUCCESS) + { + /* To change the system clock source from fast to slow, configure the divider after selecting the clock source, + because it is safe to divide the slow frequency with the old divider */ + if((pSysClkConfig != NULL_PTR) && (u32NewClkFreq <= u32CurClkFreq)) + { + u32RegValue = SCG_HWA_GetCCR(); + u32RegValue &= ~(SCG_CCR_SYSCLK_CME_MASK | SCG_CCR_DIVCORE_MASK | SCG_CCR_DIVBUS_MASK | SCG_CCR_DIVSLOW_MASK); + u32RegValue |= (uint32_t)((uint32_t)SCG_CCR_SYSCLK_CME(pSysClkConfig->bSysClkMonitor) | + (uint32_t)SCG_CCR_DIVCORE(pSysClkConfig->eDivCore) | + (uint32_t)SCG_CCR_DIVBUS(pSysClkConfig->eDivBus) | + (uint32_t)SCG_CCR_DIVSLOW(pSysClkConfig->eDivSlow)); + SCG_HWA_SetCCR(u32RegValue); + + u32Timeout = SCG_CLKSRC_STABILIZATION_TIMEOUT; + while(SCG_HWA_GetSysClkUPRD() == false) + { + --u32Timeout; + if(u32Timeout == 0U) + { + eStatusVal = SCG_STATUS_TIMEOUT; + break; + } + } + } + } + + } + + } + return eStatusVal; +} + +/***************** Global Functions *********************/ +/** + * @brief Enable SOSC + * + * @param pSoscConfig SOSC configuration + * @return SCG_StatusType Function status + */ +SCG_StatusType SCG_EnableSOSC(const SCG_SoscType *const pSoscConfig) +{ + SCG_StatusType eStatusVal = SCG_STATUS_SUCCESS; + uint32_t u32TempVal; + + DEV_ASSERT(NULL_PTR != pSoscConfig); + DEV_ASSERT(32768U == SOSC_FREQUENCY); + + /* Configure SOSC */ + SCG_HWA_SetSoscRecommendCfg(); + + /* Unlock CSR register first */ + SCG_HWA_UnlockSoscCsrReg(); + + /* Configure SOSC CSR register */ + u32TempVal = SCG_HWA_GetSoscCsr(); + u32TempVal &= ~(uint32_t)(SCG_SOSCCSR_BYPASS_MASK | SCG_SOSCCSR_CM_MASK | SCG_SOSCCSR_CMRE_MASK); + u32TempVal |= SCG_SOSCCSR_BYPASS(pSoscConfig->bBypass); + SCG_HWA_SetSoscCsr(u32TempVal); + + /* Enable SOSC*/ + SCG_HWA_EnableSosc(); + + /* Wait SOSC valid */ + u32TempVal = SOSC_STABILIZATION_TIMEOUT; + SCG_CheckClockAckStatus((false == SCG_HWA_GetClockVliad(SCG_SOSC_CLOCK_SYMBOL)), u32TempVal, eStatusVal) + + if (eStatusVal == SCG_STATUS_SUCCESS) + { + if (pSoscConfig->bCm) + { + SCG_HWA_EnableSoscClockMonitor(); + } + + if (pSoscConfig->bCmre) + { + SCG_HWA_EnableSoscClockMonitorReset(); + } + + if (pSoscConfig->bLock) + { + /* Lock CSR */ + SCG_HWA_LockSoscCsrReg(); + } + } + else + { + SCG_HWA_SetSoscCsr(0U); + } + + return eStatusVal; +} + +/** + * @brief Disable SOSC + * + * @return SCG_StatusType Function status + */ +SCG_StatusType SCG_DisableSOSC(void) +{ + SCG_StatusType eStatusVal; + uint32_t u32TempVal; + + /* Unlock CSR register first */ + SCG_HWA_UnlockSoscCsrReg(); + + /* Disable SOSC */ + SCG_HWA_DisableSosc(); + + /* Wait SOSC valid */ + u32TempVal = SOSC_STABILIZATION_TIMEOUT; + SCG_CheckClockAckStatus((true == SCG_HWA_GetClockVliad(SCG_SOSC_CLOCK_SYMBOL)), u32TempVal, eStatusVal) + + if (eStatusVal == SCG_STATUS_SUCCESS) + { + /* Clear CSR register */ + SCG_HWA_SetSoscCsr(0U); + } + + return eStatusVal; +} + +/** + * @brief Enable FOSC clock with input configuration + * + * @param pFoscConfig FOSC configuration + * @return SCG_StatusType function status + */ +SCG_StatusType SCG_EnableFOSC(const SCG_FoscType *const pFoscConfig) +{ + SCG_StatusType eStatusVal = SCG_STATUS_SUCCESS; + uint32_t u32TempVal,u32FoscFreq; + uint8_t u8MSBVal; + uint32_t u32DivHClockFreq = 0U; + uint32_t u32DivMClockFreq = 0U; + uint32_t u32DivLClockFreq = 0U; + uint32_t u32FoscDivEn = 0U; + + DEV_ASSERT(NULL_PTR != pFoscConfig); + + /* Check DIV clock frequency is valid or not */ + if(pFoscConfig->eDivH != SCG_ASYNC_CLOCK_DISABLE) + { + u32DivHClockFreq = (uint32_t)FOSC_FREQUENCY >> ((uint32_t)pFoscConfig->eDivH - 1U); + u32FoscDivEn |= (uint32_t)SCG_CLOCK_DIV_H; + } + if(pFoscConfig->eDivM != SCG_ASYNC_CLOCK_DISABLE) + { + u32DivMClockFreq = (uint32_t)FOSC_FREQUENCY >> ((uint32_t)pFoscConfig->eDivM - 1U); + u32FoscDivEn |= (uint32_t)SCG_CLOCK_DIV_M; + } + if(pFoscConfig->eDivL != SCG_ASYNC_CLOCK_DISABLE) + { + u32DivLClockFreq = (uint32_t)FOSC_FREQUENCY >> ((uint32_t)pFoscConfig->eDivL - 1U); + u32FoscDivEn |= (uint32_t)SCG_CLOCK_DIV_L; + } + + if ((u32DivHClockFreq > FOSC_DIVH_MAX_CLOCK) || (u32DivMClockFreq > FOSC_DIVM_MAX_CLOCK) || (u32DivLClockFreq > FOSC_DIVL_MAX_CLOCK)) + { + eStatusVal = SCG_STATUS_PARAM_ERROR; + } + + if (eStatusVal == SCG_STATUS_SUCCESS) + { + /* Unlock CSR register */ + SCG_HWA_UnlockFoscCsrReg(); + + /* COMP_EN is setting to 1 COMP_EN must be 1 when using an external crystal */ + /* Configure GM to the max value, GM_SEL: 15U */ + u32TempVal = SCG_FOSCCFG_BYPASS(pFoscConfig->bBypass) | SCG_FOSCCFG_COMP_EN(!pFoscConfig->bBypass) | + SCG_FOSCCFG_EOCV(50U) | SCG_FOSCCFG_GM_SEL(15U) | + SCG_FOSCCFG_ALC_D(1U) | SCG_FOSCCFG_HYST_D(0U); + SCG_HWA_SetFoscCfg(u32TempVal); + + /* Configure CSR register */ + u32TempVal = SCG_HWA_GetFoscCsr(); + u32TempVal &= ~(uint32_t)(SCG_FOSCCSR_STEN_MASK | SCG_FOSCCSR_CM_MASK | SCG_FOSCCSR_CMRE_MASK); + u32TempVal |= SCG_FOSCCSR_STEN(pFoscConfig->bSten); + SCG_HWA_SetFoscCsr(u32TempVal); + + /* Configure DIV value */ + SCG_HWA_DiableFoscDiv(SCG_CLOCK_DIV_ALL); + u32TempVal = SCG_HWA_GetClockDiv(SCG_FOSC_CLOCK_SYMBOL); + u32TempVal &= ~(uint32_t)(SCG_FOSCDIV_DIVL_MASK | SCG_FOSCDIV_DIVM_MASK | SCG_FOSCDIV_DIVH_MASK); + u32TempVal |= (SCG_FOSCDIV_DIVH(pFoscConfig->eDivH) | SCG_FOSCDIV_DIVM(pFoscConfig->eDivM) | SCG_FOSCDIV_DIVL( + pFoscConfig->eDivL)); + SCG_HWA_SetFoscDiv(u32TempVal) ; + + /* Enable FOSC */ + SCG_HWA_EnableFosc(); + + /* Wait FOSC vaild */ + u32TempVal = FOSC_STABILIZATION_TIMEOUT; + SCG_CheckClockAckStatus((false == SCG_HWA_GetClockVliad(SCG_FOSC_CLOCK_SYMBOL)), u32TempVal, eStatusVal) + + if (eStatusVal == SCG_STATUS_SUCCESS) + { + /* Enable DIV */ + SCG_HWA_EnableFoscDiv((SCG_DivEnableType)u32FoscDivEn); + + if (pFoscConfig->bCm) + { + SCG_HWA_EnableFoscClockMonitor(); + } + + if (pFoscConfig->bCmre) + { + SCG_HWA_EnableFoscClockMonitorReset(); + } + + if (pFoscConfig->bLock) + { + /* Lock FOSC CSR register */ + SCG_HWA_LockFoscCsrReg(); + } + + /* Wait DIV[ACK] change to 1 */ + u32TempVal = CLOCK_DIV_STABILIZATION_TIMEOUT; + SCG_CheckClockAckStatus((SCG_HWA_GetFoscDivAck((SCG_DivEnableType)u32FoscDivEn) != true), u32TempVal, eStatusVal) + + /* if OSC >= 40M ,set 5, if OSC = 32M,set 10, if OSC = 24M, set 15, if OSC = 16M, set 20, if OSC = 8M, set 25*/ + /* This is the protection measure during low power wake up, if SCG register not valid after the setting time, the chip will reset + * and will set clock error flag in RGM register */ + u32FoscFreq = FOSC_FREQUENCY; + u8MSBVal = ((u32FoscFreq / 8000000U) >= 5U) ? (uint8_t)5U : (uint8_t)((6U - (FOSC_FREQUENCY / 8000000U)) * 5U); + SCG_HWA_SetWKPWDG(u8MSBVal); + } + else + { + /* Clear CSR configuration */ + SCG_HWA_SetFoscCsr(0U); + + /* Clear CFG configuration*/ + SCG_HWA_SetFoscCfg(0U); + + /* Clear DIV configuration*/ + SCG_HWA_SetFoscDiv(0U); + } + } + return eStatusVal; +} + +/** + * @brief Disable FOSC + * + * @return SCG_StatusType function status + */ +SCG_StatusType SCG_DisableFOSC(void) +{ + SCG_StatusType eStatusVal = SCG_STATUS_SUCCESS; + uint32_t u32TempVal; + uint8_t u8ClkSrc; + + u8ClkSrc = SCG_HWA_GetSysClkSrc(); + if ((uint8_t)SCG_CLOCK_SRC_FOSC == u8ClkSrc) + { + eStatusVal = SCG_STATUS_SEQUENCE_ERROR; + } + else if ((SCG_HWA_GetPllSrc(SCG_PLL0_CLOCK_SYMBOL) == (uint8_t)SCG_PLLSOURCE_FOSC) && ((uint8_t)SCG_CLOCK_SRC_PLL0 == u8ClkSrc)) + { + eStatusVal = SCG_STATUS_SEQUENCE_ERROR; + } + else + { + /* do nothing */ + } + + if (eStatusVal == SCG_STATUS_SUCCESS) + { + /* Unlock CSR register */ + SCG_HWA_UnlockFoscCsrReg(); + + /* Clear FOSC[EN] bit */ + SCG_HWA_DisableFosc(); + + u32TempVal = CLOCK_OFF_STABILIZATION_TIMEOUT; + SCG_CheckClockAckStatus((true == SCG_HWA_GetClockVliad(SCG_FOSC_CLOCK_SYMBOL)), u32TempVal, eStatusVal) + + if (eStatusVal == SCG_STATUS_SUCCESS) + { + /* Clear CSR register */ + SCG_HWA_SetFoscCsr(0U); + + /* In order to avoid the DIV register value not cleared, Clear FOSC DIV register twice */ + SCG_HWA_SetFoscDiv(0U); + SCG_HWA_SetFoscDiv(0U); + } + } + + return eStatusVal; +} + +/** + * @brief Set SIRC configuration and configure SIRC DIV + * + * @param pSircConfig SIRC configuration + * @return SCG_StatusType function status + */ +SCG_StatusType SCG_SetSIRC(const SCG_SircType *const pSircConfig) +{ + SCG_StatusType eStatusVal = SCG_STATUS_SUCCESS; + uint32_t u32TempVal; + uint32_t u32SircDivEn = 0U; + uint16_t u16TrimDiv = 0U; + + DEV_ASSERT(NULL_PTR != pSircConfig); + DEV_ASSERT(pSircConfig->eDivH <= (uint32_t)SCG_ASYNCCLOCKDIV_BY64); + DEV_ASSERT(pSircConfig->eDivM <= (uint32_t)SCG_ASYNCCLOCKDIV_BY64); + DEV_ASSERT(pSircConfig->eDivL <= (uint32_t)SCG_ASYNCCLOCKDIV_BY64); + + /* Unlock SIRC CSR register */ + SCG_HWA_UnlockSircCsrReg(); + + /* Configure CSR register */ + u32TempVal = SCG_HWA_GetSircCsr(); + u32TempVal &= ~(uint32_t)(SCG_SIRCCSR_STEN_MASK | SCG_SIRCCSR_LPEN_MASK | SCG_SIRCCSR_TREN_MASK | SCG_SIRCCSR_TRUP_MASK | SCG_SIRCCSR_CM_MASK); + u32TempVal |= (uint32_t)(SCG_SIRCCSR_TRUP(pSircConfig->bTrEn) | SCG_SIRCCSR_TREN(pSircConfig->bTrEn) | SCG_SIRCCSR_LPEN(pSircConfig->bLpen) | SCG_SIRCCSR_STEN(pSircConfig->bSten)); + SCG_HWA_SetSircCsr(u32TempVal); + + /* Disable SIRC DIV[EN] bit */ + SCG_HWA_DiableSircDiv(SCG_CLOCK_DIV_ALL); + + if (pSircConfig->bCm) + { + SCG_HWA_EnableSircClockMonitor(); + } + + if (pSircConfig->bLock) + { + /* lock CSR */ + SCG_HWA_LockSircCsrReg(); + } + + /* Configure SIRC DIV */ + u32TempVal = SCG_HWA_GetClockDiv(SCG_SIRC_CLOCK_SYMBOL); + u32TempVal &= ~(uint32_t)(SCG_SIRCDIV_DIVL_MASK | SCG_SIRCDIV_DIVM_MASK | SCG_SIRCDIV_DIVH_MASK); + u32TempVal |= (uint32_t)(SCG_SIRCDIV_DIVL(pSircConfig->eDivL) | SCG_SIRCDIV_DIVM(pSircConfig->eDivM) | SCG_SIRCDIV_DIVH( + pSircConfig->eDivH)); + SCG_HWA_SetSircDiv(u32TempVal); + + /* Enable SIRC DIV */ + u32SircDivEn |= (pSircConfig->eDivH != SCG_ASYNC_CLOCK_DISABLE) ? (uint32_t)SCG_CLOCK_DIV_H : 0U; + u32SircDivEn |= (pSircConfig->eDivM != SCG_ASYNC_CLOCK_DISABLE) ? (uint32_t)SCG_CLOCK_DIV_M : 0U; + u32SircDivEn |= (pSircConfig->eDivL != SCG_ASYNC_CLOCK_DISABLE) ? (uint32_t)SCG_CLOCK_DIV_L : 0U; + SCG_HWA_EnableSircDiv((SCG_DivEnableType)u32SircDivEn); + u32TempVal = CLOCK_DIV_STABILIZATION_TIMEOUT; + SCG_CheckClockAckStatus((SCG_HWA_GetSircDivAck((SCG_DivEnableType)u32SircDivEn) != true), u32TempVal, eStatusVal) + + if (SCG_STATUS_SUCCESS != eStatusVal) + { + /* Clear SIRC DIV register */ + SCG_HWA_SetSircDiv(0U); + } + + /* Set SIRCTCFG register */ + if (pSircConfig->bTrEn == true) + { + /* set SIRCTCFG trim configuration */ + if (pSircConfig->u8TrimSrc == (uint8_t)SCG_IRC_TRIMSRC_FOSC) + { + /* Trim clock source choose FOSC */ + u16TrimDiv = (uint16_t)(FOSC_FREQUENCY / 250000U - 1U); + } + else if (pSircConfig->u8TrimSrc == (uint8_t)SCG_IRC_TRIMSRC_SOSC) + { + /* Trim clock source choose SOSC */ + u16TrimDiv = 0U; + } + else + { + /* Do nothing */ + } + u32TempVal = (uint32_t)(SCG_SIRCTCFG_TRIMSRC(pSircConfig->u8TrimSrc) | SCG_SIRCTCFG_TRIMDIV(u16TrimDiv)); + SCG_HWA_SetSircTcfg(u32TempVal); + } + + return eStatusVal; +} + +/** + * @brief Disable SIRC DIV and clear DIV configuration + * + * @return SCG_StatusType function status + */ +SCG_StatusType SCG_ClearSIRC(void) +{ + SCG_StatusType eStatusVal = SCG_STATUS_SUCCESS; + + /* check SIRC is invalid, if invalid, do not configure SIRC */ + if (true != SCG_HWA_GetClockVliad(SCG_SIRC_CLOCK_SYMBOL)) + { + eStatusVal = SCG_STATUS_SEQUENCE_ERROR; + } + + if (eStatusVal == SCG_STATUS_SUCCESS) + { + /* Unlock SIRC CSR register */ + SCG_HWA_UnlockSircCsrReg(); + + /* Disable SIRC DIV[EN] bit */ + SCG_HWA_DiableSircDiv(SCG_CLOCK_DIV_ALL); + + /* Clear SIRC DIV register */ + SCG_HWA_SetSircDiv(0U); + } + + return eStatusVal; +} + +/** + * @brief Enable SIRC32K + * + * @param pSirc32kConfig SIRC32K configuration + * @return SCG_StatusType function status + */ +SCG_StatusType SCG_EnableSIRC32K(const SCG_Sirc32kType *const pSirc32kConfig) +{ + SCG_StatusType eStatusVal = SCG_STATUS_SUCCESS; + uint32_t u32TempVal; + + DEV_ASSERT(NULL_PTR != pSirc32kConfig); + + /* Unlock SIRC32K CSR register */ + SCG_HWA_UnlockSirc32kCsrReg(); + + /* Enable SIRC32K */ + SCG_HWA_EnableSirc32kCsr(); + + /* Wait SIRC32K valid */ + u32TempVal = SIRC_STABILIZATION_TIMEOUT; + SCG_CheckClockAckStatus((false == SCG_HWA_GetClockVliad(SCG_SIRC32K_CLOCK_SYMBOL)), u32TempVal, eStatusVal) + + if (eStatusVal == SCG_STATUS_SUCCESS) + { + if (pSirc32kConfig->bLock) + { + /* Lock SIRC32K CSR register */ + SCG_HWA_LockSirc32kCsrReg(); + } + } + + return eStatusVal; +} + +/** + * @brief Disable SIRC32K + * + * @return SCG_StatusType function status + */ +SCG_StatusType SCG_DisableSIRC32K(void) +{ + SCG_StatusType eStatusVal; + uint32_t u32TempVal; + + /* Unlock SIRC32K CSR register */ + SCG_HWA_UnlockSirc32kCsrReg(); + + /* Disable SIRC32K */ + SCG_HWA_DisableSirc32kCsr(); + + /* Wait SIRC32K not valid */ + u32TempVal = SIRC_STABILIZATION_TIMEOUT; + SCG_CheckClockAckStatus((true == SCG_HWA_GetClockVliad(SCG_SIRC32K_CLOCK_SYMBOL)), u32TempVal, eStatusVal) + + return eStatusVal; +} + +/** + * @brief Enable FIRC + * + * @param pFircConfig FIRC configuration + * @return SCG_StatusType function status + */ +SCG_StatusType SCG_EnableFIRC(const SCG_FircType *const pFircConfig) +{ + SCG_StatusType eStatusVal = SCG_STATUS_SUCCESS; + uint32_t u32TempVal, u32DivLClockFreq = 0U; + uint32_t u32FircDivEn = 0U; + uint16_t u16TrimDiv = 0U; + + DEV_ASSERT(NULL_PTR != pFircConfig); + DEV_ASSERT(pFircConfig->eDivH <= (uint32_t)SCG_ASYNCCLOCKDIV_BY64); + DEV_ASSERT(pFircConfig->eDivM <= (uint32_t)SCG_ASYNCCLOCKDIV_BY64); + DEV_ASSERT(pFircConfig->eDivL <= (uint32_t)SCG_ASYNCCLOCKDIV_BY64); + + /* Check DIV clock frequency is valid or not */ + if(pFircConfig->eDivL != SCG_ASYNC_CLOCK_DISABLE) + { + u32DivLClockFreq = (uint32_t)(FIRC_CLOCK >> (pFircConfig->eDivL - 1)); + u32FircDivEn |= (uint32_t)SCG_CLOCK_DIV_L; + } + if (u32DivLClockFreq > FIRC_DIVL_MAX_CLOCK) + { + eStatusVal = SCG_STATUS_PARAM_ERROR; + } + + if (eStatusVal == SCG_STATUS_SUCCESS) + { + /* Unlock CSR register */ + SCG_HWA_UnlockFircCsrReg(); + + /* Configure recommend value */ + SCG_HWA_SetFircCfg(SCG_FIRCCFG_CLKEN(3U)); + + /* Configure CSR register */ + u32TempVal = SCG_HWA_GetFircCsr(); + u32TempVal &= ~(uint32_t)(SCG_FIRCCSR_STEN_MASK | SCG_FIRCCSR_TREN_MASK | SCG_FIRCCSR_TRUP_MASK | SCG_FIRCCSR_CM_MASK); + u32TempVal |= (uint32_t)(SCG_FIRCCSR_TRUP(pFircConfig->bTrEn) | /* configure TRUP and EN together with TREN setting */ + SCG_FIRCCSR_TREN(pFircConfig->bTrEn) | + SCG_FIRCCSR_STEN(pFircConfig->bSten)); + SCG_HWA_SetFircCsr(u32TempVal); + + /* Configure DIV value */ + SCG_HWA_DiableFircDiv(SCG_CLOCK_DIV_ALL); + u32TempVal = SCG_HWA_GetClockDiv(SCG_FIRC_CLOCK_SYMBOL); + u32TempVal &= ~(uint32_t)(SCG_FIRCDIV_DIVL_MASK | SCG_FIRCDIV_DIVM_MASK | SCG_FIRCDIV_DIVH_MASK); + u32TempVal |= (SCG_FIRCDIV_DIVH(pFircConfig->eDivH) | SCG_FIRCDIV_DIVM(pFircConfig->eDivM) | SCG_FIRCDIV_DIVL( + pFircConfig->eDivL)); + SCG_HWA_SetFircDiv(u32TempVal) ; + + /* Set CSR[EN] bit to 1 */ + SCG_HWA_EnableFirc(); + + /* Wait FIRC valid */ + u32TempVal = FIRC_STABILIZATION_TIMEOUT; + SCG_CheckClockAckStatus((false == SCG_HWA_GetClockVliad(SCG_FIRC_CLOCK_SYMBOL)), u32TempVal, eStatusVal) + + if (eStatusVal == SCG_STATUS_SUCCESS) + { + if (pFircConfig->bCm) + { + SCG_HWA_EnableFircClockMonitor(); + } + + if (pFircConfig->bLock) + { + /* lock CSR register */ + SCG_HWA_LockFircCsrReg(); + } + + /* Enable DIV */ + u32FircDivEn |= (pFircConfig->eDivH != SCG_ASYNC_CLOCK_DISABLE) ? (uint32_t)SCG_CLOCK_DIV_H : 0U; + u32FircDivEn |= (pFircConfig->eDivM != SCG_ASYNC_CLOCK_DISABLE) ? (uint32_t)SCG_CLOCK_DIV_M : 0U; + SCG_HWA_EnableFircDiv((SCG_DivEnableType)u32FircDivEn); + + /* Wait DIV[ACK] change to 1 */ + u32TempVal = CLOCK_DIV_STABILIZATION_TIMEOUT; + SCG_CheckClockAckStatus((SCG_HWA_GetSircDivAck((SCG_DivEnableType)u32FircDivEn) != true), u32TempVal, eStatusVal) + + /* For clock auto trim, set TREN to True together with TRUP to True */ + if (pFircConfig->bTrEn == true) + { + /* set FIRCTCFG trim configuration */ + if (pFircConfig->u8TrimSrc == (uint8_t)SCG_IRC_TRIMSRC_FOSC) + { + /* Trim clock source choose FOSC */ + u16TrimDiv = (uint16_t)(FOSC_FREQUENCY / 250000U - 1U); + } + else if (pFircConfig->u8TrimSrc == (uint8_t)SCG_IRC_TRIMSRC_SOSC) + { + /* Trim clock source choose SOSC */ + u16TrimDiv = 0U; + } + else + { + /* do nothing */ + } + u32TempVal = (uint32_t)(SCG_FIRCTCFG_TRIMSRC(pFircConfig->u8TrimSrc) | SCG_FIRCTCFG_TRIMDIV(u16TrimDiv)); + SCG_HWA_SetFircTcfg(u32TempVal); + } + else + { + /* Trim disabled, just using IC internal IRC trim value */ + } + + } + else + { + /* Clear CSR configuration */ + SCG_HWA_SetFircCsr(0U); + + /* Clear DIV configuration*/ + SCG_HWA_SetFircDiv(0U); + } + } + return eStatusVal; +} + +/** + * @brief Disable FIRC + * + * @return SCG_StatusType function status + */ +SCG_StatusType SCG_DisableFIRC(void) +{ + SCG_StatusType eStatusVal = SCG_STATUS_SUCCESS; + uint32_t u32TempVal; + uint8_t u8ClkSrc; + + u8ClkSrc = SCG_HWA_GetSysClkSrc(); + if ((uint8_t)SCG_CLOCK_SRC_FIRC == u8ClkSrc) + { + eStatusVal = SCG_STATUS_SEQUENCE_ERROR; + } + else if ((SCG_HWA_GetPllSrc(SCG_PLL0_CLOCK_SYMBOL) == (uint8_t)SCG_PLLSOURCE_FIRC) && ((uint8_t)SCG_CLOCK_SRC_PLL0 == u8ClkSrc)) + { + eStatusVal = SCG_STATUS_SEQUENCE_ERROR; + } + else + { + /* do nothing */ + } + + if (eStatusVal == SCG_STATUS_SUCCESS) + { + /* Unlock CSR register */ + SCG_HWA_UnlockFircCsrReg(); + + /* Disable FIRC */ + SCG_HWA_DisableFirc(); + + /* Wait FIRC not valid */ + u32TempVal = FIRC_STABILIZATION_TIMEOUT; + SCG_CheckClockAckStatus((true == SCG_HWA_GetClockVliad(SCG_FIRC_CLOCK_SYMBOL)), u32TempVal, eStatusVal) + + if (eStatusVal == SCG_STATUS_SUCCESS) + { + /* Clear CSR register */ + SCG_HWA_SetFircCsr(0U); + + /* In order to avoid the DIV register value not cleared, Clear FIRC DIV register twice */ + SCG_HWA_SetFircDiv(0U); + SCG_HWA_SetFircDiv(0U); + } + } + return eStatusVal; +} + + +/** + * @brief Enable PLL + * + * @param ePLL PLL instance + * @param pPllConfig PLL configuration + * @return SCG_StatusType function status + */ +SCG_StatusType SCG_EnablePLL(const SCG_PllClkType ePll, const SCG_PllType *const pPllConfig) +{ + SCG_StatusType eStatusVal = SCG_STATUS_SUCCESS; + + DEV_ASSERT(NULL_PTR != pPllConfig); + DEV_ASSERT(((ePll == SCG_PLL0) || (ePll == SCG_PLL1))); + DEV_ASSERT(((pPllConfig->eSrc == SCG_PLLSOURCE_FOSC) || (pPllConfig->eSrc == SCG_PLLSOURCE_FIRC))); + DEV_ASSERT((pPllConfig->u16Mult > 95U) && (pPllConfig->u16Mult < 512U)); + DEV_ASSERT(pPllConfig->u8Prediv < 32U); + DEV_ASSERT(pPllConfig->u8Prediv != 2U); + DEV_ASSERT((pPllConfig->ePstDiv == SCG_PLLPSTDIV_BY2) || + (pPllConfig->ePstDiv == SCG_PLLPSTDIV_BY4) || + (pPllConfig->ePstDiv == SCG_PLLPSTDIV_BY8)); + DEV_ASSERT(pPllConfig->eDivH <= (uint32_t)SCG_ASYNCCLOCKDIV_BY64); + DEV_ASSERT(pPllConfig->eDivM <= (uint32_t)SCG_ASYNCCLOCKDIV_BY64); + DEV_ASSERT(pPllConfig->eDivL <= (uint32_t)SCG_ASYNCCLOCKDIV_BY64); + + + if ((true != SCG_HWA_GetClockVliad(SCG_FOSC_CLOCK_SYMBOL)) && (SCG_PLLSOURCE_FOSC == pPllConfig->eSrc)) + { + eStatusVal = SCG_STATUS_SEQUENCE_ERROR; + } + else if ((true != SCG_HWA_GetClockVliad(SCG_FIRC_CLOCK_SYMBOL)) && (SCG_PLLSOURCE_FIRC == pPllConfig->eSrc)) + { + eStatusVal = SCG_STATUS_SEQUENCE_ERROR; + } + else + { + /* do nothing */ + } + + if (eStatusVal == SCG_STATUS_SUCCESS) + { + if (SCG_PLL0 == ePll) + { + eStatusVal = SCG_EnablePLL0(pPllConfig); + } + else if (SCG_PLL1 == ePll) + { + eStatusVal = SCG_EnablePLL1(pPllConfig); + } + else + { + /* do nothing */ + } + } + + return eStatusVal; +} + +/** + * @brief Disable PLL + * + * @param ePll PLL instance + * @return SCG_StatusType function status + */ +SCG_StatusType SCG_DisablePLL(const SCG_PllClkType ePll) +{ + SCG_StatusType eStatusVal = SCG_STATUS_SUCCESS; + + if (SCG_PLL0 == ePll) + { + if (SCG_HWA_GetSysClkSrc() == (uint8_t)SCG_CLOCK_SRC_PLL0) + { + eStatusVal = SCG_STATUS_SEQUENCE_ERROR; + } + else + { + eStatusVal = SCG_DisablePLL0(); + } + } + else + { + /* (SCG_PLL1 == ePll) */ + eStatusVal = SCG_DisablePLL1(); + } + + return eStatusVal; +} + +/** + * @brief Set system run time clock and related CORE/BUS/SLOW clock. + * + * @param pSysClkConfig pointer to the clockCtrlType structure data instance,which defined for system clock selection. + * @return SCG_StatusType function status + * SCG_STATUS_SUCCESS : clock source and dividers are valid,and switch system clock successfully + * SCG_STATUS_SEQUENCE_ERROR: new clock source is not enabled + * SCG_STATUS_PARAM_ERROR: the core bus slow divider are invalid + * SCG_STATUS_TIMEOUT: switch system clock procedure time out + */ +SCG_StatusType SCG_SetClkCtrl(const SCG_ClockCtrlType *const pSysClkConfig) +{ + DEV_ASSERT(NULL_PTR != pSysClkConfig); + + return SCG_SwitchSystemClockWithConfig(pSysClkConfig->eSrc,pSysClkConfig); +} + +/** + * @brief Get clock frequency + * + * @param eScgClockName Clock source type + * @return uint32_t frequency value + */ +uint32_t SCG_GetScgClockFreq(const SCG_ClkSrcType eScgClockName) +{ + uint32_t u32Freq; + DEV_ASSERT(eScgClockName < SCG_END_OF_CLOCKS); + + if ((SCG_CORE_CLK == eScgClockName) || + (SCG_BUS_CLK == eScgClockName) || + (SCG_SLOW_CLK == eScgClockName)) + { + u32Freq = SCG_CalculateSystemFreq(eScgClockName); + } + else if ((SCG_SIRC_CLK == eScgClockName) || + (SCG_SIRCDIVH_CLK == eScgClockName) || + (SCG_SIRCDIVM_CLK == eScgClockName) || + (SCG_SIRCDIVL_CLK == eScgClockName)) + { + u32Freq = SCG_CalculateSircFreq(eScgClockName); + } + else if ((SCG_FIRC_CLK == eScgClockName) || + (SCG_FIRCDIVH_CLK == eScgClockName) || + (SCG_FIRCDIVM_CLK == eScgClockName) || + (SCG_FIRCDIVL_CLK == eScgClockName)) + { + u32Freq = SCG_CalculateFircFreq(eScgClockName); + } + else if ((SCG_FOSC_CLK == eScgClockName) || + (SCG_FOSCDIVH_CLK == eScgClockName) || + (SCG_FOSCDIVM_CLK == eScgClockName) || + (SCG_FOSCDIVL_CLK == eScgClockName)) + { + u32Freq = SCG_CalculateFoscFreq(eScgClockName); + } + else if ((SCG_PLL0_CLK == eScgClockName) || + (SCG_PLL0DIVH_CLK == eScgClockName) || + (SCG_PLL0DIVM_CLK == eScgClockName) || + (SCG_PLL0DIVL_CLK == eScgClockName)) + { + u32Freq = SCG_CalculatePll0Freq(eScgClockName); + } + else if ((SCG_PLL1_CLK == eScgClockName) || + (SCG_PLL1DIVH_CLK == eScgClockName) || + (SCG_PLL1DIVM_CLK == eScgClockName) || + (SCG_PLL1DIVL_CLK == eScgClockName)) + { + u32Freq = SCG_CalculatePll1Freq(eScgClockName); + } + else if (SCG_SIRC32K_CLK == eScgClockName) + { + u32Freq = SIRC32K_CLOCK; + } + else if (SCG_SOSC_CLK == eScgClockName) + { + u32Freq = SOSC_FREQUENCY; + } + else if (SCG_SCG_CLKOUT_CLK == eScgClockName) + { + u32Freq = SCG_CalculateClkOutFreq(); + } + else if(SCG_NVMINIT_CLK == eScgClockName) + { + u32Freq = NVM_CLOCK; + } + else if(SCG_CMU4REF_CLK == eScgClockName) + { + u32Freq = SCG_CalculateCMU4RefFreq(); + } + else + { + u32Freq = UNKNOWN_CLOCK; + } + + if (UNKNOWN_CLOCK == u32Freq) + { + u32Freq = 0U; + } + + return u32Freq; +} + +/** + * @brief Select clock out source + * + * @param eClkoutSel clock out source + */ +void SCG_SetClkOut(const SCG_ClockoutSrcType eClkoutSel) +{ + DEV_ASSERT(eClkoutSel <= SCG_CLOCKOUT_SRC_SIRC32K); + + SCG_HWA_SetClkOutSel((uint8_t)eClkoutSel); +} + +/** + * @brief Select NVM clock source + * + * @param eNvmClkSrc NVM clock source + * @return uint32_t function status + */ +SCG_StatusType SCG_SetNvmClk(const SCG_NvmClkSrcType eNvmClkSrc) +{ + SCG_StatusType eStatusVal = SCG_STATUS_SUCCESS; + DEV_ASSERT((eNvmClkSrc == SCG_NVMCLK_SRC_SIRC) || (eNvmClkSrc == SCG_NVMCLK_SRC_FIRC)); + + if ((true != SCG_HWA_GetClockVliad(SCG_FIRC_CLOCK_SYMBOL)) && (eNvmClkSrc == SCG_NVMCLK_SRC_FIRC)) + { + eStatusVal = SCG_STATUS_SEQUENCE_ERROR; + } + + if (eStatusVal == SCG_STATUS_SUCCESS) + { + SCG_HWA_SetNvmClk(((uint32_t)1U << eNvmClkSrc)); + } + + return eStatusVal; +} + +/** + * @brief Select CMU4 clock source + * + * @param eCmu4ClkSrc CMU4 clock source + * @return SCG_StatusType function status + */ +SCG_StatusType SCG_SetCmu4Clk(const SCG_Cmu4ClkSrcType eCmu4ClkSrc) +{ + SCG_StatusType eStatusVal = SCG_STATUS_SUCCESS; + DEV_ASSERT((eCmu4ClkSrc == SCG_CMU4CLK_SRC_SIRC) || (eCmu4ClkSrc == SCG_CMU4CLK_SRC_FOSC)); + + if ((true != SCG_HWA_GetClockVliad(SCG_FOSC_CLOCK_SYMBOL)) && (eCmu4ClkSrc == SCG_CMU4CLK_SRC_FOSC)) + { + eStatusVal = SCG_STATUS_SEQUENCE_ERROR; + } + + if (eStatusVal == SCG_STATUS_SUCCESS) + { + SCG_HWA_SetCmu4Clk(((uint32_t)1U << eCmu4ClkSrc)); + } + return eStatusVal; +} + +/** + * @brief Generate the origion SCG register CRC result, and configure the SCG register CRC option. + * + * @param eMode The SCG register CRC trigger mode + * @return CRC configure status + * SCG_STATUS_SUCCESS : CRC configure successfully + * SCG_STATUS_TIMEOUT : CRC configure time out + */ +SCG_StatusType SCG_RegCrcConfig(SCG_CrcModeType eMode) +{ + SCG_StatusType eStatusVal = SCG_STATUS_SUCCESS; + uint32_t u32Timeout = 0xFFFFU; + + DEV_ASSERT((eMode == SCG_CRC_SW_MODE) || (eMode == SCG_CRC_TRIGGER_MODE)); + + /* Deinit CRC register */ + SCG_HWA_DisableCrcCheck(); + SCG_HWA_DisableCrcTriggerMode(); + SCG_HWA_DisableCrcErrorOutput(); + SCG_HWA_ClearCrcErrorFlag(); + + /* Generate original CRC result */ + SCG_HWA_GenCrcVal(); + while (SCG_HWA_GetCrcBusyStatus() == true) + { + u32Timeout--; + if (u32Timeout == 0U) + { + eStatusVal = SCG_STATUS_TIMEOUT; + break; + } + } + + if (eStatusVal == SCG_STATUS_SUCCESS) + { + if (eMode == SCG_CRC_TRIGGER_MODE) + { + SCG_HWA_EnableCrcTriggerMode(); + } + + /* Enable SCG CRC error to FCSMU in CSC0_SMU_CTRL4[SCG_CRC] */ + CSC0_HWA_CTRL4_EnableReqToSMU(CSC_SMU_SCG_CRC); + /* Generate CRC error output */ + SCG_HWA_EnableCrcErrorOutput(); + /* Generate CRC check */ + SCG_HWA_EnableCrcCheck(); + } + return eStatusVal; +} + +/** + * @brief Trigger the SCG register CRC generation by software + * + */ +void SCG_RegCrcGenerate(void) +{ + SCG_HWA_GenCrcVal(); +} + +/** + * @brief Trigger the SCG register CRC generation by software,and wait the CRC check result + * + * @return CRC check result + */ +SCG_CrcCheckResType SCG_RegCrcGenerateWaitResult(void) +{ + SCG_CrcCheckResType eStatusVal = SCG_CRC_CHECK_SUCCESS; + uint32_t u32Timeout = 0xFFFFU; + + SCG_HWA_GenCrcVal(); + while (SCG_HWA_GetCrcBusyStatus() == true) + { + u32Timeout--; + if (u32Timeout == 0U) + { + eStatusVal = SCG_CRC_GEN_TIMEOUT; + break; + } + } + + /* Check CRC is success or not */ + if (SCG_HWA_GetCrcErrorStatus()) + { + eStatusVal = SCG_CRC_CHECK_FAILED; + } + + return eStatusVal; +} + +/** + * @brief Clock source De-init + * + * @return SCG_StatusType function status + */ +SCG_StatusType SCG_Deinit(void) +{ + SCG_StatusType eStatusVal = SCG_STATUS_SUCCESS; + SCG_FircType tFircCfg = + { + .bLock = false, + .bCm = false, + .bTrEn = false, + .bSten = false, + .u8TrimSrc = 0U, + .eDivL = SCG_ASYNCCLOCKDIV_BY4, + .eDivM = SCG_ASYNCCLOCKDIV_BY2, + .eDivH = SCG_ASYNCCLOCKDIV_BY1 + }; + + if (SCG_HWA_GetSysClkSrc() != (uint8_t)SCG_CLOCK_SRC_FIRC) + { + eStatusVal = SCG_SwitchSystemClockWithConfig(SCG_CLOCK_SRC_FIRC,NULL_PTR); + if (SCG_STATUS_SEQUENCE_ERROR == eStatusVal) + { + eStatusVal = SCG_EnableFIRC(&tFircCfg); + if (SCG_STATUS_TIMEOUT != eStatusVal) + { + eStatusVal = SCG_SwitchSystemClockWithConfig(SCG_CLOCK_SRC_FIRC,NULL_PTR); + } + } + } + + if (SCG_STATUS_SUCCESS == eStatusVal) + { + /* Disable all clock source */ + (void)SCG_DisablePLL(SCG_PLL1); + (void)SCG_DisablePLL(SCG_PLL0); + (void)SCG_DisableFOSC(); + (void)SCG_DisableSOSC(); + (void)SCG_DisableSIRC32K(); + } + + return eStatusVal; +} + diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_scm.c b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_scm.c new file mode 100644 index 0000000..2b0edfa --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_scm.c @@ -0,0 +1,482 @@ +/** + * @file fc7xxx_driver_scm.h + * @author Flagchip + * @brief FC7xxx csc driver type definition and API + * @version 0.1.0 + * @date 2024-01-12 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + */ + +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-01-12 Flagchip085 N/A First version for FC7240 + ******************************************************************************** */ + +#include "fc7xxx_driver_scm.h" + +/** + * @brief Get unique identification for the chip, loaded from NVR. + * + * @param pUid Pointer to UID + * + */ +void SCM_GetChip_UID(uint32 *pUid) +{ + DEV_ASSERT(NULL_PTR != pUid); + + pUid[0] = SCM_HWA_GetData_UIDL(); + pUid[1] = SCM_HWA_GetData_UIDML(); + pUid[2] = SCM_HWA_GetData_UIDMH(); + pUid[3] = SCM_HWA_GetData_UIDH(); +} + +/** + * @brief Get CCMx status. + * + * @param eCCMType CCM type + * @param u32Value selection to get + * + */ +uint32_t SCM_GetStatus_CCMx(SCM_CCM_Type eCCMType, uint32_t u32Value) +{ + uint32_t u32Temp; + + DEV_ASSERT(eCCMType == SCM_CCM0); + DEV_ASSERT((u32Value & SCM_CCM0_STATUS_MASK) == 0U); + + if (SCM_CCM0 == eCCMType) + { + u32Temp = SCM_HWA_GetStatus_CCM0(); + } + + return (u32Temp & u32Value); +} + +/** + * @brief Get matrix status. + * + * @param eMatrixType Matrix type + * @param u32Value selection to get + * + */ +uint32_t SCM_GetStatus_Matrix(SCM_MatrixStatusType eMatrixType, uint32_t u32Value) +{ + uint32_t u32Temp; + DEV_ASSERT((uint32_t)eMatrixType <= (uint32_t)SCM_MatrixStatus_ID); + + if (SCM_MatrixStatus_0 == eMatrixType) + { + u32Temp = SCM_HWA_GetStatus_MATRIX_STATUS0(); + } + else if (SCM_MatrixStatus_1 == eMatrixType) + { + u32Temp = SCM_HWA_GetStatus_MATRIX_STATUS1(); + } + else if (SCM_MatrixStatus_2 == eMatrixType) + { + u32Temp = SCM_HWA_GetStatus_MATRIX_STATUS2(); + } + else if (SCM_MatrixStatus_5 == eMatrixType) + { + u32Temp = SCM_HWA_GetStatus_MATRIX_STATUS5(); + } + else if (SCM_MatrixStatus_6 == eMatrixType) + { + u32Temp = SCM_HWA_GetStatus_MATRIX_STATUS6(); + } + else if (SCM_MatrixStatus_7 == eMatrixType) + { + u32Temp = SCM_HWA_GetStatus_MATRIX_STATUS7(); + } + else + { + u32Temp = SCM_HWA_GetStatus_MATRIX_ID_STATUS0(); + } + + return (u32Temp & u32Value); +} + +/** + * @brief Set cpu to control MAM ECC enable register 0. + * + * @param eCpuType Cpu to use + * @param bLockStatus Lock the cpu control settings + * + * @return Set operation success/failed + */ +SCM_RetStatusType SCM_SetCpuCtrl_MAMECCR0(const SCM_WPB_CpuType eCpuType, bool bLockStatus) +{ + SCM_RetStatusType eRetVal; + DEV_ASSERT((uint32_t)eCpuType < (uint32_t)SCM_WP_CPU_NONE); + + if (0U == SCM_HWA_MAMECCEN0_GetWPBLockStatus()) + { + SCM_HWA_MAMECCEN0_SetCpuWritePermit(eCpuType); + + if (true == bLockStatus) + { + /* Lock the cpu to control settings until reset */ + SCM_HWA_MAMECCEN0_LockWritePermit(); + } + + eRetVal = SCM_E_OK; + } + else + { + eRetVal = SCM_E_LOCK; + } + + return eRetVal; +} + +/** + * @brief Set cpu to control MAM ECC enable register 1. + * + * @param eCpuType Cpu to use + * @param bLockStatus Lock the cpu control settings + * + * @return Set operation success/failed + */ +SCM_RetStatusType SCM_SetCpuCtrl_MAMECCR1(const SCM_WPB_CpuType eCpuType, bool bLockStatus) +{ + SCM_RetStatusType eRetVal; + DEV_ASSERT((uint32_t)eCpuType < (uint32_t)SCM_WP_CPU_NONE); + + if (0U == SCM_HWA_MAMECCEN1_GetWPBLockStatus()) + { + SCM_HWA_MAMECCEN1_SetCpuWritePermit(eCpuType); + + if (true == bLockStatus) + { + /* Lock the cpu to control settings until reset */ + SCM_HWA_MAMECCEN1_LockWritePermit(); + } + + eRetVal = SCM_E_OK; + } + else + { + eRetVal = SCM_E_LOCK; + } + + return eRetVal; +} + +/** + * @brief Set cpu to control CPU0 ECC enable register. + * + * @param eCpuType Cpu to use + * @param bLockStatus Lock the cpu control settings + * + * @return Set operation success/failed + */ +SCM_RetStatusType SCM_SetCpuCtrl_CPU0ECCEN(const SCM_WPB_CpuType eCpuType, bool bLockStatus) +{ + SCM_RetStatusType eRetVal; + DEV_ASSERT((uint32_t)eCpuType < (uint32_t)SCM_WP_CPU_NONE); + + if (0U == SCM_HWA_CPU0ECCEN_GetWPBLockStatus()) + { + SCM_HWA_CPU0ECCEN_SetCpuWritePermit(eCpuType); + + if (true == bLockStatus) + { + /* Lock the cpu to control settings until reset */ + SCM_HWA_CPU0ECCEN_LockWritePermit(); + } + + eRetVal = SCM_E_OK; + } + else + { + eRetVal = SCM_E_LOCK; + } + + return eRetVal; +} + +/** + * @brief Set cpu to control SOCMISC register. + * + * @param eCpuType Cpu to use + * @param bLockStatus Lock the cpu control settings + * + * @return Set operation success/failed + */ +SCM_RetStatusType SCM_SetCpuCtrl_SOCMISC(const SCM_WPB_CpuType eCpuType, bool bLockStatus) +{ + SCM_RetStatusType eRetVal; + + if (0U == SCM_HWA_SOCMISC_GetWPBLockStatus()) + { + SCM_HWA_SOCMISC_SetCpuWritePermit(eCpuType); + + if (true == bLockStatus) + { + /* Lock the cpu to control settings until reset */ + SCM_HWA_SOCMISC_LockWritePermit(); + } + + eRetVal = SCM_E_OK; + } + else + { + eRetVal = SCM_E_LOCK; + } + + return eRetVal; +} + +/** + * @brief Set cpu to control Subsystem pcc register. + * + * @param eCpuType Cpu to use + * @param bLockStatus Lock the cpu control settings + * + * @return Set operation success/failed + */ +SCM_RetStatusType SCM_SetCpuCtrl_SUBSYS_PCC(const SCM_WPB_CpuType eCpuType, bool bLockStatus) +{ + SCM_RetStatusType eRetVal; + + if (0U == SCM_HWA_SUBSYS_PCC_GetWPBLockStatus()) + { + SCM_HWA_SUBSYS_PCC_SetCpuWritePermit(eCpuType); + + if (true == bLockStatus) + { + /* Lock the cpu to control settings until reset */ + SCM_HWA_SUBSYS_PCC_LockWritePermit(); + } + + eRetVal = SCM_E_OK; + } + else + { + eRetVal = SCM_E_LOCK; + } + + return eRetVal; +} + +/** + * @brief Set cpu to control master halt request register. + * + * @param eCpuType Cpu to use + * @param bLockStatus Lock the cpu control settings + * + * @return Set operation success/failed + */ +SCM_RetStatusType SCM_SetCpuCtrl_MASTER_HALT_REQ(const SCM_WPB_CpuType eCpuType, bool bLockStatus) +{ + SCM_RetStatusType eRetVal; + + if (0U == SCM_HWA_MASTER_HALT_REQ_GetWPBLockStatus()) + { + SCM_HWA_MASTER_HALT_REQ_SetCpuWritePermit(eCpuType); + + if (true == bLockStatus) + { + /* Lock the cpu to control settings until reset */ + SCM_HWA_MASTER_HALT_REQ_LockWritePermit(); + } + + eRetVal = SCM_E_OK; + } + else + { + eRetVal = SCM_E_LOCK; + } + + return eRetVal; +} + +/** + * @brief Set lock FTU_ROUTING register. + * + */ +void SCM_SetLock_FTU_ROUTING(void) +{ + if (0U == SCM_HWA_FTU_ROUTING_GetLockStatus()) + { + SCM_HWA_LockFTU_ROUTING(); + } +} + +/** + * @brief Set lock FTU_GTB register. + * + */ +void SCM_SetLock_FTU_GTB(void) +{ + if (0U == SCM_HWA_FTU_GTB_GetLockStatus()) + { + SCM_HWA_LockFTU_GTB(); + } +} + +/** + * @brief Set lock DEBUG_TRACE register. + * + */ +void SCM_SetLock_DEBUG_TRACE(void) +{ + if (0U == SCM_HWA_DEBUG_TRACE_GetLockStatus()) + { + SCM_HWA_LockDEBUG_TRACE(); + } +} + +/** + * @brief Set lock FLEXCAN_ROUTING register. + * + */ +void SCM_SetLock_FLEXCAN_ROUTING(void) +{ + if (0U == SCM_HWA_FLEXCAN_ROUTING_GetLockStatus()) + { + SCM_HWA_LockFLEXCAN_ROUTING(); + } +} + +/** + * @brief Set lock MSC0_ROUTING register. + * + */ +void SCM_SetLock_MSC0_ROUTING(void) +{ + if (0U == SCM_HWA_MSC0_ROUTING_GetLockStatus()) + { + SCM_HWA_LockMSC0_ROUTING(); + } +} + +/** + * @brief Set lock INT_ROUTER_NMI register. + * + */ +void SCM_SetLock_INT_ROUTER_NMI(void) +{ + if (0U == SCM_HWA_INT_ROUTER_NMI_GetLockStatus()) + { + SCM_HWA_LockINT_ROUTER_NMI(); + } +} + +/** + * @brief Set NMI interrupt router . + * + * @param eCpuType Cpu to use + * @param bEnable Enable/Disable + * @return Set operation success/failed + */ +SCM_RetStatusType SCM_SetEnable_NMIIntRouter(const SCM_WPB_CpuType eCpuType, bool bEnable) +{ + SCM_RetStatusType eRetVal; + + if (SCM_WP_CPU_0 == eCpuType) + { + SCM_HWA_SetEnable_Cpu0NMIIrqRouter(bEnable); + eRetVal = SCM_E_OK; + } + else + { + eRetVal = SCM_E_PARAM; + } + + return eRetVal; +} + +/** + * @brief Generate the origion SCM register CRC result, and configure the SCM register CRC option. + * + * @param eMode The SCM register CRC trigger mode + * @return CRC configure status + * SCM_E_OK : CRC configure successfully + * SCM_E_TIMEOUT : CRC configure time out + */ +SCM_RetStatusType SCM_RegCrcConfig(SCM_CrcModeType eMode) +{ + SCM_RetStatusType eStatusVal = SCM_E_OK; + uint32_t u32Timeout = 0xFFFFU; + + DEV_ASSERT((eMode == SCM_CRC_SW_MODE) || (eMode == SCM_CRC_TRIGGER_MODE)); + + /* Deinit CRC register */ + SCM_HWA_SetEnable_CrcCheck(false); + SCM_HWA_SetEnable_CrcTrigger(false); + SCM_HWA_SetEnable_CrcErrOut(false); + SCM_HWA_ClearCrcErrorFlag(); + + /* Generate original CRC result */ + SCM_HWA_SetEnable_CrcSwGen(true); + while (SCM_HWA_GetStatus_CrcBusyFlag() != 0U) + { + u32Timeout--; + if (u32Timeout == 0U) + { + eStatusVal = SCM_E_TIMEOUT; + break; + } + } + + if (eStatusVal == SCM_E_OK) + { + if (eMode == SCM_CRC_TRIGGER_MODE) + { + SCM_HWA_SetEnable_CrcTrigger(true); + } + + /* Enable SCM CRC error to FCSMU in CSC0_SMU_CTRL4[SCM_CRC] */ + CSC0_HWA_CTRL4_EnableReqToSMU(CSC_SMU_SCM_CRC); + /* Generate CRC error output */ + SCM_HWA_SetEnable_CrcErrOut(true); + /* Generate CRC check */ + SCM_HWA_SetEnable_CrcCheck(true); + } + return eStatusVal; +} + +/** + * @brief Trigger the SCM register CRC generation by software + * + */ +void SCM_RegCrcGenerate(void) +{ + SCM_HWA_SetEnable_CrcSwGen(true); +} + +/** + * @brief Trigger the SCM register CRC generation by software,and wait the CRC check result + * + * @return CRC check result + */ +SCM_RetStatusType SCM_RegCrcGenerateWaitResult(void) +{ + SCM_RetStatusType eStatusVal = SCM_E_OK; + uint32_t u32Timeout = 0xFFFFU; + + SCM_HWA_SetEnable_CrcSwGen(true); + while (SCM_HWA_GetStatus_CrcBusyFlag() != 0U) + { + u32Timeout--; + if (u32Timeout == 0U) + { + eStatusVal = SCM_E_TIMEOUT; + break; + } + } + + /* Check CRC is success or not */ + if (0U != SCM_HWA_GetStatus_CrcErrFlag()) + { + eStatusVal = SCM_E_CRC; + } + + return eStatusVal; +} diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_scst.c b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_scst.c new file mode 100644 index 0000000..e6388b9 --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_scst.c @@ -0,0 +1,230 @@ +/** + * @file fc7xxx_driver_scst.c + * @author Flagchip + * @brief FC7xxx scst driver source code + * @version 0.1.0 + * @date 2023-12-29 + * + * @copyright Copyright (c) 2023 Flagchip Semiconductors Co., Ltd. + * + */ +/********************************************************************************* +* Revision History: +* +* Version Date Initials CR# Descriptions +* --------- ---------- ------------ ---------- --------------- +* 0.1.0 2023-12-29 qxw074 N/A First version for FC7240 +******************************************************************************** */ + +#include "fc7xxx_driver_scst.h" + +/** + * @brief The address of the specific implementation of the M7ST API + * + */ +#define M7ST_ROM_BASE 0x04812800 + +/** + * @brief The SCST Atomic Test function prototype + * + */ +typedef Type_M7ST_AtomicStatus (*Type_M7ST_RegressionTest) (uint32_t TestStart, uint32_t TestEnd, uint32_t InjectEnable, uint32_t RamBase); + +/** + * @brief The SCST Run selected tests function prototype + * + */ +typedef Type_M7ST_AtomicStatus (*Type_M7ST_AtomicTest) (uint32_t TestID, uint32_t InjectEnable, uint32_t RamBase); + +/** + * @brief M7ST API structure + * + */ +typedef struct Struct_M7ST_RomTable +{ + Type_M7ST_RegressionTest RegressionTest; + Type_M7ST_AtomicTest AluTest; + Type_M7ST_AtomicTest AluMLATest; + Type_M7ST_AtomicTest AluSHIFTTest; + Type_M7ST_AtomicTest AluTest1; + Type_M7ST_AtomicTest AluTest2; + Type_M7ST_AtomicTest AluTest3; + Type_M7ST_AtomicTest AluTest4; + Type_M7ST_AtomicTest AluTest5; + Type_M7ST_AtomicTest AluTest6; + Type_M7ST_AtomicTest RegbankTest1; + Type_M7ST_AtomicTest RegbankTest2; + Type_M7ST_AtomicTest RegbankTest3; + Type_M7ST_AtomicTest RegbankTest4; + Type_M7ST_AtomicTest RegbankTest5; + Type_M7ST_AtomicTest RegbankTest6; + Type_M7ST_AtomicTest LoadStoreTest1; + Type_M7ST_AtomicTest LoadStoreTest2; + Type_M7ST_AtomicTest LoadStoreTest3; + Type_M7ST_AtomicTest LoadStoreTest4; + Type_M7ST_AtomicTest LoadStoreTest5; + Type_M7ST_AtomicTest LoadStoreTest6; + Type_M7ST_AtomicTest SimdSatTest1; + Type_M7ST_AtomicTest SimdSatTest2; + Type_M7ST_AtomicTest SimdSatTest3; + Type_M7ST_AtomicTest SimdSatTest4; + Type_M7ST_AtomicTest MacTest1; + Type_M7ST_AtomicTest MacTest2; + Type_M7ST_AtomicTest FetchTest; + Type_M7ST_AtomicTest StatusTest1; + Type_M7ST_AtomicTest StatusTest2; + Type_M7ST_AtomicTest BranchTest1; + Type_M7ST_AtomicTest BranchTest2; +} Type_M7ST_RomTable; + +/** + * @brief This function is used to get the result of the executed test + * + * @param test_index is test number,0U..32U + * @param s_u32RamBase The first address of the 1k memory that the program needs to run + * @return M7ST_ErrorM7ST_TestPass is ok, others are not ok + */ +Type_M7ST_AtomicStatus SCST_ExecuteTest(SCST_TestIndexType test_index,uint32_t *s_u32RamBase) +{ + Type_M7ST_AtomicStatus Status = M7ST_FaultInjectError; + Type_M7ST_RomTable *M7ST_RomEntry = (Type_M7ST_RomTable *)M7ST_ROM_BASE; + switch(test_index) + { + case M7ST_AluTest: + Status = M7ST_RomEntry->AluTest(0,0,(uint32_t)&s_u32RamBase[0]); + break; + + case M7ST_AluMLATest: + Status = M7ST_RomEntry->AluMLATest(1,0,(uint32_t)&s_u32RamBase[0]); + break; + + case M7ST_AluSHIFTTest: + Status = M7ST_RomEntry->AluSHIFTTest(2,0,(uint32_t)&s_u32RamBase[0]); + break; + + case M7ST_AluTes1t: + Status = M7ST_RomEntry->AluTest1(3,0,(uint32_t)&s_u32RamBase[0]); + break; + + case M7ST_AluTest2: + Status = M7ST_RomEntry->AluTest2(4,0,(uint32_t)&s_u32RamBase[0]); + break; + + case M7ST_AluTest3: + Status = M7ST_RomEntry->AluTest3(5,0,(uint32_t)&s_u32RamBase[0]); + break; + + case M7ST_AluTest4: + Status = M7ST_RomEntry->AluTest4(6,0,(uint32_t)&s_u32RamBase[0]); + break; + + case M7ST_AluTest5: + Status = M7ST_RomEntry->AluTest5(7,0,(uint32_t)&s_u32RamBase[0]); + break; + + case M7ST_AluTest6: + Status = M7ST_RomEntry->AluTest6(8,0,(uint32_t)&s_u32RamBase[0]); + break; + + case M7ST_RegbankTest1: + Status = M7ST_RomEntry->RegbankTest1(9,0,(uint32_t)&s_u32RamBase[0]); + break; + + case M7ST_RegbankTest2: + Status = M7ST_RomEntry->RegbankTest2(10,0,(uint32_t)&s_u32RamBase[0]); + break; + + case M7ST_RegbankTest3: + Status = M7ST_RomEntry->RegbankTest3(11,0,(uint32_t)&s_u32RamBase[0]); + break; + + case M7ST_RegbankTest4: + Status = M7ST_RomEntry->RegbankTest4(12,0,(uint32_t)&s_u32RamBase[0]); + break; + + case M7ST_RegbankTest5: + Status = M7ST_RomEntry->RegbankTest5(13,0,(uint32_t)&s_u32RamBase[0]); + break; + + case M7ST_RegbankTest6: + Status = M7ST_RomEntry->RegbankTest6(14,0,(uint32_t)&s_u32RamBase[0]); + break; + + case M7ST_LoadStoreTest1: + Status = M7ST_RomEntry->LoadStoreTest1(15,0,(uint32_t)&s_u32RamBase[0]); + break; + + case M7ST_LoadStoreTest2: + Status = M7ST_RomEntry->LoadStoreTest2(16,0,(uint32_t)&s_u32RamBase[0]); + break; + + case M7ST_LoadStoreTest3: + Status = M7ST_RomEntry->LoadStoreTest3(17,0,(uint32_t)&s_u32RamBase[0]); + break; + + case M7ST_LoadStoreTest4: + Status = M7ST_RomEntry->LoadStoreTest4(18,0,(uint32_t)&s_u32RamBase[0]); + break; + + case M7ST_LoadStoreTest5: + Status = M7ST_RomEntry->LoadStoreTest5(19,0,(uint32_t)&s_u32RamBase[0]); + break; + + case M7ST_LoadStoreTest6: + Status = M7ST_RomEntry->LoadStoreTest6(20,0,(uint32_t)&s_u32RamBase[0]); + break; + + case M7ST_SimdSatTest1: + Status = M7ST_RomEntry->SimdSatTest1(21,0,(uint32_t)&s_u32RamBase[0]); + break; + + case M7ST_SimdSatTest2: + Status = M7ST_RomEntry->SimdSatTest2(22,0,(uint32_t)&s_u32RamBase[0]); + break; + + case M7ST_SimdSatTest3: + Status = M7ST_RomEntry->SimdSatTest3(23,0,(uint32_t)&s_u32RamBase[0]); + break; + + case M7ST_SimdSatTest4: + Status = M7ST_RomEntry->SimdSatTest4(24,0,(uint32_t)&s_u32RamBase[0]); + break; + + case M7ST_MacTest1: + Status = M7ST_RomEntry->MacTest1(25,0,(uint32_t)&s_u32RamBase[0]); + break; + + case M7ST_MacTest2: + Status = M7ST_RomEntry->MacTest2(26,0,(uint32_t)&s_u32RamBase[0]); + break; + + case M7ST_FetchTest: + Status = M7ST_RomEntry->FetchTest(27,0,(uint32_t)&s_u32RamBase[0]); + break; + + case M7ST_StatusTest1: + Status = M7ST_RomEntry->StatusTest1(28,0,(uint32_t)&s_u32RamBase[0]); + break; + + case M7ST_StatusTest2: + Status = M7ST_RomEntry->StatusTest2(29,0,(uint32_t)&s_u32RamBase[0]); + break; + + case M7ST_BranchTest1: + Status = M7ST_RomEntry->BranchTest1(30,0,(uint32_t)&s_u32RamBase[0]); + break; + + case M7ST_BranchTest2: + Status = M7ST_RomEntry->BranchTest2(31,0,(uint32_t)&s_u32RamBase[0]); + break; + + case M7ST_RegressionTest: + Status = M7ST_RomEntry->RegressionTest(0,31,0,(uint32_t)&s_u32RamBase[0]); + break; + + default: + break; + } + return Status; +} + diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_sec.c b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_sec.c new file mode 100644 index 0000000..a8d20de --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_sec.c @@ -0,0 +1,424 @@ +/** + * @file fc7xxx_driver_sec.c + * @author FlagchipXXX + * @brief FC7xxx SEC driver type definition and API + * @version 0.1.0 + * @date 2024-1-12 + * + * @copyright Copyright (c) 2023 Flagchip Semiconductors Co., Ltd. + * + * @details + */ +/******************************************************************************** +* Revision History: +* +* Version Date Initials CR# Descriptions +* --------- ---------- ------------ ---------- --------------- +* 0.1.0 2024-1-12 Flagchip113 N/A First version for FC7240 +********************************************************************************/ +#include "fc7xxx_driver_sec.h" + + + + +/** + * @brief This function can be used to enable the Debug mode. + * @return true means enable debug success ,false means enable debug failed. + * */ +bool SEC_EnDebugMode(void) +{ + bool ret = false; + if (SEC_HWA_GetWritePer()) + { + SEC_HWA_EnDebug(); + ret = true; + } + return ret; +} + +/** + * @brief This function can be used to re-enable the Debug mode by the re-enable keys. + * @param keys The Debug mode re-enable keys. + * @return true means re-enable success,false means re-enable failed. + * */ +bool SEC_ReEnDebugMode(ReEnDebug_Keys keys) +{ + bool ret = false; + if (SEC_HWA_GetReEnDebug()) + { + SEC_HWA_ChangeDBK(0u, keys.Re_key0); + SEC_HWA_ChangeDBK(1u, keys.Re_key1); + SEC_HWA_ChangeDBK(2u, keys.Re_key2); + SEC_HWA_ChangeDBK(3u, keys.Re_key3); + ret = true; + } + return ret; +} + +/** + * @brief This function can get the system state (secured or no secured). + * */ +Systemstate SEC_SystemSecureState(void) +{ + Systemstate ret = Securedstate ; + uint16_t sskey0 = SEC_HWA_GetSScontrol0(); + uint16_t sskey1 = SEC_HWA_GetSScontrol1(); + if ((sskey0 == 0xC35AU) && (sskey1 == 0xFFFFU)) + { + ret = UnSecuredstate; + } + return ret ; +} + + +/** + * @brief This function can enable the test mode. + * @return true means enable test mode success,false means enable test mode failed. + * */ +bool SEC_EnTestMode(void) +{ + + bool ret = false; + if (SEC_HWA_GetWritePer()) + { + SEC_HWA_EnTest(); + ret = true; + } + return ret; +} + + + +/** + *@brief This function can Re-enable the test mode by the re-enable key. + *@param key The test mode re-enable key.The key is up to the user to decide in advance. + *@return true means re-enable success,false means re-enable failed. + * */ +bool SEC_ReEnTestMode(uint32_t key) +{ + bool ret = false; + + bool writeper = SEC_HWA_GetWritePer(); + bool reentest = SEC_HWA_GetReEnTest(); + if ((true == writeper) && (true == reentest)) + { + SEC_HWA_ReEnTestKey(key); + ret = true; + } + return ret; +} + + + +/** + * @brief This function can used to set the NVR write and read permission. + * @return true means setPer success,false means setPer failed. + * */ +bool SEC_SetNvrPer(NVR_Per per) +{ + bool ret = false; + if (SEC_HWA_GetWritePer()) + { + + if (per.ReadEn == true) + { + SEC_HWA_EnReadB0NVR(); + } + else + { + SEC_HWA_DisReadB0NVR(); + } + if (per.WritEn == true) + { + SEC_HWA_EnWriteB0NVR(); + } + else + { + SEC_HWA_DisWriteB0NVR(); + } + + if (per.EraseEn == true) + { + SEC_HWA_EnEraseB0NVR(); + } + else + { + SEC_HWA_DisEraseB0NVR(); + } + + ret = true; + } + return ret; +} + + +/** + * @brief Get Secure Boot Enable Status + * + * @return true is enable and false is disable + */ +bool SEC_GetSecureStatus(void) +{ + return SEC_HWA_GetSB(); +} + +/** + * @brief Get ISP Status + * + * @return true is active and false is inactive + */ +bool SEC_GetISPModeStatus(void) +{ + return SEC_HWA_GetIspStatus(); +} + +/** + * @brief Get User setting bootloader address + * + * @return bootloader address + */ +uint32_t SEC_GetBootAddress(void) +{ + return SEC_HWA_GetBLAddr(); +} + + +///** +// * @brief Get the HSM Firmware Address +// * +// * @return the HSM Firmware address +// */ +//uint32_t SEC_GetHsmFwAddress(void) +//{ +// return SEC_HWA_GetHsmAddr(); +//} + + +/** + * @brief Get the lifecycle. + * + * @return the lifecycle. + */ + +SC_LifeCycle SEC_GetLifeCycle(void) +{ + SC_LifeCycle lifecycle = LIFECYCLE_INVALID; + + uint8_t lifecycle_status; + lifecycle_status = SEC_HWA_GetLCStaus(); + + switch (lifecycle_status) + { + case 1u: + lifecycle = LIFECYCLE_OEM_DEV; + break; + case 2u: + lifecycle = LIFECYCLE_OEM_PDT; + break; + case 4u: + lifecycle = LIFECYCLE_INFIELD; + break; + case 8u: + lifecycle = LIFECYCLE_PREFA; + break; + case 16u: + lifecycle = LIFECYCLE_FA; + break; + default: + break; + + } + return lifecycle; +} + + + +/** + * @brief User Key Access Enable. Only valid under non-secure boot + * @return true means User key can be read/programmed/erased by host CPU + * */ +bool SEC_HostUKAccess(void) +{ + return SEC_HWA_GetUKAS(); +} + +/** + * @brief get the Bootloader Verification Algorithm + * @return the Bootloader Verification Algorithm + * */ +BL_VerifyAlgorithm SEC_GetBLVerifyAlgorithm(void) +{ + + return (BL_VerifyAlgorithm)(uint8_t)(SEC_HWA_GetBLVer()); +} + + +/** + * @brief get the Debug/ISP/PREFA Authentication and USRK decryption algorithm + * @return decryption algorithm + * */ +Decryption_Algorithm SEC_GetDecryptAlgorithm(void) +{ + return (Decryption_Algorithm)(uint8_t)(SEC_HWA_GetDecrypt()); + + +} + + +/** + * @brief Indicate the Host User Key Read/Write/Erase Protection + * @param PHostUKAccess the structure for information + * + * */ +void SEC_GetHostUKAccess(HostUKPermission *const PHostUKAccess) +{ + PHostUKAccess->HostUKEraseEn = SEC_HWA_GetHUKErase(); + PHostUKAccess->HostUKReadEn = SEC_HWA_GetHUKRead(); + PHostUKAccess->HostUKWriteEn = SEC_HWA_GetHUKWrite(); +} + +/** + * @brief Indicate the Host NVR Read/Write/Erase Protection + *@param PHostNvrAccess the structure to initialize + * */ +void SEC_GetHostNVRAccess(HostNVRPermission *const PHostNVRAccess) +{ + PHostNVRAccess->HostNVREraseEn = SEC_HWA_GetHostNvrErase(); + PHostNVRAccess->HostNVRReadEn = SEC_HWA_GetHostNvrRead(); + PHostNVRAccess->HostNVRWriteEn = SEC_HWA_GetHostNvrWrite(); + +} + + + +/** + * @brief Get the HSM User Key Erase Protection + * @return true - HSM erase access to User Key region is enabled + * false -HSM erase access to User Key region is disabled + * */ +bool SEC_GethsmUKEraseAccess(void) +{ + return SEC_HWA_GetHsmUKErase(); + +} + + +/** + * @brief Get the HSM NVR Erase Protection + * @return true - HSM erase access to NVR region is enabled + * false -HSM erase access to NVR region is disabled + * */ +bool SEC_GethsmNVREraseAccess(void) +{ + return SEC_HWA_GetHsmNvrErase(); +} + +/** + * @brief Get Bootloader Verification Mask + * @return Bootloader Verification Mask. + * */ +uint32_t SEC_GetBLVerMask(void) +{ + return SEC_HWA_GetBLMask(); +} + +/** + * @brief Get whether Debug Backdoor Key Input Enable. + * @return + * 0011b - User can input DBK through debug mailbox, ISP is not valid. + * 1100b - User can input DBK through ISP, debug mailbox is not valid. + * 1111b - User can input DBK through both debug mailbox and ISP. + * Other Values - User cannot input DBK through both debug mailbox andISP. + * */ +uint32_t SEC_GetDMBDkeyEn(void) +{ + return SEC_HWA_GetMBBKEN(); +} + + +/** + * @brief Host Debug Auth Enable. Only valid in secure boot. (Value loaded from NVR sector) + * @return true means Host debug authentication enable. false means Host debug authentication disable. + */ +bool SEC_GetDebugAuthEn(void) +{ + return SEC_HWA_GetDEAUEn(); +} + + +/** + * @brief Get the isp information. + * @param pIspInfo the structure to information + * @return Get whether operation is success. + * + * */ +SEC_RetType SEC_GetIspInfo(SEC_IspInfo *const pIspInfo) +{ + + SEC_RetType eRet ; + + if (NULL == pIspInfo) + { + eRet = SEC_STATUS_FAILED; + } + else + { + bool ispen = SEC_HWA_GetIspStatus(); + if (!ispen) + { + eRet = SEC_STATUS_FAILED; + } + else + { + pIspInfo->IspModeEn = SEC_HWA_GetIspStatus(); + pIspInfo->IspPinEn = SEC_HWA_GetIspEn(); + pIspInfo->IspAuthEn = SEC_HWA_GetISPAU(); + Isp_Instance ispins = (Isp_Instance)(uint8_t)(SEC_HWA_GetIspIns()); + if ((ispins == ISP_FCUART1) || (ispins == ISP_FCUART3)) + { + pIspInfo->Ispfcuartbaudrate = (FCUART_ISP_BAUDRATE)(uint8_t)(SEC_HWA_GetUartBR()); + pIspInfo->Ispflexcanbaudrate = ISP_FLEXCAN_INVALID; + } + else if ((ispins == ISP_FLEXCAN1) || (ispins == ISP_FLEXCAN5)) + { + pIspInfo->Ispfcuartbaudrate = ISP_FCUART_INVALID; + pIspInfo->Ispflexcanbaudrate = (FLEXCAN_ISP_BAUDRATE)(uint8_t)(SEC_HWA_GetCanBR()); + } + else + { + /*do nothing*/ + } + eRet = SEC_STATUS_SUCCESS; + } + } + return eRet; +} + +/** + * @brief Get the boot information. + * @param pBootInfo the structure for information + * @return Get whether operation is success. + * + * */ +SEC_RetType SEC_GetBootInfo(SEC_BootInfo *const pBootInfo) +{ + + SEC_RetType eRet ; + if (NULL == pBootInfo) + { + eRet = SEC_STATUS_FAILED; + } + else + { + pBootInfo->BootRom = SEC_HWA_GetBootRom(); + pBootInfo->NmiPinEn = SEC_HWA_GetNmiPin(); + pBootInfo->SecBootEn = SEC_HWA_GetSB(); + pBootInfo->OscEn = SEC_HWA_GetOSCAvail(); + pBootInfo->OscFreq = (Osc_FreqInfo)(uint8_t)(SEC_HWA_GetOSCFre()); + pBootInfo->FastBootSpeed = (FastBoot_Speed)(uint8_t)(SEC_HWA_GetFastBootClock()); + eRet = SEC_STATUS_SUCCESS; + } + return eRet; +} + + diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_sent.c b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_sent.c new file mode 100644 index 0000000..2111c29 --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_sent.c @@ -0,0 +1,896 @@ +/** + * @file fc7xxx_driver_sent.c + * @author Flagchip + * @brief FC7xxx SENT driver source code + * @version 0.2.0 + * @date 2022-12-30 + * + * @copyright Copyright (c) 2022 Flagchip Semiconductors Co., Ltd. + * + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Author CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2022-12-14 Flagchip N/A First version for FC7300 SENT + * 0.2.0 2022-12-30 Flagchip N/A Support SPC mode for SENT + ******************************************************************************** */ + +#include "fc7xxx_driver_sent.h" +#include "interrupt_manager.h" +#include "HwA_sent.h" + +#define SENT_GLBL_CTL_PRESCALER_MAX 255U +#define SENT_GLBL_CTL_WATERMARK_MAX 16U + +static SENT_Type* const aSent_Base[] = SENT_BASE_PTRS; +static bool aSentInit[SENT_INSTANCE_COUNT] = {0u}; +static SENT_GBISRCallbackType aGBISRCallback[SENT_INSTANCE_MAX] = {NULL}; +static SENT_CHISRCallbackType aCHISRCallback[SENT_INSTANCE_MAX] = {NULL}; + +void SENT0_IRQHandler(void); +void SENT1_IRQHandler(void); + +static void SENT_IRQ_Handler(const Sent_InstanceType eInstance) +{ + uint8_t u8Channel; + uint32_t u32ChannelStatus; + SENT_Type *pSent = aSent_Base[eInstance]; + + + for(u8Channel = 0U; u8Channel < SENT_CHANNEL_COUNT; u8Channel++) + { + if(true == SENT_HWA_GetChannelReceive(pSent, u8Channel)) + { + if(true == SENT_HWA_GetSLowMessageUnderflowFlag(pSent, u8Channel)) + { + if(NULL != aGBISRCallback[eInstance]) + { + SENT_HWA_ClearSLowMessageUnderflowFlag(pSent, u8Channel); + aGBISRCallback[eInstance]((Sent_ChannelType)u8Channel, SENT_SLOW_MSG_DMA_UF_IT); + } + } + if(true == SENT_HWA_GetFastMessageReadyFlag(pSent, u8Channel)) + { + if(NULL != aGBISRCallback[eInstance]) + { + SENT_HWA_ClearFastMessageReadyFlag(pSent, u8Channel); + aGBISRCallback[eInstance]((Sent_ChannelType)u8Channel, SENT_FAST_MSG_READY_IT); + } + } + if(true == SENT_HWA_GetSlowMessageReadyFlag(pSent, u8Channel)) + { + if(NULL != aGBISRCallback[eInstance]) + { + SENT_HWA_ClearSlowMessageReadyFlag(pSent, u8Channel); + aGBISRCallback[eInstance]((Sent_ChannelType)u8Channel, SENT_SLOW_MSG_READY_IT); + } + } + if(true == SENT_HWA_GetFastMessageFIFOOverflowFlag(pSent, u8Channel)) + { + if(NULL != aGBISRCallback[eInstance]) + { + SENT_HWA_ClearFastMessageFIFOOverflowFlag(pSent, u8Channel); + aGBISRCallback[eInstance]((Sent_ChannelType)u8Channel, SENT_FAST_MSG_FIFO_OF_IT); + } + } + if(true == SENT_HWA_GetFastMessageDMAUnderflowFlag(pSent, u8Channel)) + { + if(NULL != aGBISRCallback[eInstance]) + { + SENT_HWA_ClearFastMessageDMAUnderflowFlag(pSent, u8Channel); + aGBISRCallback[eInstance]((Sent_ChannelType)u8Channel, SENT_FAST_MSG_DMA_DF_IT); + } + } + u32ChannelStatus = SENT_HWA_GetChannelStatus(pSent, u8Channel); + if(0U != u32ChannelStatus) + { + if(NULL != aCHISRCallback[eInstance]) + { + SENT_HWA_ClearChannelStatus(pSent, u8Channel, u32ChannelStatus); + aCHISRCallback[eInstance]((Sent_ChannelType)u8Channel, u32ChannelStatus); + } + } + } + } +} + +Sent_ReturnType SENT_Init(const Sent_InstanceType eInstance, const Sent_ConfigType *pCfg) +{ + Sent_ReturnType eRet = SENT_RETURN_OK; + SENT_Type *pSent; + + if(false == aSentInit[eInstance]) + { + if((NULL != pCfg) && (eInstance < SENT_INSTANCE_MAX) && \ + (pCfg->u8DmaWaterMark <= SENT_GLBL_CTL_WATERMARK_MAX) && \ + (pCfg->u8PreScaler < SENT_GLBL_CTL_PRESCALER_MAX)) + { + pSent = aSent_Base[eInstance]; + + SENT_HWA_SetGlobalPreScaler(pSent, pCfg->u8PreScaler); + SENT_HWA_SetDMAWaterMark(pSent, pCfg->u8DmaWaterMark); + if(true == pCfg->bDebugModeEn) + { + SENT_HWA_EnableDebugMode(pSent); + } + else + { + SENT_HWA_DisableDebugMode(pSent); + } + if(true == pCfg->bAutoClearReadyFlag) + { + SENT_HWA_EnableDataOverflowFlagFastClear(pSent); + } + else + { + SENT_HWA_DisableDataOverflowFlagFastClear(pSent); + } + aGBISRCallback[eInstance] = pCfg->pGBCallback; + aCHISRCallback[eInstance] = pCfg->pCHCallback; + SENT_HWA_EnableGlobal(pSent); + aSentInit[eInstance] = true; + } + else + { + eRet = SENT_RETURN_E_PARAM; + } + } + else + { + eRet = SENT_RETURN_E_ALREADY_INIT; + } + + return eRet; +} + +Sent_ReturnType SENT_SetChannelConfig(const Sent_InstanceType eInstance, const Sent_ChannelType eChannel, const Sent_ChannelConfigType *pCfg) +{ + Sent_ReturnType eRet = SENT_RETURN_OK; + SENT_Type *pSent; + + if(true == aSentInit[eInstance]) + { + if((NULL != pCfg) && (eInstance < SENT_INSTANCE_MAX) && (eChannel < SENT_CHANNEL_MAX)) + { + pSent = aSent_Base[eInstance]; + if(true == pCfg->bChannelEn) + { + if((pCfg->u8DataNibbleNumber > 0U) && (pCfg->u8DataNibbleNumber < 6U)) + { + SENT_HWA_DisableChannelReceive(pSent, (uint8_t)eChannel); + + SENT_HWA_SetChannelIdleCount(pSent, (uint8_t)eChannel, (uint8_t)pCfg->eIdleCount); + SENT_HWA_SetChannelDigitalFilterCount(pSent, (uint8_t)eChannel, pCfg->u8DigitalFilterCount); + SENT_HWA_SetChannelNibbleNumber(pSent, (uint8_t)eChannel, pCfg->u8DataNibbleNumber); + SENT_HWA_SetChannelPreScaler(pSent, (uint8_t)eChannel, (uint16_t)pCfg->u16TickScaler); + SENT_HWA_SetChannelNibbleDataMode(pSent, (uint8_t)eChannel, (SENT_NibbleDataModeType)(pCfg->eDataNibbleMode)); + + if(SENT_CALIBRATION_PULSE_DIAG_OPTION1 != pCfg->eCalDiagOption) + { + SENT_HWA_DisableChannelSPCOption1(pSent, (uint8_t)eChannel); + } + else + { + SENT_HWA_EnableChannelSPCOption1(pSent, (uint8_t)eChannel); + } + if(true == pCfg->bPausePulseEn) + { + SENT_HWA_EnableChannelPausePulse(pSent, (uint8_t)eChannel); + } + else + { + SENT_HWA_DisableChannelPausePulse(pSent, (uint8_t)eChannel); + } + if(true == pCfg->bTickCompensateEn) + { + SENT_HWA_EnableChannelCompensate(pSent, (uint8_t)eChannel); + } + else + { + SENT_HWA_DisableChannelCompensate(pSent, (uint8_t)eChannel); + } + + if(true == pCfg->bFastMessageFifoEn) + { + SENT_HWA_EnableChannelFIFO(pSent, (uint8_t)eChannel); + } + else + { + SENT_HWA_DisableChannelFIFO(pSent, (uint8_t)eChannel); + } + + if(true == pCfg->bFastMsgCRCAugEn) + { + SENT_HWA_EnableChannelFastMessageAugmentation(pSent, (uint8_t)eChannel); + } + else + { + SENT_HWA_DisableChannelFastMessageAugmentation(pSent, (uint8_t)eChannel); + } + + if(true == pCfg->bFastMsgCRCCheckEn) + { + SENT_HWA_EnableChannelFastMessageCRCCheck(pSent, (uint8_t)eChannel); + } + else + { + SENT_HWA_DisableChannelFastMessageCRCCheck(pSent, (uint8_t)eChannel); + } + + if(true == pCfg->bFastMsgCRCWithSCEn) + { + SENT_HWA_EnableChannelFastMessageCRCWithSC(pSent, (uint8_t)eChannel); + } + else + { + SENT_HWA_DisableChannelFastMessageCRCWithSC(pSent, (uint8_t)eChannel); + } + + if(true == pCfg->bFastMsgDataChangeEn) + { + SENT_HWA_EnableChannelFastMessageDataChange(pSent, (uint8_t)eChannel); + } + else + { + SENT_HWA_DisableChannelFastMessageDataChange(pSent, (uint8_t)eChannel); + } + + + if(true == pCfg->bSlowMsgCRCAugEn) + { + SENT_HWA_EnableChannelSlowMessageAugmentation(pSent, (uint8_t)eChannel); + } + else + { + SENT_HWA_DisableChannelSlowMessageAugmentation(pSent, (uint8_t)eChannel); + } + + if(true == pCfg->bUseAlternativeCrc) + { + SENT_HWA_EnableChannelAltCRC(pSent, (uint8_t)eChannel); + } + else + { + SENT_HWA_DisableChannelAltCRC(pSent, (uint8_t)eChannel); + } + + if(SENT_CALIBRATION_VALID_WITHIN_20 == pCfg->eCalValid) + { + SENT_HWA_DisableChannelCalValid20To25(pSent, (uint8_t)eChannel); + SENT_HWA_EnableChannelCalValidDiagnostic(pSent, (uint8_t)eChannel); + } + else if(SENT_CALIBRATION_VALID_FROM_20_TO_25 == pCfg->eCalValid) + { + SENT_HWA_EnableChannelCalValid20To25(pSent, (uint8_t)eChannel); + SENT_HWA_EnableChannelCalValidDiagnostic(pSent, (uint8_t)eChannel); + } + else + { + SENT_HWA_DisableChannelCalValid20To25(pSent, (uint8_t)eChannel); + SENT_HWA_DisableChannelCalValidDiagnostic(pSent, (uint8_t)eChannel); + } + SENT_HWA_EnableChannelReceive(pSent, (uint8_t)eChannel); + } + else + { + eRet = SENT_RETURN_E_PARAM; + } + } + else + { + SENT_HWA_DisableChannelReceive(pSent, (uint8_t)eChannel); + } + } + } + else + { + eRet = SENT_RETURN_E_UNINIT; + } + + return eRet; +} + +Sent_ReturnType SENT_SetDMAConfig(const Sent_InstanceType eInstance, const Sent_ChannelType eChannel, Sent_DMAConfigType *pCfg) +{ + Sent_ReturnType eRet = SENT_RETURN_OK; + SENT_Type *pSent; + + if(true == aSentInit[eInstance]) + { + if((NULL != pCfg) && (eInstance < SENT_INSTANCE_MAX) && (eChannel < SENT_CHANNEL_MAX)) + { + pSent = aSent_Base[eInstance]; + + if(true == pCfg->bFastMsgDmaEn) + { + SENT_HWA_EnableChannelFastMessageDmaRequest(pSent, (uint8_t)eChannel); + } + else + { + SENT_HWA_DisableChannelFastMessageDmaRequest(pSent, (uint8_t)eChannel); + } + + if(true == pCfg->bSlowMsgDmaEn) + { + SENT_HWA_EnableChannelSlowMessageDmaRequest(pSent, (uint8_t)eChannel); + } + else + { + SENT_HWA_DisableChannelSlowMessageDmaRequest(pSent, (uint8_t)eChannel); + } + } + else + { + eRet = SENT_RETURN_E_PARAM; + } + } + else + { + eRet = SENT_RETURN_E_UNINIT; + } + + return eRet; +} + +Sent_ReturnType SENT_SetSPCConfig(const Sent_InstanceType eInstance, const Sent_ChannelType eChannel, const Sent_SpcConfigType *pCfg) +{ + Sent_ReturnType eRet = SENT_RETURN_OK; + SENT_Type *pSent; + + if(true == aSentInit[eInstance]) + { + if((NULL != pCfg) && (eInstance < SENT_INSTANCE_MAX) && (eChannel < SENT_CHANNEL_MAX)) + { + pSent = aSent_Base[eInstance]; + + SENT_HWA_DisableChannelSPCMode(pSent, (uint8_t)eChannel); + SENT_HWA_SetChannelSPCTickBase(pSent, (uint8_t)eChannel, (SENT_SPCTickType)(pCfg->eSpcTickBase)); + SENT_HWA_SetChannelSPCTriggerMethod(pSent, (uint8_t)eChannel, (SENT_SPCTriggerType)(pCfg->eSpcTrigger)); + SENT_HWA_SetChannelSPCPulseDelay(pSent, (uint8_t)eChannel, pCfg->u8PulseDelay); + SENT_HWA_SetChannelSPCPulseWidth(pSent, (uint8_t)eChannel, pCfg->u8PulseWidth); + if(true == pCfg->bCalDiagEn) + { + SENT_HWA_EnableChannelCalibrationDiag(pSent, (uint8_t)eChannel); + } + else + { + SENT_HWA_DisableChannelCalibrationDiag(pSent, (uint8_t)eChannel); + } + if(true == pCfg->bSpcModeEn) + { + SENT_HWA_EnableChannelSPCMode(pSent, (uint8_t)eChannel); + } + else + { + SENT_HWA_DisableChannelSPCMode(pSent, (uint8_t)eChannel); + } + } + else + { + eRet = SENT_RETURN_E_PARAM; + } + } + else + { + eRet = SENT_RETURN_E_UNINIT; + } + + return eRet; +} + +Sent_ReturnType SENT_GetFastMessageData(const Sent_InstanceType eInstance, const Sent_ChannelType eChannel, Sent_FastMessageDataType *pMsg) +{ + Sent_ReturnType eRet = SENT_RETURN_OK; + SENT_Type *pSent; + uint8_t u8DataShift; + + if(true == aSentInit[eInstance]) + { + if((NULL != pMsg) && (eInstance < SENT_INSTANCE_MAX) && (eChannel < SENT_CHANNEL_MAX)) + { + pSent = aSent_Base[eInstance]; + + pMsg->u8CRC = SENT_HWA_GetChannelFastMessageCRCNibble(pSent, (uint8_t)eChannel); + pMsg->u8SC = SENT_HWA_GetChannelFastMessageStatusNibble(pSent, (uint8_t)eChannel); + pMsg->u32Timestamp = SENT_HWA_GetChannelFastMessageTimeStamp(pSent, (uint8_t)eChannel); + u8DataShift = (5U - SENT_HWA_GetChannelNibbleNumber(pSent, (uint8_t)eChannel)) << 2U; + pMsg->u32Data = SENT_HWA_GetChannelDataNibble(pSent, (uint8_t)eChannel) >> (SENT_CHN_FDATA_DATA6_SHIFT + u8DataShift); + } + else + { + eRet = SENT_RETURN_E_PARAM; + } + } + else + { + eRet = SENT_RETURN_E_UNINIT; + } + + return eRet; +} + +Sent_ReturnType SENT_GetSlowMessageData(const Sent_InstanceType eInstance, const Sent_ChannelType eChannel, Sent_SlowMessageDataType *pMsg) +{ + Sent_ReturnType eRet = SENT_RETURN_OK; + SENT_Type *pSent; + + if(true == aSentInit[eInstance]) + { + if((NULL != pMsg) && (eInstance < SENT_INSTANCE_MAX) && (eChannel < SENT_CHANNEL_MAX)) + { + pSent = aSent_Base[eInstance]; + + pMsg->eMsgType = (Sent_SerialMessageType)SENT_HWA_GetChannelSLowMessageType(pSent, (uint8_t)eChannel); + pMsg->u32Timestamp = SENT_HWA_GetChannelSlowMessageTimeStamp(pSent, (uint8_t)eChannel); + if(SENT_SERIAL_MESSAGE_SHORT == pMsg->eMsgType) + { + pMsg->u8CRC = SENT_HWA_GetChannelBit2CRC(pSent, (uint8_t)eChannel) & 0xFU; + pMsg->u16Data = (uint16_t)SENT_HWA_GetChannelBit2DATA(pSent, (uint8_t)eChannel) & 0xFFU; + pMsg->u8ID = SENT_HWA_GetChannelBit2DATA(pSent, (uint8_t)eChannel) >> 8U; + } + else if(SENT_SERIAL_MESSAGE_ENHANCE_12DATA_8ID == pMsg->eMsgType) + { + pMsg->u8CRC = SENT_HWA_GetChannelBit2CRC(pSent, (uint8_t)eChannel); + pMsg->u16Data = SENT_HWA_GetChannelBit2DATA(pSent, (uint8_t)eChannel); + pMsg->u8ID = (SENT_HWA_GetChannelBit3EnhancedID7_4_OR_ID3_0(pSent, (uint8_t)eChannel) << 4U) | SENT_HWA_GetChannelBit3EnhancedID3_0_OR_DATA15_12(pSent, (uint8_t)eChannel); + } + else if(SENT_SERIAL_MESSAGE_ENHANCE_16DATA_4ID == pMsg->eMsgType) + { + pMsg->u8CRC = SENT_HWA_GetChannelBit2CRC(pSent, (uint8_t)eChannel); + pMsg->u16Data = ((uint16_t)SENT_HWA_GetChannelBit3EnhancedID3_0_OR_DATA15_12(pSent, (uint8_t)eChannel) << 12U) | (uint16_t)SENT_HWA_GetChannelBit2DATA(pSent, (uint8_t)eChannel); + pMsg->u8ID = SENT_HWA_GetChannelBit3EnhancedID7_4_OR_ID3_0(pSent, (uint8_t)eChannel); + } + else + { + eRet = SENT_RETURN_E_NOT_OK; + } + } + else + { + eRet = SENT_RETURN_E_PARAM; + } + } + else + { + eRet = SENT_RETURN_E_UNINIT; + } + + return eRet; +} + +Sent_ReturnType SENT_DecodeFastMessageWithDMABuffer(uint32_t *pDmaBuffer, uint32_t u32BufferLength, Sent_FastMessageDataType *pMsg) +{ + Sent_ReturnType eRet = SENT_RETURN_OK; + + if((NULL != pMsg) && (NULL != pDmaBuffer) && (12U == u32BufferLength)) + { + pMsg->u8CRC = (uint8_t)((pDmaBuffer[1] & SENT_CHN_FCRC_CRC_DATA_MASK) >> SENT_CHN_FCRC_CRC_DATA_SHIFT); + pMsg->u8SC = (uint8_t)((pDmaBuffer[1] & SENT_CHN_FCRC_SC_NB_MASK) >> SENT_CHN_FCRC_SC_NB_SHIFT); + pMsg->u32Timestamp = ((pDmaBuffer[2] & SENT_CHN_FTS_TIMESTAMP_VAL_MASK) >> SENT_CHN_FTS_TIMESTAMP_VAL_SHIFT); + pMsg->u32Data = (pDmaBuffer[0] >> SENT_CHN_FDATA_DATA6_SHIFT); + } + else + { + eRet = SENT_RETURN_E_PARAM; + } + + return eRet; +} + +Sent_ReturnType SENT_DecodeSlowMessageWithDMABuffer(uint32_t *pDmaBuffer, uint32_t u32BufferLength, Sent_SlowMessageDataType *pMsg) +{ + Sent_ReturnType eRet = SENT_RETURN_OK; + + if((NULL != pMsg) && (NULL != pDmaBuffer) && (12U == u32BufferLength)) + { + if(SENT_CHN_SBIT3__MSG_TYPE_MASK == (pDmaBuffer[0] & SENT_CHN_SBIT3__MSG_TYPE_MASK)) + { + if(SENT_CHN_SBIT3__CFG_MASK == (pDmaBuffer[0] & SENT_CHN_SBIT3__CFG_MASK)) + { + pMsg->eMsgType = (Sent_SerialMessageType)SENT_SLOW_MESSAGE_ENHANCE_16DATA_4ID; + } + else + { + pMsg->eMsgType = (Sent_SerialMessageType)SENT_SLOW_MESSAGE_ENHANCE_12DATA_8ID; + } + } + else + { + pMsg->eMsgType = (Sent_SerialMessageType)SENT_SLOW_MESSAGE_SHORT; + } + pMsg->u32Timestamp = ((pDmaBuffer[2] & SENT_CHN_STS_SMSG_TIMESTAMP_MASK) >> SENT_CHN_STS_SMSG_TIMESTAMP_SHIFT); + if(SENT_SERIAL_MESSAGE_SHORT == pMsg->eMsgType) + { + pMsg->u8CRC =(uint8_t)(((pDmaBuffer[1] & SENT_CHN_SBIT2__SMSG_CRC_MASK) >> SENT_CHN_SBIT2__SMSG_CRC_SHIFT) & 0xFU); + pMsg->u16Data = (uint16_t)(((pDmaBuffer[1] & SENT_CHN_SBIT2__SMSG_DATA_MASK) >> SENT_CHN_SBIT2__SMSG_DATA_SHIFT) & 0xFFU); + pMsg->u8ID = (uint8_t)(((pDmaBuffer[1] & SENT_CHN_SBIT2__SMSG_DATA_MASK) >> SENT_CHN_SBIT2__SMSG_DATA_SHIFT) >> 8U); + } + else if(SENT_SERIAL_MESSAGE_ENHANCE_12DATA_8ID == pMsg->eMsgType) + { + pMsg->u8CRC = (uint8_t)((pDmaBuffer[1] & SENT_CHN_SBIT2__SMSG_CRC_MASK) >> SENT_CHN_SBIT2__SMSG_CRC_SHIFT); + pMsg->u16Data = (uint16_t)((pDmaBuffer[1] & SENT_CHN_SBIT2__SMSG_DATA_MASK) >> SENT_CHN_SBIT2__SMSG_DATA_SHIFT); + pMsg->u8ID = (uint8_t)((((pDmaBuffer[0] & SENT_CHN_SBIT3__ID7_4_OR_ID3_0_MASK) >> SENT_CHN_SBIT3__ID7_4_OR_ID3_0_SHIFT) << 4U) |\ + ((pDmaBuffer[0] & SENT_CHN_SBIT3__ID3_0_OR_DATA15_12_MASK) >> SENT_CHN_SBIT3__ID3_0_OR_DATA15_12_SHIFT)); + } + else if(SENT_SERIAL_MESSAGE_ENHANCE_16DATA_4ID == pMsg->eMsgType) + { + pMsg->u8CRC = (uint8_t)((pDmaBuffer[1] & SENT_CHN_SBIT2__SMSG_CRC_MASK) >> SENT_CHN_SBIT2__SMSG_CRC_SHIFT); + pMsg->u16Data = (uint16_t)((((pDmaBuffer[0] & SENT_CHN_SBIT3__ID3_0_OR_DATA15_12_MASK) >> SENT_CHN_SBIT3__ID3_0_OR_DATA15_12_SHIFT) << 12U) |\ + ((pDmaBuffer[1] & SENT_CHN_SBIT2__SMSG_DATA_MASK) >> SENT_CHN_SBIT2__SMSG_DATA_SHIFT)); + pMsg->u8ID = (uint8_t)((pDmaBuffer[0] & SENT_CHN_SBIT3__ID7_4_OR_ID3_0_MASK) >> SENT_CHN_SBIT3__ID7_4_OR_ID3_0_SHIFT); + } + else + { + eRet = SENT_RETURN_E_NOT_OK; + } + } + else + { + eRet = SENT_RETURN_E_PARAM; + } + + return eRet; +} + +Sent_ReturnType SENT_EnableGlobalFastMsgNotification(const Sent_InstanceType eInstance, const Sent_ChannelType eChannel) +{ + Sent_ReturnType eRet = SENT_RETURN_OK; + SENT_Type *pSent; + + if(true == aSentInit[eInstance]) + { + if((eInstance < SENT_INSTANCE_MAX) && (eChannel < SENT_CHANNEL_MAX)) + { + pSent = aSent_Base[eInstance]; + + SENT_HWA_EnableChannelFastMessageInterrupt(pSent, (uint8_t)eChannel); + } + else + { + eRet = SENT_RETURN_E_PARAM; + } + } + else + { + eRet = SENT_RETURN_E_UNINIT; + } + + return eRet; +} + +Sent_ReturnType SENT_DisableGlobalFastMsgNotification(const Sent_InstanceType eInstance, const Sent_ChannelType eChannel) +{ + Sent_ReturnType eRet = SENT_RETURN_OK; + SENT_Type *pSent; + + if(true == aSentInit[eInstance]) + { + if((eInstance < SENT_INSTANCE_MAX) && (eChannel < SENT_CHANNEL_MAX)) + { + pSent = aSent_Base[eInstance]; + + SENT_HWA_DisableChannelFastMessageInterrupt(pSent, (uint8_t)eChannel); + } + else + { + eRet = SENT_RETURN_E_PARAM; + } + } + else + { + eRet = SENT_RETURN_E_UNINIT; + } + + return eRet; +} + +Sent_ReturnType SENT_EnableGlobalSlowMsgNotification(const Sent_InstanceType eInstance, const Sent_ChannelType eChannel) +{ + Sent_ReturnType eRet = SENT_RETURN_OK; + SENT_Type *pSent; + + if(true == aSentInit[eInstance]) + { + if((eInstance < SENT_INSTANCE_MAX) && (eChannel < SENT_CHANNEL_MAX)) + { + pSent = aSent_Base[eInstance]; + + SENT_HWA_EnableChannelSlowMessageInterrupt(pSent, (uint8_t)eChannel); + } + else + { + eRet = SENT_RETURN_E_PARAM; + } + } + else + { + eRet = SENT_RETURN_E_UNINIT; + } + + return eRet; +} + +Sent_ReturnType SENT_DisableGlobalSlowMsgNotification(const Sent_InstanceType eInstance, const Sent_ChannelType eChannel) +{ + Sent_ReturnType eRet = SENT_RETURN_OK; + SENT_Type *pSent; + + if(true == aSentInit[eInstance]) + { + if((eInstance < SENT_INSTANCE_MAX) && (eChannel < SENT_CHANNEL_MAX)) + { + pSent = aSent_Base[eInstance]; + + SENT_HWA_DisableChannelSlowMessageInterrupt(pSent, (uint8_t)eChannel); + } + else + { + eRet = SENT_RETURN_E_PARAM; + } + } + else + { + eRet = SENT_RETURN_E_UNINIT; + } + + return eRet; +} + +Sent_ReturnType SENT_EnableGlobalFastFifoMsgNotification(const Sent_InstanceType eInstance) +{ + Sent_ReturnType eRet = SENT_RETURN_OK; + SENT_Type *pSent; + + if(true == aSentInit[eInstance]) + { + if(eInstance < SENT_INSTANCE_MAX) + { + pSent = aSent_Base[eInstance]; + + SENT_HWA_EnableFastMessageFIFOOverflowInterrupt(pSent); + } + else + { + eRet = SENT_RETURN_E_PARAM; + } + } + else + { + eRet = SENT_RETURN_E_UNINIT; + } + + return eRet; +} + +Sent_ReturnType SENT_DisableGlobalFastFifoMsgNotification(const Sent_InstanceType eInstance) +{ + Sent_ReturnType eRet = SENT_RETURN_OK; + SENT_Type *pSent; + + if(true == aSentInit[eInstance]) + { + if(eInstance < SENT_INSTANCE_MAX) + { + pSent = aSent_Base[eInstance]; + + SENT_HWA_DisableFastMessageFIFOOverflowInterrupt(pSent); + } + else + { + eRet = SENT_RETURN_E_PARAM; + } + } + else + { + eRet = SENT_RETURN_E_UNINIT; + } + + return eRet; +} + +Sent_ReturnType SENT_ConfigChannelStatusNotification(const Sent_InstanceType eInstance, const Sent_ChannelType eChannel, const Sent_ChannelInterruptType *sInterruptEn) +{ + Sent_ReturnType eRet = SENT_RETURN_OK; + SENT_Type *pSent; + + if(true == aSentInit[eInstance]) + { + if((eInstance < SENT_INSTANCE_MAX) && (eChannel < SENT_CHANNEL_MAX)) + { + pSent = aSent_Base[eInstance]; + + SENT_HWA_EnableChannelBusIdleInterrupt(pSent, (uint8_t)eChannel, sInterruptEn->bBusIdleITEn); + SENT_HWA_EnableChannelSPCOverRunInterrupt(pSent, (uint8_t)eChannel, sInterruptEn->bSpcOverrunITEn); + SENT_HWA_EnableChannelCALDiagInterrupt(pSent, (uint8_t)eChannel, sInterruptEn->bCalDiagErrITEn); + SENT_HWA_EnableChannelCalFailInterrupt(pSent, (uint8_t)eChannel, sInterruptEn->bCalFailITEn); + SENT_HWA_EnableChannelCalResyncInterrupt(pSent, (uint8_t)eChannel, sInterruptEn->bCalResyncErrITEn); + SENT_HWA_EnableChannelEdgeERRInterrupt(pSent, (uint8_t)eChannel, sInterruptEn->bFallingEdgeNumErrITEn); + SENT_HWA_EnableChannelFCRCInterrupt(pSent, (uint8_t)eChannel, sInterruptEn->bFastMsgCrcErrITEn); + SENT_HWA_EnableChannelFOVFLInterrupt(pSent, (uint8_t)eChannel, sInterruptEn->bFastMsgOFITEn); + SENT_HWA_EnableChannelNibbleErrorInterrupt(pSent, (uint8_t)eChannel, sInterruptEn->bNibbleValueErrITEn); + SENT_HWA_EnableChannelPPDiagInterrupt(pSent, (uint8_t)eChannel, sInterruptEn->bPrePulseDiagErrITEn); + SENT_HWA_EnableChannelSCRCInterrupt(pSent, (uint8_t)eChannel, sInterruptEn->bSlowMsgCrcErrITEn); + SENT_HWA_EnableChannelSOVFLInterrupt(pSent, (uint8_t)eChannel, sInterruptEn->bSlowMsgOFITEn); + SENT_HWA_EnableChannelCalERRInterrupt(pSent, (uint8_t)eChannel, sInterruptEn->bCalErrITEn); + //SENT_HWA_EnableChannelAllErrorInterrupt(pSent, eChannel); + } + else + { + eRet = SENT_RETURN_E_PARAM; + } + } + else + { + eRet = SENT_RETURN_E_UNINIT; + } + + return eRet; +} + +Sent_ReturnType SENT_RequestSPCPulse(const Sent_InstanceType eInstance, const Sent_ChannelType eChannel) +{ + Sent_ReturnType eRet = SENT_RETURN_OK; + SENT_Type *pSent; + + if(true == aSentInit[eInstance]) + { + if((eInstance < SENT_INSTANCE_MAX) && (eChannel < SENT_CHANNEL_MAX)) + { + pSent = aSent_Base[eInstance]; + + SENT_HWA_StartChannelSPC(pSent, (uint8_t)eChannel); + } + else + { + eRet = SENT_RETURN_E_PARAM; + } + } + else + { + eRet = SENT_RETURN_E_UNINIT; + } + + return eRet; +} + +Sent_ReturnType SENT_GetFastMsgReadyFlag(const Sent_InstanceType eInstance, const Sent_ChannelType eChannel, bool *pFlag) +{ + Sent_ReturnType eRet = SENT_RETURN_OK; + SENT_Type *pSent; + + if(true == aSentInit[eInstance]) + { + if((eInstance < SENT_INSTANCE_MAX) && (eChannel < SENT_CHANNEL_MAX)) + { + pSent = aSent_Base[eInstance]; + + *pFlag = SENT_HWA_GetFastMessageReadyFlag(pSent, (uint8_t)eChannel); + } + else + { + eRet = SENT_RETURN_E_PARAM; + } + } + else + { + eRet = SENT_RETURN_E_UNINIT; + } + + return eRet; +} + +Sent_ReturnType SENT_GetSlowMsgReadyFlag(const Sent_InstanceType eInstance, const Sent_ChannelType eChannel, bool *pFlag) +{ + Sent_ReturnType eRet = SENT_RETURN_OK; + SENT_Type *pSent; + + if(true == aSentInit[eInstance]) + { + if((eInstance < SENT_INSTANCE_MAX) && (eChannel < SENT_CHANNEL_MAX)) + { + pSent = aSent_Base[eInstance]; + + *pFlag = SENT_HWA_GetSlowMessageReadyFlag(pSent, (uint8_t)eChannel); + } + else + { + eRet = SENT_RETURN_E_PARAM; + } + } + else + { + eRet = SENT_RETURN_E_UNINIT; + } + + return eRet; +} + +Sent_ReturnType SENT_GetChannelStatus(const Sent_InstanceType eInstance, const Sent_ChannelType eChannel, uint32_t *pStatus) +{ + Sent_ReturnType eRet = SENT_RETURN_OK; + SENT_Type *pSent; + + if(true == aSentInit[eInstance]) + { + if((eInstance < SENT_INSTANCE_MAX) && (eChannel < SENT_CHANNEL_MAX)) + { + pSent = aSent_Base[eInstance]; + + *pStatus = SENT_HWA_GetChannelStatus(pSent, (uint8_t)eChannel); + } + else + { + eRet = SENT_RETURN_E_PARAM; + } + } + else + { + eRet = SENT_RETURN_E_UNINIT; + } + + return eRet; +} + +Sent_ReturnType SENT_ClearChannelStatus(const Sent_InstanceType eInstance, const Sent_ChannelType eChannel, uint32_t Status) +{ + Sent_ReturnType eRet = SENT_RETURN_OK; + SENT_Type *pSent; + + if(true == aSentInit[eInstance]) + { + if((eInstance < SENT_INSTANCE_MAX) && (eChannel < SENT_CHANNEL_MAX)) + { + pSent = aSent_Base[eInstance]; + + SENT_HWA_ClearChannelStatus(pSent, (uint8_t)eChannel, Status); + } + else + { + eRet = SENT_RETURN_E_PARAM; + } + } + else + { + eRet = SENT_RETURN_E_UNINIT; + } + + return eRet; +} + +Sent_ReturnType SENT_GetChannelSPCBusyFlag(const Sent_InstanceType eInstance, const Sent_ChannelType eChannel, bool *pflag) +{ + Sent_ReturnType eRet = SENT_RETURN_OK; + SENT_Type *pSent; + + if(true == aSentInit[eInstance]) + { + if((eInstance < SENT_INSTANCE_MAX) && (eChannel < SENT_CHANNEL_MAX)) + { + pSent = aSent_Base[eInstance]; + + *pflag = SENT_HWA_GetChanneSPCBusyFlag(pSent, (uint8_t)eChannel); + } + else + { + eRet = SENT_RETURN_E_PARAM; + } + } + else + { + eRet = SENT_RETURN_E_UNINIT; + } + + return eRet; +} + +void SENT0_IRQHandler(void) +{ + SENT_IRQ_Handler(SENT_INSTANCE_0); +} + +void SENT1_IRQHandler(void) +{ + SENT_IRQ_Handler(SENT_INSTANCE_1); +} diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_smc.c b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_smc.c new file mode 100644 index 0000000..cdb4ec0 --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_smc.c @@ -0,0 +1,122 @@ +/** + * @file fc7xxx_driver_smc.c + * @author Flagchip0105 + * @brief FC7xxx SMC driver type definition and API + * @version 0.1.0 + * @date 2024-01-08 + * + * @copyright Copyright (c) 2023 Flagchip Semiconductors Co., Ltd. + * + * @details + */ +/******************************************************************************** +* Revision History: +* +* Version Date Initials CR# Descriptions +* --------- ---------- ------------ ---------- --------------- +* 0.1.0 2024-01-08 Flagchip0105 N/A FC7240 First version +********************************************************************************/ +#include "fc7xxx_driver_smc.h" + +/** + * @brief Set system mode + * + * @param eMode MCU low power mode + * @return Smc return type + */ +SMC_StatusType SMC_SetSystemMode(const SMC_ModeType eMode) +{ + SMC_StatusType eRet = SMC_STATUS_SUCCESS; + + DEV_ASSERT(eMode <= SMC_MODE_STANBY_3); + + switch (eMode) + { + case SMC_MODE_RUN: + /* Clear the SLEEPDEEP bit to disable deep sleep mode */ + CM7_HWA_DisableDeepSleep(); + + break; + case SMC_MODE_STOP: + /* switch smc mode to stop mode */ + SMC_HWA_SetStopModeCtrl(SMC_STOP_MODE); + /* Set the SLEEPDEEP bit to enable deep sleep mode (STOP)*/ + CM7_HWA_EnableDeepSleep(); + + /* Cpu is going into deep sleep state */ + STANDBY(); + + break; + + case SMC_MODE_WAIT: + /* Clear the SLEEPDEEP bit to disable deep sleep mode */ + CM7_HWA_DisableDeepSleep(); + + /* Cpu is going into sleep state */ + STANDBY(); + + break; + + case SMC_MODE_STANBY_0: + /* select standby mode*/ + SMC_HWA_SetStandbyMode(SMC_CFG_STANDBY_0); + + /* switch smc mode to standby mode */ + SMC_HWA_SetStopModeCtrl(SMC_STANDBY_MODE); + /* Set the SLEEPDEEP bit to enable deep sleep mode */ + CM7_HWA_EnableDeepSleep(); + + /* Cpu is going into deep sleep state */ + STANDBY(); + + break; + + case SMC_MODE_STANBY_1: + /* select standby mode*/ + SMC_HWA_SetStandbyMode(SMC_CFG_STANDBY_1); + + /* switch smc mode to standby mode */ + SMC_HWA_SetStopModeCtrl(SMC_STANDBY_MODE); + + /* Set the SLEEPDEEP bit to enable deep sleep mode */ + CM7_HWA_EnableDeepSleep(); + + /* Cpu is going into deep sleep state */ + STANDBY(); + break; + + case SMC_MODE_STANBY_2: + /* select standby mode*/ + SMC_HWA_SetStandbyMode(SMC_CFG_STANDBY_2); + + /* switch smc mode to standby mode */ + SMC_HWA_SetStopModeCtrl(SMC_STANDBY_MODE); + + /* Set the SLEEPDEEP bit to enable deep sleep mode */ + CM7_HWA_EnableDeepSleep(); + + /* Cpu is going into deep sleep state */ + STANDBY(); + break; + + case SMC_MODE_STANBY_3: + /* select standby mode*/ + SMC_HWA_SetStandbyMode(SMC_CFG_STANDBY_3); + + /* switch smc mode to standby mode */ + SMC_HWA_SetStopModeCtrl(SMC_STANDBY_MODE); + + /* Set the SLEEPDEEP bit to enable deep sleep mode */ + CM7_HWA_EnableDeepSleep(); + + /* Cpu is going into deep sleep state */ + STANDBY(); + break; + default: + /* do nothing */ + break; + + } + + return eRet; +} diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_stcu.c b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_stcu.c new file mode 100644 index 0000000..30e5385 --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_stcu.c @@ -0,0 +1,202 @@ +/** + * @file fc7xxx_driver_stcu.c + * @author Flagchip + * @brief FC4xxx stcu driver type definition and API + * @version 0.1.0 + * @date 2023-02-15 + * + * @copyright Copyright (c) 2022 Flagchip Semiconductors Co., Ltd. + * + */ + +/* ******************************************************************************** + * Revision History: + * + * Version Date Author CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 1/10/2024 Flagchip0095 N/A First version for FC7240 + ******************************************************************************** */ +#include "HwA_stcu.h" +#include "fc7xxx_driver_stcu.h" + + + +/* ################################################################################## */ +/* ##################################### Macros ##################################### */ +#define STCU_SAFETY_KEY (0xBB40E64DU) +#define STCU_RECOMMENDED_PATTERN (0xBUL) + + +/* ################################################################################## */ +/* ################################# Local Variables ################################ */ + +/* ################################################################################## */ +/* ########################### Local Functions Prototype ############################ */ + +/* ################################################################################## */ +/* ######################### Global Functions prototype ############################ */ +void STCU0_IRQHandler(void); + +/* ################################################################################## */ +/* ################################# Local Functions ############################### */ +static Stcu_IRQCallback sIRQCallback = NULL; + +/* ################################################################################## */ +/* ################################# Global Functions ############################### */ + +/** + * \brief Init the STCU module + * + * \param pConfig the configuration structure + */ +void STCU_Init(STCU_ConfigType *pConfig) +{ + uint32_t u32Reg; + + STCU_HWA_MbistSelect(pConfig->u32MbistSel); + + STCU_HWA_SetMBISTSWAlg(pConfig->bMbistFullTest, pConfig->bMbistSramInit); + + pConfig->bInterruptEn?STCU_HWA_EnableInterrupt():STCU_HWA_DisableInterrupt(); + + sIRQCallback = pConfig->pIrqCallback; + + u32Reg = STCU_SELF_TEST_CTRL_LBIST_CLKDIV((uint32_t)(pConfig->eLbistClkDivider)) | + STCU_SELF_TEST_CTRL_LBIST_EN(pConfig->bLbistEn?1UL:0UL) | + STCU_SELF_TEST_CTRL_MBIST_LP(pConfig->bMbistLPC?1UL:0UL) | + STCU_SELF_TEST_CTRL_MBIST_EN(pConfig->bMbistEn?1UL:0UL) | + STCU_SELF_TEST_CTRL_CLK_SEL((uint32_t)(pConfig->eClkSource)) | + STCU_SELF_TEST_CTRL_MT(pConfig->u16MaxTime) | + STCU_SELF_TEST_CTRL_PE(STCU_PORT_PULL_DISABLE == pConfig->ePortPullMode?0UL:1UL) | + STCU_SELF_TEST_CTRL_PS(STCU_PORT_PULL_UP == pConfig->ePortPullMode?1UL:0UL) | + STCU_SELF_TEST_CTRL_FCSMU_TRIG(0U) | /* FCSMU reset will trigger self-test */ + STCU_SELF_TEST_CTRL_LBIST_TD(1U) | /* enable LBIST at-speed test */ + STCU_SELF_TEST_CTRL_SCHK_EN(1U) | /* self check enable */ + STCU_SELF_TEST_CTRL_STEST_BYPASS(0U);/* self-test will be not bypassed */ + + STCU_HWA_SetSelfTestCTRL(u32Reg); +} + +/** + * \brief Set the LBIST Pattern value and expected misr value. + * The two value should be load from NVR, but also can reconfigure by this API. + * The expected misr value is calculated from pattern, so please make sure this two value is right, or the LBST would fail. + * + * \param u16Pattern the LBIST Pattern value + * \param u16Pattern the LBIST expected misr value + */ +void STCU_LBIST_Set_Pattern_Misr(uint16_t u16Pattern, uint32_t u32ExpectedMisr) +{ + STCU_HWA_SetLBISTPatternAmount(u16Pattern); + STCU_HWA_SetExpectedMisr(u32ExpectedMisr); +} + +/** + * \brief Trigger to start Software self test + * + */ +void STCU_StartSelfTest(void) +{ + /* clear STCU_SELF_TEST_STATUS. */ + STCU_HWA_ClearSelfTestStatus(); + + STCU_HWA_SetSafetyKey(STCU_SAFETY_KEY); /* enable STCU_SELF_TEST_CTRL A/B access */ + + /* set the TRIG bits in both STCU_SELF_TEST_TRIG_A and STCU_SELF_TEST_TRIG_B. */ + STCU_HWA_SwTriggerA(); + STCU_HWA_SwTriggerB(); +} + +/** + * \brief Check Software Trigger Self-test result. If the LBIST is done, could call "STCU_GetLbistFailResult" to check the test result. + * If the MBIST is done, could call "STCU_GetMbistFailResult" to check the test result. + * + * \return refer to "STCU_SelfTestStatusType" enum. + */ +uint32_t STCU_CheckTriggerResult(void) +{ + return STCU_HWA_GetSelfTestStatus(); +} + +/** + * \brief Get each MBIST Fail result + * + * \return refer to "STCU_MbistFailedType" enum. + */ +uint32_t STCU_GetMbistFailResult(void) +{ + uint32_t u32Done, u32Fail; + + u32Done = STCU_GetMbistDone(); + u32Fail = STCU_GetMbistFail(); + + return (u32Done & u32Fail); +} + +/** + * \brief Get if the LBIST test result is Fail + * + * \return true means LBIST fail. false means LBIST pass. + */ +bool STCU_GetLbistFailResult(void) +{ + uint32_t u32status; + + u32status = STCU_HWA_CheckLbistStatus(); + + u32status = (u32status >> STCU_LBIST_STATUS_FAIL_SHIFT) & (u32status & STCU_LBIST_STATUS_DONE_MASK); + + return (0UL == u32status?false:true); +} + +/** + * \brief Initial DTCM with hardware + */ +void STCU_StartRamInit(STCU_InitRamConfigType *pInitCfg) +{ + STCU_HWA_SetRamInitType( pInitCfg->u32InitRamType); + STCU_HWA_StartRamInit(pInitCfg->eInitMode,pInitCfg->bLockAfterEn); +} + +/** + * \brief Get status of RAM initialize action, for more detail, could call "STCU_GetRamInitDoneStatus" + * to get more info for each SRAM + * \return the status of ram initialize action, refer to "STCU_HardwareInitRamStatusType" + */ +uint32_t STCU_GetRamInitStatus(void) +{ + return STCU_HWA_GetRamInitStatus(); +} + +/** + * \brief Get each done status of SRAM initialize + * + * \return the done status of SRAM initialize action, refer to "STCU_InitRamDoneType" + */ +uint32_t STCU_GetRamInitDoneStatus(void) +{ + return STCU_HWA_GetRamInitDone(); +} + +/** + * \brief Get LBIST actual MISR value, the value should be read and use DFT tool to decode it, if LBIST test resault is fail. + * + * \return the LBIST actual MISR value + */ +uint32_t STCU_GetLbistAcutalMisr(void) +{ + return STCU_HWA_GetActualMisr(); +} + + +void STCU0_IRQHandler(void) +{ + uint32_t u32Flag; + + u32Flag = STCU_HWA_GetInterruptFlag(); + STCU_HWA_ClearInterruptFlag(); + if(NULL != sIRQCallback) + { + sIRQCallback(u32Flag); + } +} diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_systick.c b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_systick.c new file mode 100644 index 0000000..3136b49 --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_systick.c @@ -0,0 +1,60 @@ +#include "fc7xxx_driver_systick.h" + + + +/** + * \brief Config system tick + * + * \param u32ReloadVal reload value, val is decrease from reload value + * \return 0 is ok, and others are not ok + */ +uint8_t Core_SysTick_Config(uint32_t u32ReloadVal) +{ + uint8_t u8Retval; + + if (u32ReloadVal > SysTick_LOAD_RELOAD_Msk) + { + u8Retval = 1U; + } + else + { + SysTick->LOAD = u32ReloadVal; /* set reload register */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk; /* Processor clock */ + u8Retval = 0U; + } + + return u8Retval; +} + +void Core_SysTick_DeConfig(void) +{ + SysTick->CTRL = 0U; + SysTick->LOAD = 0U; + SysTick->VAL = 0U; +} + +void Core_SysTick_ClearValue(void) +{ + SysTick->VAL = 0U; +} + +void Core_SysTick_SetValue(uint32_t u32Value) +{ + SysTick->VAL = u32Value; +} + +uint32_t Core_SysTick_GetValue(void) +{ + return SysTick->VAL; +} + +void Core_SysTick_Enable(void) +{ + SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ +} + +void Core_SysTick_Disable(void) +{ + SysTick->CTRL &= ~(SysTick_CTRL_ENABLE_Msk); +} diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_tmu.c b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_tmu.c new file mode 100644 index 0000000..c1cc487 --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_tmu.c @@ -0,0 +1,312 @@ +/** + * @file fc7xxx_driver_tmu.c + * @author Flagchip + * @brief FC7xxx TMU driver source code + * @version 0.1.0 + * @date 2023-12-29 + * + * @copyright Copyright (c) 2023 Flagchip Semiconductors Co., Ltd. + * + * @details + */ +/********************************************************************************* +* Revision History: +* +* Version Date Initials CR# Descriptions +* --------- ---------- ------------ ---------- --------------- +* 0.1.0 2023-12-29 qxw074 N/A First version for FC7240 +******************************************************************************** */ + +#include "fc7xxx_driver_tmu.h" +#include "fc7xxx_driver_pcc.h" +#include "interrupt_manager.h" + +/********* Local Variables ************/ +/** @brief TMU peripheral base pointers */ +static TMU_Type *const s_apTmuBase = TMU_BASE_PTRS; +/** @brief Temperature over 150 Celsius notify callback function point */ +static TMU_TempOver150InterruptCallbackType s_apTmuOver150Notify = NULL; +/** @brief Temperature over 125 Celsius notify callback function point */ +static TMU_TempOver125InterruptCallbackType s_apTmuOver125Notify = NULL; +/** @brief The Flag-based temperature sensor ready notify callback function point */ +static TMU_TempFlagReadyInterruptCallbackType s_apTmuFlagReadyNotify = NULL; +/** @brief The Voltage-based temperature sensor ready notify callback function point */ +static TMU_TempVoltageReadyInterruptCallbackType s_apTmuVoltgeReadyNotify = NULL; + +/***************TMU IRQ Functions*****************/ +/** @brief TMU interrupt entry */ +void TMU_IRQHandler(void); +/** + * @brief TMU irq handler + * + */ +void TMU_IRQHandler(void) +{ + TMU_Type *const pTmu = s_apTmuBase; + if (TMU_HWA_GetFlagTemperature150InterruptFlag(pTmu) == true) + { + if (TMU_HWA_Get150Flag(pTmu) == true) + { + if (s_apTmuOver150Notify != NULL) + { + s_apTmuOver150Notify(); + } + TMU_HWA_Clear150Flag(pTmu); + } + } + if (TMU_HWA_GetFlagTemperature125InterruptFlag(pTmu) == true) + { + if (TMU_HWA_Get125Flag(pTmu) == true) + { + if (s_apTmuOver125Notify != NULL) + { + s_apTmuOver125Notify(); + } + TMU_HWA_Clear125Flag(pTmu); + } + } + if (TMU_HWA_GetFlagTemperatureReadyInterruptFlag(pTmu) == true) + { + if (TMU_HWA_GetFlagTemperatureReady(pTmu) == true) + { + if (s_apTmuFlagReadyNotify != NULL) + { + s_apTmuFlagReadyNotify(); + } + TMU_HWA_SetTemperatureLockStatus(pTmu, TMU_TF_TV_UNLOCK); + TMU_HWA_SetFlagTemperatureReadyInterruptFlag(pTmu, false); + TMU_HWA_SetTemperatureLockStatus(pTmu, TMU_TF_TV_LOCK); + } + } + if (TMU_HWA_GetVoltageTemperatureReadyInterruptFlag(pTmu) == true) + { + if (TMU_HWA_GetVoltageTemperatureReady(pTmu) == true) + { + if (s_apTmuVoltgeReadyNotify != NULL) + { + s_apTmuVoltgeReadyNotify(); + } + TMU_HWA_SetTemperatureLockStatus(pTmu, TMU_TF_TV_UNLOCK); + TMU_HWA_SetVoltageTemperatureReadyInterruptFlag(pTmu, false); + TMU_HWA_SetTemperatureLockStatus(pTmu, TMU_TF_TV_LOCK); + } + } +} + +/** + * @brief Initialize the TMU instance + * + * @param pInitCfg the configurations of the TMU instance + */ +void TMU_Init(const TMU_InitType *const pInitCfg) +{ + DEV_ASSERT(pInitCfg != NULL); + + TMU_Type *const pTmu = s_apTmuBase; + uint32_t u32FlagCtrl; + uint32_t u32VoltageCtrl; + uint8_t u8FlagStartupCnt; + uint8_t u8VoltageStartupCnt; + + PCC_ClkSrcType eAdcClkName = PCC_CLK_TMU0; + uint32_t u32TmuClk; + u32TmuClk = PCC_GetPccFunctionClock(eAdcClkName); + + u8FlagStartupCnt = (uint8_t)((u32TmuClk * 11U) / 127000000U + 1U); + u8VoltageStartupCnt = (uint8_t)((u32TmuClk * 5U) / 127000000U + 1U); + if (u8FlagStartupCnt > 15U) + { + u8FlagStartupCnt = 15U; + } + if (u8VoltageStartupCnt > 7U) + { + u8VoltageStartupCnt = 7U; + } + + u32FlagCtrl = TMU_TF_CTRL_TF_150F_IE(pInitCfg->bTemperatureOver150IntEn) | + TMU_TF_CTRL_TF_125F_IE(pInitCfg->bTemperatureOver125IntEn) | + TMU_TF_CTRL_TF_RDYF_IE(pInitCfg->bFlagTempReadyIntEn) | + TMU_TF_CTRL_TF_HYSOFF(pInitCfg->eFlagTempHysteresisCon) | + TMU_TF_CTRL_TF_START_CNT(u8FlagStartupCnt) | + TMU_TF_CTRL_TF_FILT_BYP(pInitCfg->eFlagTempFilterBypassCon); + TMU_HWA_SetFlagTempCtrl(pTmu, u32FlagCtrl); + + u32VoltageCtrl = TMU_TV_CTRL_TV_RDYF_IE(pInitCfg->bVoltageTempReadyIntEn) | + TMU_TV_CTRL_TV_START_CNT(u8VoltageStartupCnt); + TMU_HWA_SetVoltageTempCtrl(pTmu, u32VoltageCtrl); + + TMU_HWA_SetStopAck(pInitCfg->bSmicsStopAckEn); + + /* interrupt callback function */ + s_apTmuOver150Notify = pInitCfg->pTemp150Notify; + s_apTmuOver125Notify = pInitCfg->pTemp125Notify; + s_apTmuFlagReadyNotify = pInitCfg->pFlagReadyNotify; + s_apTmuVoltgeReadyNotify = pInitCfg->pVoltagReadyNotify; + + TMU_HWA_SetTemperatureLockStatus(pTmu, TMU_TF_TV_LOCK); +} + +/** + * @brief Enable the Flag-based temperature sensor + * + * @return TMU_StatusType TMU_STATUS_SUCCESS when enable successfully, others fail + */ +TMU_StatusType TMU_FlagTempEnable(void) +{ + TMU_StatusType eRet; + uint32_t u32TimeOut = 15000000U; + TMU_Type *const pTmu = s_apTmuBase; + + TMU_HWA_SetTemperatureLockStatus(pTmu, TMU_TF_TV_UNLOCK); + TMU_HWA_SetFlagTemperatureEnableStatus(pTmu, true); + while ((TMU_HWA_GetFlagTemperatureReady(pTmu) != true) && (u32TimeOut != 0U)) + { + u32TimeOut--; + } + if (u32TimeOut != 0U) + { + eRet = TMU_STATUS_SUCCESS; + TMU_HWA_ClearFlagTemperatureReady(pTmu); + } + else + { + eRet = TMU_STATUS_TIMEOUT; + } + TMU_HWA_SetTemperatureLockStatus(pTmu, TMU_TF_TV_LOCK); + return eRet; +} + +/** + * @brief Disable the Flag-based temperature sensor + * + * @return TMU_StatusType TMU_STATUS_SUCCESS when disable successfully, others fail + */ +TMU_StatusType TMU_FlagTempDisable(void) +{ + TMU_StatusType eRet; + uint32_t u32TimeOut = 15000000U; + TMU_Type *const pTmu = s_apTmuBase; + + TMU_HWA_SetTemperatureLockStatus(pTmu, TMU_TF_TV_UNLOCK); + TMU_HWA_SetFlagTemperatureEnableStatus(pTmu, false); + TMU_HWA_ClearFlagTemperatureReady(pTmu); + while ((TMU_HWA_GetFlagTemperatureEnableStatus(pTmu) == true) && (u32TimeOut != 0U)) + { + u32TimeOut--; + } + if (u32TimeOut != 0U) + { + eRet = TMU_STATUS_SUCCESS; + } + else + { + eRet = TMU_STATUS_TIMEOUT; + } + TMU_HWA_SetTemperatureLockStatus(pTmu, TMU_TF_TV_LOCK); + return eRet; +} + +/** + * @brief Enable the Voltage-based temperature sensor + * + * @return TMU_StatusType TMU_STATUS_SUCCESS when enable successfully, others fail + */ +TMU_StatusType TMU_VoltageTempEnable(void) +{ + TMU_StatusType eRet; + uint32_t u32TimeOut = 15000000U; + TMU_Type *const pTmu = s_apTmuBase; + + TMU_HWA_SetTemperatureLockStatus(pTmu, TMU_TF_TV_UNLOCK); + TMU_HWA_SetVoltageTemperatureEnableStatus(pTmu, true); + while ((TMU_HWA_GetVoltageTemperatureReady(pTmu) != true) && (u32TimeOut != 0U)) + { + u32TimeOut--; + } + if (u32TimeOut != 0U) + { + eRet = TMU_STATUS_SUCCESS; + TMU_HWA_ClearVoltageTemperatureReady(pTmu); + } + else + { + eRet = TMU_STATUS_TIMEOUT; + } + TMU_HWA_SetTemperatureLockStatus(pTmu, TMU_TF_TV_LOCK); + return eRet; +} + +/** + * @brief Disable the Voltage-based temperature sensor + * + * @return TMU_StatusType TMU_STATUS_SUCCESS when disable successfully, others fail + */ +TMU_StatusType TMU_VoltageTempDisable(void) +{ + TMU_StatusType eRet; + uint32_t u32TimeOut = 15000000U; + TMU_Type *const pTmu = s_apTmuBase; + + TMU_HWA_SetTemperatureLockStatus(pTmu, TMU_TF_TV_UNLOCK); + TMU_HWA_SetVoltageTemperatureEnableStatus(pTmu, false); + TMU_HWA_ClearVoltageTemperatureReady(pTmu); + while ((TMU_HWA_GetVoltageTemperatureEnableStatus(pTmu) == true) && (u32TimeOut != 0U)) + { + u32TimeOut--; + } + if (u32TimeOut != 0U) + { + eRet = TMU_STATUS_SUCCESS; + } + else + { + eRet = TMU_STATUS_TIMEOUT; + } + TMU_HWA_SetTemperatureLockStatus(pTmu, TMU_TF_TV_LOCK); + return eRet; +} + +/** + * @brief Check if cleaning flag is required + * + */ +void TMU_TempOverClear(void) +{ + TMU_Type *const pTmu = s_apTmuBase; + if (TMU_HWA_Get150Flag(pTmu)) + { + if (!TMU_HWA_Get150Status(pTmu)) + { + TMU_HWA_Clear150Flag(pTmu); + } + } + if (TMU_HWA_Get125Flag(pTmu)) + { + if (!TMU_HWA_Get125Status(pTmu)) + { + TMU_HWA_Clear125Flag(pTmu); + } + } +} + +/** + * @brief Get the temperature code from ADC + * + * @return uint32_t the value records the ADC conversion results for voltage-based temperature sensor result in 135 Celsius + */ +uint32_t TMU_GetTcode(void) +{ + TMU_Type *const pTmu = s_apTmuBase; + return TMU_HWA_GetTemperatureCode(pTmu); +} + +/** + * @brief Get the slope factor + * + * @return uint32_t the value records the slope factor for voltage-based temperature sensor + */ +uint32_t TMU_GetTslope(void) +{ + TMU_Type *const pTmu = s_apTmuBase; + return TMU_HWA_GetSlopeFactor(pTmu); +} diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_tpu.c b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_tpu.c new file mode 100644 index 0000000..c8d72c1 --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_tpu.c @@ -0,0 +1,596 @@ + +/** + * @file module_driver_tpu.c + * @author Flagchip099 + * @brief FC7xxx TPU driver source code + * @version 0.1.0 + * @date 2024-1-12 + * + * @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd. + * + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2024-1-12 Flagchip099 N/A First version for FC7240 + ******************************************************************************** */ + +#include "fc7xxx_driver_tpu.h" + +static uint32_t u32PwmLastFrame[TPU_E_CH_COUNT]; +static uint32_t u32PwmNextEdge[TPU_E_CH_COUNT]; +static bool bMeasActivePeriodComplete[TPU_E_CH_COUNT] = {(bool)false}; +static TPU_HSACallbackType s_TpuHSANotify[TPU_E_CH_COUNT] = {NULL}; +static TPU_EventCallbackType s_TpuEventNotify[TPU_E_CH_COUNT] = {NULL}; +static TPU_TCR1OverflowCallbackType s_TpuTCR1OverflowNotify = NULL; +static TPU_TCR2OverflowCallbackType s_TpuTCR2OverflowNotify = NULL; + + +void TPU0_CH0_7_IRQHandler(void); +void TPU0_CH8_15_IRQHandler(void); +void TPU0_CH16_23_IRQHandler(void); +void TPU0_CH24_31_IRQHandler(void); + +/** + * @brief TPU_Overflow_IRQHandler + * + */ +static inline void TPU_Overflow_IRQHandler(void) +{ + TPU_E_Type *const pTpuE = TPU_E_BASE_PTRS; + if (TPU_E_HWA_GetTCR1Overflow(pTpuE)) + { + TPU_E_HWA_ClearTCR1Overflow(pTpuE); + if (s_TpuTCR1OverflowNotify != NULL) + { + s_TpuTCR1OverflowNotify(); + } + } + if (TPU_E_HWA_GetTCR2Overflow(pTpuE)) + { + TPU_E_HWA_ClearTCR2Overflow(pTpuE); + if (s_TpuTCR2OverflowNotify != NULL) + { + s_TpuTCR2OverflowNotify(); + } + } +} + +/** + * @brief TPU_Event_IRQHandler + * + */ +static inline void TPU_Event_IRQHandler(uint8_t u8MinChannel, uint8_t u8MaxChannel) +{ + TPU_H_Type *const pTpuH = TPU_H_BASE_PTRS; + uint8_t u8Channel; + + for (u8Channel = (uint8_t)u8MinChannel; u8Channel < ((uint8_t)u8MaxChannel + 1u); u8Channel++) + { + if (TPU_H_HWA_GetChEventTrigISRStatus(pTpuH, u8Channel) == true) + { + if (s_TpuEventNotify[u8Channel] != NULL) + { + s_TpuEventNotify[u8Channel](); + } + } + if (TPU_H_HWA_GetChHSAReqStatus(pTpuH, u8Channel) == true) + { + TPU_H_HWA_ClearChHSA(pTpuH, u8Channel); + s_TpuHSANotify[u8Channel](); + } + } +} + +/** + * @brief TPU_InitOverflowInterrupt + * + */ +static void TPU_InitOverflowInterrupt(const TPU_InterruptCfgType *const pInterruptCfg) +{ + DEV_ASSERT(pInterruptCfg != NULL); + + TPU_E_Type *const pTPUE = TPU_E_BASE_PTRS; + + if (pInterruptCfg->bTCR1OverFlowEventIntEn) + { + s_TpuTCR1OverflowNotify = pInterruptCfg->pTCR1OverflowNotify; + TPU_E_HWA_EnableTCR1OVFIRQ(pTPUE, (bool)true); + } + else + { + TPU_E_HWA_EnableTCR1OVFIRQ(pTPUE, (bool)false); + s_TpuTCR1OverflowNotify = NULL; + } + + if (pInterruptCfg->bTCR2OverFlowEventIntEn) + { + s_TpuTCR2OverflowNotify = pInterruptCfg->pTCR2OverflowNotify; + TPU_E_HWA_EnableTCR2OVFIRQ(pTPUE, (bool)true); + } + else + { + TPU_E_HWA_EnableTCR2OVFIRQ(pTPUE, (bool)false); + s_TpuTCR2OverflowNotify = NULL; + } +} + +/** + * @brief TPU0_CH0_7_IRQHandler + * + */ +void TPU0_CH0_7_IRQHandler(void) +{ + TPU_Event_IRQHandler(TPU_CHANNEL_0, TPU_CHANNEL_7); +} + +/** + * @brief TPU0_CH8_15_IRQHandler + * + */ +void TPU0_CH8_15_IRQHandler(void) +{ + TPU_Event_IRQHandler(TPU_CHANNEL_8, TPU_CHANNEL_15); +} + +/** + * @brief TPU0_CH16_23_IRQHandler + * + */ +void TPU0_CH16_23_IRQHandler(void) +{ + TPU_Event_IRQHandler(TPU_CHANNEL_16, TPU_CHANNEL_23); +} + +/** + * @brief TPU0_CH24_31_IRQHandler + * + */ +void TPU0_CH24_31_IRQHandler(void) +{ + TPU_Overflow_IRQHandler(); + TPU_Event_IRQHandler(TPU_CHANNEL_24, TPU_CHANNEL_31); +} + +/** + * @brief TPU_InitChannelInterrupt + * + */ +void TPU_InitChannelInterrupt(uint8_t u8Channel, const TPU_InterruptCfgType *const pInterruptCfg) +{ + DEV_ASSERT(u8Channel < TPU_E_CH_COUNT); + DEV_ASSERT(pInterruptCfg != NULL); + + TPU_E_Type *const pTPUE = TPU_E_BASE_PTRS; + TPU_H_Type *const pTPUH = TPU_H_BASE_PTRS; + + if (pInterruptCfg->bEventIntEn) + { + s_TpuEventNotify[u8Channel] = pInterruptCfg->pEventNotify; + TPU_E_HWA_EnableChEventInt(pTPUE, u8Channel, (bool)true); + TPU_E_HWA_EnableSrvReq(pTPUE, u8Channel, (bool)true); + TPU_H_HWA_SetChTrig(pTPUH, u8Channel, pInterruptCfg->eChTrigType); + } + else + { + s_TpuEventNotify[u8Channel] = NULL; + } + TPU_InitOverflowInterrupt(pInterruptCfg); +} + +/** + * @brief TPU_Init + * + */ +void TPU_Init(void) +{ + TPU_E_Type *const pTPUE = TPU_E_BASE_PTRS; + + SCM_HWA_SUBSYS_PCC_SetEnable_TPUClock((bool)true); + TPU_E_HWA_SetTimeBaseCntStopInStopMode(pTPUE, (bool)true); +} + +/** + * @brief TPU_DeInit + * + */ +void TPU_DeInit(void) +{ + TPU_E_Type *const pTPUE = TPU_E_BASE_PTRS; + + TPU_E_HWA_TrigReset(pTPUE); +} + +/** + * @brief TPU_StartChannel + * + */ +void TPU_StartChannel(void) +{ + SCM_HWA_ConfigTpuGTBSelect((bool)true); +} + +/** + * @brief TPU_SetHSR + * + */ +void TPU_SetHSR(uint8_t u8channel, uint8_t u8HSRIdx) +{ + TPU_H_Type *const pTPUH = TPU_H_BASE_PTRS; + + TPU_H_HWA_SetChHSA(pTPUH, u8channel, true); + TPU_H_HWA_SetChHSRIdx(pTPUH, u8channel, u8HSRIdx); + TPU_H_HWA_SetChHSRISR(pTPUH, u8channel, (bool)true); + TPU_H_HWA_SetChSyncISR(pTPUH, u8channel, (bool)false); +} + +/** + * @brief TPU_SendHSR + * + */ +void TPU_SendHSR(uint8_t u8channel) +{ + TPU_H_Type *const pTPUH = TPU_H_BASE_PTRS; + + TPU_H_HWA_ClearChHSR(pTPUH, u8channel); +} + +/** + * @brief TPU_GetHSA + * + */ +uint8_t TPU_GetHSA(uint8_t u8Channel) +{ + TPU_H_Type *const pTPUH = TPU_H_BASE_PTRS; + + return TPU_H_HWA_GetChHSAIdx(pTPUH, (uint8_t)u8Channel); +} + +/** + * @brief TPU_InitChannelInterrupt + * + */ +void TPU_InitChannelHSAInterrupt(uint8_t u8Channel, const TPU_InterruptCfgType *const pInterruptCfg) +{ + s_TpuHSANotify[u8Channel] = pInterruptCfg->pHSANotify; +} + +/** + * @brief TPU_InitChannelOverflowInterrupt + * + */ +void TPU_InitChannelOverflowInterrupt(const TPU_InterruptCfgType *const pInterruptCfg) +{ + s_TpuTCR1OverflowNotify = pInterruptCfg->pTCR1OverflowNotify; + s_TpuTCR2OverflowNotify = pInterruptCfg->pTCR2OverflowNotify; +} + +/** + * @brief TPU_EnableSubSystem + * + */ +void TPU_EnableSubSystem(void) +{ + SCM_HWA_SUBSYS_PCC_SetEnable_SubSystemClock((bool)true); +} + +/** + * @brief TPU_EnableEventTrigDma + * + */ +void TPU_EnableEventTrigDma(uint8_t u8Channel) +{ + TPU_H_Type *const pTPUH = TPU_H_BASE_PTRS; + + TPU_H_HWA_SetChEventDMAEnable(pTPUH, (uint8_t)u8Channel, (bool)true); +} + +void TPU_EnableEventTrigTrgSel(uint8_t u8Channel, const TPU_InterruptCfgType *const pInterruptCfg) +{ + TPU_H_Type *const pTPUH = TPU_H_BASE_PTRS; + + TPU_H_HWA_SetChTrig(pTPUH, u8Channel, pInterruptCfg->eChTrigType); +} + +/** + * @brief TPU_EnableFlexcoreTrigDma + * + */ +void TPU_EnableFlexcoreTrigDma(uint8_t u8Channel) +{ + TPU_H_Type *const pTPUH = TPU_H_BASE_PTRS; + + TPU_H_HWA_SetChReqDMAEnable(pTPUH, (uint8_t)u8Channel, (bool)true); +} + +/** + * @brief TPU_PwmModeInit + * + */ +void TPU_PwmModeInit(uint8_t u8channel, const TPU_PwmCfgType *const p_etpu_config) +{ + TPU_E_Type *const pTPUE = TPU_E_BASE_PTRS; + uint32_t u32ER1_Val; + + TPU_E_HWA_ClearMatch1CFGFlg(pTPUE, u8channel); + TPU_E_HWA_ClearMatch1Event(pTPUE, u8channel); + TPU_E_HWA_ClearTransDetect1Event(pTPUE, u8channel); + TPU_E_HWA_ClearMatch2CFGFlg(pTPUE, u8channel); + TPU_E_HWA_ClearMatch2Event(pTPUE, u8channel); + TPU_E_HWA_ClearTransDetect2Event(pTPUE, u8channel); + TPU_E_HWA_SetOPAC1(pTPUE, u8channel, TPUE_NO_CHANGE_OUTPUT); + TPU_E_HWA_SetOPAC2(pTPUE, u8channel, TPUE_NO_CHANGE_OUTPUT); + TPU_E_HWA_SetTCR1ClkControl(pTPUE, TPUE_TCR1CLK_CLK_SRC_TPUCLKDIV2); + TPU_E_HWA_SetPDCM(pTPUE, u8channel, TPUE_EM_NB_ST); + TPU_E_HWA_SetTCR1MaxCnt(pTPUE, TPU_TCR1_MAXVALUE); + TPU_E_HWA_SetTCR2MaxCnt(pTPUE, TPU_TCR1_MAXVALUE); + + if (p_etpu_config->bPwmUseTCR1) + { + TPU_E_HWA_SetMatchER1(pTPUE, u8channel, (TPU_E_HWA_GetTCR1CntVal(pTPUE) + 1U)); + u32ER1_Val = TPU_E_HWA_GetER1Val(pTPUE, u8channel); + TPU_E_HWA_SetER2(pTPUE, u8channel, (p_etpu_config->u32ActiveTime + u32ER1_Val)); + } + + u32PwmNextEdge[u8channel] = TPU_E_HWA_GetER2Val(pTPUE, u8channel); + + TPU_E_HWA_SetChOutputActiveHigh(pTPUE, u8channel, p_etpu_config->bActiveHigh); + if (p_etpu_config->bActiveHigh) + { + TPU_E_HWA_SetOPAC1(pTPUE, u8channel, TPUE_MATCH_SET_OUTPUT_HIGH); + TPU_E_HWA_SetOPAC2(pTPUE, u8channel, TPUE_MATCH_SET_OUTPUT_LOW); + TPU_E_HWA_SetChTBS1(pTPUE, u8channel, p_etpu_config->eTBS1); + TPU_E_HWA_SetChTBS2(pTPUE, u8channel, p_etpu_config->eTBS2); + TPU_E_HWA_SetChEntryTblflag1(pTPUE, u8channel, (bool)true); + } + else + { + TPU_E_HWA_SetOPAC1(pTPUE, u8channel, TPUE_MATCH_SET_OUTPUT_LOW); + TPU_E_HWA_SetOPAC2(pTPUE, u8channel, TPUE_MATCH_SET_OUTPUT_HIGH); + TPU_E_HWA_SetChTBS1(pTPUE, u8channel, p_etpu_config->eTBS1); + TPU_E_HWA_SetChTBS2(pTPUE, u8channel, p_etpu_config->eTBS2); + TPU_E_HWA_SetChEntryTblflag1(pTPUE, u8channel, (bool)false); + } + /* Set channel priority */ + + /* Here do not enable NVIC */ + + TPU_E_HWA_SetOutputSelOPAC1(pTPUE, u8channel, (bool)true); + TPU_E_HWA_SetOutputSelOPAC2(pTPUE, u8channel, (bool)true); + TPU_E_HWA_EnableChOutputBuf(pTPUE, u8channel, (bool)true); + TPU_E_HWA_EnableMatch(pTPUE, u8channel, (bool)true); + TPU_E_HWA_EnableSrvReq(pTPUE, u8channel, (bool)true); + + return; +} + +/** + * @brief TPU_PwmServiceReq + * + */ +void TPU_PwmServiceReq(uint8_t u8channel, uint32_t u32ActiveTime, uint32_t u32Period) +{ + TPU_E_Type *const pTPUE = TPU_E_BASE_PTRS; + + if (TPU_E_HWA_GetChMatchRecLatch1Status(pTPUE, u8channel) == (bool)true) + { + /* in match1 */ + TPU_E_HWA_ClearMatch1Event(pTPUE, u8channel); + TPU_E_HWA_SetChEntryTblflag0(pTPUE, u8channel, (bool)false); + u32PwmLastFrame[u8channel] = TPU_E_HWA_GetER1Val(pTPUE, u8channel); + /* Next ER1 */ + if ((u32PwmLastFrame[u8channel] + u32Period) > TPU_TCR1_MAXVALUE) + { + TPU_E_HWA_SetMatchER1(pTPUE, u8channel, (u32PwmLastFrame[u8channel] + u32Period - TPU_TCR1_MAXVALUE - 1U)); + } + else + { + TPU_E_HWA_SetMatchER1(pTPUE, u8channel, (u32PwmLastFrame[u8channel] + u32Period)); + } + + if ((TPU_E_HWA_GetER1Val(pTPUE, u8channel) + u32ActiveTime) > TPU_TCR1_MAXVALUE) + { + u32PwmNextEdge[u8channel] = TPU_E_HWA_GetER1Val(pTPUE, u8channel) + u32ActiveTime - TPU_TCR1_MAXVALUE - 1U; + } + else + { + u32PwmNextEdge[u8channel] = TPU_E_HWA_GetER1Val(pTPUE, u8channel) + u32ActiveTime; + } + TPU_E_HWA_EnableMatch(pTPUE, u8channel, (bool)true); + } + else if (TPU_E_HWA_GetChMatchRecLatch2Status(pTPUE, u8channel) == (bool)true) + { + /* in match2 */ + TPU_E_HWA_ClearMatch2Event(pTPUE, u8channel); + TPU_E_HWA_SetChEntryTblflag0(pTPUE, u8channel, (bool)true); + /* Next ER2 */ + TPU_E_HWA_SetER2(pTPUE, u8channel, u32PwmNextEdge[u8channel]); + TPU_E_HWA_EnableMatch(pTPUE, u8channel, (bool)true); + } + TPU_E_HWA_ClearChEventISRFlg(pTPUE, (uint8_t)u8channel); +} + +/** + * @brief TPU_CaptureModeInit + * + */ +void TPU_CaptureModeInit(uint8_t u8channel, const TPU_CaptureCfgType *const p_etpu_config) +{ + TPU_E_Type *const pTPUE = TPU_E_BASE_PTRS; + + TPU_E_HWA_ClearMatchEn1(pTPUE, u8channel); + TPU_E_HWA_ClearMatch1CFGFlg(pTPUE, u8channel); + TPU_E_HWA_ClearMatch1Event(pTPUE, u8channel); + TPU_E_HWA_ClearTransDetect1Event(pTPUE, u8channel); + TPU_E_HWA_ClearMatch2CFGFlg(pTPUE, u8channel); + TPU_E_HWA_ClearMatch2Event(pTPUE, u8channel); + TPU_E_HWA_ClearTransDetect2Event(pTPUE, u8channel); + TPU_E_HWA_SetTCR1ClkControl(pTPUE, TPUE_TCR1CLK_CLK_SRC_TPUCLKDIV2); + TPU_E_HWA_SetChTBS1(pTPUE, u8channel, TPUE_GREATER_OR_EQUAL_CAPBASE_TCR1_MATCHBASE_TCR1); + TPU_E_HWA_SetChTBS2(pTPUE, u8channel, TPUE_GREATER_OR_EQUAL_CAPBASE_TCR1_MATCHBASE_TCR1); + TPU_E_HWA_SetOPAC1(pTPUE, u8channel, TPUE_NO_CHANGE_OUTPUT); + TPU_E_HWA_SetOPAC2(pTPUE, u8channel, TPUE_NO_CHANGE_OUTPUT); + TPU_E_HWA_SetChEntryTblflag1(pTPUE, u8channel, (bool)false); + TPU_E_HWA_SetChEntryTblflag0(pTPUE, u8channel, (bool)false); + TPU_E_HWA_SetTCR1MaxCnt(pTPUE, TPU_TCR1_MAXVALUE); + TPU_E_HWA_SetTCR2MaxCnt(pTPUE, TPU_TCR1_MAXVALUE); + + if (p_etpu_config->eMeasureMode == TPU_DutyMeasurementActiveHigh) + { + TPU_E_HWA_SetPDCM(pTPUE, u8channel, TPUE_SM_DT); + TPU_E_HWA_SetIPAC1(pTPUE, u8channel, TPUE_DETECT_RISING_EDGE_ONLY); + TPU_E_HWA_SetIPAC2(pTPUE, u8channel, TPUE_DETECT_FALLING_EDGE_ONLY); + } + else if (p_etpu_config->eMeasureMode == TPU_DutyMeasurementActiveLow) + { + TPU_E_HWA_SetPDCM(pTPUE, u8channel, TPUE_SM_DT); + TPU_E_HWA_SetIPAC1(pTPUE, u8channel, TPUE_DETECT_FALLING_EDGE_ONLY); + TPU_E_HWA_SetIPAC2(pTPUE, u8channel, TPUE_DETECT_RISING_EDGE_ONLY); + } + else if (p_etpu_config->eMeasureMode == TPU_PeriodMeasurement) + { + TPU_E_HWA_SetPDCM(pTPUE, u8channel, TPUE_SM_ST); + TPU_E_HWA_SetIPAC1(pTPUE, u8channel, p_etpu_config->eInputType); + TPU_E_HWA_SetIPAC2(pTPUE, u8channel, TPUE_NO_TRANSITIONS); + } + else + { + /* do nothing */ + } + + TPU_E_HWA_SetMatchER1(pTPUE, u8channel, (TPU_E_HWA_GetTCR1CntVal(pTPUE) + p_etpu_config->u32SampleTime)); + TPU_E_HWA_EnableTransContinue(pTPUE, u8channel, (bool)true); + + /* Here not set channel priority */ + + /* Here not enable NVIC */ + + TPU_E_HWA_EnableChEventInt(pTPUE, u8channel, (bool)true); + TPU_E_HWA_EnableMatch(pTPUE, u8channel, (bool)true); + TPU_E_HWA_EnableSrvReq(pTPUE, u8channel, (bool)true); + + return; +} + +/** + * @brief TPU_CaptureMeasPeriodServiceReq + * + */ +void TPU_CaptureMeasPeriodServiceReq(uint8_t u8channel, TPU_CaptureCfgType *p_etpu_config) +{ + TPU_E_Type *const pTPUE = TPU_E_BASE_PTRS; + volatile bool bMeasurement = TPU_E_HWA_GetChEntryTblflag1(pTPUE, u8channel); + + if (TPU_E_HWA_GetChMatchRecLatch1Status(pTPUE, u8channel) == (bool)true) + { + TPU_E_HWA_ClearMatch1Event(pTPUE, u8channel); + TPU_E_HWA_ClearTransDetect1Event(pTPUE, u8channel); + TPU_E_HWA_ClearTransDetect2Event(pTPUE, u8channel); + p_etpu_config->LastTime = TPU_E_HWA_GetER1Val(pTPUE, u8channel); + TPU_E_HWA_SetMatchER1(pTPUE, u8channel, (p_etpu_config->LastTime + p_etpu_config->u32SampleTime)); + TPU_E_HWA_EnableMatch(pTPUE, u8channel, (bool)true); + TPU_E_HWA_ClearChEventISRFlg(pTPUE, (uint8_t)u8channel); + TPU_E_HWA_SetChEntryTblflag1(pTPUE, u8channel, (bool)false); + p_etpu_config->u32PeriodTime = 0; + } + else if (TPU_E_HWA_GetChTransDetectLatch1Status(pTPUE, u8channel) == (bool)true) + { + TPU_E_HWA_ClearTransDetect1Event(pTPUE, u8channel); + TPU_E_HWA_ClearChEventISRFlg(pTPUE, (uint8_t)u8channel); + /* transition happened */ + if (bMeasurement) + { + /* Complete once normal measurement */ + if (TPU_E_HWA_GetCaptureER1Val(pTPUE, u8channel) >= p_etpu_config->LastTime) + { + p_etpu_config->u32PeriodTime = (TPU_E_HWA_GetCaptureER1Val(pTPUE, u8channel) - p_etpu_config->LastTime); + } + else + { + p_etpu_config->u32PeriodTime = (TPU_E_HWA_GetCaptureER1Val(pTPUE, u8channel) + TPU_TCR1_MAXVALUE - p_etpu_config->LastTime + 1U); + } + + TPU_E_HWA_SetChEntryTblflag1(pTPUE, u8channel, (bool)false); + } + /* Start normal measurement */ + p_etpu_config->LastTime = TPU_E_HWA_GetCaptureER1Val(pTPUE, u8channel); + TPU_E_HWA_SetMatchER1(pTPUE, u8channel, (p_etpu_config->LastTime + p_etpu_config->u32SampleTime)); + + /* bMeasurement = active */ + TPU_E_HWA_EnableMatch(pTPUE, u8channel, (bool)true); + TPU_E_HWA_SetChEntryTblflag1(pTPUE, u8channel, (bool)true); + } +} + +/** + * @brief TPU_CaptureMeasActiveLowServiceReq + * + */ +void TPU_CaptureMeasActivePeriodServiceReq(uint8_t u8channel, TPU_CaptureCfgType *p_etpu_config) +{ + TPU_E_Type *const pTPUE = TPU_E_BASE_PTRS; + + if (TPU_E_HWA_GetChMatchRecLatch1Status(pTPUE, u8channel) == (bool)true) + { + TPU_E_HWA_ClearMatch1Event(pTPUE, u8channel); + TPU_E_HWA_ClearTransDetect1Event(pTPUE, u8channel); + TPU_E_HWA_ClearTransDetect2Event(pTPUE, u8channel); + p_etpu_config->LastTime = TPU_E_HWA_GetER1Val(pTPUE, u8channel); + TPU_E_HWA_SetMatchER1(pTPUE, u8channel, (p_etpu_config->LastTime + p_etpu_config->u32SampleTime)); + TPU_E_HWA_EnableMatch(pTPUE, u8channel, (bool)true); + TPU_E_HWA_ClearChEventISRFlg(pTPUE, (uint8_t)u8channel); + p_etpu_config->u32PeriodTime = 0; + p_etpu_config->u32ActiveTime = 0; + bMeasActivePeriodComplete[u8channel] = (bool)false; + } + else if ((TPU_E_HWA_GetChTransDetectLatch1Status(pTPUE, u8channel) == (bool)true) || (TPU_E_HWA_GetChTransDetectLatch2Status(pTPUE, u8channel) == (bool)true)) + { + /* transition1 or 2 happened */ + TPU_E_HWA_ClearTransDetect1Event(pTPUE, u8channel); + TPU_E_HWA_ClearTransDetect2Event(pTPUE, u8channel); + TPU_E_HWA_ClearChEventISRFlg(pTPUE, (uint8_t)u8channel); + + /* ER1 stores TCR1 in IPAC1 edge */ + /* Here calculate period */ + if (bMeasActivePeriodComplete[u8channel]) + { + /* Complete once normal measurement */ + if (TPU_E_HWA_GetCaptureER1Val(pTPUE, u8channel) >= p_etpu_config->StartTime) + { + p_etpu_config->u32PeriodTime = (TPU_E_HWA_GetCaptureER1Val(pTPUE, u8channel) - p_etpu_config->StartTime); + } + else + { + p_etpu_config->u32PeriodTime = (TPU_E_HWA_GetCaptureER1Val(pTPUE, u8channel) + TPU_TCR1_MAXVALUE - p_etpu_config->StartTime + 1); + } + + /* MeasurementComplete = inactive */ + bMeasActivePeriodComplete[u8channel] = (bool)false; + } + + /* Start normal low measurement */ + p_etpu_config->LastTime = TPU_E_HWA_GetCaptureER1Val(pTPUE, u8channel); + p_etpu_config->StartTime = p_etpu_config->LastTime; + + /* ER2 stores TCR1 in IPAC2 edge */ + /* Complete once normal measurement */ + if (TPU_E_HWA_GetCaptureER2Val(pTPUE, u8channel) >= p_etpu_config->LastTime) + { + p_etpu_config->u32ActiveTime = (TPU_E_HWA_GetCaptureER2Val(pTPUE, u8channel) - p_etpu_config->LastTime); + } + else + { + p_etpu_config->u32ActiveTime = (TPU_E_HWA_GetCaptureER2Val(pTPUE, u8channel) + TPU_TCR1_MAXVALUE - p_etpu_config->LastTime + 1); + } + + /* MeasurementComplete = active */ + bMeasActivePeriodComplete[u8channel] = (bool)true; + + /* Waiting for first IPAC1 edge */ + p_etpu_config->LastTime = TPU_E_HWA_GetCaptureER2Val(pTPUE, u8channel); + TPU_E_HWA_SetMatchER1(pTPUE, u8channel, (p_etpu_config->LastTime + p_etpu_config->u32SampleTime)); + TPU_E_HWA_EnableMatch(pTPUE, u8channel, (bool)true); + } +} diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_trgsel.c b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_trgsel.c new file mode 100644 index 0000000..2043fe6 --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_trgsel.c @@ -0,0 +1,314 @@ +/** + * @file fc7xxx_driver_trgsel.c + * @author Flagchip0103 + * @brief FC7xxx TRGSEL driver source code + * @version 0.1.0 + * @date 2023-12-19 + * + * @copyright Copyright (c) 2023 Flagchip Semiconductors Co., Ltd. + * + */ +/* ******************************************************************************** + * Revision History: + * + * Version Date Initials CR# Descriptions + * --------- ---------- ------------ ---------- --------------- + * 0.1.0 2023-12-19 Flagchip0103 N/A First version for FC7240 + ******************************************************************************** */ + +#include + +#include "fc7xxx_driver_trgsel.h" +#include "HwA_trgsel.h" +#include "HwA_scm.h" + +/** + * @brief Number of target outputs of TrgSel 0 + * + */ +#define TRGSEL0_NUM_OUTPUTS 38U + +/** + * @brief Number of target outputs of TrgSel 1 + * + */ +#define TRGSEL1_NUM_OUTPUTS 28U + +/** + * @brief Number of target outputs of TrgSel 2 + * + */ +#define TRGSEL2_NUM_OUTPUTS 30U + +/** + * @brief Number of target outputs of TrgSel 3 + * + */ +#define TRGSEL3_NUM_OUTPUTS 16U + +/** + * @brief Number of target outputs of TrgSel 4 + * + */ +#define TRGSEL4_NUM_OUTPUTS 10U + +/** + * @brief Number of target outputs of TrgSel 5 + * + */ +#define TRGSEL5_NUM_OUTPUTS 13U + +/** + * @brief Number of input sources of TrgSel 0 + * + */ +#define TRGSEL0_NUM_SOURCES 128U + +/** + * @brief Number of input sources of TrgSel 1 + * + */ +#define TRGSEL1_NUM_SOURCES 94U + +/** + * @brief Number of input sources of TrgSel 2 + * + */ +#define TRGSEL2_NUM_SOURCES 32U + +/** + * @brief Number of input sources of TrgSel 3 + * + */ +#define TRGSEL3_NUM_SOURCES 62U + +/** + * @brief Number of input sources of TrgSel 4 + * + */ +#define TRGSEL4_NUM_SOURCES 112U + +/** + * @brief Number of input sources of TrgSel 5 + * + */ +#define TRGSEL5_NUM_SOURCES 64U + +#define TRGSEL_NUM_SW_TRG_CHANNELS 8U + +static TRGSEL_Type *const s_trgselBase[TRGSEL_INSTANCE_COUNT] = TRGSEL_BASE_PTRS; + +#ifndef NDEBUG +/** + * @brief Check whether the TRGSEL target is valid for the TRGSEL instance + * + * @param eInstance the selected TRGSEL instance + * @param eTarget the target value to check + * @return true the TRGSEL target is valid + * @return false the TRGSEL target is invalid + */ +static inline bool TRGSEL_IsValidTarget(const TRGSEL_InstanceType eInstance, const TRGSEL_TargetType eTarget); + +/** + * @brief Check whether the TRGSEL source is valid for the TRGSEL instance + * + * @param eInstance the selected TRGSEL instance + * @param eSource the source value to check + * @return true the TRGSEL source is valid + * @return false the TRGSEL source is invalid + */ +static inline bool TRGSEL_IsValidSource(const TRGSEL_InstanceType eInstance, const TRGSEL_SourceType eSource); + +static inline bool TRGSEL_IsValidTarget(const TRGSEL_InstanceType eInstance, const TRGSEL_TargetType eTarget) +{ + bool bRet = false; + switch (eInstance) + { + case TRGSEL_INSTANCE_0: + { + bRet = (bool)((eTarget < TRGSEL0_NUM_OUTPUTS) ? true : false); + break; + } + + case TRGSEL_INSTANCE_1: + { + bRet = (bool)((eTarget < TRGSEL1_NUM_OUTPUTS) ? true : false); + break; + } + + case TRGSEL_INSTANCE_2: + { + bRet = (bool)((eTarget < TRGSEL2_NUM_OUTPUTS) ? true : false); + break; + } + + case TRGSEL_INSTANCE_3: + { + bRet = (bool)((eTarget < TRGSEL3_NUM_OUTPUTS) ? true : false); + break; + } + + case TRGSEL_INSTANCE_4: + { + bRet = (bool)((eTarget < TRGSEL4_NUM_OUTPUTS) ? true : false); + break; + } + + case TRGSEL_INSTANCE_5: + { + bRet = (bool)((eTarget < TRGSEL5_NUM_OUTPUTS) ? true : false); + break; + } + + default: + break; + } + return bRet; +} + +static inline bool TRGSEL_IsValidSource(const TRGSEL_InstanceType eInstance, const TRGSEL_SourceType eSource) +{ + bool bRet = false; + switch (eInstance) + { + case TRGSEL_INSTANCE_0: + { + bRet = (bool)((eSource < TRGSEL0_NUM_SOURCES) ? true : false); + break; + } + + case TRGSEL_INSTANCE_1: + { + bRet = (bool)((eSource < TRGSEL1_NUM_SOURCES) ? true : false); + break; + } + + case TRGSEL_INSTANCE_2: + { + bRet = (bool)((eSource < TRGSEL2_NUM_SOURCES) ? true : false); + break; + } + + case TRGSEL_INSTANCE_3: + { + bRet = (bool)((eSource < TRGSEL3_NUM_SOURCES) ? true : false); + break; + } + + case TRGSEL_INSTANCE_4: + { + bRet = (bool)((eSource < TRGSEL4_NUM_SOURCES) ? true : false); + break; + } + + case TRGSEL_INSTANCE_5: + { + bRet = (bool)((eSource < TRGSEL5_NUM_SOURCES) ? true : false); + break; + } + + default: + break; + } + return bRet; +} +#endif + +TRGSEL_SourceType TRGSEL_GetTargetTriggerSource(const TRGSEL_InstanceType eInstance, const TRGSEL_TargetType eTarget) +{ + DEV_ASSERT(eInstance < TRGSEL_INSTANCE_COUNT); + DEV_ASSERT(TRGSEL_IsValidTarget(eInstance, eTarget)); + + const TRGSEL_Type *const pTrgsel = s_trgselBase[eInstance]; + + uint32_t u32Tmp = TRGSEL_HWA_GetTargetTriggerSource(pTrgsel, eTarget); + + return (TRGSEL_SourceType)u32Tmp; +} + +void TRGSEL_SetTargetTriggerSource(const TRGSEL_InstanceType eInstance, const TRGSEL_TargetType eTarget, + const TRGSEL_SourceType eSource) +{ + DEV_ASSERT(eInstance < TRGSEL_INSTANCE_COUNT); + DEV_ASSERT(TRGSEL_IsValidTarget(eInstance, eTarget)); + DEV_ASSERT(TRGSEL_IsValidSource(eInstance, eSource)); + DEV_ASSERT(TRGSEL_GetTargetLockStatus(eInstance, eTarget) != true); + + TRGSEL_Type *const pTrgsel = s_trgselBase[eInstance]; + + TRGSEL_HWA_SetTargetTriggerSource(pTrgsel, eTarget, eSource); +} + +bool TRGSEL_GetTargetLockStatus(const TRGSEL_InstanceType eInstance, const TRGSEL_TargetType eTarget) +{ + DEV_ASSERT(eInstance < TRGSEL_INSTANCE_COUNT); + DEV_ASSERT(TRGSEL_IsValidTarget(eInstance, eTarget)); + + const TRGSEL_Type *const pTrgsel = s_trgselBase[eInstance]; + + return TRGSEL_HWA_GetTargetLockStatus(pTrgsel, eTarget); +} + +void TRGSEL_LockTargetTriggerSource(const TRGSEL_InstanceType eInstance, const TRGSEL_TargetType eTarget) +{ + DEV_ASSERT(eInstance < TRGSEL_INSTANCE_COUNT); + DEV_ASSERT(TRGSEL_IsValidTarget(eInstance, eTarget)); + + TRGSEL_Type *const pTrgsel = s_trgselBase[eInstance]; + + if (TRGSEL_GetTargetLockStatus(eInstance, eTarget) != true) + { + TRGSEL_HWA_LockTargetTriggerSource(pTrgsel, eTarget); + } +} + +void TRGSEL_GenerateSwTrigger(const TRGSEL_SwTriggerChannelType eChannel) +{ + DEV_ASSERT(eChannel < TRGSEL_NUM_SW_TRG_CHANNELS); + + switch (eChannel) + { + case TRGSEL_SW_TRIGGER_CHANNEL_0: + { + SCM_HWA_SetSwTrigx_Trgsel04(SCM_SW_TRIG_0); + break; + } + case TRGSEL_SW_TRIGGER_CHANNEL_1: + { + SCM_HWA_SetSwTrigx_Trgsel04(SCM_SW_TRIG_1); + break; + } + case TRGSEL_SW_TRIGGER_CHANNEL_2: + { + SCM_HWA_SetSwTrigx_Trgsel04(SCM_SW_TRIG_2); + break; + } + case TRGSEL_SW_TRIGGER_CHANNEL_3: + { + SCM_HWA_SetSwTrigx_Trgsel04(SCM_SW_TRIG_3); + break; + } + case TRGSEL_SW_TRIGGER_CHANNEL_4: + { + SCM_HWA_SetSwTrigx_Trgsel15(SCM_SW_TRIG_4); + break; + } + case TRGSEL_SW_TRIGGER_CHANNEL_5: + { + SCM_HWA_SetSwTrigx_Trgsel15(SCM_SW_TRIG_5); + break; + } + case TRGSEL_SW_TRIGGER_CHANNEL_6: + { + SCM_HWA_SetSwTrigx_Trgsel15(SCM_SW_TRIG_6); + break; + } + case TRGSEL_SW_TRIGGER_CHANNEL_7: + { + SCM_HWA_SetSwTrigx_Trgsel15(SCM_SW_TRIG_7); + break; + } + default: + break; + } +} diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_tstmp.c b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_tstmp.c new file mode 100644 index 0000000..0856be5 --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_tstmp.c @@ -0,0 +1,420 @@ +/** + * @file fc7xxx_driver_tstmp.c + * @author Flagchip + * @brief FC7xxx TSTMP driver source code + * @version 0.1.0 + * @date 2024-01-14 + * + * @copyright Copyright (c) 2022 Flagchip Semiconductors Co., Ltd. + * + * @details + */ +/******************************************************************************** +* Revision History: +* +* Version Date Initials CR# Descriptions +* --------- ---------- ------------ ---------- --------------- +* 0.1.0 2024-01-14 Flagchip0122 N/A FC7xxx internal release version +********************************************************************************/ + +#include "fc7xxx_driver_tstmp.h" +#include "interrupt_manager.h" + +/** @brief Tstmp instance list */ +static TSTMP_Type *s_pTstmpPtrs[TSTMP_INSTANCE_COUNT] = TSTMP_BASE_PTRS; +/** @brief Tstmp user defined interrupt function */ +static TSTMP_InterruptCallBackType s_pTstmpModulateNotifyPtr[TSTMP_INSTANCE_COUNT][MAX_MOD_NUMBER] = {NULL}; + +/** @brief TSTMP0 interrupt entry */ +void TSTMP0_IRQHandler(void); +/** @brief TSTMP1 interrupt entry */ +void TSTMP1_IRQHandler(void); + +/** @brief TSTMP common interrupt function */ +static void Tstmp_CommonProcessInterrupt(const TSTMP_InstanceType eInstance, const TSTMP_ModulateType eIntModulate); + +/** + * @brief Initialize TSTMP instance + * + * @param eInstance TSTMP instance + * @param pInitStruct TSTMP initialization structure + * @return TSTMP_StatusType TSTMP return type + * @note TSTMP0 clock source is 1MHZ and TSTMP1,TSTMP2,TSTMP3 clock source is bus clock + */ +TSTMP_StatusType TSTMP_Init(const TSTMP_InstanceType eInstance, const TSTMP_InitType *const pInitStruct) +{ + TSTMP_Type *pTstmp; + TSTMP_StatusType eRet = TSTMP_STATUS_SUCCESS; + if ((NULL == pInitStruct) || (eInstance >= TSTMP_INSTANCE_MAX)) + { + eRet = TSTMP_STATUS_PARAM_INVALID; + } + else + { + pTstmp = s_pTstmpPtrs[eInstance]; + /* clear MOD(n) match flag */ + TSTMP_HWA_ClearMod0MatchFlag(pTstmp); + TSTMP_HWA_ClearAllMod123MatchFlag(pTstmp); + + for(uint8_t i = 0; i < MAX_MOD_NUMBER; i++) + { + TSTMP_HWA_SelectClkSource(pTstmp, (TSTMP_ModulateType)i, pInitStruct->pClk[i]); + } + /* set MOD0 match value */ + TSTMP_HWA_SetModMatchValue(pTstmp, TSTMP_MOD0, pInitStruct->u32Modulate0Value); + /* set MOD1 match value */ + TSTMP_HWA_SetModMatchValue(pTstmp, TSTMP_MOD1, pInitStruct->u32Modulate1Value); + /* set MOD2 match value */ + TSTMP_HWA_SetModMatchValue(pTstmp, TSTMP_MOD2, pInitStruct->u32Modulate2Value); + /* set MOD3 match value */ + TSTMP_HWA_SetModMatchValue(pTstmp, TSTMP_MOD3, pInitStruct->u32Modulate3Value); + } + + return eRet; +} + +/** + * @brief Set the Counting mode of modulate timer counter0,1,2,3 + * + * @param eInstance TSTMP instance + * @param eCounter0Mode Counting mode of counter0 + * @param eCounter1Mode Counting mode of counter1 + * @param eCounter2Mode Counting mode of counter2 + * @param eCounter3Mode Counting mode of counter3 + * @return TSTMP_StatusType TSTMP return type + */ +TSTMP_StatusType TSTMP_SetCounterRunningMode(const TSTMP_InstanceType eInstance, const TSTMP_ModeCounterRunningMode eCounter0Mode, + const TSTMP_ModeCounterRunningMode eCounter1Mode,const TSTMP_ModeCounterRunningMode eCounter2Mode, + const TSTMP_ModeCounterRunningMode eCounter3Mode) +{ + TSTMP_Type *pTstmp; + TSTMP_StatusType eRet = TSTMP_STATUS_SUCCESS; + if (eInstance >= TSTMP_INSTANCE_MAX) + { + eRet = TSTMP_STATUS_PARAM_INVALID; + } + if( (eCounter0Mode > TSTMP_MODE_PERIOD_RUNNING) || (eCounter1Mode > TSTMP_MODE_PERIOD_RUNNING) || + (eCounter2Mode > TSTMP_MODE_PERIOD_RUNNING) || (eCounter3Mode > TSTMP_MODE_PERIOD_RUNNING)) + { + eRet = TSTMP_STATUS_PARAM_INVALID; + } + if(eRet == TSTMP_STATUS_SUCCESS) + { + pTstmp = s_pTstmpPtrs[eInstance]; + TSTMP_HWA_SetModCounterMode(pTstmp,TSTMP_MOD0, eCounter0Mode); + TSTMP_HWA_SetModCounterMode(pTstmp,TSTMP_MOD1, eCounter1Mode); + TSTMP_HWA_SetModCounterMode(pTstmp,TSTMP_MOD2, eCounter2Mode); + TSTMP_HWA_SetModCounterMode(pTstmp,TSTMP_MOD3, eCounter3Mode); + } + return eRet; +} +/** + * @brief De-initialize TSTMP instance + * + * @param eInstance TSTMP instance + * @return TSTMP_StatusType TSTMP return type + */ +TSTMP_StatusType TSTMP_Deinit(const TSTMP_InstanceType eInstance) +{ + TSTMP_Type *pTstmp; + TSTMP_StatusType eRet = TSTMP_STATUS_SUCCESS; + uint8_t u8Index; + if (eInstance >= TSTMP_INSTANCE_MAX) + { + eRet = TSTMP_STATUS_PARAM_INVALID; + } + else + { + pTstmp = s_pTstmpPtrs[eInstance]; + for (u8Index = 0U; u8Index < MAX_MOD_NUMBER; u8Index++) + { + /* Disable TSTMP MOD(n) match interrupt */ + TSTMP_HWA_DisableModMatchInterrupt(pTstmp, (TSTMP_ModulateType)u8Index); + /* Disable TSTMP MOD(n) counter */ + TSTMP_HWA_DisableModCounter(pTstmp, (TSTMP_ModulateType)u8Index); + /* Clear TSTMP MOD(n) match value set*/ + TSTMP_HWA_SetModMatchValue(pTstmp, (TSTMP_ModulateType)u8Index, (uint32_t)0U); + s_pTstmpModulateNotifyPtr[eInstance][u8Index] = NULL; + } + /* clear MOD(n) match flag */ + TSTMP_HWA_ClearMod0MatchFlag(pTstmp); + TSTMP_HWA_ClearAllMod123MatchFlag(pTstmp); + } + return eRet; +} + +/** + * @brief Initialize TSTMP interrupt functionality + * + * @param eInstance TSTMP instance + * @param pIntStruct TSTMP interrupt structure + * @return TSTMP_StatusType TSTMP return type + */ +TSTMP_StatusType TSTMP_InitInterrupt(const TSTMP_InstanceType eInstance, const TSTMP_IntType *const pIntStruct) +{ + TSTMP_StatusType eRet = TSTMP_STATUS_SUCCESS; + TSTMP_Type *pTstmp; + uint8_t u8Index; + if ((NULL == pIntStruct) || (eInstance >= TSTMP_INSTANCE_MAX)) + { + eRet = TSTMP_STATUS_PARAM_INVALID; + } + else + { + pTstmp = s_pTstmpPtrs[eInstance]; + for (u8Index = 0U; u8Index < MAX_MOD_NUMBER; u8Index++) + { + if (pIntStruct->bModulateIntEn[u8Index] == true) + { + /* Enable TSTMP MOD(n) match interrupt */ + TSTMP_HWA_EnableModMatchInterrupt(pTstmp, (TSTMP_ModulateType)u8Index); + s_pTstmpModulateNotifyPtr[eInstance][u8Index] = pIntStruct->pIsrModNotify[u8Index]; + } + else + { + /* Disable TSTMP MOD(n) match interrupt */ + TSTMP_HWA_DisableModMatchInterrupt(pTstmp, (TSTMP_ModulateType)u8Index); + s_pTstmpModulateNotifyPtr[eInstance][u8Index] = NULL; + } + } + } + return eRet; +} + +/** + * @brief Enable TSTMP interrupt function + * + * @param eInstance TSTMP instance + * @param eMod TSTMP modulate enumeration + * @return TSTMP_StatusType TSTMP return type + */ +TSTMP_StatusType TSTMP_EnableInterrupt(const TSTMP_InstanceType eInstance, const TSTMP_ModulateType eMod) +{ + TSTMP_StatusType eRet = TSTMP_STATUS_SUCCESS; + TSTMP_Type *pTstmp; + if (((uint8_t)eMod >= MAX_MOD_NUMBER) || (eInstance >= TSTMP_INSTANCE_MAX)) + { + eRet = TSTMP_STATUS_PARAM_INVALID; + } + else + { + pTstmp = s_pTstmpPtrs[eInstance]; + /* Enable TSTMP MOD(n) match interrupt */ + TSTMP_HWA_EnableModMatchInterrupt(pTstmp, eMod); + } + + return eRet; +} + +/** + * @brief Disable TSTMP interrupt function + * + * @param eInstance TSTMP instance + * @param eMod TSTMP modulate enumeration + * @return TSTMP_StatusType TSTMP return type + */ +TSTMP_StatusType TSTMP_DisableInterrupt(const TSTMP_InstanceType eInstance, const TSTMP_ModulateType eMod) +{ + TSTMP_StatusType eRet = TSTMP_STATUS_SUCCESS; + TSTMP_Type *pTstmp; + if (((uint8_t)eMod >= MAX_MOD_NUMBER) || (eInstance >= TSTMP_INSTANCE_MAX)) + { + eRet = TSTMP_STATUS_PARAM_INVALID; + } + else + { + pTstmp = s_pTstmpPtrs[eInstance]; + /* Disable TSTMP MOD(n) match interrupt */ + TSTMP_HWA_DisableModMatchInterrupt(pTstmp, eMod); + } + + return eRet; +} + +/** + * @brief Get TSTMP count value + * + * @param eInstance TSTMP instance + * @param u64TstmpValue in/out value + * @return TSTMP_StatusType TSTMP return type + */ +TSTMP_StatusType TSTMP_GetTstmpValue(const TSTMP_InstanceType eInstance, uint64_t *const u64TstmpValue) +{ + TSTMP_StatusType eRet = TSTMP_STATUS_SUCCESS; + TSTMP_Type *pTstmp; + if ((NULL == u64TstmpValue) || (eInstance >= TSTMP_INSTANCE_MAX)) + { + eRet = TSTMP_STATUS_PARAM_INVALID; + } + else + { + pTstmp = s_pTstmpPtrs[eInstance]; + *u64TstmpValue = TSTMP_HWA_ReadTstmpValue(pTstmp); + } + return eRet; +} + +/** + * @brief Update Modulate configuration + * + * @param eInstance TSTMP instance + * @param pUpdateStruct TSTMP update structure pointer + * @return TSTMP_StatusType TSTMP return type + */ +TSTMP_StatusType TSTMP_UpdateMod(const TSTMP_InstanceType eInstance, const TSTMP_UpdateType *const pUpdateStruct) +{ + TSTMP_StatusType eRet = TSTMP_STATUS_SUCCESS; + TSTMP_Type *pTstmp; + bool bIntEnStatus; + if ((NULL == pUpdateStruct) || (eInstance >= TSTMP_INSTANCE_MAX)) + { + eRet = TSTMP_STATUS_PARAM_INVALID; + } + else + { + pTstmp = s_pTstmpPtrs[eInstance]; + /* Clear MOD(n) interrupt flag */ + if (TSTMP_MOD0 == pUpdateStruct->eMod) + { + TSTMP_HWA_ClearMod0MatchFlag(pTstmp); + } + else + { + TSTMP_HWA_ClearSingleMod123MatchFlag(pTstmp, pUpdateStruct->eMod); + } + bIntEnStatus = (bool)(((uint32_t)0U == (TSTMP_HWA_ReadTstmpInterruptEnable(pTstmp) & + TSTMP_MOD_INTEN_MOD0_INTEN_MASK << (pUpdateStruct->eMod))) ? true : false); + if ((pUpdateStruct->bIntEn) == true) + { + if(bIntEnStatus == true) + { + /* Enable TSTMP MOD(n) match interrupt */ + TSTMP_HWA_EnableModMatchInterrupt(pTstmp, pUpdateStruct->eMod); + if (NULL != pUpdateStruct->pIsrModNotify) + { + s_pTstmpModulateNotifyPtr[eInstance][pUpdateStruct->eMod] = pUpdateStruct->pIsrModNotify; + } + } + }else + { + if(bIntEnStatus == false) + { + /* Disable TSTMP MOD(n) match interrupt */ + TSTMP_HWA_DisableModMatchInterrupt(pTstmp, pUpdateStruct->eMod); + } + } + /* set MOD(n) match value */ + TSTMP_HWA_SetModMatchValue(pTstmp, pUpdateStruct->eMod, pUpdateStruct->u32ModValue); + } + return eRet; +} + +/** + * @brief Set counter MOD(n) counting on or off + * + * @param eInstance TSTMP instance + * @param eMod MOD number + * @param bCounterEn Whether enable the selected Modulate Timer Counter + * @return TSTMP_StatusType TSTMP return type + */ +TSTMP_StatusType TSTMP_SetModCountConfig(const TSTMP_InstanceType eInstance, const TSTMP_ModulateType eMod, const bool bCounterEn) +{ + TSTMP_StatusType eRet = TSTMP_STATUS_SUCCESS; + TSTMP_Type *pTstmp; + if (eInstance >= TSTMP_INSTANCE_MAX || eMod > TSTMP_MOD3) + { + eRet = TSTMP_STATUS_PARAM_INVALID; + } + else + { + pTstmp = s_pTstmpPtrs[eInstance]; + if(bCounterEn) + { + TSTMP_HWA_EnableModCounter(pTstmp, eMod); + }else + { + TSTMP_HWA_DisableModCounter(pTstmp, eMod); + } + } + return eRet; +} + +/** + * @brief TSTMP common interrupt function + * + * @param eInstance TSTMP instance + * @param eIntModulate TSTMP modulate + */ +static void Tstmp_CommonProcessInterrupt(const TSTMP_InstanceType eInstance, const TSTMP_ModulateType eIntModulate) +{ + if (NULL != s_pTstmpModulateNotifyPtr[eInstance][eIntModulate]) + { + s_pTstmpModulateNotifyPtr[eInstance][eIntModulate](); + } +} + +/** + * @brief TSTMP0 interrupt handler entry + * + */ +void TSTMP0_IRQHandler(void) +{ + uint32_t u32TstmpStatus = TSTMP_HWA_ReadModMatchFlag(TSTMP0); + if ((u32TstmpStatus & TSTMP_MOD_STATUS_MOD0_MATCH_MASK)>>TSTMP_MOD_STATUS_MOD0_MATCH_SHIFT == 1U) + { + Tstmp_CommonProcessInterrupt(TSTMP_INSTANCE_0, TSTMP_MOD0); + /* Clear MOD0 interrupt flag */ + TSTMP_HWA_ClearMod0MatchFlag(TSTMP0); + } + if ((u32TstmpStatus & TSTMP_MOD_STATUS_MOD1_MATCH_MASK)>>TSTMP_MOD_STATUS_MOD1_MATCH_SHIFT == 1U) + { + Tstmp_CommonProcessInterrupt(TSTMP_INSTANCE_0, TSTMP_MOD1); + /* Clear MOD1 interrupt flag */ + TSTMP_HWA_ClearSingleMod123MatchFlag(TSTMP0, TSTMP_MOD1); + } + if ((u32TstmpStatus & TSTMP_MOD_STATUS_MOD2_MATCH_MASK)>>TSTMP_MOD_STATUS_MOD2_MATCH_SHIFT == 1U) + { + Tstmp_CommonProcessInterrupt(TSTMP_INSTANCE_0, TSTMP_MOD2); + /* Clear MOD2 interrupt flag */ + TSTMP_HWA_ClearSingleMod123MatchFlag(TSTMP0, TSTMP_MOD2); + } + if ((u32TstmpStatus & TSTMP_MOD_STATUS_MOD3_MATCH_MASK)>>TSTMP_MOD_STATUS_MOD3_MATCH_SHIFT == 1U) + { + Tstmp_CommonProcessInterrupt(TSTMP_INSTANCE_0, TSTMP_MOD3); + /* Clear MOD3 interrupt flag */ + TSTMP_HWA_ClearSingleMod123MatchFlag(TSTMP0, TSTMP_MOD3); + } +} + +/** + * @brief TSTMP1 interrupt handler entry + * + */ +void TSTMP1_IRQHandler(void) +{ + uint32_t u32TstmpStatus = TSTMP_HWA_ReadModMatchFlag(TSTMP1); + if ((u32TstmpStatus & TSTMP_MOD_STATUS_MOD0_MATCH_MASK)>>TSTMP_MOD_STATUS_MOD0_MATCH_SHIFT == 1U) + { + Tstmp_CommonProcessInterrupt(TSTMP_INSTANCE_1, TSTMP_MOD0); + /* Clear MOD0 interrupt flag */ + TSTMP_HWA_ClearMod0MatchFlag(TSTMP1); + } + if ((u32TstmpStatus & TSTMP_MOD_STATUS_MOD1_MATCH_MASK)>>TSTMP_MOD_STATUS_MOD1_MATCH_SHIFT == 1U) + { + Tstmp_CommonProcessInterrupt(TSTMP_INSTANCE_1, TSTMP_MOD1); + /* Clear MOD1 interrupt flag */ + TSTMP_HWA_ClearSingleMod123MatchFlag(TSTMP1, TSTMP_MOD1); + } + if ((u32TstmpStatus & TSTMP_MOD_STATUS_MOD2_MATCH_MASK)>>TSTMP_MOD_STATUS_MOD2_MATCH_SHIFT == 1U) + { + Tstmp_CommonProcessInterrupt(TSTMP_INSTANCE_1, TSTMP_MOD2); + /* Clear MOD2 interrupt flag */ + TSTMP_HWA_ClearSingleMod123MatchFlag(TSTMP1, TSTMP_MOD2); + } + if ((u32TstmpStatus & TSTMP_MOD_STATUS_MOD3_MATCH_MASK)>>TSTMP_MOD_STATUS_MOD3_MATCH_SHIFT == 1U) + { + Tstmp_CommonProcessInterrupt(TSTMP_INSTANCE_1, TSTMP_MOD3); + /* Clear MOD3 interrupt flag */ + TSTMP_HWA_ClearSingleMod123MatchFlag(TSTMP1, TSTMP_MOD3); + } +} diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_wdog.c b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_wdog.c new file mode 100644 index 0000000..36b04b3 --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_wdog.c @@ -0,0 +1,131 @@ +/** + * @file fc7xxx_driver_wdog.c + * @author Flagchip + * @brief FC7xxx WDOG driver source code + * @version 0.1.0 + * @date 2023-12-29 + * + * @copyright Copyright (c) 2022 Flagchip Semiconductors Co., Ltd. + * + */ + +/******************************************************************************** +* Revision History: +* +* Version Date Initials CR# Descriptions +* --------- ---------- ------------ ---------- --------------- +* 0.1.0 2023-12-29 qxw0074 N/A First version for FC7240 +********************************************************************************/ + +#include "fc7xxx_driver_wdog.h" + +/** + * @brief UNLOCK and REFRESH CMD For MPW FC100. this may not match with FC4150 user manual + */ +#define WDOG_UNLOCK_CMD (uint32_t)(0x08181982U) +#define WDOG_REFRESH_CMD (uint32_t)(0x20CFFC20U) + +static WDOG_Type *const s_apWdogBase[WDOG_INSTANCE_COUNT] = WDOG_BASE_PTRS; + +static WDOG_IRQ_Callback aIRQCallback[WDOG_INSTANCE_MAX] = {0U}; + +void WDOG0_IRQHandler(void); +void WDOG1_IRQHandler(void); +/** + * @brief unlock the wdog before Watch dog reconfigure set. + * @param instance: WDOG module instance: WDOG0/WDOG1 defined in FC4150. + */ +void WDOG_Unlock(WDOG_InstanceType eInstance) +{ + WDOG_Type *pWdog = s_apWdogBase[eInstance]; + WDOG_HWA_SetCounter(pWdog,WDOG_UNLOCK_CMD); +} + +/** + * @brief feed the watch dog by writing typical cmd to counter. + * @param instance: WDOG module instance: WDOG0/WDOG1 defined in FC4150. + */ +void WDOG_Refresh(WDOG_InstanceType eInstance) +{ + WDOG_Type *pWdog = s_apWdogBase[eInstance]; + WDOG_HWA_SetCounter(pWdog,WDOG_REFRESH_CMD); +} + +/** + * @brief Initialize the WDOG configuration setting. * + * @param pWdogCfg: point to WDOG init module type. + */ +void WDOG_Init(WDOG_InstanceType eInstance,WDOG_CfgType* pWdogCfg) +{ + WDOG_Type *pWdog = s_apWdogBase[eInstance]; + uint32_t u32Temp = 0U; + + /* Disable the global interrupt */ + __disable_irq(); + + u32Temp = WDOG_CS_WIN(pWdogCfg->bWinEnable) | WDOG_CS_PRESCALER(pWdogCfg->bPrescalerEnable) | + WDOG_CS_CLK_SEL(pWdogCfg->eClkSource) | WDOG_CS_TST(pWdogCfg->eTesttype) | + WDOG_CS_DBG(pWdogCfg->bEnableInDebug) | WDOG_CS_UPDATE_MASK | WDOG_CS_ENABLE_MASK | + WDOG_CS_WAIT(pWdogCfg->bEnableInWait) | WDOG_CS_STOP(pWdogCfg->bEnableInStop); + if(WDOG_REACTION_NO_INT != pWdogCfg->eTimeoutReaction) + { + u32Temp |= (WDOG_CS_INT_MASK | WDOG_CS_DLY_CNT_MSB(pWdogCfg->eTimeoutReaction)); + } + else + { + //Do nothing. Keep disabling the wdog interrupt and no reset dealy. + } + + WDOG_Unlock(eInstance); + + while (WDOG_HWA_GetUnlockStatus(pWdog) == false) + { + /* 0 indicate WDOG locked. Wait until registers are unlocked */ + } + + WDOG_HWA_SetCs(pWdog,u32Temp); + + WDOG_Unlock(eInstance); + + while (WDOG_HWA_GetUnlockStatus(pWdog) == false) + { + /* 0 indicate WDOG locked. Wait until registers are unlocked */ + } + + /* configure the timeout value */ + WDOG_HWA_SetTimeout(pWdog,pWdogCfg->u16TimeoutValue); + + WDOG_Unlock(eInstance); + + while (WDOG_HWA_GetUnlockStatus(pWdog) == false) + { + /* 0 indicate WDOG locked. Wait until registers are unlocked */ + } + /* configure window value */ + WDOG_HWA_SetWindow(pWdog,pWdogCfg->u16WindowValue); + + aIRQCallback[eInstance] = pWdogCfg->pISRCallback; + + /* Enable the global interrupt */ + __enable_irq(); + + +} + +void WDOG0_IRQHandler(void) +{ + WDOG_HWA_ClearInterruptFlag(WDOG0); + if(NULL != aIRQCallback[WDOG_INSTANCE_0]) + { + (aIRQCallback[WDOG_INSTANCE_0])(); + } +} + +void WDOG1_IRQHandler(void) +{ + WDOG_HWA_ClearInterruptFlag(WDOG1); + if(NULL != aIRQCallback[WDOG_INSTANCE_1]) + { + (aIRQCallback[WDOG_INSTANCE_1])(); + } +} diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_wku.c b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_wku.c new file mode 100644 index 0000000..ec16de6 --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/Src/fc7xxx_driver_wku.c @@ -0,0 +1,97 @@ +/** + * @file fc7xxx_driver_wku.c + * @author Flagchip + * @brief FC7xxx WKU driver type definition and API + * @version 0.1.0 + * @date 2023-02-13 + * + * @copyright Copyright (c) 2023 Flagchip Semiconductors Co., Ltd. + * + * @details + */ +/******************************************************************************** +* Revision History: +* +* Version Date Initials CR# Descriptions +* --------- ---------- ------------ ---------- --------------- +* 0.1.0 2024-01-05 Flagchip055 N/A FC7240 First version +********************************************************************************/ +#include "fc7xxx_driver_wku.h" + +/** + * @brief WKU Enable wakeup source for single input + * + * @param u32Input Number of input, WKU_WakeupInputType type is wakeup source definition + * @return WKU return type + */ +WKU_StatusType WKU_EnableWakeupSource(const uint32_t u32Input) +{ + uint32_t u32TempValue = 0U; + uint8_t u8Index = 0U; + WKU_StatusType eRet = WKU_STATUS_SUCCESS; + + DEV_ASSERT(((u32Input & ~(uint32_t)WKU_INPUT_ALL_MASK) == 0U)); + + u32TempValue = u32Input; + while (u32TempValue) + { + if (1U == (u32TempValue & ((uint32_t)1))) + { + WKU_HWA_EnableWakeupSource((WKU_WakeupInputType)((uint32_t)1 << u8Index)); + } + u32TempValue >>= 1U; + u8Index++; + } + + return eRet; +} + +/** + * @brief WKU Disable wakeup source for single input + * + * @param u32Input Number of input, WKU_WakeupInputType type is wakeup source definition + * @return WKU return type + */ +WKU_StatusType WKU_DisableWakeupSource(const uint32_t u32Input) +{ + uint32_t u32TempValue = 0U; + uint8_t u8Index = 0U; + WKU_StatusType eRet = WKU_STATUS_SUCCESS; + + DEV_ASSERT(((u32Input & ~(uint32_t)WKU_INPUT_ALL_MASK) == 0U)); + + u32TempValue = u32Input; + while (u32TempValue) + { + if (u32TempValue & ((uint32_t)1 << u8Index)) + { + WKU_HWA_DisableWakeupSource((WKU_WakeupInputType)((uint32_t)1 << u8Index)); + } + u32TempValue &= (uint32_t)~((uint32_t)1 << u8Index); + u8Index++; + } + + return eRet; +} + +/** + * @brief WKU get wakeup source + * + * @return output wakeup source + */ +uint32_t WKU_GetWakeupSources(void) +{ + return WKU_HWA_ReadWakeupSource(); +} + +/** + * @brief WKU set wake up delay time + * + * @param u8Delaytime The delay time is 2^(u8Delaytime+3) AON_CLK cycles + */ +void WKU_SetWakeupDelay(uint8_t u8Delaytime) +{ + WKU_HWA_DisableDelayCounter(); + WKU_HWA_SetDelayTime(u8Delaytime); + WKU_HWA_EnableDelayCounter(); +} diff --git a/MODULES/PeripheralDriver_Flagchip_FC7240/modular.json b/MODULES/PeripheralDriver_Flagchip_FC7240/modular.json new file mode 100644 index 0000000..b5604ef --- /dev/null +++ b/MODULES/PeripheralDriver_Flagchip_FC7240/modular.json @@ -0,0 +1,11 @@ +{ + "cmake": { + "inc_dirs": [ + "Inc", + "Inc_src" + ], + "srcs": [ + "Src/**.c" + ] + } +} \ No newline at end of file diff --git a/modular.json b/modular.json new file mode 100644 index 0000000..45c45d2 --- /dev/null +++ b/modular.json @@ -0,0 +1,59 @@ +{ + "dep": [ + + { + "type": "local", + + "dir": "./MODULES/CmakeConfig_GCC_CortexM7" + }, + + { + "type": "local", + + "dir": "./MODULES/CmakeConfig_RandomBuildIdGenerator" + }, + + { + "type": "local", + + "dir": "./MODULES/HwA_Flagchip_FC7240" + }, + + { + "type": "local", + + "dir": "./MODULES/PeripheralDriver_Flagchip_FC7240" + }, + + { + "type": "local", + + "dir": "./MODULES/Device_Flagchip_FC7240" + }, + + { + "type": "local", + + "dir": "./MODULES/FirmwareMetadataSection" + }, + + { + "type": "local", + + "dir": "./MODULES/InternalFlashPage_Flagchip_FC7240" + }, + + { + "type": "local", + + "dir": "./MODULES/BootJump_Flagchip_FC7240" + }, + + + { + "type": "local", + "dir": "APP" + } + ] +} +